Gazebo | Ignition | Community
Ask Your Question
0

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

asked 2019-06-26 04:21:27 -0500

Tima15 gravatar image

updated 2019-06-26 04:22:43 -0500

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 ...
(more)
edit retag flag offensive close merge delete

2 Answers

Sort by » oldest newest most voted
0

answered 2019-07-02 11:29:49 -0500

kumpakri gravatar image

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.

edit flag offensive delete link more
0

answered 2019-06-26 08:31:39 -0500

pmuthu2s gravatar image

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.

edit flag offensive delete link more

Comments

Hey, thanks for your answer. I had a look at the repo and it is roughly the same code. But sometimes, the obstacles in my worlds don´t move. It then happens, that only the first one is moving.

Tima15 gravatar imageTima15 ( 2019-06-27 00:26:44 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2019-06-26 04:21:27 -0500

Seen: 230 times

Last updated: Jul 02 '19