Retargeting User Guide

Tuning Guide

Retargeting parameter config files live under example/config/pick the file that matches your hand model:

HandLeftRight
Wuji Hand (default)adaptive_analytical_wuji_glove_left.yamladaptive_analytical_wuji_glove_right.yaml
Wuji Hand 2adaptive_analytical_wuji_glove_wh120_left.yamladaptive_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.yaml

When 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:

  1. Start tuning_tool.py.
  2. Open the YAML that matches the launch command: the default Wuji Hand uses adaptive_analytical_wuji_glove_<hand>.yaml, Wuji Hand 2 uses adaptive_analytical_wuji_glove_wh120_<hand>.yaml.
  3. Edit parameters under retarget and save.
  4. The tool hot-reloads the config. Watch the three-layer skeleton change.
  5. If the result improves, keep adjusting in small steps. If it gets worse, revert the last change.

Color legend:

ColorMeaningWhat to look for
OrangeRaw 21-point inputWhether the glove input pose looks correct
CyanTarget after scaling the orange line by the parametersWhether the target is reasonable after segment_scaling tuning
WhiteWuji Hand skeletonWhether 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]
ParameterMeaningDefaultLower / Raise
segment_scalingScales 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 scaling field that is not geometric. It belongs to pinch tuning (see below) and normally stays at 1.0.

Parameter groups

Parameters under retarget fall into five groups:

  • Joint weights: w_pos / w_dir / w_full_hand control the algorithm's preference for fingertip position, fingertip direction, and full-finger pose respectively. w_pos / w_dir mainly affect fingertip accuracy during pinch, while w_full_hand mainly affects open-hand pose.
  • Huber thresholds: huber_delta / huber_delta_dir control 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_pip trades some thumb-joint fidelity for more natural overall mapping. w_hyper / soft_min reduce hyperextension. w_couple / couple_ratio softly couple DIP flexion to PIP at a human-like ratio.
  • Smoothing: lp_alpha / norm_delta suppress output jitter. The former acts on the output layer, while the latter acts inside the optimization objective.
  • Mode / pinch tuning: pinch_thresholds / scaling / mediapipe_rotation cover 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

ParameterMeaningWuji Glove defaultLower ↓ / Raise ↑
segment_scalingScales 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_posFingertip position loss weight, wrist→tip vector error1.0↓ tolerate fingertip drift / ↑ more accurate fingertip position
w_dirFingertip direction loss weight, DIP→TIP direction error2.0↓ looser direction / ↑ more precise direction
w_full_handFull-finger pose loss weight over wrist→PIP/DIP/TIP vectors1.0↓ freer middle joints / ↑ closer to input pose
huber_deltaPosition-error Huber threshold, cm2.0↓ more tolerant of large deviations / ↑ more sensitive
huber_delta_dirDirection-error Huber threshold0.5↓ more tolerant on direction / ↑ more sensitive
thumb_skip_pipWhether to drop thumb MCP kp[2] from the FullHandVec losstrueKeep true to tolerate inaccurate SDK thumb MCP
w_hyperHyperextension penalty strength, active when PIP/DIP is below soft_min1.0↓ allow more hyperextension / ↑ enforce no hyperextension
soft_minSoft-limit minimum joint angle, rad0.0Rarely changed. 0.0 means no negative angles
w_coupleStrength of pulling DIP toward couple_ratio × PIP0.1↓ DIP and PIP more independent / ↑ DIP follows PIP more tightly
couple_ratioDIP flexion ratio relative to PIP0.7↓ DIP flexes less / ↑ DIP flexes more
lp_alphaLow-pass filter coefficient on output joint angles0.2↓ smoother but more lag / ↑ snappier but more jitter
norm_deltaInter-frame joint-velocity regularizer weight, soft rate limit0.04↓ snappier but may jitter / ↑ smoother but more conservative
pinch_thresholds.d1/d2Two-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
scalingScales 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_rotationGlobal rotation tweak on the input 21 points, degreesWuji 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 yamlUsed to correct glove coordinate orientation, small adjustments only
wrist_offset_cm / thumb_offset_cmwrist_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
  1. Start tuning_tool.py and focus on how the cyan target lines up against the white Wuji Hand skeleton.
  2. Tune segment_scaling first: fix one finger at a time when it looks too long or too short.
  3. If output jitters, tune lp_alpha / norm_delta. Lower lp_alpha is steadier, higher norm_delta is more conservative.
  4. If pinch triggers too easily or not at all, tune pinch_thresholds.d1/d2. Larger d1/d2 enters pinch sooner and prefers fingertip pinch. Smaller values enter pinch later and prefer the full-hand pose.
  5. w_pos / w_dir / w_full_hand / w_hyper / w_couple / couple_ratio are algorithm-preference weights. Avoid changing them first unless geometric scale and smoothing are already correct. Remember that w_pos / w_dir mainly affect fingertip accuracy in pinch and w_full_hand mainly affects open-hand pose.