概述
本篇实践介绍如何通过引导姿势完成手部模型标定,生成适合操作者手型的 URDF。应用场景包括适配不同操作者的手型和建立个人手部追踪模型。 对应的 Python 示例为 5.calibration.py,C 示例为 4_user_calibration.c。 标定的适用场景、产物存储与版本要求见标定与配置,本页说明集成流程和运行时行为。前置条件
硬件
标定只读传感器、只写 SDK 侧模型文件,不写固件。
软件
- Python
- C
前序步骤
切到具名 SDK 用户。 默认用户不能标定,见下一节。用--dry-run 先确认:
--dry-run 不连设备也不标定,就为确认用户。
数据流
默认用户不能标定
在默认用户下--dry-run,示例会在报错之前先给出引导:
六个引导姿势
step_total 实测为 6,顺序固定:
真人佩戴实测跑到
step 4/6,前四个捏合姿势全部通过。
每个姿势之间要真的把手动过去,状态机靠检测运动来切步,见下文 waiting_movement。
判据分两类
前四个捏合姿势只看一个指标:拇指与对应手指的指尖距离,上限 0.05 m。做起来直观,捏上就过。 后两个姿势换成四根手指朝向的三轴角约束,roll、pitch、yaw 都要落进区间:
约束作用在四指上(不含拇指),所以拇指位置不受此约束。
第五步是整个流程的实际难点。 真人实测在这一步耗尽了 120 秒,收到的提示统计:
rotate to decrease roll 43 次、rotate to increase yaw 36 次、rotate to decrease yaw 15 次。
decrease roll 的意思是 roll 要更负,也就是手指要弯得更深。凭感觉弯到四五十度远远不够,区间中心在 −90° 附近,得弯到指根到指尖接近直角。握紧成拳又会让 yaw 跑偏,四指要并排、各自弯曲,不要攥。
flat_open 的区间宽得多,自然摊平就能过。
源码里定义了 8 个姿势,另两个是
thumb_to_index_dip 与 index_to_thumb_emf。默认流程实测只走其中 6 个,step_total 恒为 6。反馈结构实测
on_feedback 回调收到的是一个 dict。实测第一步的完整内容:
metrics 里每条都自带 label、unit、当前 value、允许上限 max、超出量 error 和一句人话 hint。直接拿去渲染 UI,不用自己写文案。
两条判据是独立的
这一点从实测数据看得很清楚。手套静置在桌上、无人佩戴时:
稳不等于对。 两条都满足才会进入采集。
状态机实测
跳过约束检查跑一轮,捕获到的状态转移:
真人佩戴跑同一条流程,四个捏合姿势依次走完
waiting_movement → waiting_stable → collecting → done,与上面的转移序列一致。
流程里的几个时间常量:
waiting_movement 是卡住不动的手套过不去的那一关。上一步 done 之后,状态机检测到真实运动后,才认为下一个姿势开始。静置手套永远停在这里,直到超时。
两条超时是分开的
单步的 120 秒是固定的,
timeout_s 调的是整体上限。实测把 timeout_s 设成 25 秒时,先撞上的是整体超时,抛 WujiException。设成 200 秒时,先撞上的是 pinch_middle 的单步 120 秒,抛带 0x4101 的 WujiException。
两种超时均抛出 WujiException,通过错误消息区分整体超时与单步超时。
skip_constraints 的影响
这个选项名字看着无害,实测下来它把姿势正确性检查整个关掉了。 静置在桌上、无人佩戴的手套,在skip_constraints=True 下顺利通过了第一个姿势的全部三个阶段。 采集到的是一份完全错误的「拇指碰食指」数据。
因为 variance_ok 只管稳不稳,静置最稳。约束一关,就没有任何东西能判断这个姿势是不是真的摆对了。
所以:
- 调试流程、验证接入、跑自动化冒烟测试时可以用
- 生成真正要用的手模时绝对不要用,它会安静地产出一份垃圾模型,而且不报任何错
集成步骤
完整示例:Python 手部模型标定 和 C 手部模型标定。 以下为接入片段。Python 导入与 manager 初始化、C 初始化与连接错误分支、回调定义均沿用 Python 示例 和 C 示例。C 每次调用应检查返回状态,失败时按 Python 示例 和 C 示例 释放已有资源并退出。1. 确认具名用户
标定使用当前 SDK 用户。默认用户会被拒绝,先切换到具名用户。- Python
- C
2. 连接并启动标定
连接目标序列号后,选择可取消的异步 API。正式标定保持skip_constraints=False,为 Ctrl+C 注册取消处理。
- Python
- C
3. 读取结果并释放资源
将上一步的 Python 标定调用包在try/finally 中,取消或异常时也断开设备。C 辅助函数先释放标定会话,成功后读取并释放结果,所有退出分支都清理设备。
- Python
- C
运行与输出
- Python
- C
--mode terminal(默认)会给一屏姿势提示,--mode api 只打印回调和结果流。
实测无人佩戴、跳过约束时的状态流:
handedness 与 calibrated_urdf 路径,模型落到 ~/.wuji/sdk/models/ 下。实测标定超时退出后该目录没有新增文件,未完成的标定不会留下半成品。
注意事项
阻塞式与异步式的取消语义差别写在文档字符串里:
await glove.calibrate(...),别用 calibrate_blocking。
扩展用法
标定之前确认是哪个用户
产物按 SDK 用户进行管理,选错用户会覆盖对应用户的模型,而且不会报错。标定脚本开头打一行:换手套不用重标
模型按用户加手别存,不绑定序列号。同一用户换一只同侧手套,加载的还是这份模型。换到另一只手则要重标。把角度数值显示出来,别只显示 hints
hints 只有方向(rotate to decrease roll),没有量。真人实测卡在第五步 120 秒,就是因为不知道还差多少。把 metrics 里的当前值和允许区间一起渲染出来,调整一次就能到位:
把 hints 直接给用户看
metrics 里的 hint 是现成的人话(比如 move the two fingertips closer),label 和 unit 也齐了。做 UI 时照着渲染就行,别自己另写一套判断逻辑。
标定完验证效果
拿标定前录的一段数据,用离线管线分别跑默认手模和新手模,逐帧比关节角,就能量化标定带来的变化。方法见离线数据处理。别用 skip_constraints 生成正式手模
再说一遍:静置的手套在这个选项下能通过姿势检查。它只适合调试流程。相关内容
- SDK 本地用户管理:切到具名用户,这是标定的前置条件
- 设置自定义手部模型:换手模对求解结果影响的量化数据
- 离线数据处理:用录好的数据对比两套手模
- 触觉标定:另一条标定链路,产出接触模型