Tendon-Driven Robotic Hand — A Vision-Teleoperated MuJoCo Digital Twin
Table of Contents

docker compose up: webcam + MediaPipe landmarks on the left, the MuJoCo digital twin on the right.This is the successor to my ROS 2 MediaPipe robotic hand. That project animated a 15-DOF hand by setting joint angles in RViz. This one takes the harder, more physical route: the hand is tendon-driven and underactuated, like most 3D-printed and many research hands. Each finger has one flexor string pulled from the palm, and MuJoCo decides how that single pull curls three passive joints.
The code is open under AGPL-3.0 and DOI-archived (10.5281/zenodo.22775694), the Onshape assembly is public, and every number in the series below was measured on the repository.
Get the code on GitHub Run it in 10 minutes
The pipeline #
flowchart TB
subgraph V["🐳 vision_tracker"]
direction LR
A["📷 Webcam"] --> B["MediaPipe Hands
21 landmarks"]
B --> C["3 knuckle angles
per finger → mean"]
C --> D["Flexion
0.0 open · 1.0 closed"]
end
subgraph T["🐳 mujoco_twin"]
direction LR
E["Lerp → ±50 N"] --> F["Tendon motor
pull_{finger}"]
F --> G["Spatial tendon
through 6 sites"]
G --> H["🖐️ MuJoCo viewer"]
end
D -- "ROS 2 · /hand/target_flexions
sensor_msgs/JointState" --> E
Two containers share the host network (DDS discovery, visible across the LAN) and the host’s
shared memory (Fast DDS moves messages through /dev/shm). The code is bind-mounted, not baked into
the images, so an edit is a docker compose restart away.
| From CAD… | …to a simulated tendon routing |
|---|---|
![]() |
![]() |
Watch it #
What the measurements showed #
Building the documentation meant measuring the system instead of describing it. Three results stood out, and each gets its own article:

| Peace sign | OK sign |
|---|---|
![]() |
![]() |
Each frame shows all three layers at once: tracked hand, simulated hand, and the live tendon forces.
The 20-part series #
Written as a tutorial you can follow end to end, or dip into by layer. Each part is self-contained and links to the exact files in the repository.
Getting started #
- Run the tendon-driven hand digital twin — Docker Compose, a single Python script, the twin alone, or the model viewer.
- How a webcam moves a simulated tendon-driven hand — the whole system on one page. Start here if you only read one.
- Troubleshooting and FAQ — every error hit while building it, and the fix.
Vision — pixels to finger flexion #
- MediaPipe Hands and the 16° angle trap — the two-stage model, 21 landmarks, and what the coordinates really mean.
- Joint angles from three landmarks — dot-product geometry and its two numerical traps.
- Why three knuckles become one number — underactuation, and what averaging throws away.
- Normalizing finger curl — the inverted min-max formula and where its constants come from.
- Why the thumb gets its own thresholds — a saddle joint, a narrow window, and its trade-off.
- Calibrating hand tracking to your hand — a procedure, and real flexions from a live session.
Actuation — flexion to finger motion #
- From finger flexion to tendon force — linear interpolation, actuator lookup, and a string that pushes.
- Why the simulated finger is a switch — the measurement, the force balance, and three tested fixes.
Model — Onshape CAD to MuJoCo #
- From an Onshape assembly to MuJoCo — the current design,
onshape-to-robot, andconfig.json. - The manual MJCF edits behind a tendon hand — tendons, the “horn hack”, contacts that never happen, and motors.
- Inside the MuJoCo tendon hand model — kinematic tree, joint sign conventions, site naming.
ROS 2 and containers #
- The ROS 2 topic contract — one topic, two nodes, and pumping
rclpyinside a render loop. - Docker Compose architecture for ROS 2 — dependency-only images and mounted code.
- Shared network and shared memory in Docker — DDS discovery, domain IDs, LAN visibility, and Fast DDS SHM across containers.
- GUI, webcam and GPU passthrough — X11 on Wayland,
/dev/dri,/dev/video0, and the cost ofprivileged.
Performance and production #
- What limits the frame rate — a benchmark, what it ruled out, and the leading hypothesis.
- Roadmap to production — correctness, robustness, maintainability, real servos, deployment.
What it does not do (yet) #
- Partial poses. The twin mirrors open and closed fingers, not a half-curl — see Part 11 and issue #1.
- Hardware. It simulates commands; the SG90 servos in the CAD are not driven yet (Part 20).
- Self-collision. No geom pair in the model ever produces a contact (Part 13).
- Smoothing. Landmark jitter passes straight through to the tendon forces.
Frequently asked questions #
What is the tendon-driven robotic hand digital twin?
How is a tendon-driven hand simulated in MuJoCo?
Does the project need a depth camera, gloves, or a GPU?
How do two ROS 2 Docker containers share memory and network in this project?
How do I cite the tendon-driven hand digital twin?
Cite it #
@software{fetna_tendon_hand_mujoco_twin,
author = {Fetna, Mulham Mohammed},
title = {{Tendon-Driven Robotic Hand: Vision-Teleoperated MuJoCo Digital Twin}},
year = {2026},
publisher = {Zenodo},
doi = {10.5281/zenodo.22775694},
url = {https://doi.org/10.5281/zenodo.22775694}
}
Why the simulated tendon finger is a switch — and three fixes tested in MuJoCo
What limits the frame rate: MediaPipe, Docker and a MuJoCo viewer on one laptop
Underactuation: why three knuckle angles become one tendon command
Troubleshooting and FAQ: MuJoCo, MediaPipe and ROS 2 in Docker
The ROS 2 topic contract: one JointState topic, two nodes, and rclpy inside a render loop
The manual MJCF edits that turn a CAD export into a tendon-driven hand
Run the tendon-driven hand digital twin in 10 minutes
ROS 2 across Docker containers: shared network, discovery and Fast DDS shared memory
Normalizing finger curl: from radians to a 0–1 flexion
MediaPipe Hands for robotics — and the 16° angle trap in normalized landmarks
Inside the MuJoCo tendon hand model: bodies, joints, sites and sign conventions
How a webcam moves a simulated tendon-driven hand
GUI, webcam and GPU passthrough for ROS 2 and MuJoCo containers
From tutorial project to production robot: a roadmap for the tendon hand twin
From finger flexion to tendon force: linear interpolation onto a MuJoCo motor
From an Onshape assembly to a MuJoCo model with onshape-to-robot
Finger joint angles from three hand landmarks: the dot-product geometry
Docker Compose architecture for ROS 2: dependency-only images and mounted code



