> ## Documentation Index
> Fetch the complete documentation index at: https://docs.almond.bot/llms.txt
> Use this file to discover all available pages before exploring further.

# almond_axol.motor

> Low-level async SocketCAN interface for individual motors.

Low-level async SocketCAN interface for individual motors. Most users work through `Axol` — this layer is exposed for diagnostics, custom control modes, and bench testing individual motors.

```python theme={null}
from almond_axol.motor import CanBus, Motor, ControlMode, MotorStatus, MotorGains, Joint
```

```python theme={null}
import asyncio
from almond_axol.motor import CanBus, Motor, ControlMode, Joint

async def main():
    async with CanBus("can_alm_axol_l") as bus:
        elbow = Motor(bus, Joint.ELBOW)
        await elbow.enable()
        await elbow.set_control_mode(ControlMode.IMPEDANCE)

        pos = await elbow.get_position()  # rad
        print("elbow position:", pos)

        await elbow.set_impedance(p_des=pos, v_des=0.0, kp=100.0, kd=2.0, t_ff=0.0)
        await elbow.disable()

asyncio.run(main())
```

## `Motor` methods

| Method                                                   | Description                                                                                                                                                                                                                     |
| -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `enable()` / `disable()`                                 | Enable motor / engage brake                                                                                                                                                                                                     |
| `attach(mode)`                                           | Reconnect to an already-enabled motor without disturbing its torque state: verifies it is enabled, fault-free, and in `mode`, using reads only (`set_control_mode` would reboot a MyActuator motor, dropping torque for \~2 s)  |
| `is_holding()`                                           | `True` if the motor is enabled and holding torque (read-only). Damiao: feedback status `ENABLED` (an enabled-but-never-commanded motor also reports `True`). MyActuator: status-1 running byte set and no fault latched         |
| `clear_errors()`                                         | Clear latched error flags                                                                                                                                                                                                       |
| `set_zero_position()`                                    | Save current position as encoder zero (persisted to flash). Calibrated at a mechanical end stop, not the rest position                                                                                                          |
| `set_control_mode(mode)`                                 | Set `ControlMode`; required before mode-specific commands. **MyActuator motors reboot to switch (torque off \~2 s)** — never call it on a motor holding a load. Damiao is a plain register write; a live flip is non-disruptive |
| `get_control_mode()`                                     | Read active mode from hardware (`None` for MyActuator)                                                                                                                                                                          |
| `get_model()`                                            | Motor model string, e.g. `"X8S2V"` (`None` for Damiao)                                                                                                                                                                          |
| `get_firmware_version()`                                 | Firmware VersionDate `int`, e.g. `2026042402` (`None` for Damiao)                                                                                                                                                               |
| `get_position()`                                         | Shaft position (rad); raises if telemetry is active                                                                                                                                                                             |
| `get_velocity()`                                         | Shaft velocity (rad/s)                                                                                                                                                                                                          |
| `get_torque()`                                           | Torque estimate (Nm); raises if telemetry is active                                                                                                                                                                             |
| `get_temperature()`                                      | Motor temperature (°C)                                                                                                                                                                                                          |
| `get_voltage()`                                          | Bus voltage (V)                                                                                                                                                                                                                 |
| `get_error_code()`                                       | `MotorStatus`                                                                                                                                                                                                                   |
| `get_gains()` / `set_gains(gains)`                       | Read/write PID gains (persisted to flash)                                                                                                                                                                                       |
| `set_impedance(p_des, v_des, kp, kd, t_ff)`              | MIT impedance command; requires `IMPEDANCE` mode                                                                                                                                                                                |
| `set_position_velocity(position, max_speed)`             | Built-in position controller; requires `POSITION_VELOCITY` mode                                                                                                                                                                 |
| `set_velocity(velocity)`                                 | Built-in speed controller; requires `VELOCITY` mode                                                                                                                                                                             |
| `set_position_force(position, max_speed, max_torque)`    | Damiao only; requires `POSITION_FORCE` mode                                                                                                                                                                                     |
| `set_acceleration(acceleration, deceleration)`           | Acceleration ramp (rad/s²)                                                                                                                                                                                                      |
| `set_can_id(can_id)`                                     | Change CAN ID (persisted to flash)                                                                                                                                                                                              |
| `start_telemetry(hz, torque=False)` / `stop_telemetry()` | Background polling loop                                                                                                                                                                                                         |
| `motor.telemetry_active`                                 | `True` while the background polling loop is running (`get_position()` / `get_torque()` do direct reads and raise while it is)                                                                                                   |
| `motor.position`                                         | Cached position (rad); populated by telemetry or `set_impedance` responses                                                                                                                                                      |
| `motor.has_position`                                     | `True` once a position has been cached (i.e. telemetry has warmed up)                                                                                                                                                           |
| `motor.torque`                                           | Cached torque (Nm); populated by telemetry with `torque=True`                                                                                                                                                                   |

## Configuration parameters

Both motor families expose a named configuration table — MyActuator's `0xC0` parameters and Damiao's `0x7FF` registers — for servicing a motor over CAN without the vendor setup software. These back the [`motor.dump-config`](https://docs.almond.bot/cli/motor-dump-config), [`motor.set-config`](https://docs.almond.bot/cli/motor-set-config), and [`motor.restore-config`](https://docs.almond.bot/cli/motor-restore-config) commands; the CLI is the usual way in, but the same surface is on `Motor`.

| Method                                                             | Description                                                                                                            |
| ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
| `resolve_config_param(name)`                                       | Look up a `MotorParam` by name for this motor's family                                                                 |
| `read_config(param)`                                               | Read one parameter, in the unit its spec names                                                                         |
| `write_config(param, value)`                                       | Write one parameter and persist it to flash/ROM                                                                        |
| `dump_config(raw_range=None)`                                      | Read every known parameter; pass a `range` to sweep raw MyActuator indices                                             |
| `restore_config(values, *, include_protected=False)`               | Write a saved config back; returns the parameters actually changed (protected ones skipped unless `include_protected`) |
| `get_low_voltage_threshold()` / `set_low_voltage_threshold(volts)` | Undervoltage protection threshold (V); MyActuator only                                                                 |
| `get_can_timeout()` / `set_can_timeout(milliseconds)`              | Loss-of-comms alarm time (ms); Damiao only                                                                             |

<Note>
  MyActuator motors apply a low undervoltage threshold on `enable()` so a brief bus-voltage sag can't latch the level-2 undervoltage fault. Read-only parameters are never written, and protected ones (factory calibration, CAN IDs, baud rate) are skipped by a restore unless you opt in, since rewriting them can leave a motor unable to commutate or unreachable on the bus.
</Note>

## `ControlMode` values

| Value               | Description                                          |
| ------------------- | ---------------------------------------------------- |
| `IMPEDANCE`         | MIT impedance control (arm joints)                   |
| `POSITION_VELOCITY` | Motor built-in position controller                   |
| `VELOCITY`          | Motor built-in speed controller                      |
| `POSITION_FORCE`    | Position with hard torque cap; Damiao only (gripper) |

## `MotorStatus` values

`OK`, `DISABLED`, `OVER_VOLTAGE`, `UNDER_VOLTAGE`, `OVER_CURRENT`, `OVER_TEMPERATURE`, `MOS_OVER_TEMP`, `ROTOR_OVER_TEMP`, `LOST_COMM`, `OVERLOAD`, `MOTOR_STALL`\*, `ENCODER_ERROR`\*, `CALIBRATION_ERROR`\*, `POWER_OVERRUN`\*, `SPEEDING`\*, `UNKNOWN`

\* MyActuator only

## Joint → driver mapping

| Joint                           | Driver     | CAN ID          |
| ------------------------------- | ---------- | --------------- |
| `SHOULDER_1` – `WRIST_1`        | MyActuator | `0x01` – `0x05` |
| `WRIST_2`, `WRIST_3`, `GRIPPER` | Damiao     | `0x06` – `0x08` |
