Inside the MuJoCo tendon hand model: bodies, joints, sites and sign conventions
A fixed palm, five three-segment digits, five free-spinning servo horns, ten strings through seventy points, five motors. Every number here was read from the compiled model with MuJoCo 3.13.0. Open (+50 N) Neutral (0 N) Fist (−50 N) Index tendon only Middle tendon only Ring tendon only Pinky tendon only Thumb tendon only Previous Next At a glance # Quantity Value Notes Bodies 22 world, palm, 15 phalanges, 5 servo horns Joints / DoF 20 / 20 all hinges; no free joint — the palm is welded to the world Knuckle joints 15 passive, 90° limits Servo horn joints 5 unlimited and unactuated Geoms 87 43 visual + 43 collision meshes + floor Meshes 14 STL Sites 70 tendon via-points and anchors Tendons 10 5 flexor (actuated) + 5 extensor (passive) Actuators 5 <motor> on flexors, ±50 N Timestep / integrator 0.002 s / Euler 500 steps per simulated second Total mass 0.398 kg palm block 341.8 g The kinematic tree # flowchart TB W["world"] --> P["part_1 · palm + servo block
341.8 g · 20 sites"] P --> I1["part_2_4 · index proximal
4.6 g · index_mcp"] --> I2["part_3_4
1.8 g · index_pip"] --> I3["part_4_4
4.6 g · index_dip"] P --> M1["part_2_3 · middle
middle_mcp"] --> M2["part_3_3
middle_pip"] --> M3["part_4_3
middle_dip"] P --> R1["part_2_2 · ring
ring_mcp"] --> R2["part_3_2
ring_pip"] --> R3["part_4_2
ring_dip"] P --> K1["part_2 · pinky
pinky_mcp"] --> K2["part_3
pinky_pip"] --> K3["part_4
pinky_dip"] P --> T1["part_5 · thumb
5.4 g · thumb_cmc"] --> T2["part_6
2.4 g · thumb_mp"] --> T3["part_7
2.5 g · thumb_ip"] P --> H["servo_horn … servo_horn_5
0.3 g each"] Body names are CAD part names, not finger names. Repeated instances get _2, _3, … appended, so the pinky chain is part_2 → part_3 → part_4 and the index chain is part_2_4 → part_3_4 → part_4_4. Address joints, sites, tendons and actuators in code — never bodies. Joints and their signs # Joint Range (rad) Bend direction index_mcp, index_pip, index_dip [−1.571, 0] negative middle_mcp [−1.571, 0] negative middle_pip, middle_dip [0, +1.571] positive ring_mcp, ring_dip [−1.571, 0] negative ring_pip [0, +1.571] positive pinky_mcp, pinky_dip [−1.571, 0] negative pinky_pip [0, +1.571] positive thumb_cmc, thumb_mp, thumb_ip [−1.571, 0] negative servo_* × 5 unlimited — Bend direction is inconsistent, because each Onshape mate’s axis was exported as-is. Anything that reads joint angles must normalize per joint: