Skip to main content

rook: robot operation kit

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

Docs: docs/dm_support.md — Damiao motor protocol in 60 seconds (dual-ID architecture, MIT packing, probing, troubleshooting); docs/damiao_control_modes.md — verified Damiao control-mode state machine and CAN ID mapping; docs/fasttouch_v2_joint_map.md — URDF physical joint chain and the CAN mapping calibration boundary; docs/motor_adapters.md — multi-brand adapter architecture. 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)

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.

# 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

./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

./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

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.

python -m pip install roborook
scripts/build_python_wheels.sh all  # Linux x86_64 + aarch64 wheels
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:

# 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. Joint/ESC calibration and the non-actuating rook-arm-calibrate workflow: docs/arm_calibration.md.

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

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

Metadata

Release files for roborook 0.1.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for roborook 0.1.5
File Interpreter ABI Platform
roborook-0.1.5-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.8 abi3 Linux glibc 2.17+ x86-64 Details
roborook-0.1.5-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.8 abi3 Linux glibc 2.17+ ARM64 Details

Total release size: 1.4 MB

Release files / roborook-0.1.5-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL roborook-0.1.5-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 717.9 kB
Tags CPython 3.8 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
0ea4c21de18b4386c21ed8315b72664eec8a4b889416b8df7b35319a150ae566
BLAKE2b-256 checksum
How to use checksums
42d3eb8495bb19f3a00f1b5689440a09aec71a445c0ebe3fead4a1d4ae4c8ad0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.12

Release files / roborook-0.1.5-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL roborook-0.1.5-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 667.3 kB
Tags CPython 3.8 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
f389f5143e22ce44350017dbc7845139094508862f76fef0907394430d1efe0f
BLAKE2b-256 checksum
How to use checksums
f4f27942dad880256418045caa8baba0de15197b6c14928d8f148890fb3a0c52
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.12

Release history Release notifications | RSS feed

This release

0.1.5 This release

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page