Nav2 Navigation Stack - rolling  main
ROS 2 Navigation Stack
localization_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 (EqualsSubstitution, LaunchConfiguration, NotEqualsSubstitution,
22  PythonExpression)
23 from launch_ros.actions import LoadComposableNodes, Node, PushROSNamespace, SetParameter
24 from launch_ros.descriptions import ComposableNode, ParameterFile
25 from nav2_common.launch import LaunchConfigAsBool, RewrittenYaml
26 
27 
28 def generate_launch_description() -> LaunchDescription:
29  # Get the launch directory
30  bringup_dir = get_package_share_directory('nav2_bringup')
31 
32  namespace = LaunchConfiguration('namespace')
33  map_yaml_file = LaunchConfiguration('map')
34  use_sim_time = LaunchConfigAsBool('use_sim_time')
35  autostart = LaunchConfigAsBool('autostart')
36  params_file = LaunchConfiguration('params_file')
37  use_composition = LaunchConfigAsBool('use_composition')
38  container_name = LaunchConfiguration('container_name')
39  container_name_full = (namespace, '/', container_name)
40  use_respawn = LaunchConfigAsBool('use_respawn')
41  log_level = LaunchConfiguration('log_level')
42 
43  lifecycle_nodes = ['map_server', 'amcl']
44 
45  # Map fully qualified names to relative ones so the node's namespace can be prepended.
46  remappings = [('/tf', 'tf'), ('/tf_static', 'tf_static')]
47 
48  configured_params = ParameterFile(
49  RewrittenYaml(
50  source_file=params_file,
51  root_key=namespace,
52  param_rewrites={},
53  convert_types=True,
54  ),
55  allow_substs=True,
56  )
57 
58  stdout_linebuf_envvar = SetEnvironmentVariable(
59  'RCUTILS_LOGGING_BUFFERED_STREAM', '1'
60  )
61 
62  declare_namespace_cmd = DeclareLaunchArgument(
63  'namespace', default_value='', description='Top-level namespace'
64  )
65 
66  declare_map_yaml_cmd = DeclareLaunchArgument(
67  'map', default_value='', description='Full path to map yaml file to load'
68  )
69 
70  declare_use_sim_time_cmd = DeclareLaunchArgument(
71  'use_sim_time',
72  default_value='false',
73  description='Use simulation (Gazebo) clock if true',
74  )
75 
76  declare_params_file_cmd = DeclareLaunchArgument(
77  'params_file',
78  default_value=os.path.join(bringup_dir, 'params', 'nav2_params.yaml'),
79  description='Full path to the ROS2 parameters file to use for all launched nodes',
80  )
81 
82  declare_autostart_cmd = DeclareLaunchArgument(
83  'autostart',
84  default_value='true',
85  description='Automatically startup the nav2 stack',
86  )
87 
88  declare_use_composition_cmd = DeclareLaunchArgument(
89  'use_composition',
90  default_value='False',
91  description='Use composed bringup if True',
92  )
93 
94  declare_container_name_cmd = DeclareLaunchArgument(
95  'container_name',
96  default_value='nav2_container',
97  description='the name of container that nodes will load in if use composition',
98  )
99 
100  declare_use_respawn_cmd = DeclareLaunchArgument(
101  'use_respawn',
102  default_value='False',
103  description='Whether to respawn if a node crashes. Applied when composition is disabled.',
104  )
105 
106  declare_log_level_cmd = DeclareLaunchArgument(
107  'log_level', default_value='info', description='log level'
108  )
109 
110  load_nodes = GroupAction(
111  condition=IfCondition(PythonExpression(['not ', use_composition])),
112  actions=[
113  PushROSNamespace(namespace),
114  SetParameter('use_sim_time', use_sim_time),
115  Node(
116  condition=IfCondition(
117  EqualsSubstitution(LaunchConfiguration('map'), '')
118  ),
119  package='nav2_map_server',
120  executable='map_server',
121  name='map_server',
122  output='screen',
123  respawn=use_respawn,
124  respawn_delay=2.0,
125  parameters=[configured_params],
126  arguments=['--ros-args', '--log-level', log_level],
127  remappings=remappings,
128  ),
129  Node(
130  condition=IfCondition(
131  NotEqualsSubstitution(LaunchConfiguration('map'), '')
132  ),
133  package='nav2_map_server',
134  executable='map_server',
135  name='map_server',
136  output='screen',
137  respawn=use_respawn,
138  respawn_delay=2.0,
139  parameters=[configured_params, {'yaml_filename': map_yaml_file}],
140  arguments=['--ros-args', '--log-level', log_level],
141  remappings=remappings,
142  ),
143  Node(
144  package='nav2_amcl',
145  executable='amcl',
146  name='amcl',
147  output='screen',
148  respawn=use_respawn,
149  respawn_delay=2.0,
150  parameters=[configured_params],
151  arguments=['--ros-args', '--log-level', log_level],
152  remappings=remappings,
153  ),
154  Node(
155  package='nav2_lifecycle_manager',
156  executable='lifecycle_manager',
157  name='lifecycle_manager_localization',
158  output='screen',
159  arguments=['--ros-args', '--log-level', log_level],
160  parameters=[{'autostart': autostart}, {'node_names': lifecycle_nodes}],
161  ),
162  ],
163  )
164  # LoadComposableNode for map server twice depending if we should use the
165  # value of map from a CLI or launch default or user defined value in the
166  # yaml configuration file. They are separated since the conditions
167  # currently only work on the LoadComposableNodes commands and not on the
168  # ComposableNode node function itself
169  load_composable_nodes = GroupAction(
170  condition=IfCondition(use_composition),
171  actions=[
172  PushROSNamespace(namespace),
173  SetParameter('use_sim_time', use_sim_time),
174  LoadComposableNodes(
175  target_container=container_name_full,
176  condition=IfCondition(
177  EqualsSubstitution(LaunchConfiguration('map'), '')
178  ),
179  composable_node_descriptions=[
180  ComposableNode(
181  package='nav2_map_server',
182  plugin='nav2_map_server::MapServer',
183  name='map_server',
184  parameters=[configured_params],
185  remappings=remappings,
186  ),
187  ],
188  ),
189  LoadComposableNodes(
190  target_container=container_name_full,
191  condition=IfCondition(
192  NotEqualsSubstitution(LaunchConfiguration('map'), '')
193  ),
194  composable_node_descriptions=[
195  ComposableNode(
196  package='nav2_map_server',
197  plugin='nav2_map_server::MapServer',
198  name='map_server',
199  parameters=[
200  configured_params,
201  {'yaml_filename': map_yaml_file},
202  ],
203  remappings=remappings,
204  ),
205  ],
206  ),
207  LoadComposableNodes(
208  target_container=container_name_full,
209  composable_node_descriptions=[
210  ComposableNode(
211  package='nav2_amcl',
212  plugin='nav2_amcl::AmclNode',
213  name='amcl',
214  parameters=[configured_params],
215  remappings=remappings,
216  ),
217  ComposableNode(
218  package='nav2_lifecycle_manager',
219  plugin='nav2_lifecycle_manager::LifecycleManager',
220  name='lifecycle_manager_localization',
221  parameters=[
222  {'autostart': autostart, 'node_names': lifecycle_nodes}
223  ],
224  ),
225  ],
226  ),
227  ],
228  )
229 
230  # Create the launch description and populate
231  ld = LaunchDescription()
232 
233  # Set environment variables
234  ld.add_action(stdout_linebuf_envvar)
235 
236  # Declare the launch options
237  ld.add_action(declare_namespace_cmd)
238  ld.add_action(declare_map_yaml_cmd)
239  ld.add_action(declare_use_sim_time_cmd)
240  ld.add_action(declare_params_file_cmd)
241  ld.add_action(declare_autostart_cmd)
242  ld.add_action(declare_use_composition_cmd)
243  ld.add_action(declare_container_name_cmd)
244  ld.add_action(declare_use_respawn_cmd)
245  ld.add_action(declare_log_level_cmd)
246 
247  # Add the actions to launch all of the localiztion nodes
248  ld.add_action(load_nodes)
249  ld.add_action(load_composable_nodes)
250 
251  return ld