Skip to content

Commit

Permalink
Bindings for SRange, LaneSRange. (#60)
Browse files Browse the repository at this point in the history
Signed-off-by: Franco Cipollone <[email protected]>
  • Loading branch information
francocipollone authored Apr 16, 2024
1 parent f7de26c commit 16ca008
Show file tree
Hide file tree
Showing 4 changed files with 313 additions and 0 deletions.
33 changes: 33 additions & 0 deletions maliput-sys/src/api/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <maliput/api/lane_data.h>
#include <maliput/api/road_network.h>
#include <maliput/api/road_geometry.h>
#include <maliput/api/regions.h>
#include <maliput/api/segment.h>

#include <rust/cxx.h>
Expand Down Expand Up @@ -237,5 +238,37 @@ std::unique_ptr<Rotation> Rotation_Reverse(const Rotation& rotation) {
return std::make_unique<Rotation>(rotation.Reverse());
}

std::unique_ptr<SRange> SRange_new(rust::f64 start, rust::f64 end) {
return std::make_unique<SRange>(start, end);
}

std::unique_ptr<SRange> SRange_GetIntersection(const SRange& s_range, const SRange& other_s_range, rust::f64 tolerance) {
const auto intersection = s_range.GetIntersection(other_s_range, tolerance);
if (intersection) {
return std::make_unique<SRange>(*intersection);
}
return nullptr;
}

std::unique_ptr<LaneSRange> LaneSRange_new(const rust::String& lane_id, const SRange& s_range) {
return std::make_unique<LaneSRange>(LaneId{std::string(lane_id)}, s_range);
}

rust::String LaneSRange_lane_id(const LaneSRange& lane_s_range) {
return lane_s_range.lane_id().string();
}

std::unique_ptr<SRange> LaneSRange_s_range(const LaneSRange& lane_s_range) {
return std::make_unique<SRange>(lane_s_range.s_range());
}

std::unique_ptr<LaneSRange> LaneSRange_GetIntersection(const LaneSRange& lane_s_range, const LaneSRange& other_lane_s_range, rust::f64 tolerance) {
const auto intersection = lane_s_range.GetIntersection(other_lane_s_range, tolerance);
if (intersection) {
return std::make_unique<LaneSRange>(*intersection);
}
return nullptr;
}

} // namespace api
} // namespace maliput
27 changes: 27 additions & 0 deletions maliput-sys/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,33 @@ pub mod ffi {
type HBounds;
fn min(self: &HBounds) -> f64;
fn max(self: &HBounds) -> f64;

// SRange bindings definitions
type SRange;
fn SRange_new(s0: f64, s1: f64) -> UniquePtr<SRange>;
fn s0(self: &SRange) -> f64;
fn s1(self: &SRange) -> f64;
fn set_s0(self: Pin<&mut SRange>, s0: f64);
fn set_s1(self: Pin<&mut SRange>, s1: f64);
fn size(self: &SRange) -> f64;
fn WithS(self: &SRange) -> bool;
fn Intersects(self: &SRange, other: &SRange, tolerance: f64) -> bool;
fn Contains(self: &SRange, s_range: &SRange, tolerance: f64) -> bool;
fn SRange_GetIntersection(s_range: &SRange, other: &SRange, tolerance: f64) -> UniquePtr<SRange>;

// LaneSRange bindings definitions
type LaneSRange;
fn LaneSRange_new(lane_id: &String, s_range: &SRange) -> UniquePtr<LaneSRange>;
fn length(self: &LaneSRange) -> f64;
fn Intersects(self: &LaneSRange, other: &LaneSRange, tolerance: f64) -> bool;
fn Contains(self: &LaneSRange, lane_s_range: &LaneSRange, tolerance: f64) -> bool;
fn LaneSRange_lane_id(lane_s_range: &LaneSRange) -> String;
fn LaneSRange_s_range(lane_s_range: &LaneSRange) -> UniquePtr<SRange>;
fn LaneSRange_GetIntersection(
lane_s_range: &LaneSRange,
other: &LaneSRange,
tolerance: f64,
) -> UniquePtr<LaneSRange>;
}
impl UniquePtr<RoadNetwork> {}
impl UniquePtr<LanePosition> {}
Expand Down
60 changes: 60 additions & 0 deletions maliput-sys/tests/api_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -293,4 +293,64 @@ mod api_test {
assert!((reversed_rotation.yaw() - PI).abs() < tol);
}
}

mod s_range_test {
use maliput_sys::api::ffi::SRange_GetIntersection;
use maliput_sys::api::ffi::SRange_new;

#[test]
fn s_range_api() {
let mut s_range = SRange_new(1.0, 11.0);
assert_eq!(s_range.s0(), 1.0);
assert_eq!(s_range.s1(), 11.0);
assert_eq!(s_range.size(), 10.0);
s_range.as_mut().expect("").set_s0(2.0);
s_range.as_mut().expect("").set_s1(12.0);
assert_eq!(s_range.s0(), 2.0);
assert_eq!(s_range.s1(), 12.0);
assert!(s_range.WithS());

let s_range_2 = SRange_new(5.0, 20.0);
assert!(s_range.Intersects(&s_range_2, 1e-3));
assert!(!s_range.Contains(&s_range_2, 1e-3));

let intersection = SRange_GetIntersection(&s_range, &s_range_2, 1e-3);
assert!(!intersection.is_null());
assert_eq!(intersection.s0(), 5.0);
assert_eq!(intersection.s1(), 12.0);

let non_intersected_s_range = SRange_new(150.0, 200.0);
assert!(!s_range.Intersects(&non_intersected_s_range, 1e-3));
let intersection = SRange_GetIntersection(&s_range, &non_intersected_s_range, 1e-3);
assert!(intersection.is_null());
}
}

mod lane_s_range_test {
use maliput_sys::api::ffi::LaneSRange_GetIntersection;
use maliput_sys::api::ffi::LaneSRange_lane_id;
use maliput_sys::api::ffi::LaneSRange_new;
use maliput_sys::api::ffi::LaneSRange_s_range;
use maliput_sys::api::ffi::SRange_new;

#[test]
fn lane_s_range_api() {
let expected_s_range = SRange_new(1.0, 2.0);
let expected_lane_id = String::from("0_0_1");
let lane_s_range = LaneSRange_new(&expected_lane_id, &expected_s_range);
assert_eq!(LaneSRange_lane_id(&lane_s_range), expected_lane_id);
assert_eq!(lane_s_range.length(), 1.0);
let s_range = LaneSRange_s_range(&lane_s_range);
assert_eq!(s_range.s0(), expected_s_range.s0());
assert_eq!(s_range.s1(), expected_s_range.s1());
let lane_s_range_2 = LaneSRange_new(&expected_lane_id, &SRange_new(1.5, 2.5));
assert!(lane_s_range.Intersects(&lane_s_range_2, 1e-3));
assert!(!lane_s_range.Contains(&lane_s_range_2, 1e-3));
let intersection = LaneSRange_GetIntersection(&lane_s_range, &lane_s_range_2, 1e-3);
assert!(!intersection.is_null());
let s_range = LaneSRange_s_range(&intersection);
assert_eq!(s_range.s0(), 1.5);
assert_eq!(s_range.s1(), 2.0);
}
}
}
193 changes: 193 additions & 0 deletions maliput/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,113 @@ impl Rotation {
}
}

/// Directed, inclusive longitudinal (s value) range from s0 to s1.
/// Wrapper around C++ implementation `maliput::api::SRange`.
pub struct SRange {
s_range: cxx::UniquePtr<maliput_sys::api::ffi::SRange>,
}

impl SRange {
/// Create a new `SRange` with the given `s0` and `s1`.
pub fn new(s0: f64, s1: f64) -> SRange {
SRange {
s_range: maliput_sys::api::ffi::SRange_new(s0, s1),
}
}
/// Get the s0 of the `SRange`.
pub fn s0(&self) -> f64 {
self.s_range.s0()
}
/// Get the s1 of the `SRange`.
pub fn s1(&self) -> f64 {
self.s_range.s1()
}
/// Set the s0 of the `SRange`.
pub fn set_s0(&mut self, s0: f64) {
self.s_range.as_mut().expect("Underlying SRange is null").set_s0(s0);
}
/// Set the s1 of the `SRange`.
pub fn set_s1(&mut self, s1: f64) {
self.s_range.as_mut().expect("Underlying SRange is null").set_s1(s1);
}
/// Get the size of the `SRange`.
pub fn size(&self) -> f64 {
self.s_range.size()
}
/// Returns true When this SRange is in the direction of +s.
pub fn with_s(&self) -> bool {
self.s_range.WithS()
}
/// Determines whether this SRange intersects with `s_range`.
pub fn intersects(&self, s_range: &SRange, tolerance: f64) -> bool {
self.s_range.Intersects(&s_range.s_range, tolerance)
}
/// Determines whether this SRange contains `s_range`.
pub fn contains(&self, s_range: &SRange, tolerance: f64) -> bool {
self.s_range.Contains(&s_range.s_range, tolerance)
}
/// Get the intersection of this SRange with `s_range`.
/// Returns None if the intersection is empty.
pub fn get_intersection(&self, s_range: &SRange, tolerance: f64) -> Option<SRange> {
let intersection = maliput_sys::api::ffi::SRange_GetIntersection(&self.s_range, &s_range.s_range, tolerance);
match intersection.is_null() {
true => None,
false => Some(SRange { s_range: intersection }),
}
}
}

/// Directed longitudinal range of a specific Lane, identified by a LaneId.
/// Wrapper around C++ implementation `maliput::api::LaneSRange`.
pub struct LaneSRange {
lane_s_range: cxx::UniquePtr<maliput_sys::api::ffi::LaneSRange>,
}

impl LaneSRange {
/// Create a new `LaneSRange` with the given `lane_id` and `s_range`.
pub fn new(lane_id: &String, s_range: &SRange) -> LaneSRange {
LaneSRange {
lane_s_range: maliput_sys::api::ffi::LaneSRange_new(lane_id, &s_range.s_range),
}
}
/// Get the lane id of the `LaneSRange`.
pub fn lane_id(&self) -> String {
maliput_sys::api::ffi::LaneSRange_lane_id(&self.lane_s_range)
}
/// Get the s range of the `LaneSRange`.
pub fn s_range(&self) -> SRange {
SRange {
s_range: maliput_sys::api::ffi::LaneSRange_s_range(&self.lane_s_range),
}
}
/// Get the length of the `LaneSRange`.
pub fn length(&self) -> f64 {
self.lane_s_range.length()
}
/// Determines whether this LaneSRange intersects with `lane_s_range`.
pub fn intersects(&self, lane_s_range: &LaneSRange, tolerance: f64) -> bool {
self.lane_s_range.Intersects(&lane_s_range.lane_s_range, tolerance)
}
/// Determines whether this LaneSRange contains `lane_s_range`.
pub fn contains(&self, lane_s_range: &LaneSRange, tolerance: f64) -> bool {
self.lane_s_range.Contains(&lane_s_range.lane_s_range, tolerance)
}
/// Get the intersection of this LaneSRange with `lane_s_range`.
pub fn get_intersection(&self, lane_s_range: &LaneSRange, tolerance: f64) -> Option<LaneSRange> {
let intersection = maliput_sys::api::ffi::LaneSRange_GetIntersection(
&self.lane_s_range,
&lane_s_range.lane_s_range,
tolerance,
);
match intersection.is_null() {
true => None,
false => Some(LaneSRange {
lane_s_range: intersection,
}),
}
}
}

mod tests {
mod lane_position {
#[test]
Expand Down Expand Up @@ -1069,4 +1176,90 @@ mod tests {
assert_eq!(matrix.row(2), crate::math::Vector3::new(0.0, 0.0, 1.0));
}
}

mod s_range {
#[test]
fn s_range_new() {
let s_range = crate::api::SRange::new(1.0, 2.0);
assert_eq!(s_range.s0(), 1.0);
assert_eq!(s_range.s1(), 2.0);
}
#[test]
fn s_range_api() {
let s_range_1 = crate::api::SRange::new(1.0, 3.0);
let s_range_2 = crate::api::SRange::new(2.0, 4.0);
assert_eq!(s_range_1.size(), 2.0);
assert!(s_range_1.with_s());
assert!(s_range_1.intersects(&s_range_2, 0.0));
assert!(!s_range_1.contains(&s_range_2, 0.0));
}
#[test]
fn s_range_setters() {
let mut s_range = crate::api::SRange::new(0.0, 4.0);
s_range.set_s0(1.0);
s_range.set_s1(3.0);
assert_eq!(s_range.s0(), 1.0);
assert_eq!(s_range.s1(), 3.0);
}
#[test]
fn s_range_get_intersection_with_intersection() {
let s_range_1 = crate::api::SRange::new(1.0, 3.0);
let s_range_2 = crate::api::SRange::new(2.0, 4.0);
let intersection = s_range_1.get_intersection(&s_range_2, 0.0);
assert!(intersection.is_some());
let intersection = intersection.unwrap();
assert_eq!(intersection.s0(), 2.0);
assert_eq!(intersection.s1(), 3.0);
}
#[test]
fn s_range_get_intersection_with_no_intersection() {
let s_range_1 = crate::api::SRange::new(1.0, 2.0);
let s_range_2 = crate::api::SRange::new(3.0, 4.0);
let intersection = s_range_1.get_intersection(&s_range_2, 0.0);
assert!(intersection.is_none());
}
}

mod lane_s_range {
#[test]
fn lane_s_range_new() {
let lane_s_range =
crate::api::LaneSRange::new(&String::from("lane_test"), &crate::api::SRange::new(1.0, 2.0));
assert_eq!(lane_s_range.lane_id(), "lane_test");
assert_eq!(lane_s_range.s_range().s0(), 1.0);
assert_eq!(lane_s_range.s_range().s1(), 2.0);
assert_eq!(lane_s_range.length(), 1.0);
}
#[test]
fn lane_s_range_api() {
let lane_s_range_1 =
crate::api::LaneSRange::new(&String::from("lane_test"), &crate::api::SRange::new(1.0, 2.0));
let lane_s_range_2 =
crate::api::LaneSRange::new(&String::from("lane_test"), &crate::api::SRange::new(2.0, 3.0));
assert!(lane_s_range_1.intersects(&lane_s_range_2, 0.0));
assert!(!lane_s_range_1.contains(&lane_s_range_2, 0.0));
}
#[test]
fn lane_s_range_get_intersection_with_intersection() {
let lane_s_range_1 =
crate::api::LaneSRange::new(&String::from("lane_test"), &crate::api::SRange::new(1.0, 3.0));
let lane_s_range_2 =
crate::api::LaneSRange::new(&String::from("lane_test"), &crate::api::SRange::new(2.0, 4.0));
let intersection = lane_s_range_1.get_intersection(&lane_s_range_2, 0.0);
assert!(intersection.is_some());
let intersection = intersection.unwrap();
assert_eq!(intersection.lane_id(), "lane_test");
assert_eq!(intersection.s_range().s0(), 2.0);
assert_eq!(intersection.s_range().s1(), 3.0);
}
#[test]
fn lane_s_range_get_intersection_with_no_intersection() {
let lane_s_range_1 =
crate::api::LaneSRange::new(&String::from("lane test_1"), &crate::api::SRange::new(1.0, 3.0));
let lane_s_range_2 =
crate::api::LaneSRange::new(&String::from("lane_test_2"), &crate::api::SRange::new(2.0, 4.0));
let intersection = lane_s_range_1.get_intersection(&lane_s_range_2, 0.0);
assert!(intersection.is_none());
}
}
}

0 comments on commit 16ca008

Please sign in to comment.