clankers 0.1.6

clankeRS — Rust SDK for robotics applications in the ROS 2 ecosystem
Documentation
<p align="center">
  <strong>clankeRS</strong><br>
  <em>Train in PyTorch. Deploy in Rust or C++. Replay-test against real robot logs.</em>
</p>

<p align="center">
  <a href="https://crates.io/crates/clankers"><img src="https://img.shields.io/static/v1?label=crates.io&message=v0.1.6&color=orange&style=flat-square" alt="crates.io"></a>
  <a href="https://docs.rs/clankers"><img src="https://docs.rs/clankers/badge.svg?style=flat-square" alt="docs.rs"></a>
  <a href="https://github.com/PvRao-29/clankeRS/blob/main/LICENSE"><img src="https://img.shields.io/crates/l/clankers.svg?style=flat-square" alt="MIT license"></a>
</p>

<p align="center">
  <a href="https://docs.rs/clankers">API docs</a> ·
  <a href="https://github.com/PvRao-29/clankeRS">GitHub</a> ·
  <a href="https://crates.io/crates/clankers-cli">CLI crate</a>
</p>

---

**clankeRS** is a Rust SDK for robotics teams on ROS 2 and PyTorch. Build memory-safe robot nodes, run ONNX inference in Rust, replay MCAP logs in tests, and ship with confidence — without replacing your existing stack.

<p align="center">
  <img
    src="https://raw.githubusercontent.com/PvRao-29/clankeRS/main/docs/assets/camera_replay.gif"
    alt="MCAP camera log replayed through ONNX inference with a latency report"
    width="640"
  >
</p>

<p align="center"><sub>Golden-path demo: MCAP → preprocess → ONNX → detections → sim pub/sub</sub></p>

## Install

```toml
# Cargo.toml
clankers = "0.1"
```

```bash
cargo add clankers
```

**Requirements:** Rust stable. First build downloads the ONNX Runtime binary automatically (network required).

For scaffolding and tooling, install the CLI separately (`clankers new` bundles templates — no clone required):

```bash
cargo install clankers-cli
```

## Quick example

A minimal perception node: subscribe to camera frames, run ONNX with zero-copy inputs, publish detections.

```rust
use clankers::prelude::*;

#[clankers::node]
async fn perception(ctx: RobotContext) -> RobotResult<()> {
    let model_cfg = ctx.model_config("detector")?;
    let model_path = ctx.resolve_path(&model_cfg.path);
    let mut model = ModelBuilder::from_config(&model_cfg, model_path)?.build()?;
    let input_name = model.engine().input_specs()[0].name.clone();

    let node = RobotNode::new(ctx.node_name().as_str()).await?;
    let mut images = node
        .subscribe::<ImageMsg>("/camera/image_raw", QosProfile::sensor_data())
        .await?;
    let detections_pub = node
        .publish::<DetectionArray>("/detections", QosProfile::default())
        .await?;

    while let Some(frame) = images.next().await {
        let tensor = ImageTensor::from_ros_msg(&frame)?
            .resize(224, 224)?
            .normalize_imagenet()?
            .to_nchw()?;

        let shape = tensor.nchw_shape();
        let view = tensor.as_nchw_view(&shape)?;
        let outputs = model.run_named([(input_name.as_str(), view)])?;

        detections_pub
            .publish(DetectionArray {
                stamp_nanos: Timestamp::now().as_nanos(),
                frame_id: frame.frame_id.clone(),
                detections: vec![/* map model output → Detection */],
            })
            .await?;
    }
    Ok(())
}
```

Replay-test against a recorded MCAP log:

```rust
use clankers::prelude::*;

#[clankers::replay_test("tests/fixtures/camera_log.mcap")]
async fn camera_log_replays_cleanly(ctx: ReplayContext) -> RobotResult<()> {
    let result = ctx.run_replay(|_msg| async { Ok(()) }).await?;
    assert_no_panics(&result)?;
    assert_topic_exists(&result, "/camera/image_raw")?;
    Ok(())
}
```

## What you get

One dependency pulls in the full SDK surface:

| Module | Highlights |
|--------|------------|
| `clankers::ros2` | `RobotNode`, pub/sub, `ImageMsg`, `DetectionArray`, QoS profiles |
| `clankers::ml` | Optimized `Model` inference, backends, validation |
| `clankers::tensor` | `TensorView` zero-copy views, `ImageTensor` preprocessing |
| `clankers::data` | MCAP `Replay`, logging, inspection |
| `clankers::recording` | `McapRecorder` — tape node I/O to MCAP via `[logging] record_mcap` |
| `clankers::testing` | `ReplayContext`, replay assertions |
| `clankers::runtime` | `RobotRuntime`, metrics, scheduling |
| `clankers::geometry` | `TfBuffer` frame lookups, `Isometry`, `Pose`, `Twist` |
| `clankers::prelude` | Common imports for everyday node code |

## The workflow

```text
  PyTorch model
   ONNX export ──► reference outputs (offline)
  Rust ONNX inference (clankers-ml)
  MCAP replay test (clankers-testing)
  deploy as a ROS 2 node
```

## Honest scope (v0.1.6)

- **Sim pub/sub works out of the box** — no ROS 2 install required for development and tests.
- **Recording is real**`[logging] record_mcap = true` (or `clankers record`) tapes configured topics to a replayable MCAP, finalized on exit or Ctrl-C.
- **Real DDS / `rclrs`** is available from the [GitHub repo]https://github.com/PvRao-29/clankeRS as colcon packages under `ros2/` (ROS 2 Humble). It does not ship through this crate.
- **C++ inference**[`clankers-ffi`]https://crates.io/crates/clankers-ffi + `cpp/` wrap the same `InferenceEngine` as Rust. An rclcpp perception node is planned next.
- APIs are early — expect changes before v1.0.

## Learn more

- [Installation]https://github.com/PvRao-29/clankeRS/blob/main/docs/installation.md
- [Getting started]https://github.com/PvRao-29/clankeRS/blob/main/docs/getting_started.md
- [ROS 2 integration]https://github.com/PvRao-29/clankeRS/blob/main/docs/ros2_integration.md
- [Model validation]https://github.com/PvRao-29/clankeRS/blob/main/docs/model_validation.md
- [MCAP replay testing]https://github.com/PvRao-29/clankeRS/blob/main/docs/mcap_replay.md
- [C++ SDK]https://github.com/PvRao-29/clankeRS/blob/main/cpp/README.md

## License

MIT — see [LICENSE](https://github.com/PvRao-29/clankeRS/blob/main/LICENSE).