The answer is based on the turtlebot robot, but of course it can be used with any robot(s).
For multiple robots the key point is to manage the namespaces and tf_prefixes. Although usually we will set them to the same value for each robot in this example I will you different for purpose.
In setting up the navigation stack(s) each robot must operate in it's own namespace, but they do have to share the map (and usually robot_description). So the effect we want to achieve is:
/map
/robot1/robot_state_publisher /robot2/robot_state_publisher
/robot1/robot_pose_ekf /robot2/robot_pose_ekf
/robot1/amcl /robot2/amcl
/robot1/move_base /robot2/move_base
Simulation
First of all we have to launch the simulation, in our case gazebo.
To make things more readable I split launch files in few files.
Launch file for one robot. We name it one_robot.launch:
<launch>
<arg name="robot_name"/>
<arg name="init_pose"/>
<node name="spawn_minibot_model" pkg="gazebo" type="spawn_model"
args="$(arg init_pose) -urdf -param /robot_description -model $(arg robot_name)"
respawn="false" output="screen" />
<node pkg="robot_state_publisher" type="state_publisher"
name="robot_state_publisher" output="screen"/>
<!-- The odometry estimator, throttling, fake laser etc. go here -->
<!-- All the stuff as from usual robot launch file -->
</launch>
Two things to mention for above launch file:
- create two arguments to pass for robot initialization: name and position
- notice that -param /robot_description is with the slash i.e. fully-qualified, as it will be shared.
Having the robot declaration we can now play with the namespaces. Your main launch file for
multiple robots should look like (robots.launch):
<launch>
<!-- No namespace here as we will share this description.
Access with slash at the beginning -->
<param name="robot_description"
command="$(find xacro)/xacro.py $(find turtlebot_description)/urdf/turtlebot.urdf.xacro" />
<!-- BEGIN ROBOT 1-->
<group ns="robot1">
<param name="tf_prefix" value="robot1_tf" />
<include file="$(find your_pkg)/launch/one_robot.launch" >
<arg name="init_pose" value="-x 1 -y 1 -z 0" />
<arg name="robot_name" value="Robot1" />
</include>
</group>
<!-- BEGIN ROBOT 2-->
<group ns="robot2">
<param name="tf_prefix" value="robot2_tf" />
<include file="$(find your_pkg)/launch/one_robot.launch" >
<arg name="init_pose" value="-x -1 -y 1 -z 0" />
<arg name="robot_name" value="Robot2" />
</include>
</group>
</launch>
Last thing of course is to include it in your simulation launch file:
<launch>
<param name="/use_sim_time" value="true" />
<!-- start world -->
<node name="gazebo" pkg="gazebo" type="gazebo"
args="$(find your_pkg)/worlds/your.world" respawn="false" output="screen" />
<!-- start gui -->
<node name="gazebo_gui" pkg="gazebo" type="gui" respawn="false" output="screen"/>
<!-- include our robots -->
<include file="$(find your_pkg)/launch/robots.launch"/>
</launch>
Navigation
For setting up the navigation stack we follow the tutorial RobotSetup, but we have to add the namespace tricks for it.
We use the same approach of splitting files. First the move_base.launch for one robot, as from tutorial:
<launch>
<!--- Run AMCL -->
<include file="$(find amcl)/examples/amcl_diff.launch" />
<!-- Define your move_base node -->
<node pkg="move_base" type="move_base" respawn="false" name="move_base" output="screen">
<rosparam file="$(find your_pkg)/costmap_common_params.yaml" command="load" ns="global_costmap"/>
<rosparam file="$(find your_pkg)/costmap_common_params.yaml" command ...
(more)
Hi @Jacub, thanks for this extraordinary contributions on forum. There is a similar problem (extended version) which can probably be solved only by you (given your expertise).( http://robotics.stackexchange.com/que... )
Hi @Jacub,thank you for give us a so wonderful tutorial about Multiple robots simulation and navigation, but I still have some trouble about this. I could do single-robot navigation in gazebo, but when i add the the namespace in the launch file,there may be a error in the amcl.
@PrasadNR and @huang_y you should make your own questions because, although related, they appear to be different than this question.
I was able to run multiple TB3 simulation and navigation on ROS Melodic. I noticed that the robots are not aware of each other and they collide with each other. What is needed to make the robots avoid collisions with each other?
@Anas Kanhouch please don't use an answer to ask a question as this isn't a forum. Please create a new question and reference this one instead so that you get more visibility and have a better chance of getting your question answered (this question is almost 9 years old at this point).
sure noted @jayess
Check out this article for multi robot in ROS2 with nav2 stack: https://medium.com/@arshad.mehmood/a-...