use core::time::Duration;
use vexide::time::Instant;
#[derive(Default, Debug, Copy, Clone, PartialEq, PartialOrd)]
pub struct Tolerances {
tolerance_timestamp: Option<Instant>,
pub duration: Option<Duration>,
pub error_tolerance: Option<f64>,
pub velocity_tolerance: Option<f64>,
}
impl Tolerances {
#[must_use]
pub const fn new() -> Self {
Self {
tolerance_timestamp: None,
duration: None,
error_tolerance: None,
velocity_tolerance: None,
}
}
#[must_use]
pub const fn error(&mut self, tolerance: f64) -> Self {
self.error_tolerance = Some(tolerance);
*self
}
#[must_use]
pub const fn velocity(&mut self, tolerance: f64) -> Self {
self.velocity_tolerance = Some(tolerance);
*self
}
#[must_use]
pub const fn duration(&mut self, duration: Duration) -> Self {
self.duration = Some(duration);
*self
}
pub fn check(&mut self, error: f64, velocity: f64) -> bool {
let in_tolerances = self
.error_tolerance
.is_none_or(|tolerance| error.abs() < tolerance)
&& self
.velocity_tolerance
.is_none_or(|tolerance| velocity.abs() < tolerance);
if in_tolerances {
if self.tolerance_timestamp.is_none() {
self.tolerance_timestamp = Some(Instant::now());
}
if self
.duration
.is_none_or(|time| self.tolerance_timestamp.unwrap().elapsed() > time)
{
self.tolerance_timestamp = None;
return true;
}
} else if self.tolerance_timestamp.is_some() {
self.tolerance_timestamp = None;
}
false
}
}