Back to robots

robonix.robot.linkerbot.linker_hand_o6

LinkerHand O6 standalone dexterous-hand deployment — finger dance and static gesture skill.

README

robot-linkerbot-linker_hand_o6

中文版

Robonix deployment for a standalone LinkerHand O6 five-finger dexterous hand (six axes, CAN bus) — no arm, no mobile base, no camera. The hand performs a finger "dance" on voice or text command through pilot.

This repository is the assembly, and holds no actual package source — the primitive and the skill each live in their own repository and are fetched by url: at build time into rbnx-boot/cache/. What lives here is:

  • robonix_manifest.yaml — the deployment manifest listing every package to bring up, with its runtime config.
  • soma.yaml + urdf/linkerhand_o6_right.urdf — the body description and URDF served by robonix-soma (see urdf/README.md).
  • .env.example — the LLM endpoint credential template (copy to .env).

LinkerHand O6 five-finger dexterous hand


1. What it can do

Capability Tool Example request
Finger dance gesture_dance "跳个舞" / "wiggle your fingers for 5 seconds"
Per-axis position / speed / torque the hand primitive's contracts (programmatic)

It cannot reach, lift, move or see anything: there is no arm and no camera in this deployment. soma.yaml's cannot_do states this explicitly so pilot does not attempt object manipulation.


2. Package roster

Manifest order is boot order. The names below match - name: in robonix_manifest.yaml, which is also what rbnx caps displays.

Section Name Repository
primitive o6_hand primitive-linkerbot-linker_hand_o6-hand-rbnx
skill hand_gesture skill-hand-gesture-rbnx

The primitive owns the CAN bus and serves the six robonix/primitive/hand/* contracts. The LinkerHand SDK — which is not on PyPI — is vendored inside it, so a build needs no extra network access beyond fetching the two packages.

The skill is a standalone, generic package, reused verbatim rather than forked. Nothing in it is tied to a particular robot: it is a pure consumer that discovers the primitive through atlas, reads the axis order from hand/info at activation, and drives a 6-axis dance vector — exactly the O6 layout.


3. Prerequisites

  • Hardware: a LinkerHand O6 hand and a USB-CAN adapter, wired and powered.
  • robonix-cli (rbnx) on PATH, with the robonix source tree registered (rbnx setup in that tree).
  • Python env with python-can, numpy, grpcio, grpcio-tools, mcp, fastmcp. Each package's scripts/start.sh carries a default interpreter path; override per package with LINKERHAND_O6_PYTHON / HAND_GESTURE_PYTHON.
  • An LLM endpoint for pilot. Copy .env.example.env and fill VLM_BASE_URL / VLM_API_KEY / VLM_MODEL. No image input is needed — this deployment has no camera, so the model is only a text planner.

4. Configuration — what to check before running

4.1 CAN bus

Bring the bus up before booting, at 1 Mbps:

sudo ip link set can0 up type can bitrate 1000000
ip -br link show can0          # confirm it exists and is up

The primitive will raise the interface itself if it is down, but that needs elevated rights (PREFLIGHT_SUDO_PASS, see .env.example). Bringing it up beforehand is preferred: then nothing in the deployment needs privileges.

Shut down any other controller on the bus first — the LinkerHand ROS/ROS2 SDK, a mocap glove, the vendor GUI. Two writers on one CAN bus fight over the hand.

4.2 Manifest knobs

Everything tunable is in robonix_manifest.yaml:

  • hand_typeright (CAN id 0x27) or left (0x28). A wrong value means the hand never answers and init fails on the state readback.
  • can_iface / baudrate — default can0 at 1 Mbps.

The skill takes no config (config: {}) — the dance duration is a per-call argument.


5. Build and run

5.1 Per-session bring-up

rbnx build -f robonix_manifest.yaml     # fetch both packages + run their codegen
rbnx boot  -f robonix_manifest.yaml     # bring up the stack, until Ctrl-C

Then, in another shell:

rbnx caps -v                # every capability and its provider state
rbnx tools                  # the MCP tools pilot can call
rbnx chat                   # talk to the robot

rbnx shutdown tears down a stack brought up by rbnx boot.

5.2 After changing a package

After changing code in one of the package repos, drop the cached checkout or the old copy keeps booting:

rbnx clean -f robonix_manifest.yaml --cache
rbnx build -f robonix_manifest.yaml

6. Body model

soma.yaml describes a single body part — the hand — rooted at hand_base_link, with the six actuated axes and the contracts serving them. It is served verbatim to pilot as LLM body context.

urdf/linkerhand_o6_right.urdf is a standalone right-hand model: the arm, head and base links of the whole-body URDF it came from were dropped and hand_base_link promoted to the root. Joint names match the axis names the primitive reports through hand/info. The distal joints are mimic — six actuators, with each distal link following its proximal one mechanically. The vendor ships no O6 URDF in either its Python or ROS2 SDK, which is why this is derived rather than imported.

The footprint in soma.yaml is the hand base's own static hull, not a drivable base; soma validates that a footprint encloses the origin, and this deployment has no chassis.


7. Repository layout

robot-linkerbot-linker_hand_o6/
├── robonix_manifest.yaml   # what to deploy, and with what config
├── soma.yaml               # body model served to pilot
├── .env.example            # LLM endpoint + optional sudo password for CAN
├── assets/robot.jpg        # catalog preview image
└── urdf/
    ├── README.md                  # URDF provenance, joint tree, frame conventions
    ├── linkerhand_o6_right.urdf   # standalone right hand, root link = hand_base_link
    └── meshes/right_hand/*.STL    # meshes referenced by the URDF

rbnx-boot/ (fetched packages and runtime logs) is git-ignored.


8. Units

Every hand value is normalized to [0, 1] per axis: position 0 = open and 1 = closed; speed and torque limits 0 = min and 1 = max. The O6 firmware's raw 0–255 units — and the inverted polarity of its position values — are converted inside the primitive package.


9. Safety

  • Secure the hand before the first run; a dance moves all five fingers at once.
  • Lower the ceiling with set_joint_torque_limits before the first open/close to avoid pinching a finger or damaging a knuckle.
  • The hand is commanded fully open at the end of every dance, on any error, and on shutdown — it is never left mid-clench.
  • Keep hands and objects clear of the fingers while the stack is running.

10. Troubleshooting

Symptom Likely cause Fix
Init fails on the state readback; the hand never answers Wrong hand_type — right is CAN id 0x27, left 0x28 Fix hand_type in robonix_manifest.yaml (§4.2)
The primitive won't start, reporting a missing interface can0 is down Run the ip link set from §4.1; confirm with ip -br link show can0
Twitchy motion, or commands landing intermittently Another writer on the bus (ROS/ROS2 SDK, mocap glove, vendor GUI) Shut the other controllers down — one writer per CAN bus
Package code changed but behaviour didn't The old checkout in rbnx-boot/cache/ is what booted Run the rbnx clean --cache from §5.2, then build
Pilot tries to grasp or carry something soma.yaml's cannot_do was edited or isn't taking effect There is no arm and no camera here; confirm cannot_do is intact

For deeper digging, every package leaves stdout/stderr in rbnx-boot/logs/<name>.log.


11. Reference

Each package's own README covers its contracts and failure modes in detail. When a package misbehaves, start there.


12. License

MulanPSL-2.0