Skip to main content

Overview

How far off are the joint angles the built-in generic model computes for your hand? Swapping models measures up to 58° of difference. Hand model calibration closes that gap: wear the glove through six guided poses and the SDK generates a URDF that matches your hand. Calibration output is scoped by SDK user and hand side, not bound to a particular glove. Switch to another glove of the same side under the same user and it loads the same model, with no need to recalibrate. Matching examples: examples/python/wuji_glove/5.calibration.py and examples/c/wuji_glove/4_user_calibration.c. For when to calibrate, where output is stored, and version requirements, see Calibration and Configuration. This page covers only how to run it and what the measurements show.
On hardware, a person wearing the glove completed the first four pinch poses, and the fifth pose four_finger_bend_90 timed out, so no final URDF was produced. The user gate, the six-pose list with each constraint threshold, the feedback structure, the state machine, both timeout error codes, and the real behavior of skip_constraints are all measured. The result structure after a successful calibration is described from the API contract.

Prerequisites

Hardware

Calibration reads sensors and writes an SDK-side model file. It writes no firmware.

Software

Before You Start

Switch to a named SDK user. The default user can’t calibrate, as the next section shows. Confirm with --dry-run first:
Output:
--dry-run neither connects nor calibrates. It exists to confirm the user.

The Default User Can’t Calibrate

Running --dry-run under the default user, the example warns before any error appears:
Run it for real and the SDK raises with an error code:
Remember 0x4108, which means this and only this.

Data Flow

Six Guided Poses

step_total measures 6, in a fixed order: A person wearing the glove reached step 4/6, passing all four pinch poses. Between poses you have to actually move your hand, because the state machine advances on detected motion. See waiting_movement below.

Two Kinds of Criteria

The four pinch poses check exactly one metric: the distance between the thumb tip and the matching fingertip, capped at 0.05 m. It’s intuitive, and pinching passes. The last two poses switch to three-axis orientation constraints on the four fingers, where roll, pitch, and yaw must all fall inside their ranges: The constraints apply to the four fingers and exclude the thumb, so thumb placement doesn’t matter. Step five is the practical sticking point. A person wearing the glove burned the full 120 seconds there, receiving rotate to decrease roll 43 times, rotate to increase yaw 36 times, and rotate to decrease yaw 15 times. decrease roll means roll needs to go more negative, which means bending the fingers further. Bending to what feels like 40 or 50 degrees falls well short, since the range centers near −90°, so bend until knuckle to fingertip approaches a right angle. Clenching into a fist instead throws yaw off, so keep the four fingers side by side and bend each one without squeezing. flat_open has a much wider range and passes on a natural flat hand.
The source defines 8 poses, the other two being thumb_to_index_dip and index_to_thumb_emf. The default flow walks 6 of them, with step_total always 6.

Feedback Structure

on_feedback receives a dict. The full contents at step one:
The fields fall into three groups: Every entry in metrics carries its own label, unit, current value, allowed max, the error by which it exceeds, and a plain-language hint. Render them directly rather than writing your own copy.

The Two Criteria Are Independent

The measurements make this clear. On a glove resting on a desk, unworn: Steady isn’t correct. Capture begins only when both pass.

State Machine

Running one round with constraint checking skipped:
A person wearing the glove walked the same flow, with all four pinch poses stepping through waiting_movement → waiting_stable → collecting → done, matching the sequence above. The timing constants in this flow: waiting_movement is the gate a motionless glove never passes. After done, the state machine needs to detect real motion before it accepts that you’ve started the next pose. A resting glove sits here until it times out.

Two Separate Timeouts

The 120-second per-step limit is fixed while timeout_s sets the overall ceiling. With timeout_s at 25 seconds, the overall timeout fires first and raises WujiException. At 200 seconds, pinch_middle hits its per-step limit first and raises a WujiException carrying 0x4101. Both timeouts raise WujiException. Use the error message to distinguish an overall timeout from a per-step timeout.

Effects of skip_constraints

The name sounds harmless, and in practice it turns off pose-correctness checking entirely. A glove resting on a desk with nobody wearing it passed all three stages of the first pose under skip_constraints=True. What it captured was a completely wrong “thumb touching index” sample. That happens because variance_ok only measures steadiness, and resting is the steadiest state there is. With constraints off, nothing remains to judge whether the pose is actually correct. So:
  • Use it to debug the flow, verify an integration, or run an automated smoke test
  • Never use it to generate a hand model you intend to keep, because it quietly produces a garbage model and reports no error at all

Runtime Handling

The docstring states the cancellation difference between the two forms:
To let users interrupt at any point, use await glove.calibrate(...) rather than calibrate_blocking.

Integration Steps

Running It

--mode terminal, the default, shows a screen of pose prompts, while --mode api prints only the callback and result flow. The state flow measured unworn with constraints skipped:
Measured on a right-hand Wuji Glove under a named SDK user. The glove rested unworn, so the flow stopped at motion detection for the second pose. A successful calibration returns handedness and a calibrated_urdf path, with the model landing in ~/.wuji/sdk/models/. After a timeout exit, that directory gained no new files, so an incomplete calibration leaves nothing half-written.

Adapting It

Confirm the User Before Calibrating

Output is scoped per user, and calibrating under the wrong one overwrites someone else’s model without an error. Print one line at the top of your calibration script:

Switching Gloves Needs No Recalibration

Models are stored by user and hand side, not by serial number. Switch to another glove of the same side under the same user and it loads the same model. Switching to the other hand does need a new calibration.

Display Angles and Hints

hints gives a direction (rotate to decrease roll) without a magnitude. The person wearing the glove burned 120 seconds on step five precisely because nothing said how far off they were. Render the current value from metrics alongside its allowed range and one adjustment gets there:
For a calibration wizard, this is the single most worthwhile piece of effort.

Show Hints Directly

The hint in each metrics entry is already plain language (move the two fingertips closer), with label and unit alongside. Render them as they are instead of writing a parallel set of checks.

Verify the Result

Take a recording made before calibration, run it through the offline pipeline against both the default and the new model, and compare joint angles frame by frame to quantify what changed. See Replaying Data Offline.

Don’t Generate a Real Model With skip_constraints

Once more: a resting glove passes pose checking under that option. It suits debugging the flow and nothing else.