Tuning Guide
Retargeting parameter config files live under example/config/ — pick the file that matches your hand model:
| Hand | Left | Right |
|---|---|---|
| Wuji Hand (default) | adaptive_analytical_wuji_glove_left.yaml | adaptive_analytical_wuji_glove_right.yaml |
| Wuji Hand 2 | adaptive_analytical_wuji_glove_wh120_left.yaml | adaptive_analytical_wuji_glove_wh120_right.yaml |
Wuji Hand 2 configs are the files with wh120 in the name. They point the optimizer at the Wuji Hand 2 model through optimizer.urdf_path / mjcf_path / link_naming. Editing the wrong file (for example, tuning Wuji Hand 2 by editing the default Wuji Hand yaml) has no effect. The tuning_tool.py launch below must also pass the matching --config.
All tunable parameters sit under the retarget block in the YAML. For any change, start tuning_tool.py first, then edit the YAML, save, and confirm the result visually. Tune the geometric correction segment_scaling first.
Start and use tuning_tool
tuning_tool.py is the main observation tool during tuning. It shows hand motion captured by the data glove alongside Wuji Hand motion and the mapping between them, so you can see whether the target skeleton is reasonable and whether Wuji Hand follows the expected pose.
Launch:
cd example
# Replace <YOUR_SN> in all commands below with your glove serial number before running
# === Wuji Hand (default) ===
# Without --config, --wuji-glove loads config/adaptive_analytical_wuji_glove_<hand>.yaml
python tuning_tool.py --wuji-glove --hand right --glove-sn <YOUR_SN>
python tuning_tool.py --wuji-glove --hand left --glove-sn <YOUR_SN>
# === Wuji Hand 2 ===
# Pass --config explicitly to the wh120 file, otherwise it falls back to the default Wuji Hand config
python tuning_tool.py --wuji-glove --hand right --glove-sn <YOUR_SN> \
--config config/adaptive_analytical_wuji_glove_wh120_right.yaml
python tuning_tool.py --wuji-glove --hand left --glove-sn <YOUR_SN> \
--config config/adaptive_analytical_wuji_glove_wh120_left.yamlWhen tuning Wuji Hand 2, the --config you launch with and the yaml you edit must be the same wh120 file, otherwise you are watching the default Wuji Hand behavior.
Workflow:
- Start
tuning_tool.py. - Open the YAML that matches the launch command: the default Wuji Hand uses
adaptive_analytical_wuji_glove_<hand>.yaml, Wuji Hand 2 usesadaptive_analytical_wuji_glove_wh120_<hand>.yaml. - Edit parameters under
retargetand save. - The tool hot-reloads the config. Watch the three-layer skeleton change.
- If the result improves, keep adjusting in small steps. If it gets worse, revert the last change.
Color legend:
| Color | Meaning | What to look for |
|---|---|---|
| Orange | Raw 21-point input | Whether the glove input pose looks correct |
| Cyan | Target after scaling the orange line by the parameters | Whether the target is reasonable after segment_scaling tuning |
| White | Wuji Hand skeleton | Whether Wuji Hand follows the cyan target |
Olive (dark green) appears where orange and cyan overlap. It shows up when a finger's segment_scaling = 1.0, meaning the glove input is mapped without scaling.
Most common: segment_scaling
Geometric scaling. Adjusts target vector length per finger (wrist→PIP, wrist→DIP, wrist→TIP) to fix mismatches between a finger and the Wuji Hand skeleton. All geometric correction goes through segment_scaling.
Parameter location:
retarget:
segment_scaling:
thumb: [1.0, 1.0, 1.0]
index: [1.0, 1.0, 1.0]
middle: [1.0, 1.0, 1.0]
ring: [1.0, 1.0, 1.0]
pinky: [1.05, 1.05, 1.1]| Parameter | Meaning | Default | Lower / Raise |
|---|---|---|---|
segment_scaling | Scales each finger's wrist→PIP / wrist→DIP / wrist→TIP target vectors independently to match the user's finger proportions (also accepts a 4-element [MCP, PIP, DIP, TIP] form) | Left pinky [1.05, 1.0, 1.1], right pinky [1.05, 1.05, 1.1], others mostly 1.0 | ↓ shorter target for that finger / ↑ longer target for that finger |
Tips:
- If a finger looks too short and can't reach (cyan shorter than the white skeleton), raise its three values. If a finger overshoots or hyperextends (cyan longer than white), lower the three values.
- Save, watch whether cyan target snaps onto the white skeleton, then continue.
- The YAML also has a
scalingfield that is not geometric. It belongs to pinch tuning (see below) and normally stays at1.0.
Parameter groups
Parameters under retarget fall into five groups:
- Joint weights:
w_pos/w_dir/w_full_handcontrol the algorithm's preference for fingertip position, fingertip direction, and full-finger pose respectively.w_pos/w_dirmainly affect fingertip accuracy during pinch, whilew_full_handmainly affects open-hand pose. - Huber thresholds:
huber_delta/huber_delta_dircontrol where position error and direction error transition from quadratic to linear penalty, governing the algorithm's sensitivity to large deviations. - Soft limits / pose constraints:
thumb_skip_pip/w_hyper/soft_min/w_couple/couple_ratio.thumb_skip_piptrades some thumb-joint fidelity for more natural overall mapping.w_hyper/soft_minreduce hyperextension.w_couple/couple_ratiosoftly couple DIP flexion to PIP at a human-like ratio. - Smoothing:
lp_alpha/norm_deltasuppress output jitter. The former acts on the output layer, while the latter acts inside the optimization objective. - Mode / pinch tuning:
pinch_thresholds/scaling/mediapipe_rotationcover the pinch / open-hand mode switch threshold, the global scale of the fingertip target during pinch, and a fine rotation on the input coordinate system.
Parameter quick reference
| Parameter | Meaning | Wuji Glove default | Lower ↓ / Raise ↑ |
|---|---|---|---|
segment_scaling | Scales each finger's wrist→PIP / wrist→DIP / wrist→TIP target vectors independently (also accepts a 4-element [MCP, PIP, DIP, TIP] form) | Left pinky [1.05, 1.0, 1.1], right pinky [1.05, 1.05, 1.1], others mostly 1.0 | ↓ shorter target / ↑ longer target, tuned most often |
w_pos | Fingertip position loss weight, wrist→tip vector error | 1.0 | ↓ tolerate fingertip drift / ↑ more accurate fingertip position |
w_dir | Fingertip direction loss weight, DIP→TIP direction error | 2.0 | ↓ looser direction / ↑ more precise direction |
w_full_hand | Full-finger pose loss weight over wrist→PIP/DIP/TIP vectors | 1.0 | ↓ freer middle joints / ↑ closer to input pose |
huber_delta | Position-error Huber threshold, cm | 2.0 | ↓ more tolerant of large deviations / ↑ more sensitive |
huber_delta_dir | Direction-error Huber threshold | 0.5 | ↓ more tolerant on direction / ↑ more sensitive |
thumb_skip_pip | Whether to drop thumb MCP kp[2] from the FullHandVec loss | true | Keep true to tolerate inaccurate SDK thumb MCP |
w_hyper | Hyperextension penalty strength, active when PIP/DIP is below soft_min | 1.0 | ↓ allow more hyperextension / ↑ enforce no hyperextension |
soft_min | Soft-limit minimum joint angle, rad | 0.0 | Rarely changed. 0.0 means no negative angles |
w_couple | Strength of pulling DIP toward couple_ratio × PIP | 0.1 | ↓ DIP and PIP more independent / ↑ DIP follows PIP more tightly |
couple_ratio | DIP flexion ratio relative to PIP | 0.7 | ↓ DIP flexes less / ↑ DIP flexes more |
lp_alpha | Low-pass filter coefficient on output joint angles | 0.2 | ↓ smoother but more lag / ↑ snappier but more jitter |
norm_delta | Inter-frame joint-velocity regularizer weight, soft rate limit | 0.04 | ↓ snappier but may jitter / ↑ smoother but more conservative |
pinch_thresholds.d1/d2 | Two-distance pinch trigger (cm) between thumb and fingertip: dist ≥ d2 → full FullHand, dist ≤ d1 → pinch weight saturates (capped at 0.7, the remaining 30% stays FullHand) | 2.0 / 4.0 | ↓ enter pinch later / ↑ enter pinch earlier |
scaling | Scales only the fingertip position target in pinch mode (does not affect FullHand loss or the cyan target display) | 1.0 | ↓ closer fingertip target in pinch / ↑ farther, usually kept at 1.0 |
mediapipe_rotation | Global rotation tweak on the input 21 points, degrees | Wuji Hand: left (5, -5, 20), right (-5, -5, -20). Wuji Hand 2 uses different defaults because its wrist link is oriented differently — see the matching wh120 yaml | Used to correct glove coordinate orientation, small adjustments only |
wrist_offset_cm / thumb_offset_cm | wrist_offset_cm: translates the 16 non-thumb keypoints uniformly. thumb_offset_cm: translates the 4 thumb keypoints uniformly. Unit cm | [0, 0, 0] | Off by default. The SDK already calibrates per SN, so customers are not advised to change these |
Recommended tuning order
- Start
tuning_tool.pyand focus on how the cyan target lines up against the white Wuji Hand skeleton. - Tune
segment_scalingfirst: fix one finger at a time when it looks too long or too short. - If output jitters, tune
lp_alpha/norm_delta. Lowerlp_alphais steadier, highernorm_deltais more conservative. - If pinch triggers too easily or not at all, tune
pinch_thresholds.d1/d2. Largerd1/d2enters pinch sooner and prefers fingertip pinch. Smaller values enter pinch later and prefer the full-hand pose. w_pos/w_dir/w_full_hand/w_hyper/w_couple/couple_ratioare algorithm-preference weights. Avoid changing them first unless geometric scale and smoothing are already correct. Remember thatw_pos/w_dirmainly affect fingertip accuracy in pinch andw_full_handmainly affects open-hand pose.