Skip to main content

motor_codec/
motor.rs

1//! Vendor-tagged motor identifiers and value types.
2
3/// Vendor-tagged motor type identifier.
4///
5/// Each variant carries an opaque `u16` discriminant that the owning vendor's
6/// codec interprets internally — no two vendors need to coordinate their
7/// discriminant spaces.
8#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
9#[non_exhaustive]
10pub enum MotorTypeId {
11    /// Damiao motor SKU (DM4310, DM4340, ...). The `u16` is the SKU discriminant
12    /// defined in `can-motor-damiao-codec`.
13    Damiao(u16),
14    /// Robostride motor SKU. Reserved for a future vendor codec crate.
15    Robostride(u16),
16}
17
18/// Borrowed view of a motor's identity, suitable for passing into codec encode
19/// methods without taking ownership of the motor's mutable state.
20#[derive(Copy, Clone, Debug)]
21pub struct MotorRef<'a> {
22    /// The motor's vendor type identifier.
23    pub motor_type: MotorTypeId,
24    /// CAN ID this motor accepts commands on.
25    pub send_id: u32,
26    /// CAN ID this motor emits state and replies from.
27    pub recv_id: u32,
28    /// Human-readable motor name from the robot config.
29    pub name: &'a str,
30}
31
32/// Per-motor-type physical limits used to scale MIT commands and unscale
33/// state replies.
34#[derive(Copy, Clone, Debug, PartialEq)]
35pub struct Limits {
36    /// Position magnitude limit (radians).
37    pub p_max: f64,
38    /// Velocity magnitude limit (rad/s).
39    pub v_max: f64,
40    /// Torque magnitude limit (Nm).
41    pub t_max: f64,
42}
43
44#[cfg(test)]
45mod tests {
46    use super::*;
47
48    #[test]
49    fn damiao_variant_round_trips() {
50        let id = MotorTypeId::Damiao(7);
51        match id {
52            MotorTypeId::Damiao(d) => assert_eq!(d, 7),
53            _ => panic!("wrong variant"),
54        }
55    }
56
57    #[test]
58    fn non_exhaustive_match_falls_through() {
59        // Simulate the consumer pattern in design.md Decision 11.
60        fn classify(t: MotorTypeId) -> &'static str {
61            match t {
62                MotorTypeId::Damiao(_) => "damiao",
63                _ => "other",
64            }
65        }
66        assert_eq!(classify(MotorTypeId::Damiao(0)), "damiao");
67        assert_eq!(classify(MotorTypeId::Robostride(0)), "other");
68    }
69
70    #[test]
71    fn motor_ref_construction() {
72        let r = MotorRef {
73            motor_type: MotorTypeId::Damiao(0),
74            send_id: 0x01,
75            recv_id: 0x11,
76            name: "j0",
77        };
78        assert_eq!(r.name, "j0");
79        assert_eq!(r.send_id, 0x01);
80    }
81}