Nav2 Navigation Stack - humble  humble
ROS 2 Navigation Stack
unique_multi_tb3_simulation_launch.py
1 # Copyright (c) 2018 Intel Corporation
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 """
16 Example for spawning multiple robots in Gazebo.
17 
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.
21 """
22 
23 import os
24 
25 from ament_index_python.packages import get_package_share_directory
26 
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
33 
34 
35 def generate_launch_description():
36  # Get the launch directory
37  bringup_dir = get_package_share_directory('nav2_bringup')
38  launch_dir = os.path.join(bringup_dir, 'launch')
39 
40  # Names and poses of the robots
41  robots = [
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}]
46 
47  # Simulation settings
48  world = LaunchConfiguration('world')
49  simulator = LaunchConfiguration('simulator')
50 
51  # On this example all robots are launched with the same settings
52  map_yaml_file = LaunchConfiguration('map')
53 
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')
59 
60  # Declare the launch arguments
61  declare_world_cmd = DeclareLaunchArgument(
62  'world',
63  default_value=os.path.join(bringup_dir, 'worlds', 'world_only.model'),
64  description='Full path to world file to load')
65 
66  declare_simulator_cmd = DeclareLaunchArgument(
67  'simulator',
68  default_value='gazebo',
69  description='The simulator to use (gazebo or gzserver)')
70 
71  declare_map_yaml_cmd = DeclareLaunchArgument(
72  'map',
73  default_value=os.path.join(bringup_dir, 'maps', 'turtlebot3_world.yaml'),
74  description='Full path to map file to load')
75 
76  declare_robot1_params_file_cmd = DeclareLaunchArgument(
77  'robot1_params_file',
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')
80 
81  declare_robot2_params_file_cmd = DeclareLaunchArgument(
82  'robot2_params_file',
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')
85 
86  declare_autostart_cmd = DeclareLaunchArgument(
87  'autostart', default_value='false',
88  description='Automatically startup the stacks')
89 
90  declare_rviz_config_file_cmd = DeclareLaunchArgument(
91  'rviz_config',
92  default_value=os.path.join(bringup_dir, 'rviz', 'nav2_namespaced_view.rviz'),
93  description='Full path to the RVIZ config file to use.')
94 
95  declare_use_robot_state_pub_cmd = DeclareLaunchArgument(
96  'use_robot_state_pub',
97  default_value='True',
98  description='Whether to start the robot state publisher')
99 
100  declare_use_rviz_cmd = DeclareLaunchArgument(
101  'use_rviz',
102  default_value='True',
103  description='Whether to start RVIZ')
104 
105  # Start Gazebo with plugin providing the robot spawning service
106  start_gazebo_cmd = ExecuteProcess(
107  cmd=[simulator, '--verbose', '-s', 'libgazebo_ros_init.so',
108  '-s', 'libgazebo_ros_factory.so', world],
109  output='screen')
110 
111  # Define commands for launching the navigation instances
112  nav_instances_cmds = []
113  for robot in robots:
114  params_file = LaunchConfiguration(f"{robot['name']}_params_file")
115 
116  group = GroupAction([
117  IncludeLaunchDescription(
118  PythonLaunchDescriptionSource(
119  os.path.join(launch_dir, 'rviz_launch.py')),
120  condition=IfCondition(use_rviz),
121  launch_arguments={
122  'namespace': TextSubstitution(text=robot['name']),
123  'use_namespace': 'True',
124  'rviz_config': rviz_config_file}.items()),
125 
126  IncludeLaunchDescription(
127  PythonLaunchDescriptionSource(os.path.join(bringup_dir,
128  'launch',
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,
136  'use_rviz': 'False',
137  'use_simulator': 'False',
138  'headless': '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()),
147 
148  LogInfo(
149  condition=IfCondition(log_settings),
150  msg=['Launching ', robot['name']]),
151  LogInfo(
152  condition=IfCondition(log_settings),
153  msg=[robot['name'], ' map yaml: ', map_yaml_file]),
154  LogInfo(
155  condition=IfCondition(log_settings),
156  msg=[robot['name'], ' params yaml: ', params_file]),
157  LogInfo(
158  condition=IfCondition(log_settings),
159  msg=[robot['name'], ' rviz config file: ', rviz_config_file]),
160  LogInfo(
161  condition=IfCondition(log_settings),
162  msg=[robot['name'], ' using robot state pub: ', use_robot_state_pub]),
163  LogInfo(
164  condition=IfCondition(log_settings),
165  msg=[robot['name'], ' autostart: ', autostart])
166  ])
167 
168  nav_instances_cmds.append(group)
169 
170  # Create the launch description and populate
171  ld = LaunchDescription()
172 
173  # Declare the launch options
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)
183 
184  # Add the actions to start gazebo, robots and simulations
185  ld.add_action(start_gazebo_cmd)
186 
187  for simulation_instance_cmd in nav_instances_cmds:
188  ld.add_action(simulation_instance_cmd)
189 
190  return ld