# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

Raiden is an end-to-end data collection and policy inference toolkit for YAM bimanual robot arms. It covers camera calibration, teleoperation, multi-camera recording, dataset conversion, sharding, and closed-loop policy inference.

## Build & Development

Package manager: **uv** (uses `pyproject.toml` + `uv.lock`)

```bash
uv sync                     # install all deps into .venv
uv sync --extra zed         # include ZED SDK support
uv sync --extra ffs         # include Fast Foundation Stereo
uv sync --extra docs        # include mkdocs for documentation
```

The CLI entry point is `rd` (defined in `pyproject.toml [project.scripts]`). All commands are dispatched through `raiden/cli.py`.

## Linting

CI runs ruff (format + check) via GitHub Actions:

```bash
uvx ruff format --check .
uvx ruff check .
uvx ruff format .           # auto-fix formatting
```

Third-party code (`third_party/`) is excluded from ruff.

## Testing

No test suite exists for the raiden package itself. The `third_party/i2rt` submodule has its own tests.

## Architecture

### CLI (`raiden/cli.py`)
All `rd <command>` subcommands are tyro dataclasses dispatched manually. Adding a new command means defining a dataclass and adding an `elif` branch in `main()`.

### Configuration (`raiden/_config.py`)
User config lives at `~/.config/raiden/`:
- `camera.json` — camera serial numbers and roles
- `calibration_results.json` — extrinsic calibration output
- `spacemouse.json` — hidraw device paths
- `db/` — pysondb JSON database (demonstration metadata)
- `weights/` — model checkpoints, ONNX files, TRT engines

### Hardware Abstraction
- **Cameras** (`raiden/cameras/`): `Camera` ABC with `ZedCamera` and `RealsenseCamera` implementations. Supports live capture and SVO2/bag file playback.
- **Control** (`raiden/control/`): `TeleopInterface` ABC with `YAMInterface` (leader-follower) and `SpaceMouseInterface` (end-effector velocity).
- **Robot** (`raiden/robot/controller.py`): `RobotController` wraps i2rt motor chains over CAN. Uses PyRoki + J-Parse for IK.

### Data Pipeline
1. `rd record` → raw data in `data/raw/<task>/<episode>/` (SVO2/bag + robot_data.npz)
2. `rd convert` → processed data in `data/processed/<task>/<episode>/` (PNG frames + depth + lowdim pickles)
3. `rd shardify` → WebDataset `.tar` shards in `data/shards/`

### Policy Serving / Inference
- **`rd serve`** (`raiden/server.py`): `RaidenPolicyServer` exposes live observations over the chiral WebSocket protocol. A remote policy client sends joint commands back.
- **`rd infer`** (`raiden/inference.py`): `RaidenInferenceLoop` subclasses `RaidenPolicyServer` and runs the policy locally via a `ModelBridge` plugin. Bridge implementations live in model repos, not in raiden. Pass `--dry_run` to run the full sensor + inference pipeline without commanding motors (useful for verifying predictions before going live).

### ModelBridge Interface
External model repos implement `ModelBridge` (load/predict/reset). `predict()` receives a `chiral.types.Observation` and returns a `(14,)` float32 array: `[right_joints(6), right_grip(1), left_joints(6), left_grip(1)]`.

### Third-Party
- `third_party/i2rt` — git submodule; low-level motor/CAN driver for YAM arms (also a uv path dependency)
- `third_party/Fast-FoundationStereo` — optional; added to sys.path at runtime for FFS depth

### Key Conventions
- Bimanual joint layout in inference: `[right(7), left(7)]` (raiden convention). The chiral WebSocket protocol uses `[left, right]`.
- Extrinsics are expressed in the left-arm base frame.
- Cameras in `_FLIP_CAMERAS` are mounted upside-down; images are rotated 180° at capture time.
- Python 3.11 only (`requires-python = ">=3.11,<3.12"`).
