use kernelvex::pose::Pose;
use kernelvex::si::QAngle;
use std::f64::consts::PI;
#[test]
fn test_pose_new() {
let pose = Pose::new(1.5, 2.0, QAngle::from_degrees(45.0));
let (x, y) = pose.position();
assert_eq!(x, 1.5);
assert_eq!(y, 2.0);
assert!((pose.heading().as_degrees() - 45.0).abs() < 1e10);
}
#[test]
fn test_pose_identity() {
let identity = Pose::identity();
let (x, y) = identity.position();
assert_eq!(x, 0.0);
assert_eq!(y, 0.0);
assert_eq!(identity.heading().as_radians(), 0.0);
}
#[test]
fn test_pose_default() {
let default: Pose = Default::default();
let (x, y) = default.position();
assert_eq!(x, 0.0);
assert_eq!(y, 0.0);
assert_eq!(default.heading().as_radians(), 0.0);
}
#[test]
fn test_pose_position() {
let pose = Pose::new(3.0, 4.0, QAngle::from_degrees(90.0));
let (x, y) = pose.position();
assert_eq!(x, 3.0);
assert_eq!(y, 4.0);
}
#[test]
fn test_pose_heading() {
let pose = Pose::new(0.0, 0.0, QAngle::from_degrees(45.0));
assert!((pose.heading().as_degrees() - 45.0).abs() < 1e10);
}
#[test]
fn test_pose_distance_horizontal() {
let p1 = Pose::new(0.0, 0.0, QAngle::from_degrees(0.0));
let p2 = Pose::new(3.0, 0.0, QAngle::from_degrees(0.0));
let dist = p1.distance(p2);
assert_eq!(dist.as_meters(), 3.0);
}
#[test]
fn test_pose_distance_vertical() {
let p1 = Pose::new(0.0, 0.0, QAngle::from_degrees(0.0));
let p2 = Pose::new(0.0, 4.0, QAngle::from_degrees(0.0));
let dist = p1.distance(p2);
assert_eq!(dist.as_meters(), 4.0);
}
#[test]
fn test_pose_distance_diagonal() {
let p1 = Pose::new(0.0, 0.0, QAngle::from_degrees(0.0));
let p2 = Pose::new(3.0, 4.0, QAngle::from_degrees(0.0));
let dist = p1.distance(p2);
assert_eq!(dist.as_meters(), 5.0);
}
#[test]
fn test_pose_distance_symmetric() {
let p1 = Pose::new(1.0, 2.0, QAngle::from_degrees(0.0));
let p2 = Pose::new(3.0, 4.0, QAngle::from_degrees(0.0));
let dist1 = p1.distance(p2);
let dist2 = p2.distance(p1);
assert_eq!(dist1.as_meters(), dist2.as_meters());
}
#[test]
fn test_pose_distance_zero() {
let p1 = Pose::new(1.0, 2.0, QAngle::from_degrees(0.0));
let p2 = Pose::new(1.0, 2.0, QAngle::from_degrees(0.0));
let dist = p1.distance(p2);
assert_eq!(dist.as_meters(), 0.0);
}
#[test]
fn test_pose_angle_horizontal() {
let p1 = Pose::new(0.0, 0.0, QAngle::from_degrees(0.0));
let p2 = Pose::new(1.0, 0.0, QAngle::from_degrees(0.0));
let angle = p1.angle(p2);
assert_eq!(angle.as_radians(), 0.0);
}
#[test]
fn test_pose_angle_vertical() {
let p1 = Pose::new(0.0, 0.0, QAngle::from_degrees(0.0));
let p2 = Pose::new(0.0, 1.0, QAngle::from_degrees(0.0));
let angle = p1.angle(p2);
assert!((angle.as_radians() - PI / 2.0).abs() < 1e10);
}
#[test]
fn test_pose_angle_diagonal() {
let p1 = Pose::new(0.0, 0.0, QAngle::from_degrees(0.0));
let p2 = Pose::new(1.0, 1.0, QAngle::from_degrees(0.0));
let angle = p1.angle(p2);
assert!((angle.as_degrees() - 45.0).abs() < 1e10);
}
#[test]
fn test_pose_angle_negative_y() {
let p1 = Pose::new(1.0, 1.0, QAngle::from_degrees(0.0));
let p2 = Pose::new(1.0, 0.0, QAngle::from_degrees(0.0));
let angle = p1.angle(p2);
assert_eq!(angle.as_degrees(), -90.);
}
#[test]
fn test_pose_rotate() {
let pose = Pose::new(1.0, 2.0, QAngle::from_degrees(0.0));
let rotated = pose.rotate(QAngle::from_degrees(90.0));
let (x, y) = rotated.position();
assert_eq!(x, 1.0);
assert_eq!(y, 2.0);
assert!((rotated.heading().as_degrees() - 90.0).abs() < 1e10);
}
#[test]
fn test_pose_rotate_multiple() {
let pose = Pose::new(0.0, 0.0, QAngle::from_degrees(30.0));
let rotated = pose.rotate(QAngle::from_degrees(60.0));
assert!((rotated.heading().as_degrees() - 90.0).abs() < 1e10);
}
#[test]
fn test_pose_rotate_negative() {
let pose = Pose::new(1.0, 1.0, QAngle::from_degrees(90.0));
let rotated = pose.rotate(QAngle::from_degrees(-45.0));
assert!((rotated.heading().as_degrees() - 45.0).abs() < 1e10);
}
#[test]
fn test_pose_add() {
let p1 = Pose::new(1.0, 2.0, QAngle::from_degrees(45.0));
let p2 = Pose::new(3.0, 4.0, QAngle::from_degrees(90.0));
let sum = p1 + p2;
let (x, y) = sum.position();
assert_eq!(x, 4.0);
assert_eq!(y, 6.0);
assert!((sum.heading().as_degrees() - 45.0).abs() < 1e10);
}
#[test]
fn test_pose_add_identity() {
let p1 = Pose::new(1.0, 2.0, QAngle::from_degrees(30.0));
let identity = Pose::identity();
let sum = p1 + identity;
let (x, y) = sum.position();
assert_eq!(x, 1.0);
assert_eq!(y, 2.0);
}
#[test]
fn test_pose_sub() {
let p1 = Pose::new(5.0, 7.0, QAngle::from_degrees(45.0));
let p2 = Pose::new(2.0, 3.0, QAngle::from_degrees(90.0));
let diff = p1 - p2;
let (x, y) = diff.position();
assert_eq!(x, 3.0);
assert_eq!(y, 4.0);
assert!((diff.heading().as_degrees() - 45.0).abs() < 1e10);
}
#[test]
fn test_pose_sub_identity() {
let p1 = Pose::new(3.0, 4.0, QAngle::from_degrees(60.0));
let identity = Pose::identity();
let diff = p1 - identity;
let (x, y) = diff.position();
assert_eq!(x, 3.0);
assert_eq!(y, 4.0);
assert!((diff.heading().as_degrees() - 60.0).abs() < 1e10);
}
#[test]
fn test_pose_mul_identity() {
let p1 = Pose::new(1.0, 2.0, QAngle::from_degrees(45.0));
let identity = Pose::identity();
let result = p1 * identity;
let (x, y) = result.position();
assert!((x - 1.0).abs() < 1e10);
assert!((y - 2.0).abs() < 1e10);
assert!((result.heading().as_degrees() - 45.0).abs() < 1e10);
}
#[test]
fn test_pose_mul_translation_only() {
let p1 = Pose::identity();
let p2 = Pose::new(1.0, 2.0, QAngle::from_degrees(0.0));
let result = p1 * p2;
let (x, y) = result.position();
assert!((x - 1.0).abs() < 1e10);
assert!((y - 2.0).abs() < 1e10);
}
#[test]
fn test_pose_mul_rotation_only() {
let p1 = Pose::new(0.0, 0.0, QAngle::from_degrees(90.0));
let p2 = Pose::new(1.0, 0.0, QAngle::from_degrees(0.0));
let result = p1 * p2;
let (x, y) = result.position();
assert!((x - 0.0).abs() < 1e10);
assert!((y - 1.0).abs() < 1e10);
assert!((result.heading().as_degrees() - 90.0).abs() < 1e10);
}
#[test]
fn test_pose_mul_combined() {
let p1 = Pose::new(1.0, 0.0, QAngle::from_degrees(90.0));
let p2 = Pose::new(0.0, 1.0, QAngle::from_degrees(90.0));
let result = p1 * p2;
assert!((result.heading().as_degrees() - 180.0).abs() < 1e10);
}
#[test]
fn test_pose_mul_scalar() {
let pose = Pose::new(2.0, 3.0, QAngle::from_degrees(45.0));
let scaled = pose * 2.0;
let (x, y) = scaled.position();
assert_eq!(x, 4.0);
assert_eq!(y, 6.0);
assert!((scaled.heading().as_degrees() - 45.0).abs() < 1e10);
}
#[test]
fn test_pose_mul_scalar_zero() {
let pose = Pose::new(1.0, 2.0, QAngle::from_degrees(30.0));
let scaled = pose * 0.0;
let (x, y) = scaled.position();
assert_eq!(x, 0.0);
assert_eq!(y, 0.0);
assert!((scaled.heading().as_degrees() - 30.0).abs() < 1e10);
}
#[test]
fn test_pose_mul_scalar_negative() {
let pose = Pose::new(1.0, 2.0, QAngle::from_degrees(45.0));
let scaled = pose * -1.0;
let (x, y) = scaled.position();
assert_eq!(x, -1.0);
assert_eq!(y, -2.0);
assert!((scaled.heading().as_degrees() - 45.0).abs() < 1e10);
}
#[test]
fn test_pose_div_scalar() {
let pose = Pose::new(4.0, 6.0, QAngle::from_degrees(60.0));
let scaled = pose / 2.0;
let (x, y) = scaled.position();
assert_eq!(x, 2.0);
assert_eq!(y, 3.0);
}
#[test]
fn test_pose_div_scalar_fractional() {
let pose = Pose::new(1.0, 2.0, QAngle::from_degrees(45.0));
let scaled = pose / 4.0;
let (x, y) = scaled.position();
assert_eq!(x, 0.25);
assert_eq!(y, 0.5);
}
#[test]
fn test_pose_move_local() {
let robot = Pose::new(0.0, 0.0, QAngle::from_degrees(0.0));
let local = Pose::new(1.0, 0.0, QAngle::from_degrees(0.0));
let global = robot.move_local(local);
let (x, y) = global.position();
assert!((x - 1.0).abs() < 1e10);
assert!((y - 0.0).abs() < 1e10);
}
#[test]
fn test_pose_move_local_rotated() {
let robot = Pose::new(0.0, 0.0, QAngle::from_degrees(90.0));
let local = Pose::new(1.0, 0.0, QAngle::from_degrees(0.0));
let global = robot.move_local(local);
let (x, y) = global.position();
assert!((x - 0.0).abs() < 1e10);
assert!((y - 1.0).abs() < 1e10);
}
#[test]
fn test_pose_move_local_translated() {
let robot = Pose::new(2.0, 3.0, QAngle::from_degrees(0.0));
let local = Pose::new(1.0, 0.0, QAngle::from_degrees(0.0));
let global = robot.move_local(local);
let (x, y) = global.position();
assert!((x - 3.0).abs() < 1e10);
assert!((y - 3.0).abs() < 1e10);
}
#[test]
fn test_pose_move_global() {
let p1 = Pose::new(1.0, 2.0, QAngle::from_degrees(45.0));
let p2 = Pose::new(3.0, 4.0, QAngle::from_degrees(90.0));
let result = p1.move_global(p2);
let (x, y) = result.position();
assert_eq!(x, 1.0);
assert_eq!(y, 5.0);
assert!(result.heading().as_radians() - 135.0 < f64::EPSILON);
}
#[test]
fn test_pose_move_global_zero() {
let p1 = Pose::new(1.0, 2.0, QAngle::from_degrees(30.0));
let zero = Pose::identity();
let result = p1.move_global(zero);
let (x, y) = result.position();
assert_eq!(x, 1.0);
assert_eq!(y, 2.0);
let z = result.heading().as_degrees();
assert!((z - 30.0).abs() < 1e-10);
}
#[test]
fn test_pose_transformation_matrix_zero_rotation() {
let pose = Pose::new(1.0, 2.0, QAngle::from_degrees(0.0));
let (x, y) = pose.position();
assert_eq!(x, 1.0);
assert_eq!(y, 2.0);
assert!((pose.heading().cos() - 1.0).abs() < 1e10);
assert!((pose.heading().sin() - 0.0).abs() < 1e10);
}
#[test]
fn test_pose_transformation_matrix_ninety_rotation() {
let pose = Pose::new(0.0, 0.0, QAngle::from_degrees(90.0));
assert!((pose.heading().cos() - 0.0).abs() < 1e10);
assert!((pose.heading().sin() - 1.0).abs() < 1e10);
}
#[test]
fn test_pose_chained_transformations() {
let start = Pose::identity();
let forward = Pose::new(1.0, 0.0, QAngle::from_degrees(0.0));
let rotate = Pose::new(0.0, 0.0, QAngle::from_degrees(90.0));
let forward2 = Pose::new(1.0, 0.0, QAngle::from_degrees(0.0));
let result = start * forward * rotate * forward2;
let _position = result.position();
assert!((result.heading().as_degrees() - 90.0).abs() < 1e10);
}
#[test]
fn test_pose_roundtrip() {
let original = Pose::new(1.5, 2.5, QAngle::from_degrees(45.0));
let (x, y) = original.position();
let heading = original.heading();
let recreated = Pose::new(x, y, heading);
let (x2, y2) = recreated.position();
assert_eq!(x, x2);
assert_eq!(y, y2);
assert!((heading.as_degrees() - recreated.heading().as_degrees()).abs() < 1e10);
}
#[test]
fn test_pose_clone() {
let p1 = Pose::new(1.0, 2.0, QAngle::from_degrees(45.0));
let p2 = p1;
let (x1, y1) = p1.position();
let (x2, y2) = p2.position();
assert_eq!(x1, x2);
assert_eq!(y1, y2);
assert!((p1.heading().as_degrees() - p2.heading().as_degrees()).abs() < 1e10);
}