Metadata-Version: 2.4
Name: roborook
Version: 0.1.5
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Rust
Classifier: Operating System :: POSIX :: Linux
Summary: Python bindings for the Rook robot operation SDK
License: Apache-2.0
Requires-Python: >=3.8
Description-Content-Type: text/markdown

# rook: **ro**bot **o**peration **k**it

Pure-Rust robot-arm control SDK modelled after the reference C++/Python
`startouch_sdk` (vendored at `vendor/startouch_sdk`).

> **Docs**: [docs/dm_support.md](docs/dm_support.md) — Damiao motor protocol
> in 60 seconds (dual-ID architecture, MIT packing, probing, troubleshooting);
> [docs/damiao_control_modes.md](docs/damiao_control_modes.md) — verified Damiao
> control-mode state machine and CAN ID mapping;
> [docs/fasttouch_v2_joint_map.md](docs/fasttouch_v2_joint_map.md) — URDF physical
> joint chain and the CAN mapping calibration boundary;
> [docs/motor_adapters.md](docs/motor_adapters.md) — multi-brand adapter architecture.
> [docs/high_level_motor_control.md](docs/high_level_motor_control.md) — vendor-neutral single-motor control API.

## Architecture

```
┌─────────────────────────────────────────────────────────┐
│ robots/   generic controller, state, safety, dynamics   │
│   arms/       TouchArm and future arm families          │
│   grippers/   gripper types and calibration             │
│   dexhands/   reserved for dexterous hands              │
├─────────────────────────────────────────────────────────┤
│ kinematics/  homogeneous-transform FK + DLS IK          │
│ motion/      joint/Cartesian trajectories + sampling    │
├─────────────────────────────────────────────────────────┤
│ motor/    Damiao protocol: MIT 16/12/12-bit packing,    │
│           enable/disable frames, 0x7FF register access, │
│           feedback parsing, P/V/T_MAX per model         │
├─────────────────────────────────────────────────────────┤
│ can/      Linux SocketCAN (raw PF_CAN via libc),        │
│           DM firmware simulator, mock bus, discovery    │
└─────────────────────────────────────────────────────────┘
```

## Layout

| Path | Purpose |
|---|---|
| `src/can/bus.rs` | `SocketCanBus` (real CAN), `MockCanBus`, `list_can_interfaces()` |
| `src/can/sim.rs` | `DmSimulatedBus` — in-process DM drive simulator |
| `src/motor/protocol.rs` | byte-level DM wire format (pure functions) |
| `src/motor/damiao.rs` | `DamiaoMotor` driver on a shared bus |
| `src/kinematics/` | `RobotModel` (incl. `fasttouch_v2()`), `JacobianIK` |
| `src/robots/` | generic `ArmController`, state, safety, and dynamics |
| `src/robots/arms/` | concrete arm families and the shared `RobotArm` capability |
| `src/robots/grippers/` | gripper types and type-specific physical calibration |
| `examples/` | demos that run **without hardware** |
| `src/bin/` | hardware test tools |

## Examples (no hardware needed)

```bash
cargo run --example mock_bus_demo     # full stack vs simulated drives
cargo run --example kinematics_demo   # FK sweep + IK round-trip
cargo run --example trajectory_demo   # joint/waypoint/cartesian planning
cargo run --example dm_frame_demo     # hex dump of every wire frame
cargo run --example dm_arm_control -- --dry-run --execute --waypoint 0 0 0 0 0 0
```

## Joint waypoint control (`dm_arm_control`)

High-level, non-interactive trajectory control through `TouchArm`. The user
provides complete six-joint waypoints and a maximum joint speed; the SDK owns
CAN, motor protocol, live profile discovery, enable/disable, and the position
stream. A requested speed is enforced as an upper bound for every joint.

```bash
# Safe trajectory rehearsal: select CSV left-arm columns; press a key before each row
cargo run --example dm_arm_control -- --dry-run --execute --side left

# Physical arm: replay the right-arm columns continuously only after dry-run validation
sudo cargo run --release --example dm_arm_control -- --interface can1 --execute \
  --trajectory data/test_traj.txt --side right --no-input --speed-rad-s 0.05
```

`dm_arm_control` does not construct an IK solver itself. `TouchArm` loads the
URDF and defaults to the built-in Rust backend; pass `--ik-backend pinocchio`
only in a build made with `--features pinocchio`. Joint replay does not invoke
IK, but the backend remains available for pose control through the same robot
API.

Built-in safety layers:

1. real motors are never opened/enabled without `--execute`;
2. the replay CSV is selected by actual `left_joint_1..6` or `right_joint_1..6`
   header names; gripper columns are not sent to the six-axis arm;
3. every waypoint is validated against the selected URDF position limits;
4. the requested speed must be below both URDF and motor configured velocity
   limits, and each segment is timed from its greatest joint displacement;
5. static motor expectation is cross-checked against the live PMAX/VMAX/TMAX
   profile, and live values are always used for wire encoding;
6. cleanup disables all joints after normal completion or any reported error;
7. `--dry-run` executes the identical robot API flow against simulated drives.

## One-click build

```bash
./install.sh                 # detect OS/arch, build release + run tests
./install.sh --install       # also copy bins into $PREFIX/bin (~/.local)
PREFIX=/usr/local sudo -E ./install.sh --install
```

## Hardware test tools

```bash
./install.sh --install   # build + test + install to ~/.local/bin (see below)

# 1. list CAN interfaces + setup hints
rook-can-list

# 2. configure the bus (1 Mbit/s is the DM default)
sudo ip link set can0 up type can bitrate 1000000

# 3. sniff traffic / send a raw frame
rook-can-sniff -i can0 -d 10 --send 0x001 FFFFFFFFFFFFFC

# 4. discover Damiao drives (refresh requests only — never enables motors)
rook-dm-probe -i can0 --esc-ids 1-6

# 5. exercise one motor (enable -> MIT sweep -> disable)
sudo rook-dm-probe -i can0 --esc 1 --master 0x11 \
    --motor-type DM4310 --execute --sweep 0.3

# 6. full arm smoke test (states only; add --execute to move ±0.1 rad)
sudo rook-arm-smoke -i can0 [--execute] [--kp 30 --kd 2]
```

## Library quick start

```rust
use rook::robots::arms::TouchArm;
use rook::robots::IkBackend;
use rook::types::Waypoint;

let arm = TouchArm::open("can0", TouchArm::bundled_urdf(), IkBackend::Rust)?;
let q = arm.get_state_joint_positions()?;
arm.move_joint_waypoints_at_speed(
    vec![Waypoint::new_joint(vec![0.1; 6])],
    0.1,
)?;
arm.close(); // stop internal communications and safely disable
```

## Python package

The distribution name is `roborook`; the import name is `rook`. The native
extension uses Python's stable `abi3-py38` ABI, so one wheel per CPU
architecture supports CPython 3.8 and newer.

```bash
python -m pip install roborook
scripts/build_python_wheels.sh all  # Linux x86_64 + aarch64 wheels
```

```python
import rook

with rook.robots.arms.TouchArm.open(
    "can0",
    gripper=rook.robots.grippers.Gripper.LJ,
) as arm:
    print(arm.get_state_joint_positions())
    print(arm.get_state_eepose_euler())
    arm.move_joint_waypoints_at_speed([[0.0] * 6], 0.2)
```

For an application-level example that configures only one or two CAN
interfaces (not motor IDs or motor models), run:

```bash
# Safe rehearsal on a simulated bus
cargo run --example robot_control -- --dry-run --joint 0 0.3 -0.6 0.2 0 0 --execute

# One real robot on can0; add --can1 can1 for a second independent robot
cargo run --release --example robot_control -- --can0 can0 --joint 0 0.3 -0.6 0.2 0 0 --execute

# Use a calibrated/custom robot model; Rust IK and optional Pinocchio use this URDF.
cargo run --release --example robot_control -- --can0 can0 \
  --urdf /path/to/robot.urdf --pose 0.30 0 0.25 0 0 0 --execute
```

IK backends and optional Pinocchio integration: [docs/ik_backends.md](docs/ik_backends.md).
Joint/ESC calibration and the non-actuating `rook-arm-calibrate` workflow:
[docs/arm_calibration.md](docs/arm_calibration.md).

For a conservative URDF-derived rectangle preview (then optional execution):

```bash
cargo run --example robot_control_simple -- --dry-run
cargo run --release --example robot_control_simple -- --can can0 --execute
```

## Testing without hardware

`TouchArm::simulated(...)` runs the identical code path against the
in-process DM firmware simulator; `cargo test` (62 tests) covers byte-level
protocol golden vectors, the solver, and end-to-end flows.
A virtual CAN interface also works with the bins:
`sudo ip link add dev vcan0 type vcan && sudo ip link set vcan0 up`.

## Reference

<https://github.com/AstroRoboticsTech/rs-pinocchio>

