1use std::collections::HashMap;
32use strum_macros::{Display, EnumString};
33
34#[derive(Debug, Copy, Clone, PartialEq, Eq, EnumString, Display)]
35pub enum RoadObjectType {
37 None,
38 Unknown,
39 Barrier,
40 GuardWall,
41 GuardRail,
42 Building,
43 Gantry,
44 Obstacle,
45 Pole,
46 TrafficIsland,
47 Tree,
48 Vegetation,
49 Pylon,
50 Delineator,
51 BikeStatic,
52 BusStatic,
53 CarStatic,
54 MotorbikeStatic,
55 Patch,
56 PedestrianStatic,
57 Railing,
58 RoadSurface,
59 SoundBarrier,
60 StreetLamp,
61 TrailerStatic,
62 TrainStatic,
63 TramStatic,
64 VanStatic,
65 Wind,
66}
67
68fn road_object_type_from_cpp(obj_type: maliput_sys::api::objects::ffi::RoadObjectType) -> RoadObjectType {
69 match obj_type {
70 maliput_sys::api::objects::ffi::RoadObjectType::kUnknown => RoadObjectType::Unknown,
71 maliput_sys::api::objects::ffi::RoadObjectType::kBarrier => RoadObjectType::Barrier,
72 maliput_sys::api::objects::ffi::RoadObjectType::kGuardWall => RoadObjectType::GuardWall,
73 maliput_sys::api::objects::ffi::RoadObjectType::kGuardRail => RoadObjectType::GuardRail,
74 maliput_sys::api::objects::ffi::RoadObjectType::kBuilding => RoadObjectType::Building,
75 maliput_sys::api::objects::ffi::RoadObjectType::kGantry => RoadObjectType::Gantry,
76 maliput_sys::api::objects::ffi::RoadObjectType::kObstacle => RoadObjectType::Obstacle,
77 maliput_sys::api::objects::ffi::RoadObjectType::kPole => RoadObjectType::Pole,
78 maliput_sys::api::objects::ffi::RoadObjectType::kTrafficIsland => RoadObjectType::TrafficIsland,
79 maliput_sys::api::objects::ffi::RoadObjectType::kTree => RoadObjectType::Tree,
80 maliput_sys::api::objects::ffi::RoadObjectType::kVegetation => RoadObjectType::Vegetation,
81 maliput_sys::api::objects::ffi::RoadObjectType::kPylon => RoadObjectType::Pylon,
82 maliput_sys::api::objects::ffi::RoadObjectType::kDelineator => RoadObjectType::Delineator,
83 maliput_sys::api::objects::ffi::RoadObjectType::kBikeStatic => RoadObjectType::BikeStatic,
84 maliput_sys::api::objects::ffi::RoadObjectType::kBusStatic => RoadObjectType::BusStatic,
85 maliput_sys::api::objects::ffi::RoadObjectType::kCarStatic => RoadObjectType::CarStatic,
86 maliput_sys::api::objects::ffi::RoadObjectType::kMotorbikeStatic => RoadObjectType::MotorbikeStatic,
87 maliput_sys::api::objects::ffi::RoadObjectType::kPatch => RoadObjectType::Patch,
88 maliput_sys::api::objects::ffi::RoadObjectType::kPedestrianStatic => RoadObjectType::PedestrianStatic,
89 maliput_sys::api::objects::ffi::RoadObjectType::kRailing => RoadObjectType::Railing,
90 maliput_sys::api::objects::ffi::RoadObjectType::kRoadSurface => RoadObjectType::RoadSurface,
91 maliput_sys::api::objects::ffi::RoadObjectType::kSoundBarrier => RoadObjectType::SoundBarrier,
92 maliput_sys::api::objects::ffi::RoadObjectType::kStreetLamp => RoadObjectType::StreetLamp,
93 maliput_sys::api::objects::ffi::RoadObjectType::kTrailerStatic => RoadObjectType::TrailerStatic,
94 maliput_sys::api::objects::ffi::RoadObjectType::kTrainStatic => RoadObjectType::TrainStatic,
95 maliput_sys::api::objects::ffi::RoadObjectType::kTramStatic => RoadObjectType::TramStatic,
96 maliput_sys::api::objects::ffi::RoadObjectType::kVanStatic => RoadObjectType::VanStatic,
97 maliput_sys::api::objects::ffi::RoadObjectType::kWind => RoadObjectType::Wind,
98 _ => RoadObjectType::None,
99 }
100}
101
102fn road_object_type_to_cpp(obj_type: &RoadObjectType) -> maliput_sys::api::objects::ffi::RoadObjectType {
103 match obj_type {
104 RoadObjectType::None => maliput_sys::api::objects::ffi::RoadObjectType::kUnknown,
105 RoadObjectType::Unknown => maliput_sys::api::objects::ffi::RoadObjectType::kUnknown,
106 RoadObjectType::Barrier => maliput_sys::api::objects::ffi::RoadObjectType::kBarrier,
107 RoadObjectType::GuardWall => maliput_sys::api::objects::ffi::RoadObjectType::kGuardWall,
108 RoadObjectType::GuardRail => maliput_sys::api::objects::ffi::RoadObjectType::kGuardRail,
109 RoadObjectType::Building => maliput_sys::api::objects::ffi::RoadObjectType::kBuilding,
110 RoadObjectType::Gantry => maliput_sys::api::objects::ffi::RoadObjectType::kGantry,
111 RoadObjectType::Obstacle => maliput_sys::api::objects::ffi::RoadObjectType::kObstacle,
112 RoadObjectType::Pole => maliput_sys::api::objects::ffi::RoadObjectType::kPole,
113 RoadObjectType::TrafficIsland => maliput_sys::api::objects::ffi::RoadObjectType::kTrafficIsland,
114 RoadObjectType::Tree => maliput_sys::api::objects::ffi::RoadObjectType::kTree,
115 RoadObjectType::Vegetation => maliput_sys::api::objects::ffi::RoadObjectType::kVegetation,
116 RoadObjectType::Pylon => maliput_sys::api::objects::ffi::RoadObjectType::kPylon,
117 RoadObjectType::Delineator => maliput_sys::api::objects::ffi::RoadObjectType::kDelineator,
118 RoadObjectType::BikeStatic => maliput_sys::api::objects::ffi::RoadObjectType::kBikeStatic,
119 RoadObjectType::BusStatic => maliput_sys::api::objects::ffi::RoadObjectType::kBusStatic,
120 RoadObjectType::CarStatic => maliput_sys::api::objects::ffi::RoadObjectType::kCarStatic,
121 RoadObjectType::MotorbikeStatic => maliput_sys::api::objects::ffi::RoadObjectType::kMotorbikeStatic,
122 RoadObjectType::Patch => maliput_sys::api::objects::ffi::RoadObjectType::kPatch,
123 RoadObjectType::PedestrianStatic => maliput_sys::api::objects::ffi::RoadObjectType::kPedestrianStatic,
124 RoadObjectType::Railing => maliput_sys::api::objects::ffi::RoadObjectType::kRailing,
125 RoadObjectType::RoadSurface => maliput_sys::api::objects::ffi::RoadObjectType::kRoadSurface,
126 RoadObjectType::SoundBarrier => maliput_sys::api::objects::ffi::RoadObjectType::kSoundBarrier,
127 RoadObjectType::StreetLamp => maliput_sys::api::objects::ffi::RoadObjectType::kStreetLamp,
128 RoadObjectType::TrailerStatic => maliput_sys::api::objects::ffi::RoadObjectType::kTrailerStatic,
129 RoadObjectType::TrainStatic => maliput_sys::api::objects::ffi::RoadObjectType::kTrainStatic,
130 RoadObjectType::TramStatic => maliput_sys::api::objects::ffi::RoadObjectType::kTramStatic,
131 RoadObjectType::VanStatic => maliput_sys::api::objects::ffi::RoadObjectType::kVanStatic,
132 RoadObjectType::Wind => maliput_sys::api::objects::ffi::RoadObjectType::kWind,
133 }
134}
135
136#[cfg(test)]
137mod tests {
138 use super::{road_object_type_from_cpp, road_object_type_to_cpp, RoadObjectType};
139
140 #[test]
141 fn unknown_from_cpp_stays_unknown() {
142 let cpp = maliput_sys::api::objects::ffi::RoadObjectType::kUnknown;
143 assert_eq!(road_object_type_from_cpp(cpp), RoadObjectType::Unknown);
144 }
145
146 #[test]
147 fn none_to_cpp_maps_to_unknown() {
148 assert!(
149 road_object_type_to_cpp(&RoadObjectType::None) == maliput_sys::api::objects::ffi::RoadObjectType::kUnknown
150 );
151 }
152}
153
154pub struct RoadObjectPosition {
159 pub inertial_position: crate::api::InertialPosition,
160 pub lane_position: Option<(String, f64, f64, f64)>,
161}
162
163pub struct OutlineCorner {
167 pub x: f64,
168 pub y: f64,
169 pub z: f64,
170 pub height: Option<f64>,
171}
172
173pub struct ContinuousObject {
178 pub width: f64,
179 pub height: f64,
180 pub point_sample: crate::api::InertialPosition,
181}
182
183pub struct Outline<'a> {
185 pub(crate) outline: &'a maliput_sys::api::objects::ffi::Outline,
186}
187
188impl<'a> Outline<'a> {
189 pub fn id(&self) -> String {
191 maliput_sys::api::objects::ffi::Outline_id(self.outline)
192 }
193
194 pub fn is_closed(&self) -> bool {
196 maliput_sys::api::objects::ffi::Outline_is_closed(self.outline)
197 }
198
199 pub fn num_corners(&self) -> i32 {
201 maliput_sys::api::objects::ffi::Outline_num_corners(self.outline)
202 }
203
204 pub fn corners(&self) -> Vec<OutlineCorner> {
206 maliput_sys::api::objects::ffi::Outline_corners(self.outline)
207 .into_iter()
208 .map(|c| OutlineCorner {
209 x: c.x,
210 y: c.y,
211 z: c.z,
212 height: if c.has_height { Some(c.height) } else { None },
213 })
214 .collect()
215 }
216}
217
218pub struct RoadObject<'a> {
223 pub(crate) road_object: &'a maliput_sys::api::objects::ffi::RoadObject,
224}
225
226impl<'a> RoadObject<'a> {
227 pub fn id(&self) -> String {
229 maliput_sys::api::objects::ffi::RoadObject_id(self.road_object)
230 }
231
232 pub fn name(&self) -> Option<String> {
234 let wrapper = maliput_sys::api::objects::ffi::RoadObject_name(self.road_object);
235 if wrapper.is_null() {
236 return None;
237 }
238 Some(wrapper.value.clone())
239 }
240
241 pub fn object_type(&self) -> RoadObjectType {
243 let t = maliput_sys::api::objects::ffi::RoadObject_object_type(self.road_object);
244 road_object_type_from_cpp(t)
245 }
246
247 pub fn subtype(&self) -> Option<String> {
249 let wrapper = maliput_sys::api::objects::ffi::RoadObject_subtype(self.road_object);
250 if wrapper.is_null() {
251 return None;
252 }
253 Some(wrapper.value.clone())
254 }
255
256 pub fn position(&self) -> RoadObjectPosition {
258 let inertial_position = maliput_sys::api::objects::ffi::RoadObject_position_inertial(self.road_object);
259 let has_lane = maliput_sys::api::objects::ffi::RoadObject_position_has_lane_position(self.road_object);
260 let lane_position = if has_lane {
261 Some((
262 maliput_sys::api::objects::ffi::RoadObject_position_lane_id(self.road_object),
263 maliput_sys::api::objects::ffi::RoadObject_position_lane_s(self.road_object),
264 maliput_sys::api::objects::ffi::RoadObject_position_lane_r(self.road_object),
265 maliput_sys::api::objects::ffi::RoadObject_position_lane_h(self.road_object),
266 ))
267 } else {
268 None
269 };
270 RoadObjectPosition {
271 inertial_position: crate::api::InertialPosition { ip: inertial_position },
272 lane_position,
273 }
274 }
275
276 pub fn orientation(&self) -> crate::api::Rotation {
278 let rotation = maliput_sys::api::objects::ffi::RoadObject_orientation(self.road_object);
279 crate::api::Rotation { r: rotation }
280 }
281
282 pub fn bounding_box(&self) -> crate::math::BoundingBox {
284 let b = maliput_sys::api::objects::ffi::RoadObject_bounding_box(self.road_object);
285 crate::math::BoundingBox { b }
286 }
287
288 pub fn is_dynamic(&self) -> bool {
290 maliput_sys::api::objects::ffi::RoadObject::is_dynamic(self.road_object)
291 }
292
293 pub fn is_movable(&self) -> bool {
295 maliput_sys::api::objects::ffi::RoadObject::is_movable(self.road_object)
296 }
297
298 pub fn related_lanes(&self) -> Vec<String> {
300 maliput_sys::api::objects::ffi::RoadObject_related_lanes(self.road_object)
301 }
302
303 pub fn num_outlines(&self) -> i32 {
305 maliput_sys::api::objects::ffi::RoadObject::num_outlines(self.road_object)
306 }
307
308 pub fn outlines(&self) -> Vec<Outline<'_>> {
310 maliput_sys::api::objects::ffi::RoadObject_outlines(self.road_object)
311 .into_iter()
312 .map(|ptr| Outline {
313 outline: unsafe { ptr.outline.as_ref().expect("Outline pointer is null") },
314 })
315 .collect()
316 }
317
318 pub fn properties(&self) -> HashMap<String, String> {
320 maliput_sys::api::objects::ffi::RoadObject_properties(self.road_object)
321 .into_iter()
322 .map(|p| (p.key, p.value))
323 .collect()
324 }
325
326 pub fn continuous_properties(&self) -> Vec<ContinuousObject> {
330 maliput_sys::api::objects::ffi::RoadObject_continuous_properties(self.road_object)
331 .into_iter()
332 .map(|c| ContinuousObject {
333 width: c.width,
334 height: c.height,
335 point_sample: crate::api::InertialPosition::new(c.x, c.y, c.z),
336 })
337 .collect()
338 }
339}
340
341pub struct RoadObjectBook<'a> {
343 pub(super) road_object_book: &'a maliput_sys::api::objects::ffi::RoadObjectBook,
344}
345
346impl<'a> RoadObjectBook<'a> {
347 pub fn road_objects(&self) -> Vec<RoadObject<'_>> {
349 maliput_sys::api::objects::ffi::RoadObjectBook_RoadObjects(self.road_object_book)
350 .into_iter()
351 .map(|ptr| RoadObject {
352 road_object: unsafe { ptr.road_object.as_ref().expect("RoadObject pointer is null") },
353 })
354 .collect()
355 }
356
357 pub fn get_road_object(&self, id: &String) -> Option<RoadObject<'_>> {
359 let ptr = maliput_sys::api::objects::ffi::RoadObjectBook_GetRoadObject(self.road_object_book, id);
360 if ptr.is_null() {
361 return None;
362 }
363 Some(RoadObject {
364 road_object: unsafe { ptr.as_ref().expect("Unable to get underlying RoadObject pointer") },
365 })
366 }
367
368 pub fn find_by_type(&self, obj_type: &RoadObjectType) -> Vec<RoadObject<'_>> {
370 let obj_type_ffi = road_object_type_to_cpp(obj_type);
371 maliput_sys::api::objects::ffi::RoadObjectBook_FindByType(self.road_object_book, obj_type_ffi)
372 .into_iter()
373 .map(|ptr| RoadObject {
374 road_object: unsafe { ptr.road_object.as_ref().expect("RoadObject pointer is null") },
375 })
376 .collect()
377 }
378
379 pub fn find_by_lane(&self, lane_id: &String) -> Vec<RoadObject<'_>> {
381 maliput_sys::api::objects::ffi::RoadObjectBook_FindByLane(self.road_object_book, lane_id)
382 .into_iter()
383 .map(|ptr| RoadObject {
384 road_object: unsafe { ptr.road_object.as_ref().expect("RoadObject pointer is null") },
385 })
386 .collect()
387 }
388
389 pub fn find_in_radius(&self, x: f64, y: f64, z: f64, radius: f64) -> Vec<RoadObject<'_>> {
392 maliput_sys::api::objects::ffi::RoadObjectBook_FindInRadius(self.road_object_book, x, y, z, radius)
393 .into_iter()
394 .map(|ptr| RoadObject {
395 road_object: unsafe { ptr.road_object.as_ref().expect("RoadObject pointer is null") },
396 })
397 .collect()
398 }
399}
400
401pub type RoadMarkingType = crate::api::rules::TrafficControlDeviceType;
403
404#[derive(Debug, Copy, Clone, PartialEq, Eq)]
405pub enum RoadMarkingValueUnit {
407 MetersPerSecond,
408 KilometersPerHour,
409 MilesPerHour,
410}
411
412fn road_marking_value_unit_from_cpp(u: maliput_sys::api::objects::ffi::RoadMarkingValueUnit) -> RoadMarkingValueUnit {
413 match u {
414 maliput_sys::api::objects::ffi::RoadMarkingValueUnit::kMetersPerSecond => RoadMarkingValueUnit::MetersPerSecond,
415 maliput_sys::api::objects::ffi::RoadMarkingValueUnit::kKilometersPerHour => {
416 RoadMarkingValueUnit::KilometersPerHour
417 }
418 maliput_sys::api::objects::ffi::RoadMarkingValueUnit::kMilesPerHour => RoadMarkingValueUnit::MilesPerHour,
419 _ => RoadMarkingValueUnit::MetersPerSecond,
420 }
421}
422
423#[derive(Debug, Copy, Clone, PartialEq)]
425pub struct RoadMarkingValue {
426 pub value: f64,
427 pub unit: RoadMarkingValueUnit,
428}
429
430pub struct RoadMarking<'a> {
432 pub(crate) road_marking: &'a maliput_sys::api::objects::ffi::RoadMarking,
433}
434
435impl<'a> RoadMarking<'a> {
436 pub fn id(&self) -> String {
438 maliput_sys::api::objects::ffi::RoadMarking_id(self.road_marking)
439 }
440
441 pub fn name(&self) -> Option<String> {
443 let wrapper = maliput_sys::api::objects::ffi::RoadMarking_name(self.road_marking);
444 if wrapper.is_null() {
445 return None;
446 }
447 Some(wrapper.value.clone())
448 }
449
450 pub fn marking_type(&self) -> RoadMarkingType {
452 let t = maliput_sys::api::objects::ffi::RoadMarking_marking_type(self.road_marking);
453 crate::api::rules::traffic_control_device_type_from_cpp(&t)
454 }
455
456 pub fn position(&self) -> RoadObjectPosition {
458 let inertial_position = maliput_sys::api::objects::ffi::RoadMarking_position_inertial(self.road_marking);
459 let has_lane = maliput_sys::api::objects::ffi::RoadMarking_position_has_lane_position(self.road_marking);
460 let lane_position = if has_lane {
461 Some((
462 maliput_sys::api::objects::ffi::RoadMarking_position_lane_id(self.road_marking),
463 maliput_sys::api::objects::ffi::RoadMarking_position_lane_s(self.road_marking),
464 maliput_sys::api::objects::ffi::RoadMarking_position_lane_r(self.road_marking),
465 maliput_sys::api::objects::ffi::RoadMarking_position_lane_h(self.road_marking),
466 ))
467 } else {
468 None
469 };
470 RoadObjectPosition {
471 inertial_position: crate::api::InertialPosition { ip: inertial_position },
472 lane_position,
473 }
474 }
475
476 pub fn orientation(&self) -> crate::api::Rotation {
478 let rotation = maliput_sys::api::objects::ffi::RoadMarking_orientation(self.road_marking);
479 crate::api::Rotation { r: rotation }
480 }
481
482 pub fn bounding_box(&self) -> crate::math::BoundingBox {
484 let b = maliput_sys::api::objects::ffi::RoadMarking_bounding_box(self.road_marking);
485 crate::math::BoundingBox { b }
486 }
487
488 pub fn related_lanes(&self) -> Vec<String> {
490 maliput_sys::api::objects::ffi::RoadMarking_related_lanes(self.road_marking)
491 }
492
493 pub fn num_outlines(&self) -> i32 {
495 maliput_sys::api::objects::ffi::RoadMarking::num_outlines(self.road_marking)
496 }
497
498 pub fn outlines(&self) -> Vec<Outline<'_>> {
500 maliput_sys::api::objects::ffi::RoadMarking_outlines(self.road_marking)
501 .into_iter()
502 .map(|ptr| Outline {
503 outline: unsafe { ptr.outline.as_ref().expect("Outline pointer is null") },
504 })
505 .collect()
506 }
507
508 pub fn value(&self) -> Option<RoadMarkingValue> {
510 let data = maliput_sys::api::objects::ffi::RoadMarking_value(self.road_marking);
511 if !data.has_value {
512 return None;
513 }
514 Some(RoadMarkingValue {
515 value: data.value,
516 unit: road_marking_value_unit_from_cpp(data.unit),
517 })
518 }
519}
520
521pub struct RoadMarkingBook<'a> {
523 pub(super) road_marking_book: &'a maliput_sys::api::objects::ffi::RoadMarkingBook,
524}
525
526impl<'a> RoadMarkingBook<'a> {
527 pub fn road_markings(&self) -> Vec<RoadMarking<'_>> {
529 maliput_sys::api::objects::ffi::RoadMarkingBook_RoadMarkings(self.road_marking_book)
530 .into_iter()
531 .map(|ptr| RoadMarking {
532 road_marking: unsafe { ptr.road_marking.as_ref().expect("RoadMarking pointer is null") },
533 })
534 .collect()
535 }
536
537 pub fn get_road_marking(&self, id: &String) -> Option<RoadMarking<'_>> {
539 let ptr = maliput_sys::api::objects::ffi::RoadMarkingBook_GetRoadMarking(self.road_marking_book, id);
540 if ptr.is_null() {
541 return None;
542 }
543 Some(RoadMarking {
544 road_marking: unsafe { ptr.as_ref().expect("Unable to get underlying RoadMarking pointer") },
545 })
546 }
547
548 pub fn find_by_lane(&self, lane_id: &String) -> Vec<RoadMarking<'_>> {
550 maliput_sys::api::objects::ffi::RoadMarkingBook_FindByLane(self.road_marking_book, lane_id)
551 .into_iter()
552 .map(|ptr| RoadMarking {
553 road_marking: unsafe { ptr.road_marking.as_ref().expect("RoadMarking pointer is null") },
554 })
555 .collect()
556 }
557
558 pub fn find_by_type(&self, marking_type: &RoadMarkingType) -> Vec<RoadMarking<'_>> {
560 let t_ffi = crate::api::rules::traffic_control_device_type_to_cpp(marking_type);
561 maliput_sys::api::objects::ffi::RoadMarkingBook_FindByType(self.road_marking_book, t_ffi)
562 .into_iter()
563 .map(|ptr| RoadMarking {
564 road_marking: unsafe { ptr.road_marking.as_ref().expect("RoadMarking pointer is null") },
565 })
566 .collect()
567 }
568}