use crate::SyncActuator;
use crate::act::{Interruptible, InterruptReason};
use syunit::*;
use serde::{Serialize, Deserialize};
mod endswitch;
pub use endswitch::*;
mod sonar;
pub use sonar::*;
pub trait Measurable<V> {
type Error;
fn meas(&mut self) -> Result<V, Self::Error>;
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct SimpleMeasData {
pub set_gamma : Gamma,
pub max_dist : Delta,
pub meas_speed : Factor,
#[serde(default = "default_add_samples")]
pub add_samples : usize,
pub sample_dist : Option<Delta>
}
const fn default_add_samples() -> usize { 1 }
#[derive(Debug, Clone, Default)]
pub struct SimpleMeasResult {
pub samples : usize,
pub gammas : Vec<Gamma>,
pub gamma_av : Gamma,
pub corr : Delta
}
impl SimpleMeasResult {
pub fn gamma_max(&self) -> Gamma {
*self.gammas.iter().reduce(Gamma::max_ref).expect("Gamma array must contain a value")
}
pub fn gamma_min(&self) -> Gamma {
*self.gammas.iter().reduce(Gamma::min_ref).expect("Gamma array must contain a value")
}
pub fn max_inacc(&self) -> Delta {
self.gamma_max() - self.gamma_min()
}
}
pub fn take_simple_meas<C : SyncActuator + Interruptible + ?Sized>(comp : &mut C, data : &SimpleMeasData, speed : Factor) -> Result<SimpleMeasResult, crate::Error> {
let mut gammas : Vec<Gamma> = Vec::new();
comp.drive_rel(data.max_dist, data.meas_speed * speed)?;
if comp.intr_reason().ok_or("The measurement failed! No interrupt was triggered")? != InterruptReason::EndReached {
return Err("Bad interrupt reason!".into()); }
gammas.push(comp.gamma());
for _ in 0 .. data.add_samples {
println!("- Gamma: {}", comp.gamma());
comp.drive_rel(-data.sample_dist.unwrap_or(data.max_dist * 0.25) / 2.0, speed)?;
println!("- Gamma: {}", comp.gamma());
comp.drive_rel(data.sample_dist.unwrap_or(data.max_dist * 0.25), data.meas_speed * speed)?;
println!("- Gamma: {}", comp.gamma());
if comp.intr_reason().ok_or("The measurement failed! No interrupt was triggered")? != InterruptReason::EndReached {
return Err("Bad interrupt reason!".into()); }
gammas.push(comp.gamma());
}
let gamma_av = Gamma(gammas.iter().map(|g| g.0).sum()) / (gammas.len() as f32);
let gamma_diff = comp.gamma() - gamma_av;
let gamma_new = data.set_gamma + gamma_diff;
comp.set_end(gamma_av);
comp.set_gamma(gamma_new);
Ok(SimpleMeasResult {
samples: data.add_samples,
gammas: gammas,
gamma_av: gamma_av,
corr: gamma_diff
})
}