# 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.
- CubeMars direct servo command builders.
- 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:

```toml
kcan = "0.1"
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:

```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:

```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>(())
```

Run the CLI help:

```sh
cargo run --bin kcan -- help
```

List supported models:

```sh
cargo run --bin kcan -- models
```

Build a CubeMars direct velocity frame:

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

Build a RobStride status query frame:

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

Enable SocketCAN support with:

```toml
kcan = { version = "0.1", features = ["socketcan"] }
```

Run the sample TUI dashboard with:

```sh
cargo run --example tui_dashboard --features tui
```

List supported CubeMars models and generated frame IDs with:

```sh
cargo run --example cubemars_models
```

Print hardware-free CubeMars direct frames:

```sh
cargo run --example cubemars_direct_frames
```

Print hardware-free RobStride frames:

```sh
cargo run --example robstride_frames
```

Run a simulated CAN monitor with:

```sh
cargo run --example can_monitor_demo --features tui
```

Run a live SocketCAN monitor with:

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

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

```sh
cargo run --example socketcan_dashboard --features socketcan,tui -- can0 cubemars:ak60-6:0x03 robstride:rs01:0x01
```
