accel_stepper/
utils.rs

1use core::time::Duration;
2
3pub(crate) trait Clamp {
4    fn clamp(self, lower: Self, upper: Self) -> Self;
5}
6
7impl<C: PartialOrd> Clamp for C {
8    fn clamp(self, lower: Self, upper: Self) -> Self {
9        if self < lower {
10            lower
11        } else if upper < self {
12            upper
13        } else {
14            self
15        }
16    }
17}
18
19/// Workarounds because working with `Duration` and `f32` requires nightly (see
20/// the `duration_float` feature).
21pub(crate) trait DurationHelpers {
22    fn from_secs_f32_2(secs: f32) -> Self;
23
24    fn as_secs_f32_2(&self) -> f32;
25}
26
27const NANOS_PER_SEC: u32 = 1_000_000_000;
28
29impl DurationHelpers for Duration {
30    fn from_secs_f32_2(secs: f32) -> Self {
31        // copied straight from libcore/time.rs
32
33        let nanos = secs * (NANOS_PER_SEC as f32);
34        assert!(nanos.is_finite());
35
36        let nanos = nanos as u128;
37        Duration::new(
38            (nanos / u128::from(NANOS_PER_SEC)) as u64,
39            (nanos % u128::from(NANOS_PER_SEC)) as u32,
40        )
41    }
42
43    fn as_secs_f32_2(&self) -> f32 {
44        (self.as_secs() as f32)
45            + (self.subsec_nanos() as f32) / (NANOS_PER_SEC as f32)
46    }
47}
48
49/// A helper type for determining the number of steps to take when moving a
50/// distance in the real world, taking rounding errors into consideration.
51#[derive(Debug, Clone, PartialEq)]
52pub struct CummulativeSteps {
53    steps_per_unit: f32,
54    steps: f32,
55}
56
57impl CummulativeSteps {
58    /// Create a new [`CummulativeSteps`] which will use the provided ratio as
59    /// the number of steps to take per "real" unit.
60    pub const fn new(steps_per_unit: f32) -> CummulativeSteps {
61        CummulativeSteps {
62            steps: 0.0,
63            steps_per_unit,
64        }
65    }
66
67    /// The current location in "real" units.
68    pub const fn real_location(&self) -> f32 { self.steps }
69
70    /// Get the number of steps travelled per "real" unit.
71    pub const fn steps_per_unit(&self) -> f32 { self.steps_per_unit }
72
73    pub const fn with_steps_per_unit(
74        &self,
75        steps_per_unit: f32,
76    ) -> CummulativeSteps {
77        CummulativeSteps {
78            steps_per_unit,
79            steps: self.steps,
80        }
81    }
82
83    /// Execute a relative movement, retrieving the number of steps to take.
84    pub fn move_by(&mut self, delta: f32) -> i64 {
85        let previous_steps = self.steps.round();
86
87        self.steps += delta * self.steps_per_unit;
88        let rounded_steps = (self.steps - previous_steps).round();
89
90        rounded_steps as i64
91    }
92}