1- # Copyright 2023 Tier IV, Inc. All rights reserved.
1+ # Copyright 2025 Tier IV, Inc. All rights reserved.
22#
33# Licensed under the Apache License, Version 2.0 (the "License");
44# you may not use this file except in compliance with the License.
@@ -57,24 +57,32 @@ def get_vehicle_info(context):
5757 return p
5858
5959
60- def get_vehicle_mirror_info (context ):
61- path = LaunchConfiguration ("vehicle_mirror_param_file" ).perform (context )
62- with open (path , "r" ) as f :
63- p = yaml .safe_load (f )["/**" ]["ros__parameters" ]
64- return p
60+ def load_composable_node_param (context , param_path ):
61+ with open (LaunchConfiguration (param_path ).perform (context ), "r" ) as f :
62+ return yaml .safe_load (f )["/**" ]["ros__parameters" ]
6563
6664
67- def launch_setup (context , * args , ** kwargs ):
68- def load_composable_node_param (param_path ):
69- with open (LaunchConfiguration (param_path ).perform (context ), "r" ) as f :
70- return yaml .safe_load (f )["/**" ]["ros__parameters" ]
65+ def create_parameter_dict (* args ):
66+ result = {}
67+ for x in args :
68+ result [x ] = LaunchConfiguration (x )
69+ return result
70+
71+
72+ def make_common_nodes (context ):
73+ if UnlessCondition (LaunchConfiguration ("use_shared_container" )).evaluate (context ):
74+ return [
75+ ComposableNode (
76+ package = "autoware_glog_component" ,
77+ plugin = "autoware::glog_component::GlogComponent" ,
78+ name = "glog_component" ,
79+ )
80+ ]
81+
82+ return []
7183
72- def create_parameter_dict (* args ):
73- result = {}
74- for x in args :
75- result [x ] = LaunchConfiguration (x )
76- return result
7784
85+ def make_nebula_nodes (context ):
7886 # Model and make
7987 sensor_model = LaunchConfiguration ("sensor_model" ).perform (context )
8088 sensor_make , sensor_extension = get_lidar_make (sensor_model )
@@ -94,27 +102,7 @@ def create_parameter_dict(*args):
94102 else : # Robosense
95103 sensor_calib_fp = ""
96104
97- # Pointcloud preprocessor parameters
98- distortion_corrector_node_param = ParameterFile (
99- param_file = LaunchConfiguration ("distortion_correction_node_param_path" ).perform (context ),
100- allow_substs = True ,
101- )
102- ring_outlier_filter_node_param = ParameterFile (
103- param_file = LaunchConfiguration ("ring_outlier_filter_node_param_path" ).perform (context ),
104- allow_substs = True ,
105- )
106-
107- nodes = []
108-
109- nodes .append (
110- ComposableNode (
111- package = "autoware_glog_component" ,
112- plugin = "autoware::glog_component::GlogComponent" ,
113- name = "glog_component" ,
114- )
115- )
116-
117- nodes .append (
105+ return [
118106 ComposableNode (
119107 package = "nebula_ros" ,
120108 plugin = sensor_make + "RosWrapper" ,
@@ -163,6 +151,86 @@ def create_parameter_dict(*args):
163151 ],
164152 extra_arguments = [{"use_intra_process_comms" : LaunchConfiguration ("use_intra_process" )}],
165153 )
154+ ]
155+
156+
157+ def make_cuda_preprocessor_nodes (context ):
158+ # Vehicle parameters
159+ vehicle_info = get_vehicle_info (context )
160+ mirror_info = load_composable_node_param (context , "vehicle_mirror_param_file" )
161+
162+ # Pointcloud preprocessor parameters
163+ distortion_corrector_node_param = ParameterFile (
164+ param_file = LaunchConfiguration ("distortion_correction_node_param_path" ).perform (context ),
165+ allow_substs = True ,
166+ )
167+ ring_outlier_filter_node_param = ParameterFile (
168+ param_file = LaunchConfiguration ("ring_outlier_filter_node_param_path" ).perform (context ),
169+ allow_substs = True ,
170+ )
171+
172+ preprocessor_parameters = {}
173+ preprocessor_parameters ["crop_box.min_x" ] = [
174+ vehicle_info ["min_longitudinal_offset" ],
175+ mirror_info ["min_longitudinal_offset" ],
176+ ]
177+ preprocessor_parameters ["crop_box.max_x" ] = [
178+ vehicle_info ["max_longitudinal_offset" ],
179+ mirror_info ["max_longitudinal_offset" ],
180+ ]
181+ preprocessor_parameters ["crop_box.min_y" ] = [
182+ vehicle_info ["min_lateral_offset" ],
183+ mirror_info ["min_lateral_offset" ],
184+ ]
185+ preprocessor_parameters ["crop_box.max_y" ] = [
186+ vehicle_info ["max_lateral_offset" ],
187+ mirror_info ["max_lateral_offset" ],
188+ ]
189+ preprocessor_parameters ["crop_box.min_z" ] = [
190+ vehicle_info ["min_height_offset" ],
191+ mirror_info ["min_height_offset" ],
192+ ]
193+ preprocessor_parameters ["crop_box.max_z" ] = [
194+ vehicle_info ["max_height_offset" ],
195+ mirror_info ["max_height_offset" ],
196+ ]
197+
198+ return [
199+ ComposableNode (
200+ package = "autoware_cuda_pointcloud_preprocessor" ,
201+ plugin = "autoware::cuda_pointcloud_preprocessor::CudaPointcloudPreprocessorNode" ,
202+ name = "cuda_pointcloud_preprocessor_node" ,
203+ parameters = [
204+ preprocessor_parameters ,
205+ distortion_corrector_node_param ,
206+ ring_outlier_filter_node_param ,
207+ ],
208+ remappings = [
209+ ("~/input/pointcloud" , "pointcloud_raw_ex" ),
210+ ("~/input/twist" , "/sensing/vehicle_velocity_converter/twist_with_covariance" ),
211+ ("~/input/imu" , "/sensing/imu/imu_data" ),
212+ ("~/output/pointcloud" , "pointcloud_before_sync" ),
213+ ("~/output/pointcloud/cuda" , "pointcloud_before_sync/cuda" ),
214+ ],
215+ # The whole node can not set use_intra_process due to type negotiation internal topics
216+ # extra_arguments=[{"use_intra_process_comms": LaunchConfiguration("use_intra_process")}],
217+ )
218+ ]
219+
220+
221+ def make_preprocessor_nodes (context ):
222+ # Vehicle parameters
223+ vehicle_info = get_vehicle_info (context )
224+ mirror_info = load_composable_node_param (context , "vehicle_mirror_param_file" )
225+
226+ # Pointcloud preprocessor parameters
227+ distortion_corrector_node_param = ParameterFile (
228+ param_file = LaunchConfiguration ("distortion_correction_node_param_path" ).perform (context ),
229+ allow_substs = True ,
230+ )
231+ ring_outlier_filter_node_param = ParameterFile (
232+ param_file = LaunchConfiguration ("ring_outlier_filter_node_param_path" ).perform (context ),
233+ allow_substs = True ,
166234 )
167235
168236 cropbox_parameters = create_parameter_dict ("input_frame" , "output_frame" )
@@ -176,6 +244,8 @@ def create_parameter_dict(*args):
176244 cropbox_parameters ["min_z" ] = vehicle_info ["min_height_offset" ]
177245 cropbox_parameters ["max_z" ] = vehicle_info ["max_height_offset" ]
178246
247+ nodes = []
248+
179249 nodes .append (
180250 ComposableNode (
181251 package = "autoware_pointcloud_preprocessor" ,
@@ -190,7 +260,6 @@ def create_parameter_dict(*args):
190260 )
191261 )
192262
193- mirror_info = get_vehicle_mirror_info (context )
194263 cropbox_parameters ["min_x" ] = mirror_info ["min_longitudinal_offset" ]
195264 cropbox_parameters ["max_x" ] = mirror_info ["max_longitudinal_offset" ]
196265 cropbox_parameters ["min_y" ] = mirror_info ["min_lateral_offset" ]
@@ -249,6 +318,58 @@ def create_parameter_dict(*args):
249318 )
250319 )
251320
321+ return nodes
322+
323+
324+ def make_blockage_diag_nodes (context ):
325+ return [
326+ ComposableNode (
327+ package = "autoware_pointcloud_preprocessor" ,
328+ plugin = "autoware::pointcloud_preprocessor::BlockageDiagComponent" ,
329+ name = "blockage_diag" ,
330+ remappings = [
331+ ("input" , "pointcloud_raw_ex" ),
332+ ("output" , "blockage_diag/pointcloud" ),
333+ ],
334+ parameters = [
335+ {
336+ "angle_range" : [
337+ float (context .perform_substitution (LaunchConfiguration ("cloud_min_angle" ))),
338+ float (context .perform_substitution (LaunchConfiguration ("cloud_max_angle" ))),
339+ ],
340+ "horizontal_ring_id" : LaunchConfiguration ("horizontal_ring_id" ),
341+ "vertical_bins" : LaunchConfiguration ("vertical_bins" ),
342+ "is_channel_order_top2down" : LaunchConfiguration ("is_channel_order_top2down" ),
343+ "max_distance_range" : LaunchConfiguration ("max_range" ),
344+ "horizontal_resolution" : LaunchConfiguration ("horizontal_resolution" ),
345+ }
346+ ]
347+ + [load_composable_node_param (context , "blockage_diagnostics_param_file" )],
348+ extra_arguments = [{"use_intra_process_comms" : LaunchConfiguration ("use_intra_process" )}],
349+ )
350+ ]
351+
352+
353+ def launch_setup (context , * args , ** kwargs ):
354+ # Check that the cuda preprocessor is only used with a shared container
355+ if IfCondition (LaunchConfiguration ("use_cuda_preprocessor" )).evaluate (context ):
356+ assert IfCondition (LaunchConfiguration ("use_shared_container" )).evaluate (
357+ context
358+ ), "The cuda preprocessor should only be used with a shared container."
359+
360+ nodes = []
361+
362+ nodes .extend (make_common_nodes (context ))
363+ nodes .extend (make_nebula_nodes (context ))
364+
365+ if IfCondition (LaunchConfiguration ("use_cuda_preprocessor" )).evaluate (context ):
366+ nodes .extend (make_cuda_preprocessor_nodes (context ))
367+ else :
368+ nodes .extend (make_preprocessor_nodes (context ))
369+
370+ if IfCondition (LaunchConfiguration ("enable_blockage_diag" )).evaluate (context ):
371+ nodes .extend (make_blockage_diag_nodes (context ))
372+
252373 # set container to run all required components in the same process
253374 container = ComposableNodeContainer (
254375 name = LaunchConfiguration ("container_name" ),
@@ -257,40 +378,16 @@ def create_parameter_dict(*args):
257378 executable = LaunchConfiguration ("container_executable" ),
258379 composable_node_descriptions = nodes ,
259380 output = "both" ,
381+ condition = UnlessCondition (LaunchConfiguration ("use_shared_container" )),
260382 )
261383
262- blockage_diag_component = ComposableNode (
263- package = "autoware_pointcloud_preprocessor" ,
264- plugin = "autoware::pointcloud_preprocessor::BlockageDiagComponent" ,
265- name = "blockage_diag" ,
266- remappings = [
267- ("input" , "pointcloud_raw_ex" ),
268- ("output" , "blockage_diag/pointcloud" ),
269- ],
270- parameters = [
271- {
272- "angle_range" : [
273- float (context .perform_substitution (LaunchConfiguration ("cloud_min_angle" ))),
274- float (context .perform_substitution (LaunchConfiguration ("cloud_max_angle" ))),
275- ],
276- "horizontal_ring_id" : LaunchConfiguration ("horizontal_ring_id" ),
277- "vertical_bins" : LaunchConfiguration ("vertical_bins" ),
278- "is_channel_order_top2down" : LaunchConfiguration ("is_channel_order_top2down" ),
279- "max_distance_range" : LaunchConfiguration ("max_range" ),
280- "horizontal_resolution" : LaunchConfiguration ("horizontal_resolution" ),
281- }
282- ]
283- + [load_composable_node_param ("blockage_diagnostics_param_file" )],
284- extra_arguments = [{"use_intra_process_comms" : LaunchConfiguration ("use_intra_process" )}],
285- )
286-
287- blockage_diag_loader = LoadComposableNodes (
288- composable_node_descriptions = [blockage_diag_component ],
289- target_container = container ,
290- condition = IfCondition (LaunchConfiguration ("enable_blockage_diag" )),
384+ load_composable_nodes = LoadComposableNodes (
385+ composable_node_descriptions = nodes ,
386+ target_container = LaunchConfiguration ("container_name" ),
387+ condition = IfCondition (LaunchConfiguration ("use_shared_container" )),
291388 )
292389
293- return [container , blockage_diag_loader ]
390+ return [container , load_composable_nodes ]
294391
295392
296393def generate_launch_description ():
@@ -336,7 +433,21 @@ def add_launch_arg(name: str, default_value=None, description=None):
336433 add_launch_arg ("advanced_diagnostics" , "false" )
337434 add_launch_arg ("use_multithread" , "False" , "use multithread" )
338435 add_launch_arg ("use_intra_process" , "False" , "use ROS 2 component container communication" )
339- add_launch_arg ("lidar_container_name" , "nebula_node_container" )
436+ add_launch_arg (
437+ "lidar_container_name" ,
438+ "nebula_node_container" ,
439+ "Name of the new container to be created when use_shared_container is false" ,
440+ )
441+ add_launch_arg (
442+ "use_shared_container" ,
443+ "False" ,
444+ "Whether to use a new container for this lidar or use an existing one" ,
445+ )
446+ add_launch_arg (
447+ "use_cuda_preprocessor" ,
448+ "False" ,
449+ "Use the cuda implementation of the pointcloud preprocessor. Requires use_shared_container to be enabled" ,
450+ )
340451 add_launch_arg ("ptp_profile" , "1588v2" )
341452 add_launch_arg ("ptp_transport_type" , "L2" )
342453 add_launch_arg ("ptp_switch_type" , "TSN" )
0 commit comments