use crate::sensors::Encoder;
use crate::si::QLength;
use crate::utils::Orientation;
#[derive(Debug, Clone, Copy, PartialEq)]
#[allow(unused)]
pub enum OmniWheel {
Omni275,
Omni325,
Omni4,
Anti275,
Anti325,
Anti4,
Custom(QLength),
}
impl OmniWheel {
#[allow(unused)]
fn size(&self) -> QLength {
match *self {
OmniWheel::Omni275 => QLength::from_inches(2.75),
OmniWheel::Omni325 => QLength::from_inches(3.25),
OmniWheel::Omni4 => QLength::from_inches(4.125),
OmniWheel::Anti275 => QLength::from_inches(2.75),
OmniWheel::Anti325 => QLength::from_inches(3.25),
OmniWheel::Anti4 => QLength::from_inches(4.),
OmniWheel::Custom(d) => d,
}
}
}
pub trait Tracking {
fn offset(&self) -> QLength;
fn distance(&mut self) -> QLength;
fn reset(&mut self);
fn delta(&mut self) -> QLength;
fn orientation(&self) -> Orientation;
}
pub struct TrackingWheel<T: Encoder> {
encoder: T,
wheel: OmniWheel,
dist: QLength,
orientation: Orientation,
total: QLength,
gearing: f64,
}
impl<T: Encoder> TrackingWheel<T> {
#[allow(unused)]
pub fn new(encoder: T, wheel: OmniWheel, dist: QLength, ratio: Option<f64>) -> Self {
let gearing: f64 = ratio.unwrap_or(1.);
if dist.as_meters() > 0. {
TrackingWheel {
encoder,
wheel,
dist,
orientation: Orientation::Right,
total: Default::default(),
gearing,
}
} else {
TrackingWheel {
encoder,
wheel,
dist,
orientation: Orientation::Left,
total: Default::default(),
gearing,
}
}
}
}
impl<T: Encoder> Tracking for TrackingWheel<T> {
fn offset(&self) -> QLength {
self.dist
}
fn distance(&mut self) -> QLength {
let circumference = self.wheel.size() * std::f64::consts::PI;
let distance = circumference * self.gearing * (self.encoder.rotations().as_radians())
/ std::f64::consts::TAU;
self.total = distance;
self.total
}
fn reset(&mut self) {
self.total = Default::default();
let _ = self.encoder.reset();
}
fn delta(&mut self) -> QLength {
let circumference = self.wheel.size() * std::f64::consts::PI;
let distance = circumference * self.gearing * (self.encoder.rotations().as_radians())
/ std::f64::consts::TAU;
let ret = distance - self.total;
self.total = distance;
ret
}
fn orientation(&self) -> Orientation {
self.orientation
}
}