autocore-std 3.3.35

Standard library for AutoCore control programs - shared memory, IPC, and logging utilities
Documentation
//! Generic hardware interface for CiA 402 servo drives.
//!
//! [`AxisView`] provides raw PDO field access. The [`Axis`](super::Axis)
//! struct handles all CiA 402 protocol logic (state machine, PP handshake,
//! homing) on top of this, so implementors only need to map PDO fields.

/// Generic hardware interface for a CiA 402 servo drive.
///
/// Maps raw PDO fields. The [`Axis`](super::Axis) struct handles all CiA 402
/// protocol logic (state machine, PP handshake, homing) on top of this.
///
/// # Implementing
///
/// Implementors just map their struct's PDO fields — no CiA 402 protocol
/// knowledge is needed:
///
/// ```ignore
/// impl AxisView for MyDriveView<'_> {
///     fn control_word(&self) -> u16 { *self.control_word }
///     fn set_control_word(&mut self, w: u16) { *self.control_word = w; }
///     fn status_word(&self) -> u16 { *self.status_word }
///     fn set_target_position(&mut self, pos: i32) { *self.target_position = pos; }
///     // ... etc
/// }
/// ```
pub trait AxisView {
    // ── Control word (RxPDO) ──

    /// Read the current control word.
    fn control_word(&self) -> u16;
    /// Write the control word.
    fn set_control_word(&mut self, word: u16);

    // ── Targets (RxPDO) ──

    /// Set the target position in encoder counts.
    fn set_target_position(&mut self, pos: i32);
    /// Set the profile velocity in counts/s.
    fn set_profile_velocity(&mut self, vel: u32);
    /// Set the profile acceleration in counts/s².
    fn set_profile_acceleration(&mut self, accel: u32);
    /// Set the profile deceleration in counts/s².
    fn set_profile_deceleration(&mut self, decel: u32);

    // ── Mode (RxPDO / TxPDO) ──

    /// Write the modes of operation register (0x6060).
    fn set_modes_of_operation(&mut self, mode: i8);
    /// Read the modes of operation display (0x6061).
    fn modes_of_operation_display(&self) -> i8;

    // ── Status (TxPDO) ──

    /// Read the status word.
    fn status_word(&self) -> u16;
    /// Read the actual position in encoder counts.
    fn position_actual(&self) -> i32;
    /// Read the actual velocity in counts/s.
    fn velocity_actual(&self) -> i32;

    // ── Optional: error code from TxPDO (vendor-mapped) ──

    /// Read the drive error code. Returns 0 if not mapped.
    fn error_code(&self) -> u16 { 0 }

    // ── Optional: limit switches and home sensor ──

    /// True when the positive-direction hardware limit switch is active.
    ///
    /// Implement this to wire a physical limit switch input from your
    /// global memory / PDO mapping. If not implemented, returns `false`
    /// (no limit switch).
    fn positive_limit_active(&self) -> bool { false }

    /// True when the negative-direction hardware limit switch is active.
    fn negative_limit_active(&self) -> bool { false }

    /// True when the home reference sensor is active.
    fn home_sensor_active(&self) -> bool { false }

    // ── Optional: dynamic (GlobalMemory-linked) software position limits ──

    /// Current maximum software position limit in user units, or `None`
    /// if no dynamic limit is configured. When `Some`, the axis rejects
    /// moves whose target exceeds this value, and quick-stops if the
    /// actual position passes it while moving in the positive direction.
    ///
    /// This is combined with the static [`AxisConfig`](super::axis_config::AxisConfig)
    /// max limit using the most-restrictive value.
    fn dynamic_max_position_limit(&self) -> Option<f64> { None }

    /// Current minimum software position limit in user units, or `None`
    /// if no dynamic limit is configured. See [`dynamic_max_position_limit`](Self::dynamic_max_position_limit).
    fn dynamic_min_position_limit(&self) -> Option<f64> { None }
}

/// High-level interface for a motion axis.
///
/// This trait provides a unified interface for both raw [`Axis`](super::Axis)
/// objects and the higher-level generated `AxisHandle` structs used in the
/// control program.
pub trait AxisHandle {
    /// Actual position in user units.
    fn position(&self) -> f64;
    /// Read-only access to the axis configuration.
    fn config(&self) -> &super::axis_config::AxisConfig;
    /// Issue a relative move command.
    fn move_relative(&mut self, distance: f64, vel: f64, accel: f64, decel: f64);
    /// Issue an absolute move command.
    fn move_absolute(&mut self, position: f64, vel: f64, accel: f64, decel: f64);
    /// Halt the axis immediately.
    fn halt(&mut self);
    /// True if the axis is currently executing an operation.
    fn is_busy(&self) -> bool;
    /// True if the axis is in an error state.
    fn is_error(&self) -> bool;
    /// True if the motor is enabled and holding torque.
    fn motor_on(&self) -> bool;
}