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.
Prerequisites
Hardware
Calibration reads sensors and writes an SDK-side model file. It writes no firmware.
Software
- Python
- C
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:
--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:
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:
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 underskip_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:
await glove.calibrate(...) rather than calibrate_blocking.
Integration Steps
- Python
- C
Running It
- Python
- C
--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:
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:
Show Hints Directly
Thehint 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.Related
- SDK User Management: switch to a named user, the hard requirement for calibration
- Setting a Custom Hand Model: quantified impact of swapping models on solver output
- Replaying Data Offline: compare two models over recorded data
- Tactile Calibration: the other calibration path, producing a contact model