diff --git a/maliput-sys/src/api/rules/mod.rs b/maliput-sys/src/api/rules/mod.rs index 3c69f8c..057eef7 100644 --- a/maliput-sys/src/api/rules/mod.rs +++ b/maliput-sys/src/api/rules/mod.rs @@ -35,6 +35,37 @@ pub mod ffi { struct ConstTrafficLightPtr { pub traffic_light: *const TrafficLight, } + /// Shared struct for `BulbState` references. + /// This is needed because `&f` can't be used directly in the CxxVector collection. + struct ConstBulbStateRef<'a> { + pub bulb_state: &'a BulbState, + } + /// Shared struct for floats types. + /// This is needed because `f64` can't be used directly in the UniquePtr type. + struct FloatWrapper { + pub value: f64, + } + + #[repr(i32)] + enum BulbColor { + kRed = 0, + kYellow, + kGreen, + } + + #[repr(i32)] + enum BulbType { + kRound = 0, + kArrow, + } + + #[repr(i32)] + enum BulbState { + kOff = 0, + kOn, + kBlinking, + } + unsafe extern "C++" { include!("api/rules/rules.h"); @@ -43,6 +74,8 @@ pub mod ffi { type InertialPosition = crate::api::ffi::InertialPosition; #[namespace = "maliput::api"] type Rotation = crate::api::ffi::Rotation; + #[namespace = "maliput::math"] + type Vector3 = crate::math::ffi::Vector3; // TrafficLightBook bindings definitions. type TrafficLightBook; @@ -54,5 +87,22 @@ pub mod ffi { fn TrafficLight_id(traffic_light: &TrafficLight) -> String; fn TrafficLight_position_road_network(traffic_light: &TrafficLight) -> UniquePtr; fn TrafficLight_orientation_road_network(traffic_light: &TrafficLight) -> UniquePtr; + + type BulbColor; + type BulbState; + type BulbType; + type Bulb; + fn Bulb_id(bulb: &Bulb) -> String; + fn Bulb_position_bulb_group(bulb: &Bulb) -> UniquePtr; + fn Bulb_orientation_bulb_group(bulb: &Bulb) -> UniquePtr; + fn color(self: &Bulb) -> &BulbColor; + // We can't automatically use the name `type` as it is a reserved keyword in Rust. + fn Bulb_type(bulb: &Bulb) -> &BulbType; + fn Bulb_arrow_orientation_rad(bulb: &Bulb) -> UniquePtr; + fn Bulb_states(bulb: &Bulb) -> UniquePtr>; + fn GetDefaultState(self: &Bulb) -> BulbState; + fn IsValidState(self: &Bulb, state: &BulbState) -> bool; + fn Bulb_bounding_box_min(bulb: &Bulb) -> UniquePtr; + fn Bulb_bounding_box_max(bulb: &Bulb) -> UniquePtr; } } diff --git a/maliput-sys/src/api/rules/rules.h b/maliput-sys/src/api/rules/rules.h index b571ce7..263e23f 100644 --- a/maliput-sys/src/api/rules/rules.h +++ b/maliput-sys/src/api/rules/rules.h @@ -34,6 +34,7 @@ #include #include +#include #include @@ -69,6 +70,45 @@ std::unique_ptr TrafficLight_orientation_road_network(co return std::make_unique(traffic_light.orientation_road_network()); } +rust::String Bulb_id(const Bulb& bulb) { + return bulb.id().string(); +} + +std::unique_ptr Bulb_position_bulb_group(const Bulb& bulb) { + return std::make_unique(bulb.position_bulb_group()); +} + +std::unique_ptr Bulb_orientation_bulb_group(const Bulb& bulb) { + return std::make_unique(bulb.orientation_bulb_group()); +} + +const BulbType& Bulb_type(const Bulb& bulb) { + return bulb.type(); +} + +std::unique_ptr Bulb_arrow_orientation_rad(const Bulb& bulb) { + const auto orientation = bulb.arrow_orientation_rad(); + return orientation.has_value() ? std::make_unique(FloatWrapper{orientation.value()}) : nullptr; +} + +std::unique_ptr> Bulb_states(const Bulb& bulb) { + const auto states_cpp = bulb.states(); + std::vector states; + states.reserve(states_cpp.size()); + for (const auto state : states_cpp) { + states.push_back({state}); + } + return std::make_unique>(std::move(states)); +} + +std::unique_ptr Bulb_bounding_box_min(const Bulb& bulb) { + return std::make_unique(bulb.bounding_box().p_BMin); +} + +std::unique_ptr Bulb_bounding_box_max(const Bulb& bulb) { + return std::make_unique(bulb.bounding_box().p_BMax); +} + } // namespace rules } // namespace api } // namespace maliput diff --git a/maliput/src/api/rules/mod.rs b/maliput/src/api/rules/mod.rs index 8326e3e..8796349 100644 --- a/maliput/src/api/rules/mod.rs +++ b/maliput/src/api/rules/mod.rs @@ -109,3 +109,166 @@ impl<'a> TrafficLight<'a> { crate::api::Rotation { r: rotation } } } + +/// Forward declaration of the [BulbGroup] struct. +pub struct BulbGroup; + +/// Defines the possible bulb colors. +pub enum BulbColor { + Red, + Yellow, + Green, +} + +/// Defines the possible bulb types. +pub enum BulbType { + Round, + Arrow, +} + +/// Defines the possible bulb types. +pub enum BulbState { + Off, + On, + Blinking, +} + +/// Models a bulb within a bulb group. +pub struct Bulb<'a> { + pub bulb: &'a maliput_sys::api::rules::ffi::Bulb, +} + +impl Bulb<'_> { + /// Returns this Bulb instance's unique identifier. + pub fn unique_id(&self) -> String { + unimplemented!() + } + + /// Get the id of the [Bulb]. + /// ## Return + /// The id of the [Bulb]. + pub fn id(&self) -> String { + maliput_sys::api::rules::ffi::Bulb_id(self.bulb) + } + + /// Get the color of the [Bulb]. + /// ## Return + /// The [BulbColor]. + pub fn color(&self) -> BulbColor { + let color = self.bulb.color(); + match *color { + maliput_sys::api::rules::ffi::BulbColor::kRed => BulbColor::Red, + maliput_sys::api::rules::ffi::BulbColor::kYellow => BulbColor::Yellow, + maliput_sys::api::rules::ffi::BulbColor::kGreen => BulbColor::Green, + _ => panic!("Invalid bulb color"), + } + } + + /// Get the type of the [Bulb]. + /// ## Return + /// The [BulbType]. + pub fn bulb_type(&self) -> BulbType { + let bulb_type = maliput_sys::api::rules::ffi::Bulb_type(self.bulb); + match *bulb_type { + maliput_sys::api::rules::ffi::BulbType::kRound => BulbType::Round, + maliput_sys::api::rules::ffi::BulbType::kArrow => BulbType::Arrow, + _ => panic!("Invalid bulb type"), + } + } + + /// Get the position of the [Bulb] in the bulb group. + /// ## Return + /// An [crate::api::InertialPosition] representing the position of the [Bulb] in the bulb group. + pub fn position_bulb_group(&self) -> crate::api::InertialPosition { + let inertial_position = maliput_sys::api::rules::ffi::Bulb_position_bulb_group(self.bulb); + crate::api::InertialPosition { ip: inertial_position } + } + + /// Get the orientation of the [Bulb] in the bulb group. + /// ## Return + /// An [crate::api::Rotation] representing the orientation of the [Bulb] in the bulb group. + pub fn orientation_bulb_group(&self) -> crate::api::Rotation { + let rotation = maliput_sys::api::rules::ffi::Bulb_orientation_bulb_group(self.bulb); + crate::api::Rotation { r: rotation } + } + + /// Returns the arrow's orientation. Only applicable if [Bulb::bulb_type] returns + /// [BulbType::Arrow]. + pub fn arrow_orientation_rad(&self) -> Option { + let arrow_orientation = maliput_sys::api::rules::ffi::Bulb_arrow_orientation_rad(self.bulb); + if arrow_orientation.is_null() { + return None; + } + Some(arrow_orientation.value) + } + + /// Get the possible states of the [Bulb]. + pub fn states(&self) -> Vec { + let states_cpp = maliput_sys::api::rules::ffi::Bulb_states(self.bulb); + states_cpp + .into_iter() + .map(|state| Bulb::_from_cpp_state_to_rust_state(state.bulb_state)) + .collect::>() + } + + /// Get the default state of the [Bulb]. + pub fn get_default_state(&self) -> BulbState { + let default_state = self.bulb.GetDefaultState(); + Bulb::_from_cpp_state_to_rust_state(&default_state) + } + + /// Check if the given state is possible valid for the [Bulb]. + pub fn is_valid_state(&self, state: &BulbState) -> bool { + self.bulb.IsValidState(&Bulb::_from_rust_state_to_cpp_state(state)) + } + + /// Returns the bounding box of the bulb. + /// ## Return + /// A tuple containing the minimum and maximum points of the bounding box. + pub fn bounding_box(&self) -> (crate::math::Vector3, crate::math::Vector3) { + let min = maliput_sys::api::rules::ffi::Bulb_bounding_box_min(self.bulb); + let max = maliput_sys::api::rules::ffi::Bulb_bounding_box_max(self.bulb); + (crate::math::Vector3 { v: min }, crate::math::Vector3 { v: max }) + } + + /// Returns the parent [BulbGroup] of the bulb. + /// ## Return + /// The parent [BulbGroup] of the bulb. + /// If the bulb is not part of any group, return None. + pub fn bulb_group(&self) -> Option { + unimplemented!() + } + + /// Convert from the C++ BulbState to the Rust BulbState + /// It is expected to be used only internally. + /// + /// ## Arguments + /// * `cpp_bulb_state` - The C++ BulbState + /// ## Return + /// The Rust BulbState + /// ## Panics + /// If the C++ BulbState is invalid. + fn _from_cpp_state_to_rust_state(cpp_bulb_state: &maliput_sys::api::rules::ffi::BulbState) -> BulbState { + match *cpp_bulb_state { + maliput_sys::api::rules::ffi::BulbState::kOff => BulbState::Off, + maliput_sys::api::rules::ffi::BulbState::kOn => BulbState::On, + maliput_sys::api::rules::ffi::BulbState::kBlinking => BulbState::Blinking, + _ => panic!("Invalid bulb state"), + } + } + + /// Convert from the Rust BulbState to the C++ BulbState + /// It is expected to be used only internally. + /// + /// ## Arguments + /// * `rust_bulb_state` - The Rust BulbState + /// ## Return + /// The C++ BulbState + fn _from_rust_state_to_cpp_state(rust_bulb_state: &BulbState) -> maliput_sys::api::rules::ffi::BulbState { + match rust_bulb_state { + BulbState::Off => maliput_sys::api::rules::ffi::BulbState::kOff, + BulbState::On => maliput_sys::api::rules::ffi::BulbState::kOn, + BulbState::Blinking => maliput_sys::api::rules::ffi::BulbState::kBlinking, + } + } +} diff --git a/maliput/src/math/mod.rs b/maliput/src/math/mod.rs index 43e49b1..562388a 100644 --- a/maliput/src/math/mod.rs +++ b/maliput/src/math/mod.rs @@ -46,7 +46,7 @@ /// assert_eq!(v.cross(&v), Vector3::new(0.0, 0.0, 0.0)); /// ``` pub struct Vector3 { - v: cxx::UniquePtr, + pub(crate) v: cxx::UniquePtr, } impl Vector3 {