bcar 0.2.1

BCar is a Rust library with basic bicycle car computations.
Documentation
//! BCar is a Rust library with basic bicycle car computations.

mod geometry;
pub use crate::geometry::Point;
pub use crate::geometry::Pose;
pub use crate::geometry::PoseRange;
pub use crate::geometry::intersect_line_line;
pub use crate::geometry::intersect_circle_line;
pub use crate::geometry::angle_between;
pub use crate::geometry::edist;

mod properties;
pub use crate::properties::Motion;
pub use crate::properties::Size;

mod bcar;
pub use crate::bcar::BCar;

mod pslot;
pub use crate::pslot::PSlot;

mod ep;
pub use crate::ep::EntryPlanner;

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn basic_geometry() {
        let bc = BCar::default();
        assert_eq!(bc.mtr(), 4.010942753884407);
        assert!(bc.ccl().x - 0.0 < 0.00001);
        assert!(bc.ccl().y - 4.010942753884407 < 1e-10);
        assert!(bc.ccr().x - 0.0 < 0.00001);
        assert!(bc.ccr().y - -4.010942753884407 < 1e-10);
    }

    #[test]
    fn drivable() {
        let bc = BCar::default();
        assert!(bc.drivable(Pose::new(0.0, 0.0, 0.0))); // pass the same pose
        assert!(bc.drivable(Pose::new(1.0, 0.0, 0.0))); // pass forward
        assert!(bc.drivable(Pose::new(-1.0, 0.0, 0.0))); // pass backward
        let d = std::f64::consts::PI / 2.0 / 100.0;
        for ai in 1..99 {
            // 1st quadrant
            let a = ai as f64 * -d;
            let mut pose = bc.pose;
            pose.rotate(bc.ccr(), a);
            assert!(bc.drivable(pose)); // pass drivable border
            let _bc = BCar::new_xyh(
                bc.pose.x + 0.00001 * bc.pose.h.cos(),
                bc.pose.y + 0.00001 * bc.pose.h.sin(),
                bc.pose.h
            );
            let mut pose = _bc.pose;
            pose.rotate(_bc.ccr(), a);
            assert!(bc.drivable(pose)); // pass near drivable border
            let _bc = BCar::new_xyh(
                bc.pose.x - 0.00001 * bc.pose.h.cos(),
                bc.pose.y - 0.00001 * bc.pose.h.sin(),
                bc.pose.h
            );
            let mut pose = _bc.pose;
            pose.rotate(_bc.ccr(), a);
            assert!(!bc.drivable(pose)); // fail near drivable border

            // 2nd quadrant
            let a = ai as f64 * d;
            let mut pose = bc.pose;
            pose.rotate(bc.ccl(), a);
            assert!(bc.drivable(pose)); // pass drivable border
            let _bc = BCar::new_xyh(
                bc.pose.x + 0.00001 * bc.pose.h.cos(),
                bc.pose.y + 0.00001 * bc.pose.h.sin(),
                bc.pose.h
            );
            let mut pose = _bc.pose;
            pose.rotate(_bc.ccl(), a);
            assert!(bc.drivable(pose)); // pass near drivable border
            let _bc = BCar::new_xyh(
                bc.pose.x - 0.00001 * bc.pose.h.cos(),
                bc.pose.y - 0.00001 * bc.pose.h.sin(),
                bc.pose.h
            );
            let mut pose = _bc.pose;
            pose.rotate(_bc.ccl(), a);
            assert!(!bc.drivable(pose)); // fail near drivable border

            // 3rd quadrant
            let a = ai as f64 * -d;
            let mut pose = bc.pose;
            pose.rotate(bc.ccl(), a);
            assert!(bc.drivable(pose)); // pass drivable border
            let _bc = BCar::new_xyh(
                bc.pose.x - 0.00001 * bc.pose.h.cos(),
                bc.pose.y - 0.00001 * bc.pose.h.sin(),
                bc.pose.h
            );
            let mut pose = _bc.pose;
            pose.rotate(_bc.ccl(), a);
            assert!(bc.drivable(pose)); // pass near drivable border
            let _bc = BCar::new_xyh(
                bc.pose.x + 0.00001 * bc.pose.h.cos(),
                bc.pose.y + 0.00001 * bc.pose.h.sin(),
                bc.pose.h
            );
            let mut pose = _bc.pose;
            pose.rotate(_bc.ccl(), a);
            assert!(!bc.drivable(pose)); // fail near drivable border

            // 4th quadrant
            let a = ai as f64 * d;
            let mut pose = bc.pose;
            pose.rotate(bc.ccr(), a);
            assert!(bc.drivable(pose)); // pass drivable border
            let _bc = BCar::new_xyh(
                bc.pose.x - 0.00001 * bc.pose.h.cos(),
                bc.pose.y - 0.00001 * bc.pose.h.sin(),
                bc.pose.h
            );
            let mut pose = _bc.pose;
            pose.rotate(_bc.ccr(), a);
            assert!(bc.drivable(pose)); // pass near drivable border
            let _bc = BCar::new_xyh(
                bc.pose.x + 0.00001 * bc.pose.h.cos(),
                bc.pose.y + 0.00001 * bc.pose.h.sin(),
                bc.pose.h
            );
            let mut pose = _bc.pose;
            pose.rotate(_bc.ccr(), a);
            assert!(!bc.drivable(pose)); // fail near drivable border
        }
    }
}