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

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.2
File Interpreter ABI Platform
roborook-0.1.2-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.2-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.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL roborook-0.1.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 711.6 kB
Tags CPython 3.8 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
ca0905b35d1c92c812e0862ce9b969aea400d93895319f1af2bf65f55be23e99
BLAKE2b-256 checksum
How to use checksums
1f27429b6406170f48c530b2d966a464d7f2806ea6a0b0bec20c328d431ec39e
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.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL roborook-0.1.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 660.0 kB
Tags CPython 3.8 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
4744f0f791978b46a741eef0ed4d3e196617a21308f9b5e0007a05b4eec10756
BLAKE2b-256 checksum
How to use checksums
85284a17c4474e4a7a0c49c5c66a5f45d9d242176f688e83c0b372f99d5c5170
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

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

This release

0.1.2 This release

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