Retargeting 使用说明

API 介绍

基础用法

from wuji_retargeting import Retargeter

# 从配置文件创建重定向器
retargeter = Retargeter.from_yaml("config/adaptive_analytical_avp.yaml", hand_side="right")

# 重定向:将 21 个关键点转换为 20 个关节角度
qpos = retargeter.retarget(raw_keypoints)  # (21, 3) -> (20,)

输入格式

输入数据为 MediaPipe 格式的手部关键点,形状为 (21, 3),包含 21 个关键点的 3D 坐标(单位:米)。无论输入源来自 Vision Pro、预录制回放、MP4 视频还是 Intel RealSense,相机或脚本最终都会统一输出为这一格式。

单位转换:输入关键点使用米制单位(MediaPipe 标准),但内部会自动转换为厘米(M_TO_CM = 100.0)。因此,配置文件中所有距离相关参数(如 huber_deltapinch_thresholds.d1/d2)应以厘米为单位填写。

关键点索引对应:

索引关键点
0手腕
1-4拇指(CMC → TIP)
5-8食指(MCP → TIP)
9-12中指(MCP → TIP)
13-16无名指(MCP → TIP)
17-20小指(MCP → TIP)

输出格式

输出为长度为 20 的关节角度数组(弧度),对应 Wuji Hand 的 20 个关节:

索引关节
0-3拇指 joint1-4
4-7食指 joint1-4
8-11中指 joint1-4
12-15无名指 joint1-4
16-19小指 joint1-4

配置文件

optimizer:
  type: "AdaptiveOptimizerAnalytical"

retarget:
  # Huber 损失阈值
  huber_delta: 2.0             # 位置 Huber 阈值(cm)
  huber_delta_dir: 0.5         # 方向 Huber 阈值

  # 损失权重
  w_pos: 1.0           # 指尖位置权重
  w_dir: 10.0          # 指尖方向权重
  w_full_hand: 1.0     # 全手权重

  # 正则化
  norm_delta: 0.04     # 速度正则化权重

  # 缩放
  scaling: 1.0         # 全局缩放

  # 每个手指的分段缩放 [PIP, DIP, TIP]
  segment_scaling:
    thumb:  [1.0, 1.0, 1.0]
    index:  [1.0, 1.03, 1.05]
    middle: [1.0, 1.0, 1.0]
    ring:   [1.0, 1.0, 1.0]
    pinky:  [1.05, 1.15, 1.15]

  # 捏合阈值(cm)
  pinch_thresholds:
    index:  { d1: 2.0, d2: 4.0 }
    middle: { d1: 2.0, d2: 4.0 }
    ring:   { d1: 2.0, d2: 4.0 }
    pinky:  { d1: 2.0, d2: 4.0 }

  # 低通滤波器(0~1,越小越平滑)
  lp_alpha: 0.2

上面的示例适用于默认的 Vision Pro 配置思路。对于视频与 RealSense 这类基于 MediaPipe 视觉输入的场景,建议使用单独的 adaptive_analytical_video.yaml

不同输入模式的配置

配置文件适用场景说明
config/adaptive_analytical_avp.yamlApple Vision Pro默认配置,针对 Vision Pro 的立体追踪数据调优
config/adaptive_analytical_video.yamlMP4 视频 / Intel RealSense针对本项目当前 RGB/MediaPipe 管线中的单目或 RGB 视觉输入调优,噪声更高,深度信息更弱
config/adaptive_analytical_wuji_glove_{left,right}.yamlWuji Glove → Wuji Hand数采手套作为输入驱动默认 Wuji Hand
config/adaptive_analytical_wuji_glove_wh120_{left,right}.yamlWuji Glove → Wuji Hand 2数采手套作为输入驱动 Wuji Hand 2,通过 optimizer.urdf_path / mjcf_path / link_naming 指向 Wuji Hand 2 模型

驱动自定义灵巧手

optimizer 块下三个键用于把同一套重定向算法指向不同手型,无需改代码:

字段作用
urdf_pathIK 用 URDF(Pinocchio 加载,不需要 mesh)
mjcf_path仿真用 MJCF(MuJoCo 加载,需要 mesh)
link_naming把算法内部的逻辑角色(palm、各指 PIP / DIP / TIP / MCP 平面参考)映射到 URDF 的实际 link 名

link_naming 支持 prefix 前缀(例如 Wuji Hand 2 左手的 l_)和 {finger} 占位符。例如 Wuji Hand 2 用解剖学命名(r_wristr_index_finger_pip 等),配置如下:

optimizer:
  link_naming:
    prefix: "r_"
    palm:    "wrist"
    fingers: [thumb, index_finger, middle_finger, ring_finger, pinky]
    pip:     "{finger}_middle"
    dip:     "{finger}_distal"
    tip:     "{finger}_tip"
    link1:   "{finger}_proximal_abd"

当 URDF 和 MJCF 的关节顺序不同(例如 Wuji Hand 2 在 URDF 中食指优先声明)时,输出 qpos 会按关节名自动重排到 MJCF 或设备的关节顺序,避免角度落到错误的手指上。如果配置了 optimizer.mjcf_path 但关节名对不齐,仿真与真机入口会在启动阶段直接报错而非静默错驱动。

对于 videorealsense 模式,示例脚本会默认切换到 config/adaptive_analytical_video.yaml。这套配置通常会:

  • 使用更强的平滑与正则项,抑制视觉输入抖动
  • 调整 segment_scaling,补偿单目关键点的指段比例偏差
  • 放宽 pinch_thresholds,提升噪声场景下的稳定性
  • 增加 mediapipe_rotation,补偿视觉输入的系统性姿态偏差

video_input 参数

adaptive_analytical_video.yaml 还包含 video_input 配置段,用于视频和 RealSense 输入预处理:

参数说明
z_scale放大 MediaPipe 单目深度变化,缓解深度压缩问题
correct_segments是否按经验手型比例修正手指各段长度
reference_wrist_to_mid_mcp用于整体缩放的参考长度(手腕到中指 MCP 距离)

参数说明

参数默认值说明
huber_delta2.0位置 Huber 阈值(cm)
huber_delta_dir0.5方向 Huber 阈值
w_pos1.0指尖位置损失权重
w_dir10.0指尖方向损失权重
w_full_hand1.0全手损失权重
norm_delta0.04速度正则化权重
scaling1.0全局缩放系数
segment_scaling-每个手指的分段缩放
pinch_thresholds-捏合距离阈值(cm)
lp_alpha0.2低通滤波器系数

默认配置针对 Apple Vision Pro 调优。对于 MP4 视频和 Intel RealSense,建议优先使用 adaptive_analytical_video.yaml,并根据手型与画面条件进一步调整 scalingsegment_scalingvideo_input 相关参数。

手型适配

如果重定向效果不佳,可以调整以下参数:

全局缩放:调整 scaling 参数匹配手掌大小

scaling: 1.1  # 手掌较大时增大
scaling: 0.9  # 手掌较小时减小

手指长度:通过 segment_scaling 调整各手指各段的长度比例

segment_scaling:
  index: [1.0, 1.05, 1.1]  # 食指各段缩放:[PIP, DIP, TIP]