kcan
CAN controller primitives and CLI tools for actuator and motor control.
Status
Published by Trevor Knott, Knott Dynamics.
Keywords: KCAN, CubeMars, RobStride, Scrin, Aisling, Trevor Knott, Knott Dynamics.
Features
- MIT force-control frame packing for supported CubeMars AK actuators, including AK60-39 V3.0 KV80.
- CubeMars direct servo command builders, including V3.2 motor-disable and feedback configuration.
- Knott Dynamics K00 (5010-class) and K01 (6512-class) standard-CAN support: NMT, probe, watchdog/heartbeat, position-velocity and position-torque PDOs, flash commands, typed SDOs, telemetry parsing, and the complete 80-parameter registry.
- Feedback decoding, tuned specs for primary AK models, conservative defaults for other AK names, unit conversions, and safe velocity clamping.
- Generic
CanBustrait for tests, embedded adapters, or Linux SocketCAN. - Optional
serdefeature for serializable actuator configs, snapshots, commands, and feedback. - Optional
socketcanfeature for direct Linux SocketCAN usage. - Optional
tuifeature for a Scrin/Scrin Widgets actuator dashboard, wide actuator pane wall, read-only telemetry analytics, and safe control-intent model. - Cross-family actuator snapshots with derived health labels and protocol-specific dashboard metrics.
- CAN monitor utilities for rolling frame logs, trace CSV export/replay, basic protocol classification, data formatting, and Scrin/Aisling TUI viewing.
- Standard
Displayoutput for CAN IDs and frames, plusFromStrfor CAN IDs with explicit standard/extended kind. DisplayandFromStrsupport for model names, direct modes, helper commands, and RobStride frame kinds.kcancommand for model listing and frame generation.
Crate Layout
kcan remains the main user-facing crate and binary name.
Use companion crates only when you need a narrower layer:
= "0.3"
= "0.1"
= "0.1"
kcan-core: no-std CAN frame/protocol primitives for embedded or dependency-light reuse.kcan-viewer: Scrin/Aisling pane-wall viewer components for larger terminal apps.kcan: actuator models, controllers, monitor utilities, optional SocketCAN/TUI integration, and thekcanCLI.
Quick Use
For a beginner cheat sheet, see docs.md.
Build a RobStride status query frame in Rust:
use ;
let model: RobStrideModel = "rs01".parse?;
let frame = robstride_status_query_frame?;
assert_eq!;
assert_eq!;
# Ok::
Build a CubeMars MIT neutral frame in Rust:
use ;
let frame = mit_command_frame?;
assert_eq!;
assert_eq!;
# Ok::
Build a Knott Dynamics K00/K01 position-velocity target frame in Rust:
use ;
let model: KnottDynamicsModel = "k01".parse?;
let frame = knott_dynamics_position_velocity_frame?;
assert_eq!;
assert_eq!;
assert_eq!;
# Ok::
Build a CubeMars AK60-39 V3.0 KV80 MIT neutral frame:
Run the CLI help:
List supported models:
Build a CubeMars direct velocity frame:
Build CubeMars V3.2 motor-disable and 32-bit position feedback configuration frames:
The feedback configuration command writes motor Flash. Build and inspect it offline first, and do not transmit it repeatedly.
Use MotorController::receive_feedback_update or MotorManager::receive_feedback_update to consume V3.2 0x29 status and optional 0x2A 32-bit position frames as separate typed events in wire order.
Build a RobStride status query frame:
Build Knott Dynamics management, command, and SDO frames:
The CLI only builds and prints frames; it does not transmit them. Commands that depend on device
state require a current_mode argument and use the checked builders. Supply a freshly read mode,
not an assumed startup mode. A stale host observation cannot replace firmware-side validation.
K00 and K01 use the same wire protocol. Model identity does not inject unverified motor limits;
safe limits and protection thresholds remain driver configuration. Calibration is deliberately
not available over CAN. Heartbeat is not a neutral command: it services the watchdog and can keep
the previous active command alive. Flash store persists the current configuration and is permitted
only while disabled or idle with PWM off. Use knott disable <node> for the canonical PWM-off
request; damping is electrical braking and is not torque-off. The typed SDO builder intentionally
rejects a zero watchdog timeout because zero disables the command watchdog.
Enable SocketCAN support with:
= { = "0.2", = ["socketcan"] }
Run the sample TUI dashboard with:
List supported CubeMars models and generated frame IDs with:
Print hardware-free CubeMars direct frames:
Print hardware-free AK60-39 V3.0 KV80 base frames:
Print hardware-free RobStride frames:
Print hardware-free Knott Dynamics frames:
Run a simulated CAN monitor with:
Run a live SocketCAN monitor with:
Run a live read-only actuator dashboard with CubeMars, RobStride, and Knott Dynamics targets: