Skip to main content

device_envoy_core/
servo.rs

1//! A device abstraction trait for direct servo control shared across platforms.
2
3#[doc(hidden)]
4pub use crate::servo_player::{
5    __servo_player_animate, __servo_player_hold, __servo_player_relax, __servo_player_set_degrees,
6    device_loop,
7};
8pub use crate::servo_player::{
9    AtEnd, ServoPlayer, ServoPlayerHandle, ServoPlayerStatic, combine, linear,
10};
11
12/// Logical angle direction for servo mapping.
13#[derive(Clone, Copy, Debug, Eq, PartialEq)]
14pub enum Direction {
15    /// `0` maps to the minimum pulse and increases toward maximum pulse.
16    Forward,
17    /// `0` maps to the maximum pulse and increases toward minimum pulse.
18    Reverse,
19}
20
21/// Platform-agnostic servo device contract.
22///
23/// Platform crates implement this trait for their concrete servo types so direct
24/// servo operations resolve through trait methods instead of inherent methods.
25///
26/// This page serves as the definitive reference for direct servo control across
27/// platforms.
28///
29/// # Example
30///
31/// This example demonstrates basic servo control: move to 45 degrees, then
32/// 90 degrees, then relax.
33///
34/// ```rust,no_run
35/// use device_envoy_core::servo::Servo;
36/// use embassy_time::{Duration, Timer};
37///
38/// async fn move_and_relax(servo: &impl Servo) {
39///     servo.set_degrees(45);                          // Move to 45 degrees and hold.
40///     Timer::after(Duration::from_secs(1)).await;     // Give servo reasonable time to reach position
41///     servo.set_degrees(90);                          // Move to 90 degrees and hold.
42///     Timer::after(Duration::from_secs(1)).await;     // Give servo reasonable time to reach position
43///     servo.relax();                                  // Let the servo relax. It will re-enable on next set_degrees()
44/// }
45///
46/// # struct ServoMock;
47/// # impl Servo for ServoMock {
48/// #     const DEFAULT_MAX_DEGREES: u16 = 180;
49/// #     fn set_degrees(&self, _degrees: u16) {}
50/// #     fn hold(&self) {}
51/// #     fn relax(&self) {}
52/// # }
53/// # let servo = ServoMock;
54/// # let _future = move_and_relax(&servo);
55/// # servo.hold();
56/// ```
57pub trait Servo {
58    /// Default maximum rotation range in degrees.
59    const DEFAULT_MAX_DEGREES: u16;
60
61    /// Set position in degrees `0..=max_degrees`.
62    ///
63    /// See the [Servo trait documentation](Self) for usage examples.
64    fn set_degrees(&self, degrees: u16);
65
66    /// Keep driving pulses at the last commanded angle.
67    fn hold(&self);
68
69    /// Stop driving pulses.
70    ///
71    /// See the [Servo trait documentation](Self) for usage examples.
72    fn relax(&self);
73}