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