dex-retarget
Description
Hand Retargeting Optimizer Design
Objective
Design a better retargeting optimizer that maps human hand joint positions to robot hand joint angles. You should implement get_objective_function() in custom_optimizer.py, which returns a closure used by nlopt (LD_SLSQP) to solve the inverse kinematics optimization.
Background
Hand retargeting maps human hand poses to dexterous robot hand configurations. Given target 3D positions for key robot links (fingertips, finger mids), the optimizer finds joint angles that minimize position error while maintaining smoothness across frames.
The evaluation tests your optimizer on three different robot hands with varying kinematics and DOF counts:
- Allegro Hand Right (16 DOF, 4 fingers, 8 target links)
- Schunk SVH Hand Right (9 DOF, 5 fingers, 10 target links)
- LEAP Hand Right (16 DOF, 4 fingers, 8 target links)
Your implementation must generalize across all three hands without hand-specific logic.
What to Implement
Edit custom_optimizer.py to implement a high-quality objective function. You can modify:
- The
get_objective_function()method - The EDITABLE AREA above the class (for helper functions, custom losses, etc.)
The objective function closure objective(x, grad) -> float must:
- Construct the full robot joint configuration from
x(optimized joints) andfixed_qpos - Compute forward kinematics to get current link positions
- Compute a scalar loss measuring retargeting quality
- Fill
grad[:]with the analytical gradient ifgrad.size > 0(required for LD_SLSQP) - Return the scalar loss value
Available Utilities
self.robot.compute_forward_kinematics(qpos)— compute FK for full joint vectorself.robot.get_link_pose(link_index)— returns 4x4 homogeneous transformself.robot.compute_single_link_local_jacobian(qpos, link_index)— returns 6xN Jacobian (body frame)self.target_link_indices— pinocchio frame IDs for the target linksself.idx_pin2target/self.idx_pin2fixed— index mappings for optimized vs fixed jointsself.adaptor— kinematic adaptor for mimic joints (handle if not None)torch.nn.SmoothL1Loss(Huber loss) — commonly used for robust position matching
Evaluation Metrics
- MPJPE (mm): Mean per-joint position error — primary metric, lower is better
- Smoothness: Mean absolute jerk of joint trajectory — lower is better
- FPS: Optimization throughput — higher is better
The evaluation runs retargeting over a 200-frame synthetic trajectory of smooth hand motions on each of the three robot hands.
Code
1"""Custom retargeting optimizer for dex-retargeting.23This file defines CustomOptimizer — a retargeting optimizer that maps human hand4joint positions to robot dexterous hand joint angles. The key method to implement5is get_objective_function(), which returns an objective closure for nlopt.67The optimizer inherits from the Optimizer base class and follows the same pattern8as PositionOptimizer / VectorOptimizer / DexPilotOptimizer.9"""1011from typing import List1213import nlopt14import numpy as np15import torch
Additional context files (read-only):
dex-retargeting/src/dex_retargeting/optimizer.pydex-retargeting/src/dex_retargeting/robot_wrapper.pydex-retargeting/src/dex_retargeting/seq_retarget.py
Results
| Model | Type | allegro mpjpe mm ↓ | allegro smoothness ↓ | allegro fps ↑ | svh mpjpe mm ↓ | svh smoothness ↓ | svh fps ↑ | leap mpjpe mm ↓ | leap smoothness ↓ | leap fps ↑ |
|---|---|---|---|---|---|---|---|---|---|---|
| dexpilot | baseline | 4972.274 | 0.084 | 77.400 | 4058.802 | 0.057 | 111.400 | 4958.516 | 0.166 | 65.700 |
| position | baseline | 21.624 | 0.051 | 106.700 | 12.032 | 0.043 | 131.600 | 22.416 | 0.056 | 99.200 |
| vector | baseline | 4970.810 | 0.051 | 101.800 | 4061.910 | 0.043 | 159.900 | 4967.199 | 0.053 | 91.700 |