# Unable to control more than one object in gazebo with one node

Hey,

I just tried to build up a changing world to train my Turtlebot3 in it. The idea is, that everytime when the robot spawns to (0, 0) again, parts of the layout and obstacles shall change. Here I try to switch positions and movement directions of my three obstacles when the Robot respawns. The problem is, only the first obstacle is moving. The other one don´t move at all. My question is, can I communicate with all obstacles from one node? In the following you can see my node code and a part of the .world file. Node:

#!/usr/bin/env python
import rospy
import time
import random
import math
from gazebo_msgs.msg import ModelState, ModelStates

class Combination():
def __init__(self):
self.pub_model = rospy.Publisher('gazebo/set_model_state', ModelState, queue_size=1)
self.moving()

def moving(self):
state = 0
while not rospy.is_shutdown():
model = rospy.wait_for_message('gazebo/model_states', ModelStates)

for i in range(len(model.name)):
if model.name[i] == 'turtlebot3_burger':
turtlebot_pos= ModelState()
turtlebot_pos.model_name=model.name[i]
turtlebot_pos.pose = model.pose[i]

if abs(turtlebot_pos.pose.position.y)<0.01  and abs(turtlebot_pos.pose.position.x)<0.02:
for i in range(len(model.name)):
if model.name[i] == 'obstacle_1':
a = random.randint(1,2)
obstacle_1 = ModelState()
obstacle_1.model_name = model.name[i]
obstacle_1.pose = model.pose[i]
obstacle_1.twist = model.twist[i]
if a==1:
obstacle_1.pose.position.x=2.5
obstacle_1.pose.position.y=2.5
if obstacle_1.pose.position.y > 2.2:
obstacle_1.twist.linear.y = -0.25
elif obstacle_1.pose.position.y < 2.2 and obstacle_1.pose.position.y > -1.2 and obstacle_1.twist.linear.y <0:
obstacle_1.twist.linear.y = -0.25
elif obstacle_1.pose.position.y < -1.2:
obstacle_1.twist.linear.y = 0.25
elif obstacle_1.pose.position.y < 2.2 and obstacle_1.pose.position.y > -1.2 and obstacle_1.twist.linear.y >0:
obstacle_1.twist.linear.y = 0.25
if a==2:
obstacle_1.pose.position.x=2.5
obstacle_1.pose.position.y=2.5
if obstacle_1.pose.position.x > 2.2:
obstacle_1.twist.linear.x = -0.25
elif obstacle_1.pose.position.x < 2.2 and obstacle_1.pose.position.x > 0 and obstacle_1.twist.linear.x <0:
obstacle_1.twist.linear.x = -0.25
elif obstacle_1.pose.position.x < 0:
obstacle_1.twist.linear.x = 0.25
elif obstacle_1.pose.position.x < 2.2 and obstacle_1.pose.position.x > 0 and obstacle_1.twist.linear.x >0:
obstacle_1.twist.linear.x = 0.25

if model.name[i] == 'obstacle_2':
b = random.randint(1,2)
obstacle_2 = ModelState()
obstacle_2.model_name = model.name[i]
obstacle_2.pose = model.pose[i]
obstacle_2.twist = model.twist[i]
if obstacle_2.pose.position.x > 2.5:
obstacle_2.twist.linear.x = -0.25
elif obstacle_2.pose.position.x < 2.5 and obstacle_2.pose.position.x > -0.5 and obstacle_2.twist.linear.x <0:
obstacle_2.twist.linear.x = -0.25
elif obstacle_2.pse.position.x < -0.5:
obstacle_2.twist.linear.x = 0.25
elif obstacle_2.pose.position.x < 2.5 and obstacle_2.pose.position.x > -0.5 and ...
edit retag close merge delete

Sort by » oldest newest most voted

You have a publisher with the queue size of 1 and you try to publish 3 messages one after another. What happens if you increase the queue size, or add some delay between the obstacle pose publishing?

General recommendation: always start with the minimal working prototype of what you want to do and after you are sure the prototype work, build up onto it. In your case first move the obstacles always the same, just to see you can move them. Then just two random direction to make sure you can change the movement during runtime. And work on every obstacle independently. First make the obstacle 1 move, then add obstacle 2 etc.

When I go through your code, I can see, that the obstacle 1 will always start at [2.5, 2.5] and move either backward (if a==2) or right (if a==1). Rest of the obstacle 1 code branch will never be executed.

As for obstacle 2, I cannot see where it is placed for the first time, but after the first loop, it will be placed at x coordinate 2.5 and there is no if branch for this condition. If the obstacle 2 starts at x coordinate 2.5 the object obstacle_2 will remain the same as it is at every loop.

When you get c==2, the obstacle 3 is set to x = -2.5 but again, there is no if statement that would satisfy this condition, so the obstacle_3 object stays the same. If c==1, you set the y coordinate to 2.5 so only the if obstacle_3.pose.position.y > 2.2: branch can ever be executed.

The idea is interesting, but the code is very ugly. It will be easier for us to help you, if you write clean code.

more

Yes, you can move all the obstacles in a single node. As an example, please refer to this repo and you will get an idea on how to move all the obstacles.

more