avg_angle = np.mean(angles) looks like noise filtering. It isn’t. It is a mechanical decision: a
human finger has three joints you can move separately, and this robot finger has one string.
Not smoothing — compression #
“Averaging” in a sensor pipeline usually means averaging over time to reduce noise. Nothing here keeps history between frames. The mean is taken across space — over the three joints of one finger in a single frame — to solve a problem called underactuation.
The 3-to-1 problem #
| Human finger | Robot finger | |
|---|---|---|
| Joints | 3 (MCP, PIP, DIP) | 3 hinges (*_mcp, *_pip, *_dip) |
| Independent actuators | many muscles; joints move semi-independently | 1 flexor tendon, 1 motor |
| Degrees of freedom you can command | ~3 | 1 |
A system with fewer actuators than joints is underactuated. A single tendon threads all three joints of each robot finger, so the only command is “pull this string with force F” — and the joints share that pull according to routing geometry and dynamics.

So the vision layer must compress three human measurements into one robot command.
Why the mean and not one joint #
Use only the base (MCP) knuckle and two poses break apart:
- Right angle — bent at the base, fingers straight: MCP ≈ 90°, the twin closes. ✔
- Claw — base straight, tips curled: MCP ≈ 180°, the twin stays flat while the finger is visibly curled. ✘
With the mean of all three, using the finger window 3.10 → 1.60 rad from Part 7:
| Human pose | MCP | PIP | DIP | Mean \(\bar\theta\) | Flexion |
|---|---|---|---|---|---|
| Open hand | 3.10 | 3.10 | 3.10 | 3.10 | 0.00 |
| Claw (tips only) | 3.10 | 2.20 | 2.20 | 2.50 | 0.40 |
| Right angle (base only) | 1.60 | 3.10 | 3.10 | 2.60 | 0.33 |
| Full fist | 1.60 | 1.60 | 1.60 | 1.60 | 1.00 |
Any curl anywhere on the finger lowers the mean, so the twin responds to every way a person closes a finger — and a tight fist gives the strongest pull.
What the mean throws away #
Averaging is lossy on purpose:
- Pose shape. “Claw” and “right angle” land close together. With one tendon the robot couldn’t reproduce the difference anyway, so nothing that matters is lost.
- Weighting is a choice. In a human grasp the MCP does most of the closing; a weighted mean such as \(0.5\,\theta_\text{MCP} + 0.3\,\theta_\text{PIP} + 0.2\,\theta_\text{DIP}\) is a valid refinement, but the weights would need tuning against the robot’s real joint coupling.
- How the robot splits the pull isn’t decided here. That depends on moment arms and joint dynamics. In this model it comes out almost identical across the three index joints — Part 11.

With more tendons #
A future hardware revision with two tendons per finger — one for MCP, one shared by PIP and DIP — makes the compression 3 → 2: average PIP and DIP (which are anatomically coupled in humans too) and send MCP on its own. The flexion topic just grows from five numbers to ten.