SDK 数据参考

手型标定

本页覆盖手型标定(IK 标定)的 SDK 接口,用 Wuji Studio 完成同类标定见 设备标定。另一类标定——触觉接触标定——训练触觉接触检测模型,仅在 Wuji Studio 中进行,与手型标定相互独立。

Wuji Glove 用 EMF 解算手部关节角度前,需要先做一次 IK 标定,生成与穿戴者手型匹配的 URDF 模型。标定产物按 SDK 用户与左右手保存,同一用户下任意同侧手套共享,更换手套无需重新标定。

何时需要标定

  • 某个 SDK 用户首次使用某一侧手套
  • 更换穿戴者,为新用户单独标定

左手套和右手套各自独立标定,互不影响。同一 SDK 用户下换用另一只同侧手套时,直接复用已有标定,无需重标。启用 SDK 用户隔离后,每位用户独立持有自己的标定 URDF,见 SDK 用户管理

SDK 用户前提

标定产物归属具名 SDK 用户。默认用户既不保存也不加载标定产物,实时 IK 始终使用内置默认模型。标定前先创建并切换到具名用户:

from wuji_sdk import SdkManager

manager = SdkManager.instance()
user = manager.create_user("alice")     # "alice" 是显示名
manager.switch_user(user["user_id"])    # 按 user_id 切换,不是显示名

在默认用户下标定或设置自定义 URDF 会报错,错误信息提示先执行 create_userswitch_user

标定流程

标定要求穿戴者按提示完成一组规定动作,SDK 采集 EMF 数据并解算出适配的 URDF。

标定开始时 SDK 自动把 EMF 降频因数临时强制为 1,采集结束恢复原值(含错误与取消路径)。预先调用 glove.emf_poses_rate_divider().set(N>1) 不会拉长标定时间。详见 输出率调节

同步阻塞调用

适合脚本与命令行工具:

from wuji_sdk import SdkManager, Handedness

manager = SdkManager.instance()
glove = manager.connect(handedness=Handedness.Left, device_name="glove")

result = glove.calibrate_blocking(timeout_s=900.0)

print("handedness:", result["handedness"])
print("calibrated urdf:", result["calibrated_urdf"])
print("poses collected:", result["poses_collected"])
print("sdk user:", result["sdk_user"]["display_name"])

calibrate_blocking() 在标定结束或超时前不返回,Ctrl+C 延迟到方法返回后才响应。

异步调用

asyncio 程序使用异步 API,支持标准 cancellation:

result = await glove.calibrate(timeout_s=900.0)

参数

参数类型默认说明
skip_constraintsboolFalse跳过稳定性和约束检查(仅调试用)
timeout_sfloat900.0整体超时(秒),必须为有限正数
on_feedbackCallableNoneNone实时反馈回调

hand_profile 参数已废弃并被忽略。标定始终按统一基准为每一侧生成单个手型模型。传入 "wujihand""wujihand2" 会触发 DeprecationWarning,传入其他值会报错。请移除这个参数。

实时反馈

通过 on_feedback 回调获取标定过程中的状态:

def on_feedback(fb):
    if fb.get("state") == "collecting":
        progress = fb.get("progress", 0.0)
        step = fb.get("step_index", 0)
        total = fb.get("step_total", 0)
        print(f"step {step}/{total}: {progress*100:.0f}%")
    for hint in fb.get("hints", []):
        print(f"hint: {hint}")

result = glove.calibrate_blocking(on_feedback=on_feedback)

fb 字典包含当前姿势序号、状态、进度、采集帧数、姿势偏差诊断指标 (metrics) 与提示文本 (hints) 等字段。

回调内抛出的异常会被 SDK 记录到日志,不会中断标定。

自定义 URDF 覆盖

glove.hand_model_path().set(path) 指定用户提供的外部 URDF 文件,是 calibration.hand_model_path 资源的规范访问器,在 URDF 查找顺序中优先级最高

# 设置自定义手部 URDF(实时 IK 最高优先级)
glove.hand_model_path().set("/path/to/custom_hand.urdf")

# 读回当前覆盖值
print(glove.hand_model_path().get())

设置路径后,在线 IK 数据流(hand_joint_angles / tip_poses / hand_skeleton)按自定义 URDF 重载。传入空路径则回退到当前用户的标定模型。仅 SDK 托管目录之外的路径算作外部覆盖,指向托管目录内的路径不生效。

自定义 URDF 覆盖仅具名 SDK 用户可用。默认用户调用 set() 会被拒绝,需先切换到具名用户,与标定产物的用户隔离一致。

URDF 查找顺序

实时 IK、tf_static 加载手部 URDF 的优先级:

  1. 外部自定义路径calibration.hand_model_path 指向 SDK 托管目录之外的文件
  2. 当前用户的标定模型:该 SDK 用户对应左右手的稳定文件 left_hand.urdf / right_hand.urdf
  3. 内置默认 URDF:按左右手返回 SDK 自带模型

默认 SDK 用户跳过第 1、2 级,始终使用内置默认模型。要使用标定产物或自定义 URDF,先切换到具名用户。

SDK 不读取任何旧格式产物——旧 profile 路径、旧版本写入的托管 hand_model_path、按序列号命名的旧标定文件运行时都不再加载,也没有自动迁移。旧数据重新标定即可。离线管线接口另支持显式传入 urdf_path,传参时优先于上述所有来源。

返回字段

calibrate() / calibrate_blocking() 返回的标定汇总:

字段类型说明
handednessstr本次标定的手别("left""right"
calibrated_urdfstr标定生成的稳定模型路径(按用户保存)
poses_collectedint采集到的姿势数
frames_per_posedict[str, int]姿势名 → 该姿势采集帧数
sdk_userdict标定当时的 SDK 用户信息(user_id / display_name / description / is_default

标定产物存储

标定生成的稳定文件按 SDK 用户与左右手命名,同一用户下所有同侧手套共享同一模型:

SDK 用户模型目录
具名用户~/.wuji/sdk/users/<user_id>/models/left_hand.urdfright_hand.urdf

唯一性由 (user_id, 左右手) 二元组保证,不再绑定设备序列号。切换 SDK 用户时,已连接设备自动重新加载该用户名下对应的模型,无需重连。写入走原子替换,标定失败不会损坏已有产物。

标定 bundle 采用新格式:手型模型提为用户级,触觉数据仍按设备序列号保存。导入旧版本 bundle 时只保留触觉数据,旧的按序列号标定一律跳过(已失效,不做迁移)。本版本导出的 bundle 需用最新 SDK 导入。

从旧版本升级

升级到本版本后,之前生成的标定 URDF 不再被加载,实时 IK 与 tf_static 回落到内置默认模型。磁盘上的旧标定文件仍保留、但运行时不再读取,需在具名 SDK 用户下重新标定一次以恢复个人标定效果。同侧更换手套无需重新标定。

  • calibration.hand_profilecalibration.hand_model_paths.*(含 hand_1 / hand_2 别名)参数已移除。对这些路径执行 SET 会报 PathNotFound,磁盘上的旧值仍可读取但运行时忽略。
  • 标定结果不再含 device_snhand_profileactive_hand_profilegenerated_hand_profilescalibrated_urdfs 字段。改用 handednesscalibrated_urdf

错误处理

场景行为
在默认 SDK 用户下标定或设置自定义 URDF报错,信息提示先 create_userswitch_user
timeout_s 非有限正数立即抛 ValueError
标定超时TimeoutError,本轮采集结果不持久化
标定中途切换 SDK 用户WujiException(错误信息含 SDK user changed during calibration),本轮采集结果丢弃,旧模型不动
URDF 写入失败WujiException自动回滚本轮新文件,旧模型保持原值
标定算法收敛失败WujiException,旧模型不动

所有失败路径都保留上一次成功的标定结果,失败的本轮不会污染已有模型,可直接重试。

资源路径速查

资源路径访问说明
calibration.hand_model_pathGET / SET用户自定义外部 URDF 覆盖(优先级最高,规范访问器 glove.hand_model_path()