use nalgebra::{Rotation3, Vector3};
#[derive(Clone, Debug)]
pub enum LegId {
Group1 { id: u64 },
Group2 { id: u64 },
}
impl LegId {
pub fn id(&self) -> usize {
match self {
LegId::Group1 { id } => *id as usize,
LegId::Group2 { id } => *id as usize,
}
}
}
#[derive(Clone, Debug)]
pub struct Leg {
pub id: LegId,
pub heading: Option<f64>,
pub home: Vector3<f64>,
}
impl Leg {
pub fn set_heading(&mut self, heading: f64) {
self.heading = Some(heading)
}
pub fn transform(
&self,
mut path: Vec<Vector3<f64>>,
cw_dir_ang: f64,
) -> Vec<Vector3<f64>> {
let rot = cw_dir_ang.to_radians() + self.heading.unwrap_or_default();
let rot_matrix = Rotation3::from_axis_angle(&Vector3::z_axis(), rot);
for pt in &mut path {
*pt = rot_matrix * *pt;
pt.x += self.home.x;
pt.y += self.home.y;
}
path
}
}
#[cfg(test)]
pub mod tests {
use std::f64::consts::PI;
use super::*;
pub fn mock_leg() -> Leg {
Leg {
id: LegId::Group2 { id: 1 },
heading: None,
home: Vector3::new(160.0, 0.0, 100.0),
}
}
#[test]
fn test_transform() {
let mut leg = mock_leg();
leg.set_heading(-PI / 3.0);
let mut path: Vec<Vector3<f64>> = vec![];
path.push(Vector3::new(0.0, -9.411764705882348, 100.0));
path.push(Vector3::new(0.0, -14.117647058823536, 100.0));
path.push(Vector3::new(0.0, -18.82352941176471, 100.0));
path = leg.transform(path, 0.0);
assert_eq!(
path[0],
Vector3::new(151.84917267026412, -4.705882352941175, 100.0)
);
assert_eq!(
path[1],
Vector3::new(147.77375900539616, -7.05882352941177, 100.0)
);
assert_eq!(
path[2],
Vector3::new(143.69834534052822, -9.411764705882357, 100.0)
)
}
}