maliput/api/rules/mod.rs
1// BSD 3-Clause License
2//
3// Copyright (c) 2024, Woven by Toyota.
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are met:
8//
9// * Redistributions of source code must retain the above copyright notice, this
10// list of conditions and the following disclaimer.
11//
12// * Redistributions in binary form must reproduce the above copyright notice,
13// this list of conditions and the following disclaimer in the documentation
14// and/or other materials provided with the distribution.
15//
16// * Neither the name of the copyright holder nor the names of its
17// contributors may be used to endorse or promote products derived from
18// this software without specific prior written permission.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31/// Interface for accessing the [TrafficLight] in the [super::RoadNetwork]
32pub struct TrafficLightBook<'a> {
33 pub(super) traffic_light_book: &'a maliput_sys::api::rules::ffi::TrafficLightBook,
34}
35
36impl<'a> TrafficLightBook<'a> {
37 /// Get all the [TrafficLight]s in the [TrafficLightBook]
38 /// ## Return
39 /// A vector of [TrafficLight]s
40 pub fn traffic_lights(&self) -> Vec<TrafficLight> {
41 let traffic_lights_cpp = maliput_sys::api::rules::ffi::TrafficLightBook_TrafficLights(self.traffic_light_book);
42 traffic_lights_cpp
43 .into_iter()
44 .map(|tl| TrafficLight {
45 traffic_light: unsafe { tl.traffic_light.as_ref().expect("") },
46 })
47 .collect::<Vec<TrafficLight>>()
48 }
49
50 /// Get a [TrafficLight] by its id
51 /// ## Arguments
52 /// * `id` - The id of the [TrafficLight]
53 /// ## Return
54 /// The [TrafficLight] with the given id.
55 /// If no [TrafficLight] is found with the given id, return None.
56 pub fn get_traffic_light(&self, id: &String) -> Option<TrafficLight> {
57 let traffic_light = maliput_sys::api::rules::ffi::TrafficLightBook_GetTrafficLight(self.traffic_light_book, id);
58 if traffic_light.is_null() {
59 return None;
60 }
61 Some(TrafficLight {
62 traffic_light: unsafe {
63 traffic_light
64 .as_ref()
65 .expect("Unable to get underlying traffic light pointer")
66 },
67 })
68 }
69}
70
71/// Models a traffic light. A traffic light is a physical signaling device
72/// typically located at road intersections. It contains one or more groups of
73/// light bulbs with varying colors and shapes. The lighting patterns of the
74/// bulbs signify right-of-way rule information to the agents navigating the
75/// intersection (e.g., vehicles, bicyclists, pedestrians, etc.). Typically, an
76/// intersection will be managed by multiple traffic lights.
77///
78/// Note that traffic lights are physical manifestations of underlying
79/// right-of-way rules and thus naturally have lower signal-to-noise ratio
80/// relative to the underlying rules. Thus, oracular agents should directly use
81/// the underlying right-of-way rules instead of traffic lights when navigating
82/// intersections. TrafficLight exists for testing autonomous vehicles that do
83/// not have access to right-of-way rules.
84pub struct TrafficLight<'a> {
85 pub traffic_light: &'a maliput_sys::api::rules::ffi::TrafficLight,
86}
87
88impl<'a> TrafficLight<'a> {
89 /// Get the id of the [TrafficLight].
90 /// ## Return
91 /// The id of the [TrafficLight].
92 pub fn id(&self) -> String {
93 maliput_sys::api::rules::ffi::TrafficLight_id(self.traffic_light)
94 }
95
96 /// Get the position of the [TrafficLight] in the road network.
97 /// ## Return
98 /// An [crate::api::InertialPosition] representing the position of the [TrafficLight] in the road network.
99 pub fn position_road_network(&self) -> crate::api::InertialPosition {
100 let inertial_position = maliput_sys::api::rules::ffi::TrafficLight_position_road_network(self.traffic_light);
101 crate::api::InertialPosition { ip: inertial_position }
102 }
103
104 /// Get the orientation of the [TrafficLight] in the road network.
105 /// ## Return
106 /// An [crate::api::Rotation] representing the orientation of the [TrafficLight] in the road network.
107 pub fn orientation_road_network(&self) -> crate::api::Rotation {
108 let rotation = maliput_sys::api::rules::ffi::TrafficLight_orientation_road_network(self.traffic_light);
109 crate::api::Rotation { r: rotation }
110 }
111
112 /// Get the bulb groups of the [TrafficLight].
113 /// ## Return
114 /// A vector of [BulbGroup]s in the [TrafficLight].
115 /// If the [TrafficLight] has no bulb groups, return an empty vector.
116 pub fn bulb_groups(&self) -> Vec<BulbGroup> {
117 let bulb_groups_cpp = maliput_sys::api::rules::ffi::TrafficLight_bulb_groups(self.traffic_light);
118 bulb_groups_cpp
119 .into_iter()
120 .map(|bg| BulbGroup {
121 bulb_group: unsafe { bg.bulb_group.as_ref().expect("") },
122 })
123 .collect::<Vec<BulbGroup>>()
124 }
125
126 /// Get a [BulbGroup] by its id.
127 /// ## Arguments
128 /// * `id` - The id of the [BulbGroup].
129 ///
130 /// ## Return
131 /// The [BulbGroup] with the given id.
132 /// If no [BulbGroup] is found with the given id, return None.
133 pub fn get_bulb_group(&self, id: &String) -> Option<BulbGroup> {
134 let bulb_group = maliput_sys::api::rules::ffi::TrafficLight_GetBulbGroup(self.traffic_light, id);
135 if bulb_group.is_null() {
136 return None;
137 }
138 Some(BulbGroup {
139 bulb_group: unsafe {
140 bulb_group
141 .as_ref()
142 .expect("Unable to get underlying bulb group pointer")
143 },
144 })
145 }
146}
147
148#[derive(Debug, Copy, Clone, PartialEq, Eq)]
149/// Defines the possible bulb colors.
150pub enum BulbColor {
151 Red,
152 Yellow,
153 Green,
154}
155
156#[derive(Debug, Copy, Clone, PartialEq, Eq)]
157/// Defines the possible bulb types.
158pub enum BulbType {
159 Round,
160 Arrow,
161}
162
163#[derive(Debug, Copy, Clone, PartialEq, Eq)]
164/// Defines the possible bulb types.
165pub enum BulbState {
166 Off,
167 On,
168 Blinking,
169}
170
171/// Models a bulb within a bulb group.
172pub struct Bulb<'a> {
173 pub bulb: &'a maliput_sys::api::rules::ffi::Bulb,
174}
175
176impl Bulb<'_> {
177 /// Returns this Bulb instance's unique identifier.
178 pub fn unique_id(&self) -> UniqueBulbId {
179 UniqueBulbId {
180 unique_bulb_id: maliput_sys::api::rules::ffi::Bulb_unique_id(self.bulb),
181 }
182 }
183
184 /// Get the id of the [Bulb].
185 /// ## Return
186 /// The id of the [Bulb].
187 pub fn id(&self) -> String {
188 maliput_sys::api::rules::ffi::Bulb_id(self.bulb)
189 }
190
191 /// Get the color of the [Bulb].
192 /// ## Return
193 /// The [BulbColor].
194 pub fn color(&self) -> BulbColor {
195 let color = self.bulb.color();
196 match *color {
197 maliput_sys::api::rules::ffi::BulbColor::kRed => BulbColor::Red,
198 maliput_sys::api::rules::ffi::BulbColor::kYellow => BulbColor::Yellow,
199 maliput_sys::api::rules::ffi::BulbColor::kGreen => BulbColor::Green,
200 _ => panic!("Invalid bulb color"),
201 }
202 }
203
204 /// Get the type of the [Bulb].
205 /// ## Return
206 /// The [BulbType].
207 pub fn bulb_type(&self) -> BulbType {
208 let bulb_type = maliput_sys::api::rules::ffi::Bulb_type(self.bulb);
209 match *bulb_type {
210 maliput_sys::api::rules::ffi::BulbType::kRound => BulbType::Round,
211 maliput_sys::api::rules::ffi::BulbType::kArrow => BulbType::Arrow,
212 _ => panic!("Invalid bulb type"),
213 }
214 }
215
216 /// Get the position of the [Bulb] in the bulb group.
217 /// ## Return
218 /// An [crate::api::InertialPosition] representing the position of the [Bulb] in the bulb group.
219 pub fn position_bulb_group(&self) -> crate::api::InertialPosition {
220 let inertial_position = maliput_sys::api::rules::ffi::Bulb_position_bulb_group(self.bulb);
221 crate::api::InertialPosition { ip: inertial_position }
222 }
223
224 /// Get the orientation of the [Bulb] in the bulb group.
225 /// ## Return
226 /// An [crate::api::Rotation] representing the orientation of the [Bulb] in the bulb group.
227 pub fn orientation_bulb_group(&self) -> crate::api::Rotation {
228 let rotation = maliput_sys::api::rules::ffi::Bulb_orientation_bulb_group(self.bulb);
229 crate::api::Rotation { r: rotation }
230 }
231
232 /// Returns the arrow's orientation. Only applicable if [Bulb::bulb_type] returns
233 /// [BulbType::Arrow].
234 pub fn arrow_orientation_rad(&self) -> Option<f64> {
235 let arrow_orientation = maliput_sys::api::rules::ffi::Bulb_arrow_orientation_rad(self.bulb);
236 if arrow_orientation.is_null() {
237 return None;
238 }
239 Some(arrow_orientation.value)
240 }
241
242 /// Get the possible states of the [Bulb].
243 pub fn states(&self) -> Vec<BulbState> {
244 let states_cpp = maliput_sys::api::rules::ffi::Bulb_states(self.bulb);
245 states_cpp
246 .into_iter()
247 .map(Bulb::_from_cpp_state_to_rust_state)
248 .collect::<Vec<BulbState>>()
249 }
250
251 /// Get the default state of the [Bulb].
252 pub fn get_default_state(&self) -> BulbState {
253 let default_state = self.bulb.GetDefaultState();
254 Bulb::_from_cpp_state_to_rust_state(&default_state)
255 }
256
257 /// Check if the given state is possible valid for the [Bulb].
258 pub fn is_valid_state(&self, state: &BulbState) -> bool {
259 self.bulb.IsValidState(&Bulb::_from_rust_state_to_cpp_state(state))
260 }
261
262 /// Returns the bounding box of the bulb.
263 /// ## Return
264 /// A tuple containing the minimum and maximum points of the bounding box.
265 pub fn bounding_box(&self) -> (crate::math::Vector3, crate::math::Vector3) {
266 let min = maliput_sys::api::rules::ffi::Bulb_bounding_box_min(self.bulb);
267 let max = maliput_sys::api::rules::ffi::Bulb_bounding_box_max(self.bulb);
268 (crate::math::Vector3 { v: min }, crate::math::Vector3 { v: max })
269 }
270
271 /// Returns the parent [BulbGroup] of the bulb.
272 /// ## Return
273 /// The parent [BulbGroup] of the bulb.
274 /// If the bulb is not part of any group, return None.
275 pub fn bulb_group(&self) -> BulbGroup {
276 BulbGroup {
277 bulb_group: unsafe {
278 maliput_sys::api::rules::ffi::Bulb_bulb_group(self.bulb)
279 .as_ref()
280 .expect("Unable to get underlying bulb group pointer. The Bulb might not be part of any BulbGroup.")
281 },
282 }
283 }
284
285 /// Convert from the C++ BulbState to the Rust BulbState
286 /// It is expected to be used only internally.
287 ///
288 /// ## Arguments
289 /// * `cpp_bulb_state` - The C++ BulbState
290 /// ## Return
291 /// The Rust BulbState
292 /// ## Panics
293 /// If the C++ BulbState is invalid.
294 fn _from_cpp_state_to_rust_state(cpp_bulb_state: &maliput_sys::api::rules::ffi::BulbState) -> BulbState {
295 match *cpp_bulb_state {
296 maliput_sys::api::rules::ffi::BulbState::kOff => BulbState::Off,
297 maliput_sys::api::rules::ffi::BulbState::kOn => BulbState::On,
298 maliput_sys::api::rules::ffi::BulbState::kBlinking => BulbState::Blinking,
299 _ => panic!("Invalid bulb state"),
300 }
301 }
302
303 /// Convert from the Rust BulbState to the C++ BulbState
304 /// It is expected to be used only internally.
305 ///
306 /// ## Arguments
307 /// * `rust_bulb_state` - The Rust BulbState
308 /// ## Return
309 /// The C++ BulbState
310 fn _from_rust_state_to_cpp_state(rust_bulb_state: &BulbState) -> maliput_sys::api::rules::ffi::BulbState {
311 match rust_bulb_state {
312 BulbState::Off => maliput_sys::api::rules::ffi::BulbState::kOff,
313 BulbState::On => maliput_sys::api::rules::ffi::BulbState::kOn,
314 BulbState::Blinking => maliput_sys::api::rules::ffi::BulbState::kBlinking,
315 }
316 }
317}
318
319/// Models a group of bulbs within a traffic light. All of the bulbs within a
320/// group should share the same approximate orientation. However, this is not
321/// programmatically enforced.
322/// About the bulb group pose:
323/// - The position of the bulb group is defined as the linear offset of this bulb group's frame
324/// relative to the frame of the traffic light that contains it. The origin of
325/// this bulb group's frame should approximate the bulb group's CoM.
326/// - The orientation of the bulb group is defined as the rotational offset of this bulb
327/// group's frame relative to the frame of the traffic light that contains it.
328/// The +Z axis should align with the bulb group's "up" direction, and the +X
329/// axis should point in the direction that the bulb group is facing.
330/// Following a right-handed coordinate frame, the +Y axis should point left
331/// when facing the +X direction.
332pub struct BulbGroup<'a> {
333 pub bulb_group: &'a maliput_sys::api::rules::ffi::BulbGroup,
334}
335
336impl BulbGroup<'_> {
337 /// Returns this BulbGroup instance's unique identifier.
338 pub fn unique_id(&self) -> UniqueBulbGroupId {
339 UniqueBulbGroupId {
340 unique_bulb_group_id: maliput_sys::api::rules::ffi::BulbGroup_unique_id(self.bulb_group),
341 }
342 }
343
344 /// Get the id of the [BulbGroup].
345 /// ## Return
346 /// The id of the [BulbGroup].
347 pub fn id(&self) -> String {
348 maliput_sys::api::rules::ffi::BulbGroup_id(self.bulb_group)
349 }
350
351 /// Get the position of the [BulbGroup] in the traffic light.
352 /// ## Return
353 /// An [crate::api::InertialPosition] representing the position of the [BulbGroup] in the traffic light.
354 pub fn position_traffic_light(&self) -> crate::api::InertialPosition {
355 let inertial_position = maliput_sys::api::rules::ffi::BulbGroup_position_traffic_light(self.bulb_group);
356 crate::api::InertialPosition { ip: inertial_position }
357 }
358
359 /// Get the orientation of the [BulbGroup] in the traffic light.
360 /// ## Return
361 /// An [crate::api::Rotation] representing the orientation of the [BulbGroup] in the traffic light.
362 pub fn orientation_traffic_light(&self) -> crate::api::Rotation {
363 let rotation = maliput_sys::api::rules::ffi::BulbGroup_orientation_traffic_light(self.bulb_group);
364 crate::api::Rotation { r: rotation }
365 }
366
367 /// Returns the bulbs in the bulb group.
368 /// ## Return
369 /// A vector of [Bulb]s in the bulb group.
370 pub fn bulbs(&self) -> Vec<Bulb> {
371 let bulbs_cpp = maliput_sys::api::rules::ffi::BulbGroup_bulbs(self.bulb_group);
372 bulbs_cpp
373 .into_iter()
374 .map(|b| Bulb {
375 bulb: unsafe { b.bulb.as_ref().expect("") },
376 })
377 .collect::<Vec<Bulb>>()
378 }
379
380 /// Get a [Bulb] by its id
381 /// ## Arguments
382 /// * `id` - The id of the [Bulb].
383 ///
384 /// ## Return
385 /// The [Bulb] with the given id.
386 /// If no [Bulb] is found with the given id, return None.
387 pub fn get_bulb(&self, id: &String) -> Option<Bulb> {
388 let bulb = maliput_sys::api::rules::ffi::BulbGroup_GetBulb(self.bulb_group, id);
389 if bulb.is_null() {
390 return None;
391 }
392 Some(Bulb {
393 bulb: unsafe { bulb.as_ref().expect("Unable to get underlying bulb pointer") },
394 })
395 }
396
397 /// Returns the parent [TrafficLight] of the bulb group.
398 /// ## Return
399 /// The parent [TrafficLight] of the bulb group.
400 pub fn traffic_light(&self) -> TrafficLight {
401 TrafficLight {
402 traffic_light: unsafe {
403 maliput_sys::api::rules::ffi::BulbGroup_traffic_light(self.bulb_group)
404 .as_ref()
405 .expect("Unable to get underlying traffic light pointer. The BulbGroup might not be registered to a TrafficLight.")
406 },
407 }
408 }
409}
410
411/// Uniquely identifies a bulb in the `Inertial` space. This consists of the
412/// concatenation of the bulb's ID, the ID of the bulb group that contains the
413/// bulb, and the the ID of the traffic light that contains the bulb group.
414///
415/// String representation of this ID is:
416/// "`traffic_light_id().string()`-`bulb_group_id.string()`-`bulb_id.string()`"
417pub struct UniqueBulbId {
418 unique_bulb_id: cxx::UniquePtr<maliput_sys::api::rules::ffi::UniqueBulbId>,
419}
420
421impl UniqueBulbId {
422 /// Get the traffic light id of the [UniqueBulbId].
423 /// ## Return
424 /// The traffic light id of the [UniqueBulbId].
425 pub fn traffic_light_id(&self) -> String {
426 maliput_sys::api::rules::ffi::UniqueBulbId_traffic_light_id(&self.unique_bulb_id)
427 }
428
429 /// Get the bulb group id of the [UniqueBulbId].
430 /// ## Return
431 /// The bulb group id of the [UniqueBulbId].
432 pub fn bulb_group_id(&self) -> String {
433 maliput_sys::api::rules::ffi::UniqueBulbId_bulb_group_id(&self.unique_bulb_id)
434 }
435
436 /// Get the bulb id of the [UniqueBulbId].
437 /// ## Return
438 /// The bulb id of the [UniqueBulbId].
439 pub fn bulb_id(&self) -> String {
440 maliput_sys::api::rules::ffi::UniqueBulbId_bulb_id(&self.unique_bulb_id)
441 }
442
443 /// Get the string representation of the [UniqueBulbId].
444 /// ## Return
445 /// The string representation of the [UniqueBulbId].
446 pub fn string(&self) -> String {
447 self.unique_bulb_id.string().to_string()
448 }
449}
450
451/// Uniquely identifies a bulb group in the `Inertial` space. This consists of
452/// the concatenation of the ID of the bulb group, and the ID of the traffic
453/// light that contains the bulb group.
454///
455/// String representation of this ID is:
456/// "`traffic_light_id().string()`-`bulb_group_id.string()`"
457pub struct UniqueBulbGroupId {
458 unique_bulb_group_id: cxx::UniquePtr<maliput_sys::api::rules::ffi::UniqueBulbGroupId>,
459}
460
461impl UniqueBulbGroupId {
462 /// Get the traffic light id of the [UniqueBulbGroupId].
463 /// ## Return
464 /// The traffic light id of the [UniqueBulbGroupId].
465 pub fn traffic_light_id(&self) -> String {
466 maliput_sys::api::rules::ffi::UniqueBulbGroupId_traffic_light_id(&self.unique_bulb_group_id)
467 }
468
469 /// Get the bulb group id of the [UniqueBulbGroupId].
470 /// ## Return
471 /// The bulb group id of the [UniqueBulbGroupId].
472 pub fn bulb_group_id(&self) -> String {
473 maliput_sys::api::rules::ffi::UniqueBulbGroupId_bulb_group_id(&self.unique_bulb_group_id)
474 }
475
476 /// Get the string representation of the [UniqueBulbGroupId].
477 /// ## Return
478 /// The string representation of the [UniqueBulbGroupId].
479 pub fn string(&self) -> String {
480 self.unique_bulb_group_id.string().to_string()
481 }
482}
483/// Abstraction for holding the output of [RoadRulebook::rules()] and [RoadRulebook::find_rules()]
484/// methods.
485/// This struct contains a map of [DiscreteValueRule]s and [RangeValueRule]s.
486/// The keys of the map are the ids of the rules.
487/// The values of the map are the rules.
488pub struct QueryResults {
489 pub discrete_value_rules: std::collections::HashMap<String, DiscreteValueRule>,
490 pub range_value_rules: std::collections::HashMap<String, RangeValueRule>,
491}
492
493/// Interface for querying "rules of the road". This interface
494/// provides access to static information about a road network (i.e.,
495/// information determined prior to the beginning of a simulation). Some
496/// rule types may refer to additional dynamic information which will be
497/// provided by other interfaces.
498pub struct RoadRulebook<'a> {
499 pub(super) road_rulebook: &'a maliput_sys::api::rules::ffi::RoadRulebook,
500}
501
502impl<'a> RoadRulebook<'a> {
503 /// Returns the DiscreteValueRule with the specified `id`.
504 /// ## Arguments
505 /// * `rule_id` - The id of the rule.
506 /// ## Return
507 /// The DiscreteValueRule with the given id.
508 pub fn get_discrete_value_rule(&self, rule_id: &String) -> DiscreteValueRule {
509 DiscreteValueRule {
510 discrete_value_rule: maliput_sys::api::rules::ffi::RoadRulebook_GetDiscreteValueRule(
511 self.road_rulebook,
512 rule_id,
513 ),
514 }
515 }
516 /// Returns the RangeValueRule with the specified `id`.
517 /// ## Arguments
518 /// * `rule_id` - The id of the rule.
519 /// ## Return
520 /// The RangeValueRule with the given id.
521 pub fn get_range_value_rule(&self, rule_id: &String) -> RangeValueRule {
522 RangeValueRule {
523 range_value_rule: maliput_sys::api::rules::ffi::RoadRulebook_GetRangeValueRule(self.road_rulebook, rule_id),
524 }
525 }
526
527 /// Returns all the rules in the road rulebook.
528 /// ## Return
529 /// A [QueryResults] containing all the rules in the road rulebook.
530 pub fn rules(&self) -> QueryResults {
531 let query_results_cpp = maliput_sys::api::rules::ffi::RoadRulebook_Rules(self.road_rulebook);
532 let discrete_value_rules_id =
533 maliput_sys::api::rules::ffi::QueryResults_discrete_value_rules(&query_results_cpp);
534 let range_value_rules_id = maliput_sys::api::rules::ffi::QueryResults_range_value_rules(&query_results_cpp);
535 let mut dvr_map = std::collections::HashMap::new();
536 for rule_id in discrete_value_rules_id {
537 let rule = self.get_discrete_value_rule(&rule_id);
538 dvr_map.insert(rule.id(), rule);
539 }
540 let mut rvr_map = std::collections::HashMap::new();
541 for rule_id in range_value_rules_id {
542 let rule = self.get_range_value_rule(&rule_id);
543 rvr_map.insert(rule.id(), rule);
544 }
545 QueryResults {
546 discrete_value_rules: dvr_map,
547 range_value_rules: rvr_map,
548 }
549 }
550
551 pub fn find_rules(&self, ranges: &Vec<super::LaneSRange>, tolerance: f64) -> QueryResults {
552 // let mut ranges_cpp = cxx::CxxVector::new().pin_mut();
553 let mut ranges_cpp = Vec::new();
554 for range in ranges {
555 ranges_cpp.push(maliput_sys::api::rules::ffi::ConstLaneSRangeRef {
556 lane_s_range: &range.lane_s_range,
557 });
558 }
559 let query_results_cpp =
560 maliput_sys::api::rules::ffi::RoadRulebook_FindRules(self.road_rulebook, &ranges_cpp, tolerance);
561
562 let discrete_value_rules_id =
563 maliput_sys::api::rules::ffi::QueryResults_discrete_value_rules(&query_results_cpp);
564 let range_value_rules_id = maliput_sys::api::rules::ffi::QueryResults_range_value_rules(&query_results_cpp);
565 let mut dvr_map = std::collections::HashMap::new();
566 for rule_id in discrete_value_rules_id {
567 let rule = self.get_discrete_value_rule(&rule_id);
568 dvr_map.insert(rule.id(), rule);
569 }
570 let mut rvr_map = std::collections::HashMap::new();
571 for rule_id in range_value_rules_id {
572 let rule = self.get_range_value_rule(&rule_id);
573 rvr_map.insert(rule.id(), rule);
574 }
575 QueryResults {
576 discrete_value_rules: dvr_map,
577 range_value_rules: rvr_map,
578 }
579 }
580}
581
582/// ## Rule
583///
584/// A Rule may have multiple states that affect agent behavior while it is
585/// driving through the rule's zone. The possible states of a Rule must be
586/// semantically coherent. The current state of a Rule is given by a
587/// [RuleStateProvider]. States can be:
588///
589/// - range based ([RangeValueRule]).
590/// - discrete ([DiscreteValueRule]).
591///
592/// ## DiscreteValueRule
593///
594/// [DiscreteValue]s are defined by a string value.
595/// Semantics of this rule are based on _all_ possible values that this
596/// [DiscreteValueRule::type_id] could have (as specified by RuleRegistry::FindRuleByType()),
597/// not only the subset of values that a specific instance of this rule can
598/// be in.
599pub struct DiscreteValueRule {
600 discrete_value_rule: cxx::UniquePtr<maliput_sys::api::rules::ffi::DiscreteValueRule>,
601}
602
603impl DiscreteValueRule {
604 /// Returns the Id of the rule as a string.
605 pub fn id(&self) -> String {
606 maliput_sys::api::rules::ffi::DiscreteValueRule_id(&self.discrete_value_rule)
607 }
608 /// Returns the type of the rule as a string.
609 /// Example: "right-of-way-rule-type-id", "direction-usage-rule-type-id"
610 pub fn type_id(&self) -> String {
611 maliput_sys::api::rules::ffi::DiscreteValueRule_type_id(&self.discrete_value_rule)
612 }
613 /// Returns a [LaneSRoute] that represents the zone that the rule applies to.
614 pub fn zone(&self) -> crate::api::LaneSRoute {
615 let lane_s_route = maliput_sys::api::rules::ffi::DiscreteValueRule_zone(&self.discrete_value_rule);
616 crate::api::LaneSRoute { lane_s_route }
617 }
618 /// Returns the states of the rule.
619 pub fn states(&self) -> Vec<DiscreteValue> {
620 let states_cpp = &self.discrete_value_rule.states();
621 states_cpp
622 .into_iter()
623 .map(|dv| DiscreteValue {
624 rule_state: RuleStateBase {
625 severity: maliput_sys::api::rules::ffi::DiscreteValueRuleDiscreteValue_severity(dv),
626 related_rules: maliput_sys::api::rules::ffi::DiscreteValueRuleDiscreteValue_related_rules(dv),
627 related_unique_ids: maliput_sys::api::rules::ffi::DiscreteValueRuleDiscreteValue_related_unique_ids(
628 dv,
629 ),
630 },
631 value: maliput_sys::api::rules::ffi::DiscreteValueRuleDiscreteValue_value(dv),
632 })
633 .collect::<Vec<DiscreteValue>>()
634 }
635}
636
637/// ## Rule
638///
639/// A Rule may have multiple states that affect agent behavior while it is
640/// driving through the rule's zone. The possible states of a Rule must be
641/// semantically coherent. The current state of a Rule is given by a
642/// [RuleStateProvider]. States can be:
643///
644/// - range based ([RangeValueRule]).
645/// - discrete ([DiscreteValueRule]).
646///
647/// ## RangeValueRule
648///
649/// [Range]s describe a numeric range based rule.
650/// Ranges are closed and continuous, defined by a minimum and maximum quantity.
651/// When only one extreme is formally defined, the other should take a
652/// semantically correct value. For example, if a speed limit only specifies a
653/// maximum value, the minimum value is typically zero.
654pub struct RangeValueRule {
655 range_value_rule: cxx::UniquePtr<maliput_sys::api::rules::ffi::RangeValueRule>,
656}
657
658impl RangeValueRule {
659 /// Returns the Id of the rule as a string.
660 pub fn id(&self) -> String {
661 maliput_sys::api::rules::ffi::RangeValueRule_id(&self.range_value_rule)
662 }
663 /// Returns the type of the rule as a string.
664 /// Example: "right-of-way-rule-type-id", "direction-usage-rule-type-id"
665 pub fn type_id(&self) -> String {
666 maliput_sys::api::rules::ffi::RangeValueRule_type_id(&self.range_value_rule)
667 }
668 /// Returns a [LaneSRoute] that represents the zone that the rule applies to.
669 pub fn zone(&self) -> crate::api::LaneSRoute {
670 let lane_s_route = maliput_sys::api::rules::ffi::RangeValueRule_zone(&self.range_value_rule);
671 crate::api::LaneSRoute { lane_s_route }
672 }
673 /// Returns the states of the rule.
674 pub fn states(&self) -> Vec<Range> {
675 let states_cpp = &self.range_value_rule.states();
676 states_cpp
677 .into_iter()
678 .map(|r| Range {
679 rule_state: RuleStateBase {
680 severity: maliput_sys::api::rules::ffi::RangeValueRuleRange_severity(r),
681 related_rules: maliput_sys::api::rules::ffi::RangeValueRuleRange_related_rules(r),
682 related_unique_ids: maliput_sys::api::rules::ffi::RangeValueRuleRange_related_unique_ids(r),
683 },
684 description: maliput_sys::api::rules::ffi::RangeValueRuleRange_description(r),
685 min: maliput_sys::api::rules::ffi::RangeValueRuleRange_min(r),
686 max: maliput_sys::api::rules::ffi::RangeValueRuleRange_max(r),
687 })
688 .collect::<Vec<Range>>()
689 }
690}
691
692/// Defines a base state for a rule.
693///
694/// ## RuleStateBase
695///
696/// - `severity` - The severity of the rule state.
697/// - `related_rules` - A map of related rules. The key is the group name and the value is a vector of rule ids.
698/// - `related_unique_ids` - A map of related unique ids. The key is the group name and the value is a vector of unique ids.
699///
700/// See [DiscreteValueRule] and [RangeValueRule] for more information.
701pub struct RuleStateBase {
702 severity: i32,
703 related_rules: cxx::UniquePtr<cxx::CxxVector<maliput_sys::api::rules::ffi::RelatedRule>>,
704 related_unique_ids: cxx::UniquePtr<cxx::CxxVector<maliput_sys::api::rules::ffi::RelatedUniqueId>>,
705}
706
707/// Defines the interface for a rule state.
708/// ## To implement by the trait user.
709/// - `get_rule_state` - Returns the base state of the rule.
710/// To be implemented by the concrete rule state.
711pub trait RuleState {
712 /// Returns the base state of the rule.
713 /// To be implemented by the concrete rule state.
714 fn get_rule_state(&self) -> &RuleStateBase;
715
716 /// Returns the severity of the rule state.
717 fn severity(&self) -> i32 {
718 self.get_rule_state().severity
719 }
720
721 /// Returns a map of related unique ids. The key is the group name and the value is a vector of unique ids.
722 fn related_rules(&self) -> std::collections::HashMap<&String, &Vec<String>> {
723 self.get_rule_state()
724 .related_rules
725 .iter()
726 .map(|rr| (&rr.group_name, &rr.rule_ids))
727 .collect::<std::collections::HashMap<&String, &Vec<String>>>()
728 }
729 /// Returns a map of related unique ids. The key is the group name and the value is a vector of unique ids.
730 fn related_unique_ids(&self) -> std::collections::HashMap<&String, &Vec<String>> {
731 self.get_rule_state()
732 .related_unique_ids
733 .iter()
734 .map(|rui| (&rui.group_name, &rui.unique_ids))
735 .collect::<std::collections::HashMap<&String, &Vec<String>>>()
736 }
737}
738
739/// Defines a discrete value for a [DiscreteValueRule].
740/// It extends the [RuleStateBase] with the value of the discrete value.
741pub struct DiscreteValue {
742 rule_state: RuleStateBase,
743 value: String,
744}
745
746impl RuleState for DiscreteValue {
747 fn get_rule_state(&self) -> &RuleStateBase {
748 &self.rule_state
749 }
750}
751
752impl DiscreteValue {
753 /// Returns the value of the discrete value.
754 pub fn value(&self) -> &String {
755 &self.value
756 }
757}
758
759/// Defines a range value for a [RangeValueRule].
760/// It extends the [RuleStateBase] with the description, and min and max values of the range.
761pub struct Range {
762 rule_state: RuleStateBase,
763 description: String,
764 min: f64,
765 max: f64,
766}
767
768impl RuleState for Range {
769 fn get_rule_state(&self) -> &RuleStateBase {
770 &self.rule_state
771 }
772}
773
774impl Range {
775 /// Returns the description of the range value.
776 pub fn description(&self) -> &String {
777 &self.description
778 }
779 /// Returns the minimum value of the range.
780 pub fn min(&self) -> f64 {
781 self.min
782 }
783 /// Returns the maximum value of the range.
784 pub fn max(&self) -> f64 {
785 self.max
786 }
787}