ActuatorFD 1.0 is the shared CAN-FD wire contract for 58-10, 58-40, and Model A. These definitions describe a host-tested reference; they do not establish board firmware or hardware timing qualification.
Frame format#
Extended 29-bit identifier:
priority[28:26],service[25:18],source[17:11],destination[10:4],major[3:0]
Scalars are little-endian. Floating-point values use finite IEEE-754 binary32. Node 0 is the host; nodes 1–126 are actuators; 127 is broadcast.
Zero to smallest valid CAN-FD DLC; reject nonzero padding and incorrect DLC.
Messages#
| Message | Service | Priority | Content bytes | DLC bytes |
|---|---|---|---|---|
| emergency_disable | 0 | 0 | 4 | 4 |
| fault | 1 | 1 | 20 | 20 |
| sync | 2 | 2 | 12 | 12 |
| command | 3 | 3 | 38 | 48 |
| state | 4 | 4 | 40 | 48 |
| health | 5 | 5 | 33 | 48 |
| discover | 16 | 6 | 10 | 12 |
| identity | 17 | 6 | 27 | 32 |
| assign_address | 18 | 6 | 21 | 24 |
| capabilities | 19 | 6 | 26 | 32 |
| session_start | 20 | 6 | 24 | 24 |
| ack | 21 | 6 | 15 | 16 |
| configure | 32 | 7 | 43 | 48 |
| calibrate | 33 | 7 | 11 | 12 |
| clear_faults | 34 | 7 | 12 | 12 |
| firmware_begin | 48 | 7 | 45 | 48 |
| firmware_chunk | 49 | 7 | 45 | 48 |
| firmware_commit | 50 | 7 | 40 | 48 |
| enable | 35 | 3 | 9 | 12 |
emergency_disable#
Latching disable; accepted without session authentication, never permits enable.
| Offset | Field | Wire type | Unit |
|---|---|---|---|
| 0 | reason | u32 | — |
fault#
Asynchronous fault event; clearing does not enable torque.
| Offset | Field | Wire type | Unit |
|---|---|---|---|
| 0 | session | u32 | — |
| 4 | sequence | u32 | — |
| 8 | fault_bits | u32 | — |
| 12 | latched_bits | u32 | — |
| 16 | time_us | u32 | — |
sync#
Coordinator monotonic time; 32-bit microseconds wrap with modular arithmetic.
| Offset | Field | Wire type | Unit |
|---|---|---|---|
| 0 | session | u32 | — |
| 4 | time_us | u32 | — |
| 8 | cycle | u32 | — |
command#
Output-axis SI units. Modes 0 disabled, 1 torque, 2 velocity, 3 impedance. Position uses impedance with feedforward. Flags must be zero in v1.
| Offset | Field | Wire type | Unit |
|---|---|---|---|
| 0 | session | u32 | — |
| 4 | sequence | u32 | — |
| 8 | execute_us | u32 | — |
| 12 | valid_until_us | u32 | — |
| 16 | position_rad | f32 | rad |
| 20 | velocity_rad_s | f32 | rad/s |
| 24 | feedforward_nm | f32 | Nm |
| 28 | kp_nm_rad | f32 | Nm/rad |
| 32 | kd_nm_s_rad | f32 | Nm s/rad |
| 36 | mode | u8 | — |
| 37 | flags | u8 | — |
state#
Sampled output and motor readings; estimated torque is not torque-sensor measurement. Position unwrapping status follows capabilities.
| Offset | Field | Wire type | Unit |
|---|---|---|---|
| 0 | session | u32 | — |
| 4 | sequence | u32 | — |
| 8 | time_us | u32 | — |
| 12 | output_position_rad | f32 | rad |
| 16 | motor_position_rad | f32 | rad |
| 20 | velocity_rad_s | f32 | rad/s |
| 24 | iq_a | f32 | A |
| 28 | estimated_torque_nm | f32 | Nm |
| 32 | temperature_c | f32 | degC |
| 36 | fault_bits | u32 | — |
health#
Lower-rate thermal, power and communication telemetry.
| Offset | Field | Wire type | Unit |
|---|---|---|---|
| 0 | session | u32 | — |
| 4 | sequence | u32 | — |
| 8 | bus_voltage_v | f32 | V |
| 12 | winding_temperature_c | f32 | degC |
| 16 | inverter_temperature_c | f32 | degC |
| 20 | uptime_ms | u32 | — |
| 24 | rx_errors | u32 | — |
| 28 | tx_errors | u32 | — |
| 32 | mode | u8 | — |
discover#
Only while all joints are disabled. Unassigned devices hash unique ID and nonce into response slots; repeat with new nonce to resolve collisions.
| Offset | Field | Wire type | Unit |
|---|---|---|---|
| 0 | nonce | u32 | — |
| 4 | slot_count | u16 | — |
| 6 | slot_duration_us | u32 | — |
identity#
Discovery response contains immutable factory unique ID.
| Offset | Field | Wire type | Unit |
|---|---|---|---|
| 0 | nonce | u32 | — |
| 4 | unique_id | bytes16 | — |
| 20 | hardware_revision | u16 | — |
| 22 | firmware_version | u32 | — |
| 26 | node_id | u8 | — |
assign_address#
Target by unique ID; node IDs 1..126. Persistent address assignment requires disabled state and acknowledgement.
| Offset | Field | Wire type | Unit |
|---|---|---|---|
| 0 | nonce | u32 | — |
| 4 | unique_id | bytes16 | — |
| 20 | node_id | u8 | — |
capabilities#
Reported configured limits must correspond to qualified revision; encoder status describes absolute/single-turn/unwrapped validity.
| Offset | Field | Wire type | Unit |
|---|---|---|---|
| 0 | protocol_minor | u16 | — |
| 2 | capability_bits | u32 | — |
| 6 | continuous_torque_nm | f32 | Nm |
| 10 | peak_torque_nm | f32 | Nm |
| 14 | maximum_velocity_rad_s | f32 | rad/s |
| 18 | watchdog_us | u32 | — |
| 22 | encoder_status | u32 | — |
session_start#
Establish a new nonzero session while disabled; reset sequence state, require valid sync before enable.
| Offset | Field | Wire type | Unit |
|---|---|---|---|
| 0 | session | u32 | — |
| 4 | unique_id | bytes16 | — |
| 20 | watchdog_us | u32 | — |
ack#
Transaction result: 0 success; 1 malformed; 2 state; 3 range; 4 stale; 5 unsupported; 6 integrity; 7 busy.
| Offset | Field | Wire type | Unit |
|---|---|---|---|
| 0 | session | u32 | — |
| 4 | sequence | u32 | — |
| 8 | request_service | u8 | — |
| 9 | result | u16 | — |
| 11 | detail | u32 | — |
configure#
Disabled-only typed configuration transaction; op 0 read, 1 stage, 2 commit; unknown keys rejected.
| Offset | Field | Wire type | Unit |
|---|---|---|---|
| 0 | session | u32 | — |
| 4 | sequence | u32 | — |
| 8 | key | u16 | — |
| 10 | operation | u8 | — |
| 11 | value | bytes32 | — |
calibrate#
Explicit supported calibration routine 0 query, 1 start, 2 abort. Factory interlock required to energize.
| Offset | Field | Wire type | Unit |
|---|---|---|---|
| 0 | session | u32 | — |
| 4 | sequence | u32 | — |
| 8 | routine | u16 | — |
| 10 | operation | u8 | — |
clear_faults#
Clear only eligible faults while disabled; does not re-enable outputs.
| Offset | Field | Wire type | Unit |
|---|---|---|---|
| 0 | session | u32 | — |
| 4 | sequence | u32 | — |
| 8 | mask | u32 | — |
firmware_begin#
Disabled-only inactive-slot staging. Image hash is integrity, not authorization; signed manifest verified by bootloader.
| Offset | Field | Wire type | Unit |
|---|---|---|---|
| 0 | session | u32 | — |
| 4 | sequence | u32 | — |
| 8 | image_bytes | u32 | — |
| 12 | image_sha256 | bytes32 | — |
| 44 | target_slot | u8 | — |
firmware_chunk#
Offset-addressed idempotent chunks, unused bytes zero; ack and retransmission required.
| Offset | Field | Wire type | Unit |
|---|---|---|---|
| 0 | session | u32 | — |
| 4 | sequence | u32 | — |
| 8 | offset | u32 | — |
| 12 | valid_bytes | u8 | — |
| 13 | data | bytes32 | — |
firmware_commit#
Verify complete size, hash, signature, board compatibility and antirollback before slot switch. Fault-tolerant recovery required.
| Offset | Field | Wire type | Unit |
|---|---|---|---|
| 0 | session | u32 | — |
| 4 | sequence | u32 | — |
| 8 | image_sha256 | bytes32 | — |
enable#
Explicit state transition: 0 disable, 1 request enable. Enabling requires valid sync, fresh valid sensors, hardware readiness and zero latched faults. Never supplies torque by itself.
| Offset | Field | Wire type | Unit |
|---|---|---|---|
| 0 | session | u32 | — |
| 4 | sequence | u32 | — |
| 8 | enabled | u8 | — |