use crate::{
accelerometer::Accelerometer,
orientation::Orientation,
vector::{Component, Vector, VectorExt},
};
use core::marker::PhantomData;
use micromath::generic_array::typenum::U3;
#[allow(unused_imports)]
use micromath::F32Ext;
pub struct Tracker<A, V>
where
A: Accelerometer<V>,
V: Vector<Axes = U3> + VectorExt,
{
accelerometer: A,
threshold: f32,
last_orientation: Orientation,
vector: PhantomData<V>,
}
impl<A, V, C> Tracker<A, V>
where
A: Accelerometer<V>,
V: Vector<Axes = U3, Component = C> + VectorExt,
C: Component + Into<f32>,
{
pub fn new(accelerometer: A, threshold: V::Component) -> Self {
Self {
accelerometer,
threshold: threshold.into(),
last_orientation: Orientation::Unknown,
vector: PhantomData,
}
}
pub fn orientation(&mut self) -> Result<Orientation, A::Error> {
let accel = self.accelerometer.acceleration()?.to_array();
let x: f32 = accel[0].into();
let y: f32 = accel[1].into();
let z: f32 = accel[2].into();
let result = if x.abs() > self.threshold {
if x >= 0.0 {
Orientation::LandscapeUp
} else {
Orientation::LandscapeDown
}
} else if y.abs() > self.threshold {
if y >= 0.0 {
Orientation::PortraitUp
} else {
Orientation::PortraitDown
}
} else if z.abs() > self.threshold {
if z >= 0.0 {
Orientation::FaceUp
} else {
Orientation::FaceDown
}
} else {
Orientation::Unknown
};
if result != Orientation::Unknown {
self.last_orientation = result;
}
Ok(result)
}
pub fn last_orientation(&self) -> Orientation {
self.last_orientation
}
}