Nav2 Navigation Stack - rolling  main
ROS 2 Navigation Stack
bringup_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 import os
16 
17 from ament_index_python.packages import get_package_share_directory
18 from launch import LaunchDescription
19 from launch.actions import (DeclareLaunchArgument, GroupAction, IncludeLaunchDescription,
20  OpaqueFunction, SetEnvironmentVariable)
21 from launch.conditions import IfCondition, UnlessCondition
22 from launch.launch_description_sources import PythonLaunchDescriptionSource
23 from launch.substitutions import LaunchConfiguration, PythonExpression
24 from launch_ros.actions import LoadComposableNodes, Node
25 from launch_ros.descriptions import ComposableNode, ParameterFile
26 from nav2_bringup.keepout_zone_launch import get_lifecycle_nodes as get_keepout_zone_nodes
27 from nav2_bringup.localization_launch import get_lifecycle_nodes as get_localization_nodes
28 from nav2_bringup.navigation_launch import get_lifecycle_nodes as get_navigation_nodes
29 from nav2_bringup.slam_launch import get_lifecycle_nodes as get_slam_nodes
30 from nav2_bringup.speed_zone_launch import get_lifecycle_nodes as get_speed_zone_nodes
31 from nav2_common.launch import LaunchConfigAsBool, RewrittenYaml
32 
33 
34 def generate_launch_description() -> LaunchDescription:
35  # Get the launch directory
36  bringup_dir = get_package_share_directory('nav2_bringup')
37  launch_dir = os.path.join(bringup_dir, 'launch')
38  # Create the launch configuration variables
39  namespace = LaunchConfiguration('namespace')
40  slam = LaunchConfigAsBool('slam')
41  map_yaml_file = LaunchConfiguration('map')
42  keepout_mask_yaml_file = LaunchConfiguration('keepout_mask')
43  speed_mask_yaml_file = LaunchConfiguration('speed_mask')
44  graph_filepath = LaunchConfiguration('graph')
45  use_sim_time = LaunchConfigAsBool('use_sim_time')
46  params_file = LaunchConfiguration('params_file')
47  autostart = LaunchConfigAsBool('autostart')
48  use_composition = LaunchConfigAsBool('use_composition')
49  use_intra_process_comms = LaunchConfigAsBool('use_intra_process_comms')
50  container_name = LaunchConfiguration('container_name')
51  use_respawn = LaunchConfigAsBool('use_respawn')
52  log_level = LaunchConfiguration('log_level')
53  use_localization = LaunchConfigAsBool('use_localization')
54  serve_static_map = LaunchConfigAsBool('serve_static_map')
55  use_keepout_zones = LaunchConfigAsBool('use_keepout_zones')
56  use_speed_zones = LaunchConfigAsBool('use_speed_zones')
57 
58  # Map fully qualified names to relative ones so the node's namespace can be prepended.
59  remappings = [('/tf', 'tf'), ('/tf_static', 'tf_static')]
60 
61  yaml_substitutions = {
62  'KEEPOUT_ZONE_ENABLED': use_keepout_zones,
63  'SPEED_ZONE_ENABLED': use_speed_zones,
64  }
65 
66  configured_params = ParameterFile(
67  RewrittenYaml(
68  source_file=params_file,
69  root_key=namespace,
70  param_rewrites={},
71  value_rewrites=yaml_substitutions,
72  convert_types=True,
73  ),
74  allow_substs=True,
75  )
76 
77  def launch_lifecycle_manager(context):
78  lifecycle_nodes = []
79 
80  if (
81  use_localization.perform(context) == 'True'
82  and slam.perform(context) == 'True'
83  ):
84  lifecycle_nodes.extend(get_slam_nodes(context))
85  else:
86  lifecycle_nodes.extend(get_localization_nodes(context))
87 
88  if use_keepout_zones.perform(context) == 'True':
89  lifecycle_nodes.extend(get_keepout_zone_nodes(context))
90 
91  if use_speed_zones.perform(context) == 'True':
92  lifecycle_nodes.extend(get_speed_zone_nodes(context))
93 
94  lifecycle_nodes.extend(get_navigation_nodes(context))
95 
96  manager_parameters = [
97  configured_params,
98  {
99  'autostart': autostart,
100  'node_names': lifecycle_nodes,
101  'use_sim_time': use_sim_time,
102  },
103  ]
104 
105  return [
106  LoadComposableNodes(
107  condition=IfCondition(use_composition),
108  target_container=(namespace, '/', container_name),
109  composable_node_descriptions=[
110  ComposableNode(
111  package='nav2_lifecycle_manager',
112  plugin='nav2_lifecycle_manager::LifecycleManager',
113  name='lifecycle_manager_nav2',
114  namespace=namespace,
115  parameters=manager_parameters,
116  extra_arguments=[{
117  'use_intra_process_comms': use_intra_process_comms
118  }],
119  ),
120  ],
121  ),
122  Node(
123  condition=UnlessCondition(use_composition),
124  package='nav2_lifecycle_manager',
125  executable='lifecycle_manager',
126  name='lifecycle_manager_nav2',
127  namespace=namespace,
128  output='screen',
129  arguments=['--ros-args', '--log-level', log_level],
130  parameters=manager_parameters,
131  ),
132  ]
133 
134  stdout_linebuf_envvar = SetEnvironmentVariable(
135  'RCUTILS_LOGGING_BUFFERED_STREAM', '1'
136  )
137 
138  declare_namespace_cmd = DeclareLaunchArgument(
139  'namespace', default_value='', description='Top-level namespace'
140  )
141 
142  declare_slam_cmd = DeclareLaunchArgument(
143  'slam', default_value='False', description='Whether run a SLAM'
144  )
145 
146  declare_map_yaml_cmd = DeclareLaunchArgument(
147  'map', default_value='', description='Full path to map yaml file to load'
148  )
149 
150  declare_keepout_mask_yaml_cmd = DeclareLaunchArgument(
151  'keepout_mask', default_value='',
152  description='Full path to keepout mask yaml file to load'
153  )
154 
155  declare_speed_mask_yaml_cmd = DeclareLaunchArgument(
156  'speed_mask', default_value='',
157  description='Full path to speed mask yaml file to load'
158  )
159 
160  declare_graph_file_cmd = DeclareLaunchArgument(
161  'graph',
162  default_value='', description='Path to the graph file to load'
163  )
164 
165  declare_use_localization_cmd = DeclareLaunchArgument(
166  'use_localization', default_value='True',
167  description='Whether to enable localization or not'
168  )
169 
170  declare_serve_static_map_cmd = DeclareLaunchArgument(
171  'serve_static_map', default_value=use_localization,
172  description='Whether to serve the static map'
173  )
174 
175  declare_use_keepout_zones_cmd = DeclareLaunchArgument(
176  'use_keepout_zones', default_value='True',
177  description='Whether to enable keepout zones or not'
178  )
179 
180  declare_use_speed_zones_cmd = DeclareLaunchArgument(
181  'use_speed_zones', default_value='True',
182  description='Whether to enable speed zones or not'
183  )
184 
185  declare_use_sim_time_cmd = DeclareLaunchArgument(
186  'use_sim_time',
187  default_value='false',
188  description='Use simulation (Gazebo) clock if true',
189  )
190 
191  declare_params_file_cmd = DeclareLaunchArgument(
192  'params_file',
193  default_value=os.path.join(bringup_dir, 'params', 'nav2_params.yaml'),
194  description='Full path to the ROS2 parameters file to use for all launched nodes',
195  )
196 
197  declare_autostart_cmd = DeclareLaunchArgument(
198  'autostart',
199  default_value='true',
200  description='Automatically startup the nav2 stack',
201  )
202 
203  declare_use_composition_cmd = DeclareLaunchArgument(
204  'use_composition',
205  default_value='True',
206  description='Whether to use composed bringup',
207  )
208 
209  declare_use_intra_process_comms_cmd = DeclareLaunchArgument(
210  'use_intra_process_comms',
211  default_value='False',
212  description='Whether to use intra process communications',
213  )
214 
215  declare_container_name_cmd = DeclareLaunchArgument(
216  'container_name',
217  default_value='nav2_container',
218  description='the name of container that nodes will load in if use composition',
219  )
220 
221  declare_use_respawn_cmd = DeclareLaunchArgument(
222  'use_respawn',
223  default_value='False',
224  description='Whether to respawn if a node crashes. Applied when composition is disabled.',
225  )
226 
227  declare_log_level_cmd = DeclareLaunchArgument(
228  'log_level', default_value='info', description='log level'
229  )
230 
231  # Specify the actions
232  bringup_cmd_group = GroupAction(
233  [
234  Node(
235  condition=IfCondition(use_composition),
236  name=container_name,
237  namespace=namespace,
238  package='rclcpp_components',
239  executable='component_container',
240  parameters=[configured_params, {'autostart': autostart}],
241  arguments=['--isolated', '--executor-type', 'single-threaded',
242  '--ros-args', '--log-level', log_level],
243  remappings=remappings,
244  output='screen',
245  ),
246  IncludeLaunchDescription(
247  PythonLaunchDescriptionSource(
248  os.path.join(launch_dir, 'slam_launch.py')
249  ),
250  condition=IfCondition(PythonExpression([slam, ' and ', use_localization])),
251  launch_arguments={
252  'namespace': namespace,
253  'use_sim_time': use_sim_time,
254  'use_respawn': use_respawn,
255  'params_file': params_file,
256  }.items(),
257  ),
258  IncludeLaunchDescription(
259  PythonLaunchDescriptionSource(
260  os.path.join(launch_dir, 'localization_launch.py')
261  ),
262  condition=UnlessCondition(
263  PythonExpression([slam, ' and ', use_localization])
264  ),
265  launch_arguments={
266  'namespace': namespace,
267  'map': map_yaml_file,
268  'use_sim_time': use_sim_time,
269  'use_localization': use_localization,
270  'serve_static_map': serve_static_map,
271  'params_file': params_file,
272  'use_composition': use_composition,
273  'use_intra_process_comms': use_intra_process_comms,
274  'use_respawn': use_respawn,
275  'container_name': container_name,
276  }.items(),
277  ),
278 
279  IncludeLaunchDescription(
280  PythonLaunchDescriptionSource(
281  os.path.join(launch_dir, 'keepout_zone_launch.py')
282  ),
283  condition=IfCondition(use_keepout_zones),
284  launch_arguments={
285  'namespace': namespace,
286  'keepout_mask': keepout_mask_yaml_file,
287  'use_sim_time': use_sim_time,
288  'params_file': params_file,
289  'use_composition': use_composition,
290  'use_intra_process_comms': use_intra_process_comms,
291  'use_respawn': use_respawn,
292  'container_name': container_name,
293  }.items(),
294  ),
295 
296  IncludeLaunchDescription(
297  PythonLaunchDescriptionSource(
298  os.path.join(launch_dir, 'speed_zone_launch.py')
299  ),
300  condition=IfCondition(use_speed_zones),
301  launch_arguments={
302  'namespace': namespace,
303  'speed_mask': speed_mask_yaml_file,
304  'use_sim_time': use_sim_time,
305  'params_file': params_file,
306  'use_composition': use_composition,
307  'use_intra_process_comms': use_intra_process_comms,
308  'use_respawn': use_respawn,
309  'container_name': container_name,
310  }.items(),
311  ),
312 
313  IncludeLaunchDescription(
314  PythonLaunchDescriptionSource(
315  os.path.join(launch_dir, 'navigation_launch.py')
316  ),
317  launch_arguments={
318  'namespace': namespace,
319  'use_sim_time': use_sim_time,
320  'autostart': autostart,
321  'graph': graph_filepath,
322  'params_file': params_file,
323  'use_composition': use_composition,
324  'use_intra_process_comms': use_intra_process_comms,
325  'use_respawn': use_respawn,
326  'use_keepout_zones': use_keepout_zones,
327  'use_speed_zones': use_speed_zones,
328  'container_name': container_name,
329  }.items(),
330  ),
331  OpaqueFunction(function=launch_lifecycle_manager),
332  ]
333  )
334 
335  # Create the launch description and populate
336  ld = LaunchDescription()
337 
338  # Set environment variables
339  ld.add_action(stdout_linebuf_envvar)
340 
341  # Declare the launch options
342  ld.add_action(declare_namespace_cmd)
343  ld.add_action(declare_slam_cmd)
344  ld.add_action(declare_map_yaml_cmd)
345  ld.add_action(declare_keepout_mask_yaml_cmd)
346  ld.add_action(declare_speed_mask_yaml_cmd)
347  ld.add_action(declare_graph_file_cmd)
348  ld.add_action(declare_use_sim_time_cmd)
349  ld.add_action(declare_params_file_cmd)
350  ld.add_action(declare_autostart_cmd)
351  ld.add_action(declare_use_composition_cmd)
352  ld.add_action(declare_use_intra_process_comms_cmd)
353  ld.add_action(declare_container_name_cmd)
354  ld.add_action(declare_use_respawn_cmd)
355  ld.add_action(declare_log_level_cmd)
356  ld.add_action(declare_use_localization_cmd)
357  ld.add_action(declare_serve_static_map_cmd)
358  ld.add_action(declare_use_keepout_zones_cmd)
359  ld.add_action(declare_use_speed_zones_cmd)
360 
361  # Add the actions to launch all of the navigation nodes
362  ld.add_action(bringup_cmd_group)
363 
364  return ld