THENAR-6
A six-axis arm with a parallel-jaw gripper. There is no CAD file — the geometry is generated by a 21-part Python kernel using numpy alone, with no CSG booleans, and every part is validated as a closed surface before it is exported. Change a constant, rerun the script, and the arm, this page, and the solver all move together.
Tasks can also ask for a second arm: the SO-101 · MG996R →
| Link | Constant | Value | Spans |
|---|---|---|---|
| Plinth | PLINTH_H | 12.0mm | granite pad the base bolts to |
| Pedestal | BASE_H | 70.0mm | tapered column to the yaw axis |
| Shoulder | SHOULDER_H | 96.0mm | J1 to the pitch axis |
| Upper arm | L1 | 210.0mm | J2 to J3 |
| Forearm | L2 | 182.0mm | J3 to J4 |
| Wrist | WRIST_H | 58.0mm | J4 to J5 |
| Yoke | YOKE_H | 52.0mm | J5 to J6 |
| Tool flange | FLANGE_H | 10.0mm | mounting face |
- J1_yawaxis Zbase rotation→ J2_pitch
- J2_pitchaxis Yshoulder→ J3_pitch
- J3_pitchaxis Yelbow→ J4_roll
- J4_rollaxis Zforearm roll→ J5_pitch
- J5_pitchaxis Ywrist→ J6_roll
- J6_rollaxis Ztool rolltool flange
The GLB ships as a named node hierarchy rather than one welded mesh, which is what lets the station drive each joint straight from the inverse kinematics solver instead of playing a baked animation.
Per-part validation
- plinth384closed
- pedestal768closed
- collar_j1640closed
- barrel_j1512closed
- shoulder144closed
- collar_j2640closed
- upper_arm144closed
- collar_j3640closed
- barrel_j3512closed
- forearm144closed
- collar_j4640closed
- wrist_housing384closed
- collar_j5640closed
- wrist_yoke144closed
- flange384closed
- collar_j6640closed
- gripper_body144closed
- finger_left144closed
- pad_left144closed
- finger_right144closed
- pad_right144closed
- shell#DFE0DE · m0.04 r0.48
- joint#151515 · m0.4 r0.42
- collar#2B50DF · m0.7 r0.34
- pad#0E0E0E · m0 r0.9
- granite#1C1C1C · m0.08 r0.76
Regenerate everything on this page with python3 cad/arm.py. It writes the GLB the viewport loads, one STL per printable part, and the JSON this page reads.
Monad carries the P-256 precompile at 0x0100, so a signature from the curve a passkey uses can be checked on chain directly. The registry binds one to an address, and a run can be authorised with it. Register a passkey →
Not a chatbot. Every answer below is read from the constant the scorer actually uses and says where it came from, and a question it cannot answer exactly is refused rather than approximated — which is the whole reason the list is short.
An arm moving in a browser invites a few assumptions. These are the ones that are wrong, stated here rather than left to be discovered. They are roadmap, and nothing in the interface presents them as working.
- Kinematic, not rigid-body physicsThe station solves inverse kinematics and grasps analytically. There is no contact simulation, no friction, and no way for the payload to topple something else.
- No trained policy existsNothing here autonomously attempts a task. A minted policy is a cap table over the trajectories that would train one, not a model that has been trained.
- No domain randomisationOne lighting setup, one camera, one set of dimensions per object. No IsaacSim augmentation pipeline.
- No post-training takeoverNo DAgger loop, and no mobile ego-centric capture.
The first of those is measured rather than left as a caveat. Every recorded run is handed to MuJoCo as the same release state and integrated to rest under rigid-body dynamics; the distance between where the recording put the payload and where physics would have is published on that run’s own page. It scores nothing and changes no payout — it exists so the gap is a figure rather than an assumption. See it on a run.