23
23
from launch_ros .actions import LoadComposableNodes
24
24
from launch_ros .descriptions import ComposableNode
25
25
from launch_ros .parameter_descriptions import ParameterFile
26
+ from launch_ros .substitutions import FindPackageShare
26
27
import yaml
27
28
from ament_index_python .packages import get_package_share_directory
28
29
from pathlib import Path
29
30
31
+ def get_lidar_make (sensor_name ):
32
+ if sensor_name [:6 ].lower () == "pandar" :
33
+ return "Hesai" , ".csv"
34
+ elif sensor_name [:3 ].lower () in ["hdl" , "vlp" , "vls" ]:
35
+ return "Velodyne" , ".yaml"
36
+ return "unrecognized_sensor_model"
30
37
31
38
def get_vehicle_info (context ):
32
39
# TODO(TIER IV): Use Parameter Substitution after we drop Galactic support
@@ -62,6 +69,99 @@ def create_parameter_dict(*args):
62
69
63
70
nodes = []
64
71
72
+ # Model and make
73
+ sensor_model = LaunchConfiguration ("sensor_model" ).perform (context )
74
+ sensor_make , sensor_extension = get_lidar_make (sensor_model )
75
+ nebula_decoders_share_dir = Path (get_package_share_directory ("nebula_decoders" ))
76
+
77
+ # Calibration file
78
+ sensor_calib_fp = (
79
+ nebula_decoders_share_dir
80
+ / "calibration"
81
+ / sensor_make .lower ()
82
+ / (sensor_model + sensor_extension )
83
+ )
84
+ assert (
85
+ sensor_calib_fp .exists ()
86
+ ), f"Sensor calib file under calibration/ was not found: { sensor_calib_fp } "
87
+ sensor_calib_fp = str (sensor_calib_fp )
88
+
89
+ nodes = []
90
+
91
+ nodes .append (
92
+ ComposableNode (
93
+ package = "glog_component" ,
94
+ plugin = "GlogComponent" ,
95
+ name = "glog_component" ,
96
+ )
97
+ )
98
+
99
+ nodes .append (
100
+ ComposableNode (
101
+ package = "nebula_ros" ,
102
+ plugin = sensor_make + "DriverRosWrapper" ,
103
+ name = sensor_make .lower () + "_driver_ros_wrapper_node" ,
104
+ parameters = [
105
+ {
106
+ "calibration_file" : sensor_calib_fp ,
107
+ "sensor_model" : sensor_model ,
108
+ ** create_parameter_dict (
109
+ "host_ip" ,
110
+ "sensor_ip" ,
111
+ "data_port" ,
112
+ "return_mode" ,
113
+ "min_range" ,
114
+ "max_range" ,
115
+ "frame_id" ,
116
+ "scan_phase" ,
117
+ "cloud_min_angle" ,
118
+ "cloud_max_angle" ,
119
+ "dual_return_distance_threshold" ,
120
+ "setup_sensor" ,
121
+ "retry_hw" ,
122
+ ),
123
+ },
124
+ ],
125
+ remappings = [
126
+ # cSpell:ignore knzo25
127
+ # TODO(knzo25): fix the remapping once nebula gets updated
128
+ ("pandar_points" , "pointcloud_raw_ex" ),
129
+ ("velodyne_points" , "pointcloud_raw_ex" ),
130
+ ],
131
+ extra_arguments = [{"use_intra_process_comms" : LaunchConfiguration ("use_intra_process" )}],
132
+ )
133
+ )
134
+
135
+ nodes .append (
136
+ ComposableNode (
137
+ package = "nebula_ros" ,
138
+ plugin = sensor_make + "HwMonitorRosWrapper" ,
139
+ name = sensor_make .lower () + "_hw_monitor_ros_wrapper_node" ,
140
+ parameters = [
141
+ {
142
+ "sensor_model" : sensor_model ,
143
+ ** create_parameter_dict (
144
+ "return_mode" ,
145
+ "frame_id" ,
146
+ "scan_phase" ,
147
+ "sensor_ip" ,
148
+ "host_ip" ,
149
+ "data_port" ,
150
+ "gnss_port" ,
151
+ "packet_mtu_size" ,
152
+ "rotation_speed" ,
153
+ "cloud_min_angle" ,
154
+ "cloud_max_angle" ,
155
+ "diag_span" ,
156
+ "dual_return_distance_threshold" ,
157
+ "delay_monitor_ms" ,
158
+ ),
159
+ },
160
+ ],
161
+ extra_arguments = [{"use_intra_process_comms" : LaunchConfiguration ("use_intra_process" )}],
162
+ )
163
+ )
164
+
65
165
cropbox_parameters = create_parameter_dict ("input_frame" , "output_frame" )
66
166
cropbox_parameters ["negative" ] = True
67
167
@@ -147,6 +247,45 @@ def create_parameter_dict(*args):
147
247
composable_node_descriptions = nodes ,
148
248
)
149
249
250
+ driver_component = ComposableNode (
251
+ package = "nebula_ros" ,
252
+ plugin = sensor_make + "HwInterfaceRosWrapper" ,
253
+ # node is created in a global context, need to avoid name clash
254
+ name = sensor_make .lower () + "_hw_interface_ros_wrapper_node" ,
255
+ parameters = [
256
+ {
257
+ "sensor_model" : sensor_model ,
258
+ "calibration_file" : sensor_calib_fp ,
259
+ ** create_parameter_dict (
260
+ "sensor_ip" ,
261
+ "host_ip" ,
262
+ "scan_phase" ,
263
+ "return_mode" ,
264
+ "frame_id" ,
265
+ "rotation_speed" ,
266
+ "data_port" ,
267
+ "gnss_port" ,
268
+ "cloud_min_angle" ,
269
+ "cloud_max_angle" ,
270
+ "packet_mtu_size" ,
271
+ "dual_return_distance_threshold" ,
272
+ "setup_sensor" ,
273
+ "ptp_profile" ,
274
+ "ptp_transport_type" ,
275
+ "ptp_switch_type" ,
276
+ "ptp_domain" ,
277
+ "retry_hw" ,
278
+ ),
279
+ }
280
+ ],
281
+ )
282
+
283
+ driver_component_loader = LoadComposableNodes (
284
+ composable_node_descriptions = [driver_component ],
285
+ target_container = container ,
286
+ condition = IfCondition (LaunchConfiguration ("launch_driver" )),
287
+ )
288
+
150
289
distortion_component = ComposableNode (
151
290
package = "autoware_pointcloud_preprocessor" ,
152
291
plugin = "autoware::pointcloud_preprocessor::DistortionCorrectorComponent" ,
@@ -185,7 +324,7 @@ def create_parameter_dict(*args):
185
324
condition = launch .conditions .UnlessCondition (LaunchConfiguration ("use_distortion_corrector" )),
186
325
)
187
326
188
- return [container , distortion_loader , distortion_relay_loader ]
327
+ return [container , driver_component_loader , distortion_loader , distortion_relay_loader ]
189
328
190
329
191
330
def generate_launch_description ():
@@ -201,21 +340,50 @@ def add_launch_arg(name: str, default_value=None, description=None):
201
340
get_package_share_directory ("common_awsim_sensor_launch" )
202
341
)
203
342
343
+ add_launch_arg ("sensor_model" , description = "sensor model name" )
344
+ add_launch_arg ("config_file" , "" , description = "sensor configuration file" )
345
+ add_launch_arg ("launch_driver" , "True" , "do launch driver" )
346
+ add_launch_arg ("setup_sensor" , "True" , "configure sensor" )
347
+ add_launch_arg ("retry_hw" , "false" , "retry hw" )
348
+ add_launch_arg ("sensor_ip" , "192.168.1.201" , "device ip address" )
349
+ add_launch_arg ("host_ip" , "255.255.255.255" , "host ip address" )
350
+ add_launch_arg ("scan_phase" , "0.0" )
204
351
add_launch_arg ("base_frame" , "base_link" , "base frame id" )
205
- add_launch_arg ("container_name" , "velodyne_composable_node_container" , "container name" )
352
+ add_launch_arg ("min_range" , "0.3" , "minimum view range for Velodyne sensors" )
353
+ add_launch_arg ("max_range" , "300.0" , "maximum view range for Velodyne sensors" )
354
+ add_launch_arg ("cloud_min_angle" , "0" , "minimum view angle setting on device" )
355
+ add_launch_arg ("cloud_max_angle" , "360" , "maximum view angle setting on device" )
356
+ add_launch_arg ("data_port" , "2368" , "device data port number" )
357
+ add_launch_arg ("gnss_port" , "2380" , "device gnss port number" )
358
+ add_launch_arg ("packet_mtu_size" , "1500" , "packet mtu size" )
359
+ add_launch_arg ("rotation_speed" , "600" , "rotational frequency" )
360
+ add_launch_arg ("dual_return_distance_threshold" , "0.1" , "dual return distance threshold" )
361
+ add_launch_arg ("frame_id" , "lidar" , "frame id" )
206
362
add_launch_arg ("input_frame" , LaunchConfiguration ("base_frame" ), "use for cropbox" )
207
363
add_launch_arg ("output_frame" , LaunchConfiguration ("base_frame" ), "use for cropbox" )
208
364
add_launch_arg (
209
365
"vehicle_mirror_param_file" , description = "path to the file of vehicle mirror position yaml"
210
366
)
211
367
add_launch_arg ("use_multithread" , "False" , "use multithread" )
212
- add_launch_arg ("use_intra_process" , "False" , "use ROS2 component container communication" )
368
+ add_launch_arg ("use_intra_process" , "False" , "use ROS 2 component container communication" )
213
369
add_launch_arg ("output_as_sensor_frame" , "False" , "output final pointcloud in sensor frame" )
214
370
add_launch_arg ("frame_id" , "base_link" , "frame id" )
215
371
add_launch_arg (
216
372
"ring_outlier_filter_node_param_path" ,
217
373
str (common_sensor_share_dir / "config" / "ring_outlier_filter_node.param.yaml" ),
218
- description = "path to parameter file of ring outlier filter node" ,
374
+ description = "path to parameter file of ring outlier filter node" )
375
+ add_launch_arg ("container_name" , "nebula_node_container" )
376
+ add_launch_arg ("ptp_profile" , "1588v2" )
377
+ add_launch_arg ("ptp_transport_type" , "L2" )
378
+ add_launch_arg ("ptp_switch_type" , "TSN" )
379
+ add_launch_arg ("ptp_domain" , "0" )
380
+ add_launch_arg ("output_as_sensor_frame" , "True" , "output final pointcloud in sensor frame" )
381
+ add_launch_arg ("diag_span" , "1000" , "" )
382
+ add_launch_arg ("delay_monitor_ms" , "2000" , "" )
383
+
384
+ add_launch_arg (
385
+ "distortion_corrector_node_param_file" ,
386
+ [FindPackageShare ("common_sensor_launch" ), "/config/distortion_corrector_node.param.yaml" ],
219
387
)
220
388
221
389
set_container_executable = SetLaunchConfiguration (
0 commit comments