16 Example for spawning multiple robots in Gazebo.
18 This is an example on how to create a launch file for spawning multiple robots into Gazebo
19 and launch multiple instances of the navigation stack, each controlling one robot.
20 The robots co-exist on a shared environment and are controlled by independent nav stacks.
25 from ament_index_python.packages
import get_package_share_directory
27 from launch
import LaunchDescription
28 from launch.actions
import (DeclareLaunchArgument, ExecuteProcess, GroupAction,
29 IncludeLaunchDescription, LogInfo)
30 from launch.conditions
import IfCondition
31 from launch.launch_description_sources
import PythonLaunchDescriptionSource
32 from launch.substitutions
import LaunchConfiguration, TextSubstitution
35 def generate_launch_description():
37 bringup_dir = get_package_share_directory(
'nav2_bringup')
38 launch_dir = os.path.join(bringup_dir,
'launch')
42 {
'name':
'robot1',
'x_pose': 0.0,
'y_pose': 0.5,
'z_pose': 0.01,
43 'roll': 0.0,
'pitch': 0.0,
'yaw': 0.0},
44 {
'name':
'robot2',
'x_pose': 0.0,
'y_pose': -0.5,
'z_pose': 0.01,
45 'roll': 0.0,
'pitch': 0.0,
'yaw': 0.0}]
48 world = LaunchConfiguration(
'world')
49 simulator = LaunchConfiguration(
'simulator')
52 map_yaml_file = LaunchConfiguration(
'map')
54 autostart = LaunchConfiguration(
'autostart')
55 rviz_config_file = LaunchConfiguration(
'rviz_config')
56 use_robot_state_pub = LaunchConfiguration(
'use_robot_state_pub')
57 use_rviz = LaunchConfiguration(
'use_rviz')
58 log_settings = LaunchConfiguration(
'log_settings', default=
'true')
61 declare_world_cmd = DeclareLaunchArgument(
63 default_value=os.path.join(bringup_dir,
'worlds',
'world_only.model'),
64 description=
'Full path to world file to load')
66 declare_simulator_cmd = DeclareLaunchArgument(
68 default_value=
'gazebo',
69 description=
'The simulator to use (gazebo or gzserver)')
71 declare_map_yaml_cmd = DeclareLaunchArgument(
73 default_value=os.path.join(bringup_dir,
'maps',
'turtlebot3_world.yaml'),
74 description=
'Full path to map file to load')
76 declare_robot1_params_file_cmd = DeclareLaunchArgument(
78 default_value=os.path.join(bringup_dir,
'params',
'nav2_multirobot_params_1.yaml'),
79 description=
'Full path to the ROS2 parameters file to use for robot1 launched nodes')
81 declare_robot2_params_file_cmd = DeclareLaunchArgument(
83 default_value=os.path.join(bringup_dir,
'params',
'nav2_multirobot_params_2.yaml'),
84 description=
'Full path to the ROS2 parameters file to use for robot2 launched nodes')
86 declare_autostart_cmd = DeclareLaunchArgument(
87 'autostart', default_value=
'false',
88 description=
'Automatically startup the stacks')
90 declare_rviz_config_file_cmd = DeclareLaunchArgument(
92 default_value=os.path.join(bringup_dir,
'rviz',
'nav2_namespaced_view.rviz'),
93 description=
'Full path to the RVIZ config file to use.')
95 declare_use_robot_state_pub_cmd = DeclareLaunchArgument(
96 'use_robot_state_pub',
98 description=
'Whether to start the robot state publisher')
100 declare_use_rviz_cmd = DeclareLaunchArgument(
102 default_value=
'True',
103 description=
'Whether to start RVIZ')
106 start_gazebo_cmd = ExecuteProcess(
107 cmd=[simulator,
'--verbose',
'-s',
'libgazebo_ros_init.so',
108 '-s',
'libgazebo_ros_factory.so', world],
112 nav_instances_cmds = []
114 params_file = LaunchConfiguration(f
"{robot['name']}_params_file")
116 group = GroupAction([
117 IncludeLaunchDescription(
118 PythonLaunchDescriptionSource(
119 os.path.join(launch_dir,
'rviz_launch.py')),
120 condition=IfCondition(use_rviz),
122 'namespace': TextSubstitution(text=robot[
'name']),
123 'use_namespace':
'True',
124 'rviz_config': rviz_config_file}.items()),
126 IncludeLaunchDescription(
127 PythonLaunchDescriptionSource(os.path.join(bringup_dir,
129 'tb3_simulation_launch.py')),
130 launch_arguments={
'namespace': robot[
'name'],
131 'use_namespace':
'True',
132 'map': map_yaml_file,
133 'use_sim_time':
'True',
134 'params_file': params_file,
135 'autostart': autostart,
137 'use_simulator':
'False',
139 'use_robot_state_pub': use_robot_state_pub,
140 'x_pose': TextSubstitution(text=str(robot[
'x_pose'])),
141 'y_pose': TextSubstitution(text=str(robot[
'y_pose'])),
142 'z_pose': TextSubstitution(text=str(robot[
'z_pose'])),
143 'roll': TextSubstitution(text=str(robot[
'roll'])),
144 'pitch': TextSubstitution(text=str(robot[
'pitch'])),
145 'yaw': TextSubstitution(text=str(robot[
'yaw'])),
146 'robot_name':TextSubstitution(text=robot[
'name']), }.items()),
149 condition=IfCondition(log_settings),
150 msg=[
'Launching ', robot[
'name']]),
152 condition=IfCondition(log_settings),
153 msg=[robot[
'name'],
' map yaml: ', map_yaml_file]),
155 condition=IfCondition(log_settings),
156 msg=[robot[
'name'],
' params yaml: ', params_file]),
158 condition=IfCondition(log_settings),
159 msg=[robot[
'name'],
' rviz config file: ', rviz_config_file]),
161 condition=IfCondition(log_settings),
162 msg=[robot[
'name'],
' using robot state pub: ', use_robot_state_pub]),
164 condition=IfCondition(log_settings),
165 msg=[robot[
'name'],
' autostart: ', autostart])
168 nav_instances_cmds.append(group)
171 ld = LaunchDescription()
174 ld.add_action(declare_simulator_cmd)
175 ld.add_action(declare_world_cmd)
176 ld.add_action(declare_map_yaml_cmd)
177 ld.add_action(declare_robot1_params_file_cmd)
178 ld.add_action(declare_robot2_params_file_cmd)
179 ld.add_action(declare_use_rviz_cmd)
180 ld.add_action(declare_autostart_cmd)
181 ld.add_action(declare_rviz_config_file_cmd)
182 ld.add_action(declare_use_robot_state_pub_cmd)
185 ld.add_action(start_gazebo_cmd)
187 for simulation_instance_cmd
in nav_instances_cmds:
188 ld.add_action(simulation_instance_cmd)