Formula Student Autonomous Systems
The code for the main driverless system
Loading...
Searching...
No Matches
formats.py
Go to the documentation of this file.
1from custom_interfaces.msg import (
2 ConeArray,
3 VehicleState,
4 PathPointArray,
5 Pose,
6 Velocities,
7)
8from visualization_msgs.msg import MarkerArray
9from geometry_msgs.msg import TransformStamped, TwistWithCovarianceStamped
10from tf_transformations import euler_from_quaternion
11from eufs_msgs.msg import ConeArrayWithCovariance, CarState
12from nav_msgs.msg import Odometry
13import numpy as np
14
15cone_color_dictionary: dict[str, int] = {
16 "blue_cone": 0,
17 "blue": 0,
18 "yellow_cone": 1,
19 "yellow": 1,
20 "orange_cone": 2,
21 "large_orange_cone": 3,
22 "unknown": 4,
23}
24
25
26def format_vehicle_pose_msg(msg: Pose) -> tuple[np.ndarray, np.ndarray]:
27 """!
28 Formats the Pose message into a numpy array.
29
30 Args:
31 msg (Pose): Vehicle pose message.
32
33 Returns:
34 np.ndarray: Numpy array of vehicle pose.
35 """
36 return np.array(
37 [
38 msg.x,
39 msg.y,
40 msg.theta,
41 ]
42 )
43
44
45def format_velocities_msg(msg: Velocities) -> tuple[np.ndarray, np.ndarray]:
46 """!
47 Formats the Velocities message into a numpy array.
48
49 Args:
50 msg (Velocities): Vehicle velocities message.
51
52 Returns:
53 np.ndarray: Numpy array of vehicle velocities.
54 """
55 return np.array(
56 [
57 msg.velocity_x,
58 msg.velocity_y,
59 msg.angular_velocity,
60 ]
61 )
62
63
64def format_vehicle_state_msg(msg: VehicleState) -> tuple[np.ndarray, np.ndarray]:
65 """!
66 Formats the VehicleState message into a numpy array.
67
68 Args:
69 msg (VehicleState): Vehicle state message.
70
71 Returns:
72 np.ndarray: Numpy array of vehicle state.
73 """
74 return (
75 np.array(
76 [
77 msg.position.x,
78 msg.position.y,
79 msg.theta,
80 ]
81 ),
82 np.array([msg.linear_velocity, msg.linear_velocity, msg.angular_velocity]),
83 )
84
85
86def format_cone_array_msg(msg: ConeArray):
87 """!
88 Formats the ConeArray message into a numpy array.
89
90 Args:
91 msg (ConeArray): Cone array message.
92
93 Returns:
94 np.ndarray: Numpy array of arrays.
95 """
96 output = []
97
98 for cone in msg.cone_array:
99 output.append(
100 np.array(
101 [
102 cone.position.x,
103 cone.position.y,
104 cone_color_dictionary[cone.color],
105 cone.confidence,
106 ]
107 )
108 )
109
110 return np.array(output)
111
112
114 if b == 1:
115 return 0
116 elif r == 1 and g == 1:
117 return 1
118 else:
119 return 2
120
121
122def format_marker_array_msg(msg: MarkerArray):
123 """!
124 Formats the MarkerArray message into a numpy array.
125
126 Args:
127 msg (MarkerArray): Marker array message.
128
129 Returns:
130 np.ndarray: Numpy array of arrays.
131 """
132 output = []
133
134 for marker in msg.markers:
135 output.append(
136 np.array(
137 [
138 marker.pose.position.x,
139 marker.pose.position.y,
141 marker.color.r, marker.color.g, marker.color.b
142 ),
143 0.0,
144 ]
145 )
146 )
147
148 return np.array(output)
149
150
151def format_transform_stamped_msg(msg: TransformStamped) -> np.ndarray:
152 """!
153 Formats the TransformStamped message into a numpy array.
154
155 Args:
156 msg (TransformStamped): TransformStamped message.
157
158 Returns:
159 np.ndarray: Numpy array of transform.
160 """
161 yaw: float = euler_from_quaternion(
162 [
163 msg.transform.rotation.x,
164 msg.transform.rotation.y,
165 msg.transform.rotation.z,
166 msg.transform.rotation.w,
167 ]
168 )[2]
169 return np.array(
170 [
171 msg.transform.translation.x,
172 msg.transform.translation.y,
173 yaw,
174 ]
175 )
176
177
178def format_twist_with_covariance_stamped_msg(
179 msg: TwistWithCovarianceStamped,
180) -> np.ndarray:
181 """!
182 Formats the TwistWithCovarianceStamped message into a numpy array.
183
184 Args:
185 msg (TwistWithCovarianceStamped): TwistWithCovarianceStamped message.
186
187 Returns:
188 np.ndarray: Numpy array of twist (used for velocities).
189 """
190 return np.array(
191 [msg.twist.twist.linear.x, msg.twist.twist.linear.y, msg.twist.twist.angular.z]
192 )
193
194
195def format_car_state_msg(
196 msg: CarState,
197) -> tuple[np.ndarray, np.ndarray]:
198 """!
199
200 Formats the CarState message from eufs into a tuple of numpy arrays.
201
202 Args: msg (CarState): CarState message from eufs
203
204 Returns: tuple[np.ndarray, np.ndarray]: (state, velocities)
205 """
206 return (
207 np.array(
208 [
209 msg.pose.pose.position.x,
210 msg.pose.pose.position.y,
211 euler_from_quaternion(
212 [
213 msg.pose.pose.orientation.x,
214 msg.pose.pose.orientation.y,
215 msg.pose.pose.orientation.z,
216 msg.pose.pose.orientation.w,
217 ]
218 )[2],
219 ]
220 ),
221 np.array(
222 [
223 msg.twist.twist.linear.x,
224 msg.twist.twist.linear.y,
225 msg.twist.twist.angular.z,
226 ],
227 ),
228 )
229
230
231def format_eufs_cone_array_with_covariance_msg(
232 msg: ConeArrayWithCovariance,
233):
234 """!
235
236 Args:
237 msg (ConeArrayWithCovariance): cone array message from eufs
238
239 Returns:
240 np.ndarray[np.ndarray]: [[x, y, color, confidence], ...]
241 """
242 output: list = []
243 cone_types: list[str] = [
244 "blue_cones",
245 "yellow_cones",
246 "orange_cones",
247 "big_orange_cones",
248 "unknown_color_cones",
249 ]
250 for i, cone_type in enumerate(cone_types):
251 for cone in getattr(msg, cone_type):
252 output.append(
253 np.array(
254 [
255 cone.point.x,
256 cone.point.y,
257 i,
258 1.0,
259 ] # TODO: confidence dependent on the cone's covariance
260 )
261 )
262
263 return np.array(output)
264
265
266def format_nav_odometry_msg(msg: Odometry) -> tuple[np.ndarray, np.ndarray]:
267 """!
268 Formats the Odometry message into a numpy array.
269
270 Args:
271 msg (Odometry): Odometry message.
272
273 Returns:
274 np.ndarray: Numpy array of odometry.
275 """
276 return (
277 np.array(
278 [
279 msg.pose.pose.position.x,
280 msg.pose.pose.position.y,
281 euler_from_quaternion(
282 [
283 msg.pose.pose.orientation.x,
284 msg.pose.pose.orientation.y,
285 msg.pose.pose.orientation.z,
286 msg.pose.pose.orientation.w,
287 ]
288 )[2],
289 ]
290 ),
291 np.array(
292 [
293 msg.twist.twist.linear.x,
294 msg.twist.twist.linear.y,
295 msg.twist.twist.angular.z,
296 ]
297 ),
298 )
299
300
301def format_path_point_array_msg(path_point_array: PathPointArray) -> np.ndarray:
302 """!
303 Converts a PathPointArray message into a numpy array.
304
305 Args:
306 path_point_array (PathPointArray): PathPointArray message.
307
308 Returns:
309 np.ndarray: Numpy array of path points.
310 """
311 path_list = []
312
313 for path_point in path_point_array.pathpoint_array:
314 path_list.append(
315 np.array(
316 [
317 path_point.x,
318 path_point.y,
319 path_point.v,
320 ]
321 )
322 )
323
324 return np.array(path_list)
325
326
327def format_point2d_msg(msg):
328 """!
329 Converts a Point2D message into a numpy array.
330
331 Args:
332 msg: Point2D message.
333
334 Returns:
335 np.ndarray: Numpy array of point.
336 """
337 return np.array([msg.x, msg.y])
338
339
340def find_closest_elements(arr1: np.ndarray, arr2: np.ndarray) -> np.ndarray:
341 """Find the closest elements in arr2 for each element in arr1.
342
343 Args:
344 arr1 (np.ndarray): array in which each element's 2 initial values are x and y positions
345 arr2 (np.ndarray): array in which each element's 2 initial values are x and y positions
346
347 Returns:
348 np.ndarray: array of elements from arr2 that are the closest to at least one element in arr1
349 """
350 # Extract the x and y positions
351 arr1_xy = arr1[:, :2]
352 arr2_xy = arr2[:, :2]
353
354 # Calculate the squared Euclidean distances
355 distances = np.linalg.norm(
356 arr1_xy[:, np.newaxis, :] - arr2_xy[np.newaxis, :, :], axis=2
357 )
358
359 # Find the indices of the closest elements in arr2 for each element in arr1
360 closest_indices = np.argmin(distances, axis=1)
361
362 # Get the unique closest elements from arr2
363 closest_elements = np.unique(arr2[closest_indices], axis=0)
364
365 return closest_elements
366
367
368def get_blue_and_yellow_cones_after_msg_treatment(
369 arr: np.ndarray,
370) -> tuple[np.ndarray, np.ndarray]:
371 """!
372 Divides the result of converting the EUFS or FSDS map message to np.ndarray into blue and yellow cones arrays, attributing orange
373 cones into blue or yellow cones.
374
375 Args:
376 arr (np.ndarray): Array of cones with the following attributes: x, y, index, confidence, type.
377
378 Returns:
379 tuple[np.ndarray, np.ndarray]: the first array is the array of blue cones and the second contains yellow cones.
380 """
381 array1 = []
382 array2 = []
383 for element in arr:
384 if element[2] == 0:
385 array1.append(element)
386 elif element[2] == 1:
387 array2.append(element)
388 elif element[2] in [2, 3]:
389 closest_distance = float("inf")
390 closest_array = None
391
392 for array in [array1, array2]:
393 for array_element in array:
394 distance = np.linalg.norm(element[:2] - array_element[:2])
395
396 if distance < closest_distance:
397 closest_distance = distance
398 closest_array = array
399
400 if closest_array is not None:
401 closest_array.append(element)
402 else:
403 raise ValueError("Invalid cone color index: %d" % element[2])
404
405 return np.array(array1), np.array(array2)
get_color_number_from_rgb(r, g, b)
Definition formats.py:113