use fixed::FixedU32;
use crate::MotionProfile;
pub struct Flat<Num = DefaultNum> {
delay: Option<Num>,
num_steps: u32,
}
impl<Num> Flat<Num> {
pub fn new() -> Self {
Self {
delay: None,
num_steps: 0,
}
}
}
impl Default for Flat<f32> {
fn default() -> Self {
Self::new()
}
}
impl<Num> MotionProfile for Flat<Num>
where
Num: Copy + num_traits::Zero + num_traits::Inv<Output = Num>,
{
type Velocity = Num;
type Delay = Num;
fn enter_position_mode(
&mut self,
max_velocity: Self::Velocity,
num_steps: u32,
) {
self.delay = if max_velocity.is_zero() {
None
} else {
Some(max_velocity.inv())
};
self.num_steps = num_steps;
}
fn next_delay(&mut self) -> Option<Self::Delay> {
if self.num_steps == 0 {
return None;
}
self.num_steps -= 1;
self.delay
}
}
pub type DefaultNum = FixedU32<typenum::U16>;
#[cfg(test)]
mod tests {
use crate::{Flat, MotionProfile as _};
#[test]
fn flat_should_pass_motion_profile_tests() {
crate::util::testing::test::<Flat<f32>>();
}
#[test]
fn flat_should_produce_constant_velocity() {
let mut flat = Flat::new();
let max_velocity = 1000.0;
flat.enter_position_mode(max_velocity, 200);
for velocity in flat.velocities() {
assert_eq!(velocity, max_velocity);
}
}
}