> ## Documentation Index
> Fetch the complete documentation index at: https://docs.wuji.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Tuning Guide

> Fine-tune retargeting parameters

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_wuji_hand_2_left.yaml` | `adaptive_analytical_wuji_glove_wuji_hand_2_right.yaml` |

<Warning>
  Wuji Hand 2 configs are the files with `wuji_hand_2` 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`.
</Warning>

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 the output shows whether the target skeleton is reasonable and whether Wuji Hand follows the expected pose.

Launch:

```bash theme={null}
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 wuji_hand_2 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_wuji_hand_2_right.yaml
python tuning_tool.py --wuji-glove --hand left  --glove-sn <YOUR_SN> \
  --config config/adaptive_analytical_wuji_glove_wuji_hand_2_left.yaml
```

<Info>
  When tuning Wuji Hand 2, the `--config` you launch with and the yaml you edit **must be the same wuji\_hand\_2 file**, otherwise you are watching the default Wuji Hand behavior.
</Info>

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

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

<Info>
  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.
</Info>

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

```yaml theme={null}
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 `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

| 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 2: left `(180, 0, -90)`, right `(0, 180, -90)` because its wrist link is oriented differently. Wuji Hand: `(0, 0, 0)` for both hands | Used to correct glove coordinate orientation. The nonzero Wuji Hand 2 defaults align the wrist frame — keep them as they are, and make only small adjustments if you tune at all |
| `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

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.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.