kcan 0.3.0

CAN controller primitives for actuator and motor control.
Documentation

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 CanBus trait for tests, embedded adapters, or Linux SocketCAN.
  • Optional serde feature for serializable actuator configs, snapshots, commands, and feedback.
  • Optional socketcan feature for direct Linux SocketCAN usage.
  • Optional tui feature 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 Display output for CAN IDs and frames, plus FromStr for CAN IDs with explicit standard/extended kind.
  • Display and FromStr support for model names, direct modes, helper commands, and RobStride frame kinds.
  • kcan command 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:

kcan = "0.3"
kcan-core = "0.1"
kcan-viewer = "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 the kcan CLI.

Quick Use

For a beginner cheat sheet, see docs.md.

Build a RobStride status query frame in Rust:

use kcan::{RobStrideModel, robstride_status_query_frame};

let model: RobStrideModel = "rs01".parse()?;
let frame = robstride_status_query_frame(0x01)?;

assert_eq!(model.to_string(), "RS-01");
assert_eq!(frame.id().raw(), 0x501);
# Ok::<(), kcan::Error>(())

Build a CubeMars MIT neutral frame in Rust:

use kcan::{MitCommand, MotorModel, mit_command_frame};

let frame = mit_command_frame(MotorModel::Ak60_6, 0x03, MitCommand::neutral())?;

assert_eq!(frame.id().raw(), 0x0803);
assert_eq!(frame.len(), 8);
# Ok::<(), kcan::Error>(())

Build a Knott Dynamics K00/K01 position-velocity target frame in Rust:

use kcan::{KnottDynamicsModel, knott_dynamics_position_velocity_frame};

let model: KnottDynamicsModel = "k01".parse()?;
let frame = knott_dynamics_position_velocity_frame(1, 1.0, -2.0)?;

assert_eq!(model.to_string(), "K01");
assert_eq!(frame.id().raw(), 0x301);
assert_eq!(frame.data(), &[0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0xC0]);
# Ok::<(), kcan::Error>(())

Build a CubeMars AK60-39 V3.0 KV80 MIT neutral frame:

cargo run --bin kcan -- cubemars mit ak60-39 0x03

Run the CLI help:

cargo run --bin kcan -- help

List supported models:

cargo run --bin kcan -- models

Build a CubeMars direct velocity frame:

cargo run --bin kcan -- cubemars direct 0x03 velocity 1000

Build CubeMars V3.2 motor-disable and 32-bit position feedback configuration frames:

cargo run --bin kcan -- cubemars direct 0x03 disable
cargo run --bin kcan -- cubemars direct 0x03 feedback-config position-32bit

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:

cargo run --bin kcan -- robstride status rs01 0x01

Build Knott Dynamics management, command, and SDO frames:

cargo run --bin kcan -- knott nmt 1 disabled idle
cargo run --bin kcan -- knott disable 1
cargo run --bin kcan -- knott probe 1
cargo run --bin kcan -- knott position-velocity 1 1.0 -2.0
cargo run --bin kcan -- knott position-torque 1 1.0 0.5
cargo run --bin kcan -- knott read 1 firmware_version
cargo run --bin kcan -- knott write 1 idle torque_limit 1.0
cargo run --bin kcan -- knott flash 1 idle store
cargo run --bin kcan -- knott heartbeat 1

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:

kcan = { version = "0.2", features = ["socketcan"] }

Run the sample TUI dashboard with:

cargo run --example tui_dashboard --features tui

List supported CubeMars models and generated frame IDs with:

cargo run --example cubemars_models

Print hardware-free CubeMars direct frames:

cargo run --example cubemars_direct_frames

Print hardware-free AK60-39 V3.0 KV80 base frames:

cargo run --example cubemars_ak60_39_base

Print hardware-free RobStride frames:

cargo run --example robstride_frames

Print hardware-free Knott Dynamics frames:

cargo run --example knott_dynamics_frames

Run a simulated CAN monitor with:

cargo run --example can_monitor_demo --features tui

Run a live SocketCAN monitor with:

cargo run --example socketcan_monitor --features socketcan,tui -- can0

Run a live read-only actuator dashboard with CubeMars, RobStride, and Knott Dynamics targets:

cargo run --example socketcan_dashboard --features socketcan,tui -- can0 cubemars:ak60-6:0x03 robstride:rs01:0x01 knott:k01:0x02