use embedded_hal::pwm::SetDutyCycle;
use syunit::*;
use crate::data::servo::ServoConst;
#[derive(Debug)]
pub struct MiniServo<P : SetDutyCycle> {
pos : PositionRad,
_consts : ServoConst,
pwm : P
}
impl<P : SetDutyCycle> MiniServo<P> {
pub fn new(consts : ServoConst, pwm : P) -> Self {
Self {
pos: consts.default_pos(),
_consts: consts,
pwm
}
}
pub fn consts(&self) -> &ServoConst {
&self._consts
}
pub fn start(&mut self) -> Result<(), P::Error> {
self.drive_default_pos()
}
pub fn stop(&mut self) -> Result<(), P::Error> {
self.pwm.set_duty_cycle_fully_off()
}
pub fn pos(&self) -> PositionRad {
self.pos
}
pub fn drive_abs(&mut self, pos : PositionRad) -> Result<(), P::Error> {
self.drive_factor_pos(Factor::try_new(pos / self._consts.position_max)
.expect("The given position is either invalid or out of range!"))
}
pub fn factor(&self) -> Factor {
unsafe { Factor::new_unchecked(self.pos / self._consts.position_max) }
}
pub fn drive_factor_pos(&mut self, factor : Factor) -> Result<(), P::Error> {
self.pwm.set_duty_cycle(factor.get_duty_for(self.pwm.max_duty_cycle()))
}
pub fn drive_default_pos(&mut self) -> Result<(), P::Error> {
self.drive_factor_pos(Factor::HALF)
}
pub fn drive_endpoint_min(&mut self) -> Result<(), P::Error> {
self.drive_factor_pos(Factor::MIN)
}
pub fn goto_endpoint_max(&mut self) -> Result<(), P::Error> {
self.drive_factor_pos(Factor::MAX)
}
}