ramp_maker/
lib.rs

1//! RampMaker - Stepper Acceleration Ramp Generator
2//!
3//! RampMaker is a library that generates motion profiles for stepper motors. It
4//! can be used independently, or together with [Step/Dir].
5//!
6//! The main API for motion profiles is defined by the [`MotionProfile`] trait.
7//! The following implementations of this trait are available:
8//!
9//! - [`Flat`]: Not for serious use, but might be useful for testing.
10//! - [`Trapezoidal`]: Constant-acceleration motion profile.
11//!
12//! Trinamic have [an overview over motion profiles][overview] on their website.
13//!
14//! # Cargo Features
15//!
16//! This library works without the standard library (`no_std`) by default. This
17//! limits support for `f32`/`f64` for motion profiles that need to compute a
18//! square root, as this operation is not available in the core library (if
19//! you're using the default fixed-point types, you're not affected by this).
20//!
21//! If you need full support for `f32`/`f64`, you have the following options:
22//! - Enable support for the standard library via the **`std`** feature. This
23//!   obviously only works, if the standard library is available for your
24//!   target, and you want to use it.
25//! - Enable the **`libm`** feature. This provides the require square root
26//!   support via [libm].
27//!
28//! [Step/Dir]: https://crates.io/crates/step-dir
29//! [overview]: https://www.trinamic.com/technology/motion-control-technology/
30//! [libm]: https://crates.io/crates/libm
31
32#![cfg_attr(all(not(test), not(feature = "std")), no_std)]
33#![deny(missing_docs, broken_intra_doc_links)]
34
35pub mod flat;
36pub mod iter;
37pub mod trapezoidal;
38pub mod util;
39
40pub use self::{flat::Flat, trapezoidal::Trapezoidal};
41
42/// Abstract interface for motion profiles
43///
44/// Implemented by all motion profiles in this library. Can be used to
45/// write abstract code that doesn't care about the specific motion profile
46/// used.
47pub trait MotionProfile: Sized {
48    /// The type used for representing velocities
49    type Velocity;
50
51    /// The type used for representing delay values
52    type Delay;
53
54    /// Enter position mode
55    ///
56    /// In position mode, the motion profile will attempt to move for a specific
57    /// number of steps and come to a stand-still at the target step.
58    ///
59    /// The number of steps given here is always relative to the current
60    /// position, as implementations of this trait are not expected to keep
61    /// track of an absolute position.
62    fn enter_position_mode(
63        &mut self,
64        max_velocity: Self::Velocity,
65        num_steps: u32,
66    );
67
68    /// Return the next step delay
69    ///
70    /// Produces the delay for the next step. The unit of this delay is
71    /// implementation-defined. `None` is returned, if no more steps need to be
72    /// taken. This should only happen, if the motion has ended.
73    ///
74    /// Please note that motion profiles yield one value per step, even though
75    /// only n-1 delay values are needed for n steps. The additional delay value
76    /// will lead to an unnecessary delay before the first or after the last
77    /// step. This was done to make accidental misuse of this trait less likely,
78    /// as the most straight-forward use is to make one step per delay value in
79    /// a loop.
80    ///
81    /// All other details of the motion profile are implementation-defined.
82    ///
83    /// If you need an iterator that produces the step delays, you can get one
84    /// by calling [`MotionProfile::delays`], which internally calls this
85    /// method.
86    fn next_delay(&mut self) -> Option<Self::Delay>;
87
88    /// Return an iterator over delay values of each step
89    ///
90    /// This is a convenience method that returns an iterator which internally
91    /// just calls [`MotionProfile::next_delay`].
92    fn delays(&mut self) -> iter::Delays<Self> {
93        iter::Delays(self)
94    }
95
96    /// Return an iterator over velocity values of each step
97    ///
98    /// This is a convenience method that returns an iterator which internally
99    /// calls [`MotionProfile::next_delay`] and converts the delay to a
100    /// velocity.
101    ///
102    /// This is mainly useful for testing and debugging.
103    fn velocities(&mut self) -> iter::Velocities<Self> {
104        iter::Velocities(self)
105    }
106
107    /// Return an iterator over the acceleration values between steps
108    ///
109    /// This is a convenience method that returns an iterator which internally
110    /// calls [`MotionProfile::next_delay`] and computes the acceleration from
111    /// each pair of delay values.
112    ///
113    /// This is mainly useful for testing and debugging.
114    fn accelerations<Accel>(&mut self) -> iter::Accelerations<Self, Accel> {
115        iter::Accelerations::new(self)
116    }
117}