Formula Student Autonomous Systems
The code for the main driverless system
Loading...
Searching...
No Matches
data_infrastructure_node.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2
3import rclpy
4import yaml
5from rclpy.node import Node
6from std_msgs.msg import Float64, Float64MultiArray
7from visualization_msgs.msg import Marker, MarkerArray
8from custom_interfaces.msg import (
9 PathPointArray,
10 Velocities,
11 ConeArray,
12 Pose,
13 ControlParameters,
14 PerceptionParameters,
15 PlanningParameters,
16 SlamParameters,
17 VelocityEstimationParameters,
18)
19
20CONTROL_PATH = "config/control/vehicle.yaml"
21PERCEPTION_PATH = "config/perception/vehicle.yaml"
22PLANNING_PATH = "config/planning/vehicle.yaml"
23SLAM_PATH = "config/slam/vehicle.yaml"
24VELOCITY_ESTIMATION_PATH = "config/velocity_estimation/vehicle.yaml"
25
26
28 def __init__(self):
29 super().__init__("data_infrastructure_node")
30 self.shutdown = False
31 self.get_logger().info("Subscribing the publishers.")
32 # Control publishers
33 self.create_subscription(
34 Marker, "/control/visualization/closest_point", self.common_callbackcommon_callback, 10
35 )
36 self.create_subscription(
37 Marker, "/control/visualization/lookahead_point", self.common_callbackcommon_callback, 10
38 )
39 # Planning publishers
40 self.create_subscription(
41 PathPointArray, "/path_planning/path", self.common_callbackcommon_callback, 10
42 )
43 self.create_subscription(
44 Float64, "/path_planning/execution_time", self.common_callbackcommon_callback, 10
45 )
46 self.create_subscription(
47 Marker, "/path_planning/smoothed_path", self.common_callbackcommon_callback, 10
48 )
49 self.create_subscription(
50 MarkerArray, "/path_planning/triangulations", self.common_callbackcommon_callback, 10
51 )
52 # Slam publishers
53 self.create_subscription(
54 ConeArray, "/state_estimation/map", self.common_callbackcommon_callback, 10
55 )
56 self.create_subscription(
57 Pose, "/state_estimation/vehicle_pose", self.common_callbackcommon_callback, 10
58 )
59 self.create_subscription(
60 MarkerArray, "/state_estimation/visualization_map", self.common_callbackcommon_callback, 10
61 )
62 self.create_subscription(
63 MarkerArray,
64 "/state_estimation/visualization_map_perception",
66 10,
67 )
68 self.create_subscription(
69 Marker, "/state_estimation/visualization/position", self.common_callbackcommon_callback, 10
70 )
71 self.create_subscription(
72 Float64MultiArray,
73 "/state_estimation/slam_execution_time",
75 10,
76 )
77 self.create_subscription(
78 Float64MultiArray,
79 "/state_estimation/slam_covariance",
81 10,
82 )
83 self.create_subscription(
84 Float64, "/state_estimation/lap_counter", self.common_callbackcommon_callback, 10
85 )
86 # Velocity Estimation publishers
87 self.create_subscription(
88 Velocities, "/state_estimation/velocities", self.common_callbackcommon_callback, 10
89 )
90
91 # Publishers
92 self.control_par_pub = self.create_publisher(
93 ControlParameters, "data_infrastructure/control_parameters", 10
94 )
95 self.perception_par_pub = self.create_publisher(
96 PerceptionParameters, "data_infrastructure/perception_parameters", 10
97 )
98 self.planning_par_pub = self.create_publisher(
99 PlanningParameters, "data_infrastructure/planning_parameters", 10
100 )
101 self.slam_par_pub = self.create_publisher(
102 SlamParameters, "data_infrastructure/slam_parameters", 10
103 )
104 self.velocity_par_pub = self.create_publisher(
105 VelocityEstimationParameters,
106 "data_infrastructure/velocity_estimation_parameters",
107 10,
108 )
109
110 def load_yaml(self, path, root_key):
111 try:
112 with open(path, "r") as file:
113 data = yaml.safe_load(file)
114 return data.get(root_key, {})
115 except Exception as e:
116 self.get_logger().error(f"Failed to load {path}: {e}")
117 return {}
118
120 control_msg = ControlParameters()
121 parameters = self.load_yaml(CONTROL_PATH, "control")
122 control_msg.lookahead_gain = float(parameters.get("lookahead_gain", 0.0))
123 control_msg.pid_kp = float(parameters.get("pid_kp", 0.0))
124 control_msg.pid_ki = float(parameters.get("pid_ki", 0.0))
125 control_msg.pid_kd = float(parameters.get("pid_kd", 0.0))
126 control_msg.pid_tau = float(parameters.get("pid_tau", 0.0))
127 control_msg.pid_t = float(parameters.get("pid_t", 0.0))
128 control_msg.pid_lim_min = float(parameters.get("pid_lim_min", 0.0))
129 control_msg.pid_lim_max = float(parameters.get("pid_lim_max", 0.0))
130 control_msg.pid_anti_windup = float(parameters.get("pid_anti_windup", 0.0))
131 control_msg.lpf_alpha = float(parameters.get("lpf_alpha", 0.0))
132 control_msg.lpf_initial_value = float(parameters.get("lpf_initial_value", 0.0))
133 self.control_par_pub.publish(control_msg)
134
136 perception_msg = PerceptionParameters()
137 parameters = self.load_yaml(PERCEPTION_PATH, "perception")
138
139 # TRACKDRIVE/AUTOCROSS
140 perception_msg.horizontal_resolution = float(
141 parameters.get("horizontal_resolution", 0.0)
142 )
143 perception_msg.vertical_resolution = float(
144 parameters.get("vertical_resolution", 0.0)
145 )
146 perception_msg.default_mission = parameters.get("default_mission", "")
147
148 # FOV
149 perception_msg.lidar_height = float(parameters.get("lidar_height", 0.0))
150 perception_msg.lidar_rotation = float(parameters.get("lidar_rotation", 0.0))
151 perception_msg.lidar_pitch = float(parameters.get("lidar_pitch", 0.0))
152 perception_msg.min_range = float(parameters.get("min_range", 0.0))
153 perception_msg.max_height = float(parameters.get("max_height", 0.0))
154
155 # TRACKDRIVE/AUTOCROSS
156 perception_msg.max_range = float(parameters.get("max_range", 0.0))
157 perception_msg.fov_trim_angle = float(parameters.get("fov_trim_angle", 0.0))
158
159 # ACCELERATION
160 perception_msg.acc_max_range = float(parameters.get("acc_max_range", 0.0))
161 perception_msg.acc_fov_trim_angle = float(
162 parameters.get("acc_fov_trim_angle", 0.0)
163 )
164 perception_msg.acc_max_y = float(parameters.get("acc_max_y", 0.0))
165
166 # SKIDPAD
167 perception_msg.skid_max_range = float(parameters.get("skid_max_range", 0.0))
168 perception_msg.skid_min_distance_to_cone = float(
169 parameters.get("skid_min_distance_to_cone", 0.0)
170 )
171
172 # Ground removal
173 perception_msg.ground_removal = parameters.get("ground_removal", "")
174 perception_msg.ransac_epsilon = float(parameters.get("ransac_epsilon", 0.0))
175 perception_msg.ransac_iterations = int(parameters.get("ransac_iterations", 0))
176
177 # TRACKDRIVE/AUTOCROSS GROUND REMOVAL
178 perception_msg.n_angular_grids = int(parameters.get("n_angular_grids", 0))
179 perception_msg.radius_resolution = float(
180 parameters.get("radius_resolution", 0.0)
181 )
182
183 # ACCELERATION GROUND REMOVAL
184 perception_msg.acc_n_angular_grids = int(
185 parameters.get("acc_n_angular_grids", 0)
186 )
187 perception_msg.acc_radius_resolution = float(
188 parameters.get("acc_radius_resolution", 0.0)
189 )
190
191 # SKIDPAD GROUND REMOVAL
192 perception_msg.skid_n_angular_grids = int(
193 parameters.get("skid_n_angular_grids", 0)
194 )
195 perception_msg.skid_radius_resolution = float(
196 parameters.get("skid_radius_resolution", 0.0)
197 )
198
199 # Clustering
200 perception_msg.clustering_n_neighbours = int(
201 parameters.get("clustering_n_neighbours", 0)
202 )
203 perception_msg.clustering_epsilon = float(
204 parameters.get("clustering_epsilon", 0.0)
205 )
206
207 # Evaluator
208 perception_msg.min_height = float(parameters.get("min_height", 0.0))
209 perception_msg.large_max_height = float(parameters.get("large_max_height", 0.0))
210 perception_msg.small_max_height = float(parameters.get("small_max_height", 0.0))
211 perception_msg.height_cap = float(parameters.get("height_cap", 0.0))
212 perception_msg.min_xoy = float(parameters.get("min_xoy", 0.0))
213 perception_msg.max_xoy = float(parameters.get("max_xoy", 0.0))
214 perception_msg.min_z = float(parameters.get("min_z", 0.0))
215 perception_msg.max_z = float(parameters.get("max_z", 0.0))
216 perception_msg.min_z_score_x = float(parameters.get("min_z_score_x", 0.0))
217 perception_msg.max_z_score_x = float(parameters.get("max_z_score_x", 0.0))
218 perception_msg.min_z_score_y = float(parameters.get("min_z_score_y", 0.0))
219 perception_msg.max_z_score_y = float(parameters.get("max_z_score_y", 0.0))
220 perception_msg.out_distance_cap = float(parameters.get("out_distance_cap", 0.0))
221 perception_msg.min_distance_x = float(parameters.get("min_distance_x", 0.0))
222 perception_msg.min_distance_y = float(parameters.get("min_distance_y", 0.0))
223 perception_msg.min_distance_z = float(parameters.get("min_distance_z", 0.0))
224 perception_msg.min_n_points = int(parameters.get("min_n_points", 0))
225 perception_msg.min_confidence = float(parameters.get("min_confidence", 0.0))
226 perception_msg.height_out_weight = float(
227 parameters.get("height_out_weight", 0.0)
228 )
229 perception_msg.height_in_weight = float(parameters.get("height_in_weight", 0.0))
230 perception_msg.cylinder_radius_weight = float(
231 parameters.get("cylinder_radius_weight", 0.0)
232 )
233 perception_msg.cylinder_height_weight = float(
234 parameters.get("cylinder_height_weight", 0.0)
235 )
236 perception_msg.cylinder_npoints_weight = float(
237 parameters.get("cylinder_npoints_weight", 0.0)
238 )
239 perception_msg.npoints_weight = float(parameters.get("npoints_weight", 0.0))
240 perception_msg.displacement_x_weight = float(
241 parameters.get("displacement_x_weight", 0.0)
242 )
243 perception_msg.displacement_y_weight = float(
244 parameters.get("displacement_y_weight", 0.0)
245 )
246 perception_msg.displacement_z_weight = float(
247 parameters.get("displacement_z_weight", 0.0)
248 )
249 perception_msg.deviation_xoy_weight = float(
250 parameters.get("deviation_xoy_weight", 0.0)
251 )
252 perception_msg.deviation_z_weight = float(
253 parameters.get("deviation_z_weight", 0.0)
254 )
255 self.perception_par_pub.publish(perception_msg)
256
258 planning_msg = PlanningParameters()
259 parameters = self.load_yaml(PLANNING_PATH, "planning")
260 planning_msg.nc_angle_gain = float(parameters.get("nc_angle_gain", 0.0))
261 planning_msg.nc_distance_gain = float(parameters.get("nc_distance_gain", 0.0))
262 planning_msg.nc_angle_exponent = float(parameters.get("nc_angle_exponent", 0.0))
263 planning_msg.nc_distance_exponent = float(
264 parameters.get("nc_distance_exponent", 0.0)
265 )
266 planning_msg.nc_max_cost = float(parameters.get("nc_max_cost", 0.0))
267 planning_msg.nc_search_depth = int(parameters.get("nc_search_depth", 0))
268 planning_msg.nc_max_points = int(parameters.get("nc_max_points", 0))
269 planning_msg.outliers_spline_order = int(
270 parameters.get("outliers_spline_order", 0)
271 )
272 planning_msg.outliers_spline_coeffs_ratio = float(
273 parameters.get("outliers_spline_coeffs_ratio", 0.0)
274 )
275 planning_msg.outliers_spline_precision = int(
276 parameters.get("outliers_spline_precision", 0)
277 )
278 planning_msg.path_calculation_dist_threshold = float(
279 parameters.get("path_calculation_dist_threshold", 0.0)
280 )
281 planning_msg.smoothing_spline_order = int(
282 parameters.get("smoothing_spline_order", 0)
283 )
284 planning_msg.smoothing_spline_coeffs_ratio = float(
285 parameters.get("smoothing_spline_coeffs_ratio", 0.0)
286 )
287 planning_msg.smoothing_spline_precision = int(
288 parameters.get("smoothing_spline_precision", 0)
289 )
290 planning_msg.publishing_visualization_msg = bool(
291 parameters.get("publishing_visualization_msg", False)
292 )
293 planning_msg.desired_velocity = float(parameters.get("desired_velocity", 0.0))
294 planning_msg.use_outlier_removal = bool(
295 parameters.get("use_outlier_removal", False)
296 )
297 planning_msg.use_path_smoothing = bool(
298 parameters.get("use_path_smoothing", False)
299 )
300 planning_msg.minimum_velocity = float(parameters.get("minimum_velocity", 0.0))
301 planning_msg.braking_acceleration = float(
302 parameters.get("braking_acceleration", 0.0)
303 )
304 planning_msg.normal_acceleration = float(
305 parameters.get("normal_acceleration", 0.0)
306 )
307 planning_msg.use_velocity_planning = bool(
308 parameters.get("use_velocity_planning", False)
309 )
310 self.planning_par_pub.publish(planning_msg)
311
313 slam_msg = SlamParameters()
314 parameters = self.load_yaml(SLAM_PATH, "slam")
315 slam_msg.motion_model_name = parameters.get("motion_model_name", "")
316 slam_msg.landmark_filter_name = parameters.get("landmark_filter_name", "")
317 slam_msg.data_association_model_name = parameters.get(
318 "data_association_model_name", ""
319 )
320 slam_msg.data_association_limit_distance = float(
321 parameters.get("data_association_limit_distance", 0.0)
322 )
323 slam_msg.data_association_gate = float(
324 parameters.get("data_association_gate", 0.0)
325 )
326 slam_msg.new_landmark_confidence_gate = float(
327 parameters.get("new_landmark_confidence_gate", 0.0)
328 )
329 slam_msg.observation_x_noise = float(parameters.get("observation_x_noise", 0.0))
330 slam_msg.observation_y_noise = float(parameters.get("observation_y_noise", 0.0))
331 slam_msg.velocity_x_noise = float(parameters.get("velocity_x_noise", 0.0))
332 slam_msg.velocity_y_noise = float(parameters.get("velocity_y_noise", 0.0))
333 slam_msg.angular_velocity_noise = float(
334 parameters.get("angular_velocity_noise", 0.0)
335 )
336 slam_msg.pose_x_initial_noise = float(
337 parameters.get("pose_x_initial_noise", 0.0)
338 )
339 slam_msg.pose_y_initial_noise = float(
340 parameters.get("pose_y_initial_noise", 0.0)
341 )
342 slam_msg.pose_theta_initial_noise = float(
343 parameters.get("pose_theta_initial_noise", 0.0)
344 )
345 slam_msg.slam_solver_name = parameters.get("slam_solver_name", "")
346 slam_msg.minimum_observation_count = int(
347 parameters.get("minimum_observation_count", 0)
348 )
349 slam_msg.minimum_frequency_of_detections = int(
350 parameters.get("minimum_frequency_of_detections", 0)
351 )
352 slam_msg.slam_min_pose_difference = float(
353 parameters.get("slam_min_pose_difference", 0.0)
354 )
355 slam_msg.slam_optimization_mode = parameters.get("slam_optimization_mode", "")
356 slam_msg.slam_optimization_type = parameters.get("slam_optimization_type", "")
357 slam_msg.preloaded_map_noise = float(parameters.get("preloaded_map_noise", 0.0))
358 slam_msg.slam_optimization_period = float(
359 parameters.get("slam_optimization_period", 0.0)
360 )
361 slam_msg.slam_isam2_relinearize_threshold = float(
362 parameters.get("slam_isam2_relinearize_threshold", 0.0)
363 )
364 slam_msg.slam_isam2_relinearize_skip = int(
365 parameters.get("slam_isam2_relinearize_skip", 0)
366 )
367 slam_msg.slam_isam2_factorization = parameters.get(
368 "slam_isam2_factorization", ""
369 )
370 slam_msg.sliding_window_size = int(parameters.get("sliding_window_size", 0))
371 self.slam_par_pub.publish(slam_msg)
372
374 velocity_msg = VelocityEstimationParameters()
375 parameters = self.load_yaml(VELOCITY_ESTIMATION_PATH, "velocity_estimation")
376 velocity_msg.estimation_method = parameters.get("estimation_method", "")
377 velocity_msg.ve_observation_model_name = parameters.get(
378 "ve_observation_model_name", ""
379 )
380 velocity_msg.process_model_name = parameters.get("process_model_name", "")
381 velocity_msg.wheel_speed_noise = float(parameters.get("wheel_speed_noise", 0.0))
382 velocity_msg.motor_rpm_noise = float(parameters.get("motor_rpm_noise", 0.0))
383 velocity_msg.steering_angle_noise = float(
384 parameters.get("steering_angle_noise", 0.0)
385 )
386 velocity_msg.imu_acceleration_noise = float(
387 parameters.get("imu_acceleration_noise", 0.0)
388 )
389 velocity_msg.imu_rotational_noise = float(
390 parameters.get("imu_rotational_noise", 0.0)
391 )
392 velocity_msg.angular_velocity_process_noise = float(
393 parameters.get("angular_velocity_process_noise", 0.0)
394 )
395 self.velocity_par_pub.publish(velocity_msg)
396
397 def common_callback(self, msg):
398 self.get_logger().info("Publishing the parameters.")
399 self.control_parameters()
402 self.slam_parameters()
404 self.shutdown = True
405
406
407def main(args=None):
408 rclpy.init(args=args)
410 while not node.shutdown:
411 rclpy.spin_once(node, timeout_sec=0.1)
412
413 node.destroy_node()
414 rclpy.shutdown()
415
416
417if __name__ == "__main__":
418 main()
Definition main.py:1