Nav2 Navigation Stack - rolling  main
ROS 2 Navigation Stack
navigation_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, SetEnvironmentVariable
20 from launch.conditions import IfCondition
21 from launch.substitutions import LaunchConfiguration, PythonExpression
22 from launch_ros.actions import LoadComposableNodes, Node, PushROSNamespace, SetParameter
23 from launch_ros.descriptions import ComposableNode, ParameterFile
24 from nav2_common.launch import LaunchConfigAsBool, RewrittenYaml
25 
26 
27 def get_lifecycle_nodes(context):
28  return (
29  'controller_server',
30  'smoother_server',
31  'planner_server',
32  'route_server',
33  'behavior_server',
34  'velocity_smoother',
35  'collision_monitor',
36  'bt_navigator',
37  'waypoint_follower',
38  'docking_server',
39  'following_server',
40  )
41 
42 
43 def generate_launch_description() -> LaunchDescription:
44  # Get the launch directory
45  bringup_dir = get_package_share_directory('nav2_bringup')
46 
47  namespace = LaunchConfiguration('namespace')
48  use_sim_time = LaunchConfigAsBool('use_sim_time')
49  autostart = LaunchConfigAsBool('autostart')
50  graph_filepath = LaunchConfiguration('graph')
51  params_file = LaunchConfiguration('params_file')
52  use_composition = LaunchConfigAsBool('use_composition')
53  use_intra_process_comms = LaunchConfigAsBool('use_intra_process_comms')
54  container_name = LaunchConfiguration('container_name')
55  container_name_full = (namespace, '/', container_name)
56  use_respawn = LaunchConfigAsBool('use_respawn')
57  log_level = LaunchConfiguration('log_level')
58  use_keepout_zones = LaunchConfigAsBool('use_keepout_zones')
59  use_speed_zones = LaunchConfigAsBool('use_speed_zones')
60 
61  # Map fully qualified names to relative ones so the node's namespace can be prepended.
62  remappings = [('/tf', 'tf'), ('/tf_static', 'tf_static')]
63 
64  # Create our own temporary YAML files that include substitutions
65  param_substitutions = {'autostart': autostart}
66 
67  yaml_substitutions = {
68  'KEEPOUT_ZONE_ENABLED': use_keepout_zones,
69  'SPEED_ZONE_ENABLED': use_speed_zones,
70  }
71 
72  # RewrittenYaml: Adds namespace to the parameters file as a root key
73  # Note: Make sure that all frames are correctly namespaced in the parameters file
74  # Do not add namespace to topics in the parameters file, as they will be remapped
75  # by the root key only if they are not prefixed with a forward slash.
76  # e.g. 'map' will be remapped to '/<namespace>/map', but '/map' will not be remapped.
77  # IMPORTANT: to make your yaml file dynamic you can refer to humble branch under
78  # nav2_bringup/launch/bringup_launch.py to see how the parameters file is configured
79  # using ReplaceString <robot_namespace>
80  configured_params = ParameterFile(
81  RewrittenYaml(
82  source_file=params_file,
83  root_key=namespace,
84  param_rewrites=param_substitutions,
85  value_rewrites=yaml_substitutions,
86  convert_types=True,
87  ),
88  allow_substs=True,
89  )
90 
91  stdout_linebuf_envvar = SetEnvironmentVariable(
92  'RCUTILS_LOGGING_BUFFERED_STREAM', '1'
93  )
94 
95  declare_namespace_cmd = DeclareLaunchArgument(
96  'namespace', default_value='', description='Top-level namespace'
97  )
98 
99  declare_use_sim_time_cmd = DeclareLaunchArgument(
100  'use_sim_time',
101  default_value='false',
102  description='Use simulation (Gazebo) clock if true',
103  )
104 
105  declare_params_file_cmd = DeclareLaunchArgument(
106  'params_file',
107  default_value=os.path.join(bringup_dir, 'params', 'nav2_params.yaml'),
108  description='Full path to the ROS2 parameters file to use for all launched nodes',
109  )
110 
111  declare_graph_file_cmd = DeclareLaunchArgument(
112  'graph',
113  default_value='', description='Path to the graph file to load'
114  )
115 
116  declare_autostart_cmd = DeclareLaunchArgument(
117  'autostart',
118  default_value='true',
119  description='Automatically startup the nav2 stack',
120  )
121 
122  declare_use_composition_cmd = DeclareLaunchArgument(
123  'use_composition',
124  default_value='False',
125  description='Use composed bringup if True',
126  )
127 
128  declare_use_intra_process_comms_cmd = DeclareLaunchArgument(
129  'use_intra_process_comms',
130  default_value='False',
131  description='Whether to use intra process communication',
132  )
133 
134  declare_container_name_cmd = DeclareLaunchArgument(
135  'container_name',
136  default_value='nav2_container',
137  description='the name of container that nodes will load in if use composition',
138  )
139 
140  declare_use_respawn_cmd = DeclareLaunchArgument(
141  'use_respawn',
142  default_value='False',
143  description='Whether to respawn if a node crashes. Applied when composition is disabled.',
144  )
145 
146  declare_log_level_cmd = DeclareLaunchArgument(
147  'log_level', default_value='info', description='log level'
148  )
149 
150  declare_use_keepout_zones_cmd = DeclareLaunchArgument(
151  'use_keepout_zones', default_value='True',
152  description='Whether to enable keepout zones or not'
153  )
154 
155  declare_use_speed_zones_cmd = DeclareLaunchArgument(
156  'use_speed_zones', default_value='True',
157  description='Whether to enable speed zones or not'
158  )
159 
160  load_nodes = GroupAction(
161  condition=IfCondition(PythonExpression(['not ', use_composition])),
162  actions=[
163  SetParameter('use_sim_time', use_sim_time),
164  PushROSNamespace(namespace=namespace),
165  Node(
166  package='nav2_controller',
167  executable='controller_server',
168  output='screen',
169  respawn=use_respawn,
170  respawn_delay=2.0,
171  parameters=[configured_params],
172  arguments=['--ros-args', '--log-level', log_level],
173  remappings=remappings + [('cmd_vel', 'cmd_vel_nav')],
174  ),
175  Node(
176  package='nav2_smoother',
177  executable='smoother_server',
178  name='smoother_server',
179  output='screen',
180  respawn=use_respawn,
181  respawn_delay=2.0,
182  parameters=[configured_params],
183  arguments=['--ros-args', '--log-level', log_level],
184  remappings=remappings,
185  ),
186  Node(
187  package='nav2_planner',
188  executable='planner_server',
189  name='planner_server',
190  output='screen',
191  respawn=use_respawn,
192  respawn_delay=2.0,
193  parameters=[configured_params],
194  arguments=['--ros-args', '--log-level', log_level],
195  remappings=remappings,
196  ),
197  Node(
198  package='nav2_route',
199  executable='route_server',
200  name='route_server',
201  output='screen',
202  respawn=use_respawn,
203  respawn_delay=2.0,
204  parameters=[configured_params, {'graph_filepath': graph_filepath}],
205  arguments=['--ros-args', '--log-level', log_level],
206  remappings=remappings),
207  Node(
208  package='nav2_behaviors',
209  executable='behavior_server',
210  name='behavior_server',
211  output='screen',
212  respawn=use_respawn,
213  respawn_delay=2.0,
214  parameters=[configured_params],
215  arguments=['--ros-args', '--log-level', log_level],
216  remappings=remappings + [('cmd_vel', 'cmd_vel_nav')],
217  ),
218  Node(
219  package='nav2_bt_navigator',
220  executable='bt_navigator',
221  name='bt_navigator',
222  output='screen',
223  respawn=use_respawn,
224  respawn_delay=2.0,
225  parameters=[configured_params],
226  arguments=['--ros-args', '--log-level', log_level],
227  remappings=remappings,
228  ),
229  Node(
230  package='nav2_waypoint_follower',
231  executable='waypoint_follower',
232  name='waypoint_follower',
233  output='screen',
234  respawn=use_respawn,
235  respawn_delay=2.0,
236  parameters=[configured_params],
237  arguments=['--ros-args', '--log-level', log_level],
238  remappings=remappings,
239  ),
240  Node(
241  package='nav2_velocity_smoother',
242  executable='velocity_smoother',
243  name='velocity_smoother',
244  output='screen',
245  respawn=use_respawn,
246  respawn_delay=2.0,
247  parameters=[configured_params],
248  arguments=['--ros-args', '--log-level', log_level],
249  remappings=remappings
250  + [('cmd_vel', 'cmd_vel_nav')],
251  ),
252  Node(
253  package='nav2_collision_monitor',
254  executable='collision_monitor',
255  name='collision_monitor',
256  output='screen',
257  respawn=use_respawn,
258  respawn_delay=2.0,
259  parameters=[configured_params],
260  arguments=['--ros-args', '--log-level', log_level],
261  remappings=remappings,
262  ),
263  Node(
264  package='opennav_docking',
265  executable='opennav_docking',
266  name='docking_server',
267  output='screen',
268  respawn=use_respawn,
269  respawn_delay=2.0,
270  parameters=[configured_params],
271  arguments=['--ros-args', '--log-level', log_level],
272  remappings=remappings,
273  ),
274  Node(
275  package='opennav_following',
276  executable='opennav_following',
277  name='following_server',
278  output='screen',
279  respawn=use_respawn,
280  respawn_delay=2.0,
281  parameters=[configured_params],
282  arguments=['--ros-args', '--log-level', log_level],
283  remappings=remappings,
284  ),
285  ],
286  )
287 
288  load_composable_nodes = GroupAction(
289  condition=IfCondition(use_composition),
290  actions=[
291  SetParameter('use_sim_time', use_sim_time),
292  PushROSNamespace(namespace=namespace),
293  LoadComposableNodes(
294  target_container=container_name_full,
295  composable_node_descriptions=[
296  ComposableNode(
297  package='nav2_controller',
298  plugin='nav2_controller::ControllerServer',
299  name='controller_server',
300  parameters=[configured_params],
301  remappings=remappings + [('cmd_vel', 'cmd_vel_nav')],
302  extra_arguments=[{'use_intra_process_comms': use_intra_process_comms}],
303  ),
304  ComposableNode(
305  package='nav2_smoother',
306  plugin='nav2_smoother::SmootherServer',
307  name='smoother_server',
308  parameters=[configured_params],
309  remappings=remappings,
310  extra_arguments=[{'use_intra_process_comms': use_intra_process_comms}],
311  ),
312  ComposableNode(
313  package='nav2_planner',
314  plugin='nav2_planner::PlannerServer',
315  name='planner_server',
316  parameters=[configured_params],
317  remappings=remappings,
318  extra_arguments=[{'use_intra_process_comms': use_intra_process_comms}],
319  ),
320  ComposableNode(
321  package='nav2_route',
322  plugin='nav2_route::RouteServer',
323  name='route_server',
324  parameters=[configured_params, {'graph_filepath': graph_filepath}],
325  remappings=remappings,
326  extra_arguments=[{'use_intra_process_comms': use_intra_process_comms}],
327  ),
328  ComposableNode(
329  package='nav2_behaviors',
330  plugin='behavior_server::BehaviorServer',
331  name='behavior_server',
332  parameters=[configured_params],
333  remappings=remappings + [('cmd_vel', 'cmd_vel_nav')],
334  extra_arguments=[{'use_intra_process_comms': use_intra_process_comms}],
335  ),
336  ComposableNode(
337  package='nav2_bt_navigator',
338  plugin='nav2_bt_navigator::BtNavigator',
339  name='bt_navigator',
340  parameters=[configured_params],
341  remappings=remappings,
342  extra_arguments=[{'use_intra_process_comms': use_intra_process_comms}],
343  ),
344  ComposableNode(
345  package='nav2_waypoint_follower',
346  plugin='nav2_waypoint_follower::WaypointFollower',
347  name='waypoint_follower',
348  parameters=[configured_params],
349  remappings=remappings,
350  extra_arguments=[{'use_intra_process_comms': use_intra_process_comms}],
351  ),
352  ComposableNode(
353  package='nav2_velocity_smoother',
354  plugin='nav2_velocity_smoother::VelocitySmoother',
355  name='velocity_smoother',
356  parameters=[configured_params],
357  remappings=remappings
358  + [('cmd_vel', 'cmd_vel_nav')],
359  extra_arguments=[{'use_intra_process_comms': use_intra_process_comms}],
360  ),
361  ComposableNode(
362  package='nav2_collision_monitor',
363  plugin='nav2_collision_monitor::CollisionMonitor',
364  name='collision_monitor',
365  parameters=[configured_params],
366  remappings=remappings,
367  extra_arguments=[{'use_intra_process_comms': use_intra_process_comms}],
368  ),
369  ComposableNode(
370  package='opennav_docking',
371  plugin='opennav_docking::DockingServer',
372  name='docking_server',
373  parameters=[configured_params],
374  remappings=remappings,
375  extra_arguments=[{'use_intra_process_comms': use_intra_process_comms}],
376  ),
377  ComposableNode(
378  package='opennav_following',
379  plugin='opennav_following::FollowingServer',
380  name='following_server',
381  parameters=[configured_params],
382  remappings=remappings,
383  extra_arguments=[{'use_intra_process_comms': use_intra_process_comms}],
384  ),
385  ],
386  ),
387  ],
388  )
389 
390  # Create the launch description and populate
391  ld = LaunchDescription()
392 
393  # Set environment variables
394  ld.add_action(stdout_linebuf_envvar)
395 
396  # Declare the launch options
397  ld.add_action(declare_namespace_cmd)
398  ld.add_action(declare_use_sim_time_cmd)
399  ld.add_action(declare_params_file_cmd)
400  ld.add_action(declare_autostart_cmd)
401  ld.add_action(declare_graph_file_cmd)
402  ld.add_action(declare_use_composition_cmd)
403  ld.add_action(declare_use_intra_process_comms_cmd)
404  ld.add_action(declare_container_name_cmd)
405  ld.add_action(declare_use_respawn_cmd)
406  ld.add_action(declare_log_level_cmd)
407  ld.add_action(declare_use_keepout_zones_cmd)
408  ld.add_action(declare_use_speed_zones_cmd)
409  # Add the actions to launch all of the navigation nodes
410  ld.add_action(load_nodes)
411  ld.add_action(load_composable_nodes)
412 
413  return ld