38 """
39 Launch Localization subsystem nodes
40 """
41
42
43 env_log_levels = EnvironmentVariable('CARMA_ROS_LOGGING_CONFIG', default_value='{ "default_level" : "WARN" }')
44 vehicle_config_param_file = LaunchConfiguration('vehicle_config_param_file')
45 subsystem_controller_default_param_file = os.path.join(
46 get_package_share_directory('subsystem_controllers'), 'config/localization_controller_config.yaml')
47
48 subsystem_controller_param_file = LaunchConfiguration('subsystem_controller_param_file')
49 declare_subsystem_controller_param_file_arg = DeclareLaunchArgument(
50 name = 'subsystem_controller_param_file',
51 default_value = subsystem_controller_default_param_file,
52 description = "Path to file containing override parameters for the subsystem controller"
53 )
54
55
56
57
58 gnss_to_map_convertor_param_file = os.path.join(
59 get_package_share_directory('gnss_to_map_convertor'), 'config/parameters.yaml')
60
61 localization_manager_convertor_param_file = os.path.join(
62 get_package_share_directory('localization_manager'), 'config/parameters.yaml')
63
64 vehicle_calibration_dir = LaunchConfiguration('vehicle_calibration_dir')
65 ndt_matching_param_file = [vehicle_calibration_dir, "/lidar_localizer/ndt_matching/params.yaml"]
66
67
68 load_type = LaunchConfiguration('load_type')
69 declare_load_type= DeclareLaunchArgument(name = 'load_type', default_value = "noupdate")
70
71 single_pcd_path = LaunchConfiguration('single_pcd_path')
72 declare_single_pcd_path = DeclareLaunchArgument(name='single_pcd_path', default_value="['/opt/carma/maps/pcd_map.pcd']", description='Path to the map pcd file if using the noupdate load type')
73
74 vehicle_config_dir = LaunchConfiguration('vehicle_config_dir')
75 declare_vehicle_config_dir_arg = DeclareLaunchArgument(
76 name = 'vehicle_config_dir',
77 default_value = "/opt/carma/vehicle/config",
78 description = "Path to vehicle configuration directory populated by carma-config"
79 )
80
81
82
83 global_params_override_file = LaunchConfiguration('global_params_override_file')
84 declare_global_params_override_file_arg = DeclareLaunchArgument(
85 name = 'global_params_override_file',
86 default_value = [vehicle_config_dir, "/GlobalParamsOverride.yaml"],
87 description = "Path to global file containing the parameters overwrite"
88 )
89
90 area = LaunchConfiguration('area')
91 declare_area = DeclareLaunchArgument(name='area', default_value="1x1")
92
93 arealist_path = LaunchConfiguration('arealist_path')
94 declare_arealist_path = DeclareLaunchArgument(name='arealist_path', default_value="/opt/carma/maps/arealist.txt")
95
96 vector_map_file = LaunchConfiguration('vector_map_file')
97 declare_map_file = DeclareLaunchArgument(name='vector_map_file', default_value='vector_map.osm', description='Path to the map osm file if using the noupdate load type')
98
99 use_sim_time = LaunchConfiguration('use_sim_time')
100 declare_use_sim_time_arg = DeclareLaunchArgument(
101 name = 'use_sim_time',
102 default_value = 'False',
103 description = "True if simulation mode is on"
104 )
105
106 gnss_to_map_convertor_container = ComposableNodeContainer(
107 package='carma_ros2_utils',
108 name='gnss_to_map_convertor_container',
109 executable='carma_component_container_mt',
110 namespace=GetCurrentNamespace(),
111 composable_node_descriptions=[
112
113 ComposableNode(
114 package='gnss_to_map_convertor',
115 plugin='gnss_to_map_convertor::Node',
116 name='gnss_to_map_convertor',
117 extra_arguments=[
118 {'use_intra_process_comms': True},
119 ],
120 remappings=[
121 ("gnss_fix_fused", [EnvironmentVariable('CARMA_INTR_NS', default_value=''),"/gnss_fix_fused"]),
122 ("georeference", "map_param_loader/georeference"),
123 ],
124 parameters=[ gnss_to_map_convertor_param_file,
125 vehicle_config_param_file,
126 global_params_override_file]
127 )
128 ])
129
130 localization_manager_container = ComposableNodeContainer(
131 package='carma_ros2_utils',
132 name='localization_manager_container',
133 executable='carma_component_container_mt',
134 namespace=GetCurrentNamespace(),
135 composable_node_descriptions=[
136 ComposableNode(
137 package='localization_manager',
138 plugin='localization_manager::Node',
139 name='localization_manager',
140 extra_arguments=[
141 {'use_intra_process_comms': True},
142 ],
143 remappings=[
144
145 ],
146 parameters=[ localization_manager_convertor_param_file,
147 vehicle_config_param_file,
148 global_params_override_file]
149 )
150 ])
151
152
153
154
155 map_param_loader_container = ComposableNodeContainer(
156 package='carma_ros2_utils',
157 name='map_param_loader_container',
158 executable='carma_component_container_mt',
159 namespace=GetCurrentNamespace(),
160 composable_node_descriptions=[
161 ComposableNode(
162 package='map_file_ros2',
163 plugin='map_param_loader::MapParamLoader',
164 name='map_param_loader',
165 extra_arguments=[
166 {'use_intra_process_comms': True},
167 ],
168 remappings=[
169 ("georeference", "map_param_loader/georeference"),
170 ],
171 parameters=[ {'file_name' : vector_map_file },
172 vehicle_config_param_file,
173 global_params_override_file]
174 )
175 ])
176
177
178 pcd_map_file_loader_container = ComposableNodeContainer(
179 package='carma_ros2_utils',
180 name='map_file_nodes_container',
181 namespace=GetCurrentNamespace(),
182 executable='carma_component_container_mt',
183 composable_node_descriptions=[
184
185 ComposableNode(
186 package='map_file_ros2',
187 plugin='points_map_loader::PointsMapLoader',
188 name='points_map_loader',
189 extra_arguments=[
190 {'use_intra_process_comms': True},
191 ],
192 parameters=[
193 {'load_type' : load_type },
194 {'pcd_path_parameter' : single_pcd_path },
195 {'area' : area },
196 {'path_area_list' : arealist_path },
197 vehicle_config_param_file,
198 global_params_override_file
199 ]
200 ),
201 ]
202 )
203
204
205 dead_reckoner_container = ComposableNodeContainer(
206 package='carma_ros2_utils',
207 name='dead_reckoner_container',
208 namespace=GetCurrentNamespace(),
209 executable='carma_component_container_mt',
210 composable_node_descriptions=[
211
212 ComposableNode(
213 package='dead_reckoner',
214 plugin='dead_reckoner::DeadReckoner',
215 name='dead_reckoner',
216 extra_arguments=[
217 {'use_intra_process_comms': True},
218 ],
219 remappings=[
220 ("current_twist", [EnvironmentVariable('CARMA_INTR_NS', default_value=''), "/vehicle/twist" ]),
221 ("current_odom", "vehicle/odom")
222 ],
223 parameters=[
224 vehicle_config_param_file, global_params_override_file
225 ]
226 ),
227 ]
228 )
229
230
231
232
233
234 ndt_matching_container = ComposableNodeContainer(
235 package='carma_ros2_utils',
236 name='ndt_matching_container',
237 namespace=GetCurrentNamespace(),
238 executable='carma_component_container_mt',
239 composable_node_descriptions=[
240
241 ComposableNode(
242 package='lidar_localizer_ros2',
243 plugin='ndt_matching::NDTMatching',
244 name='ndt_matching',
245 extra_arguments=[
246 {'use_intra_process_comms': True},
247 ],
248 remappings=[
249 ("/config/ndt", "config/ndt"),
250 ("/imu_raw", [ EnvironmentVariable('CARMA_INTR_NS', default_value=''), "/imu_raw" ] ),
251 ('filtered_points', 'random_points'),
252 ('initialpose','managed_initialpose'),
253 ('/tf', '/tf_ndt_UNUSED'),
254 ],
255 parameters=[
256 ndt_matching_param_file,
257 {'get_height' : True },
258 {'use_odom' : True },
259 {'use_gnss' : 0 },
260 {'gnss_reinit_fitness' : 10000.0 },
261 {'base_frame': "base_link"},
262 global_params_override_file
263 ]
264 )
265 ]
266 )
267
268
269
270 ekf_localizer_container = ComposableNodeContainer(
271 condition=UnlessCondition(use_sim_time),
272 package='carma_ros2_utils',
273 name='ekf_localizer_container',
274 namespace=GetCurrentNamespace(),
275 executable='carma_component_container_mt',
276 composable_node_descriptions=[
277
278 ComposableNode(
279 package='ekf_localizer',
280 plugin='ekf_localizer::EKFLocalizer',
281 name='ekf_localizer',
282 extra_arguments=[
283 {'use_intra_process_comms': True},
284 ],
285 remappings=[
286 ("in_pose","selected_pose"),
287 ("in_pose_with_covariance", "input_pose_with_cov_UNUSED"),
288 ("in_twist", [EnvironmentVariable('CARMA_INTR_NS', default_value=''), "/vehicle/twist" ]),
289 ("in_twist_with_covariance", "input_twist_with_covariance_UNUSED"),
290 ("initialpose", "managed_initialpose"),
291 ("ekf_pose", "current_pose"),
292 ("ekf_pose_with_covariance", "current_pose_with_covariance"),
293
294 ("debug", "~/debug"),
295 ("debug/measured_pose", "~/debug/measured_pose"),
296 ("estimated_yaw_bias", "~/estimated_yaw_bias")
297 ],
298 parameters=[
299 {'show_debug_info': False},
300 {'predict_frequency': 50.0},
301 {'enable_yaw_bias_estimation': True},
302 {'extend_state_step': 50},
303 {'pose_frame_id': 'map'},
304 {'child_frame_id': 'base_link'},
305 {'pose_additional_delay': 0.0},
306 {'pose_measure_uncertainty_time': 0.01},
307 {'pose_rate': 10.0},
308 {'pose_gate_dist': 10000.0},
309 {'pose_stddev_x': 0.05},
310 {'pose_stddev_y': 0.05},
311 {'pose_stddev_yaw': 0.025},
312 {'use_pose_with_covariance': False},
313 {'twist_additional_delay': 0.0},
314 {'twist_rate': 30.0},
315 {'twist_gate_dist': 10000.0},
316 {'twist_stddev_vx': 0.2},
317 {'twist_stddev_wz': 0.03},
318 {'proc_stddev_yaw_c': 0.005},
319 {'proc_stddev_yaw_bias_c': 0.001},
320 {'proc_stddev_vx_c': 0.1},
321 {'proc_stddev_wz_c': 0.05},
322 global_params_override_file
323 ],
324 )
325 ]
326 )
327
328
329
330 voxel_grid_filter_container = ComposableNodeContainer(
331 package='carma_ros2_utils',
332 name='voxel_grid_filter_container',
333 namespace=GetCurrentNamespace(),
334 executable='carma_component_container_mt',
335 composable_node_descriptions=[
336
337
338 ComposableNode(
339 package='points_downsampler',
340 plugin='voxel_grid_filter::VoxelGridFilter',
341 name='voxel_grid_filter_node',
342 extra_arguments=[
343 {'use_intra_process_comms': True},
344 ],
345 parameters=[
346 {"points_topic": [EnvironmentVariable('CARMA_INTR_NS', default_value=''), "/lidar/points_raw" ]},
347 {"output_log": False},
348 {"measurement_range": 200.0},
349 {"voxel_leaf_size": 3.0},
350 global_params_override_file
351 ],
352 ),
353 ]
354 )
355
356 random_filter_container = ComposableNodeContainer(
357 package='carma_ros2_utils',
358 name='random_filter_container',
359 namespace=GetCurrentNamespace(),
360 executable='carma_component_container_mt',
361 composable_node_descriptions=[
362
363
364 ComposableNode(
365 package='points_downsampler',
366 plugin='random_filter::RandomFilter',
367 name='random_filter_node',
368 extra_arguments=[
369 {'use_intra_process_comms': True},
370 ],
371 parameters=[
372 {"points_topic": "filtered_points"},
373 {"output_log": False},
374 {"measurement_range": 200.0},
375 {"sample_num": 700},
376 global_params_override_file
377 ],
378 ),
379 ]
380 )
381
382
383 subsystem_controller = Node(
384 package='subsystem_controllers',
385 name='localization_controller',
386 executable='localization_controller',
387 parameters=[
388 subsystem_controller_default_param_file,
389 subsystem_controller_param_file,
390 {"use_sim_time" : use_sim_time}],
391 on_exit= Shutdown(),
392 arguments=['--ros-args', '--log-level', GetLogLevel('subsystem_controllers', env_log_levels)]
393 )
394
395 return LaunchDescription([
396 declare_subsystem_controller_param_file_arg,
397 declare_load_type,
398 declare_single_pcd_path,
399 declare_area,
400 declare_arealist_path,
401 declare_map_file,
402 declare_use_sim_time_arg,
403 declare_vehicle_config_dir_arg,
404 declare_global_params_override_file_arg,
405 gnss_to_map_convertor_container,
406 localization_manager_container,
407 dead_reckoner_container,
408 voxel_grid_filter_container,
409 random_filter_container,
410 map_param_loader_container,
411 pcd_map_file_loader_container,
412 ndt_matching_container,
413 ekf_localizer_container,
414 subsystem_controller
415 ])
def generate_launch_description()