Skip to content

Commit

Permalink
Adds bindings/rust api for Bulb. (#101)
Browse files Browse the repository at this point in the history
Signed-off-by: Franco Cipollone <[email protected]>
  • Loading branch information
francocipollone authored May 21, 2024
1 parent a10e355 commit c9889dd
Show file tree
Hide file tree
Showing 4 changed files with 254 additions and 1 deletion.
50 changes: 50 additions & 0 deletions maliput-sys/src/api/rules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand All @@ -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;
Expand All @@ -54,5 +87,22 @@ pub mod ffi {
fn TrafficLight_id(traffic_light: &TrafficLight) -> String;
fn TrafficLight_position_road_network(traffic_light: &TrafficLight) -> UniquePtr<InertialPosition>;
fn TrafficLight_orientation_road_network(traffic_light: &TrafficLight) -> UniquePtr<Rotation>;

type BulbColor;
type BulbState;
type BulbType;
type Bulb;
fn Bulb_id(bulb: &Bulb) -> String;
fn Bulb_position_bulb_group(bulb: &Bulb) -> UniquePtr<InertialPosition>;
fn Bulb_orientation_bulb_group(bulb: &Bulb) -> UniquePtr<Rotation>;
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<FloatWrapper>;
fn Bulb_states(bulb: &Bulb) -> UniquePtr<CxxVector<ConstBulbStateRef>>;
fn GetDefaultState(self: &Bulb) -> BulbState;
fn IsValidState(self: &Bulb, state: &BulbState) -> bool;
fn Bulb_bounding_box_min(bulb: &Bulb) -> UniquePtr<Vector3>;
fn Bulb_bounding_box_max(bulb: &Bulb) -> UniquePtr<Vector3>;
}
}
40 changes: 40 additions & 0 deletions maliput-sys/src/api/rules/rules.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

#include <maliput/api/rules/traffic_lights.h>
#include <maliput/api/rules/traffic_light_book.h>
#include <maliput/math/vector.h>

#include <rust/cxx.h>

Expand Down Expand Up @@ -69,6 +70,45 @@ std::unique_ptr<maliput::api::Rotation> TrafficLight_orientation_road_network(co
return std::make_unique<maliput::api::Rotation>(traffic_light.orientation_road_network());
}

rust::String Bulb_id(const Bulb& bulb) {
return bulb.id().string();
}

std::unique_ptr<maliput::api::InertialPosition> Bulb_position_bulb_group(const Bulb& bulb) {
return std::make_unique<maliput::api::InertialPosition>(bulb.position_bulb_group());
}

std::unique_ptr<maliput::api::Rotation> Bulb_orientation_bulb_group(const Bulb& bulb) {
return std::make_unique<maliput::api::Rotation>(bulb.orientation_bulb_group());
}

const BulbType& Bulb_type(const Bulb& bulb) {
return bulb.type();
}

std::unique_ptr<FloatWrapper> Bulb_arrow_orientation_rad(const Bulb& bulb) {
const auto orientation = bulb.arrow_orientation_rad();
return orientation.has_value() ? std::make_unique<FloatWrapper>(FloatWrapper{orientation.value()}) : nullptr;
}

std::unique_ptr<std::vector<ConstBulbStateRef>> Bulb_states(const Bulb& bulb) {
const auto states_cpp = bulb.states();
std::vector<ConstBulbStateRef> states;
states.reserve(states_cpp.size());
for (const auto state : states_cpp) {
states.push_back({state});
}
return std::make_unique<std::vector<ConstBulbStateRef>>(std::move(states));
}

std::unique_ptr<maliput::math::Vector3> Bulb_bounding_box_min(const Bulb& bulb) {
return std::make_unique<maliput::math::Vector3>(bulb.bounding_box().p_BMin);
}

std::unique_ptr<maliput::math::Vector3> Bulb_bounding_box_max(const Bulb& bulb) {
return std::make_unique<maliput::math::Vector3>(bulb.bounding_box().p_BMax);
}

} // namespace rules
} // namespace api
} // namespace maliput
163 changes: 163 additions & 0 deletions maliput/src/api/rules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<f64> {
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<BulbState> {
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::<Vec<BulbState>>()
}

/// 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<BulbGroup> {
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,
}
}
}
2 changes: 1 addition & 1 deletion maliput/src/math/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
/// assert_eq!(v.cross(&v), Vector3::new(0.0, 0.0, 0.0));
/// ```
pub struct Vector3 {
v: cxx::UniquePtr<maliput_sys::math::ffi::Vector3>,
pub(crate) v: cxx::UniquePtr<maliput_sys::math::ffi::Vector3>,
}

impl Vector3 {
Expand Down

0 comments on commit c9889dd

Please sign in to comment.