Try it yourself!

The hand starts off with zero pre-training, kinematic/contact model, nor precollected demonstrations. After a short sequence of movements to learn its grip, it can write anything you tell it to!

Simulation preview of the Shadow Hand holding a pen

Runs in your browser · downloads about 14 MB when opened

Validated on three different hands

Physical ORCA hand: Uncut video of full writing sequence

At the start of the video, the robot has no structural knowledge of itself or the object it holds. It learns how its finger movements affect the pen through a short initialization sequence, then continues adapting as it writes.

Same control method, applied to 2 more hands in simulation

Shadow Hand (4x video)
Wuji Hand (4x video)

The simulation environment which implements the proposed controller is available on GitHub. The main code (sim.py) contains all code for the Shadow Hand demo and is kept deliberately minimal (< 400 loc), both as a demonstration of the controller's simplicity and to improve readability and extensibility. Performance was better on the Shadow Hand, which includes the wrist as part of its degrees of freedom.

System architecture

A webcam tracks the pen tip by extrapolating its position from an ArUco marker attached to the pen. After an initial excitation phase in which the hand is moved through a series of predefined grips, the controller continually updates the task Jacobian estimate and converts the desired pen motion into finger commands, while stabilizing the grip.

System architecture: a webcam feeds ArUco detection and a Kalman filter. The estimated pen-tip motion and previous joint commands update the Jacobian. Its damped pseudoinverse and approximate nullspace drive trajectory following and grip stabilization on the ORCA hand, after an initial excitation phase.
System Architecture: A perceive-estimate-act loop tracks the pen tip, updates the task Jacobian J online, inverts it and computes its nullspace. These define the desired motor commands, which are then sent to the ORCA hand. A separate controller initially moves the fingers in a predetermined trajectory to bootstrap the Jacobian estimation.

Learning the Jacobian online

The task Jacobian J maps finger-joint velocities to pen-tip velocity:

x˙ =J q˙ \dot{\mathbf{x}} = J\dot{\mathbf{q}}

We learn this map directly from motion. The estimator uses the previous commanded joint increment divided by the elapsed time as its joint-velocity input, together with the observed pen-tip velocity. A recursive least-squares update continuously updates the estimate of J using the prediction error:

p←pλ J←J+ (x˙ −Jq˙) (p⊙q˙) ⊤ p⊤ (q˙ ⊙q˙)+r \begin{gathered}\mathbf{p}\leftarrow\mathbf{p}/\lambda\\J\leftarrow J+\frac{(\dot{\mathbf{x}}-J\dot{\mathbf{q}})(\mathbf{p}\odot\dot{\mathbf{q}})^\top}{\mathbf{p}^\top(\dot{\mathbf{q}}\odot\dot{\mathbf{q}})+r}\end{gathered}

Here p stores the diagonal covariance, λ is the forgetting factor, r is the observation-noise variance, and ⊙ denotes element-wise multiplication.

Following the path while maintaining the grip

The estimated Jacobian is then used in a kinematic pen tip tracking controller. A PID controller with path-velocity feedforward produces the desired pen velocity vcmd. We convert it to finger motion with a damped pseudoinverse of the Jacobian J+, and also use its nullspace N⊥ to pull the joints toward the initial hand pose to stabilize the grip:

J+=J⊤ (JJ⊤+εI) −1 N⊥=I −J+J \begin{gathered}J^+=J^\top(JJ^\top+\varepsilon I)^{-1}\\N_\perp=I_N-J^+J\end{gathered}
Δq=( J+vcmd +kpbN⊥ (q0−q) )Δt \Delta\mathbf{q}=\bigl(J^+\mathbf{v}_{\mathrm{cmd}}+k_{\mathrm{pb}}N_\perp(\mathbf{q}_0-\mathbf{q})\bigr)\Delta t

The first term follows the writing trajectory, while the second stabilizes the grip while minimizing interference with the pen motion. Here ε sets the damping, kpb sets the grip pullback strength, and q0 is the initial joint pose.

The whole controller, including the vision system, is lightweight enough to run on a laptop CPU.