emf_poses 生成关节角、指尖位姿和骨架,以原始 IMU 帧生成融合姿态。数据录制将输入帧保存为 MCAP 文件,重放代码从该文件读取并还原帧。还原后的帧可直接传给离线解算接口,无需连接设备。
解算步骤
创建离线处理管线
创建离线处理管线时,指定采集设备的序列号与手别。序列号支持 1–64 字节的 ASCII 字母、数字、.、_ 和 -,不能仅为 . 或 ..。urdf_path 可选,用于固定手部模型,便于重复处理同一批数据。
以下示例使用右手,实际处理时替换为录制数据对应的值。
- Python
- C
hand_side 使用 "left" 或 "right",非法值抛出 WujiException。urdf_path=None 使用下方的模型查找规则。复算关节角、指尖位姿和骨架
处理录制数据时,从 MCAP 文件的/<序列号>/emf_poses 通道读取输入帧。解算接口使用的输入类型在 Python 中为 EmfPoseArray,在 C 中为 WujiEmfPoseArray。Python 的帧读取与还原方法见重放代码。
每帧包含 5 个 EMF 位姿。对同一帧依次请求关节角、指尖位姿与骨架,共享一次解算。下面的函数接收 1 帧并输出结果数量。
- Python
- C
复算 IMU 姿态
处理录制数据时,从 MCAP 文件的/<序列号>/imu_raw/palm 通道读取输入帧。解算接口使用的输入类型在 Python 中为原始 ImuData,在 C 中为原始 WujiImuData。Python 的帧读取与还原方法见重放代码。
将原始 IMU 帧传给对应的融合入口,获得姿态。6 路入口分别对应 palm、thumb、index、middle、ring 和 pinky,各自保持融合状态,均不依赖标定 URDF。Python 方法名使用 imu_data_<部位>(),C 函数名使用 wuji_glove_offline_compute_imu_data_<部位>。
- Python
- C
ImuData.raw() 将 orientation_covariance[0] 设为 -1.0,表示未融合输入。orientation_covariance[0] 为 0.0。
示例
以下程序使用合成的右手 EMF 帧和手背 IMU 样本,依次创建管线、计算手部结果与 IMU 姿态,最后释放资源。运行时无需连接设备。 真实数据可使用 Wuji Glove 录制的 MCAP 文件,文件中需包含emf_poses 和 imu_raw/palm 两条通道。按重放代码从文件还原原始帧并逐帧传入管线。序列号可从通道名核对,手别和采集时使用的 URDF 需在录制时另行记录。
- Python
- C
保存为
offline_pipeline.py,运行 python offline_pipeline.py。Fingers: 5, tips: 5, skeleton joints: 21,以及包含 4 个分量的 Orientation。姿态数值随 IMU 输入变化,手部结果数值还受手部模型影响。默认 SDK 用户使用内置模型时,日志中出现相应警告是预期行为。这一步确认解算接口可运行,真实录制数据的读取、逐帧重放和在线结果对比见 SDK 使用实践 · 离线数据处理。
注意事项
选择并核对手部模型
手部结果依赖标定模型。两种语言按相同规则选择 URDF:- 显式路径:传入
urdf_path时直接使用该文件,读取失败时报错,不回退 - 托管模型:未指定路径时,优先使用当前 SDK 用户的
calibration.hand_model_path指向的自定义文件,前提是它位于 SDK 托管目录之外。否则使用该用户对应手别的left_hand.urdf或right_hand.urdf。两者二选一,不互为回退 - 内置模型:选中的托管模型文件缺失、无法读取,或路径指向另一手别时,使用内置默认 URDF 并记录警告
urdf_source 和 urdf_source_path。序列号和手别也可从管线读回。
- Python
- C
urdf_source 为 "override"、"calibration_file" 或 "builtin_default"。内置模型的 urdf_source_path 为 None。按采集顺序处理帧
按采集顺序逐帧调用。同一管线保留解算状态,手部解算只缓存最近 1 帧。连续提交相同的手部帧不会再次求解,依次提交帧 A、帧 B、帧 A 时则会重新计算。 每个独立数据流使用独立管线,同一管线串行处理。从头重播或更换标定模型时创建新管线。 离线与在线流程复用相同解算器。对比结果时,保持输入帧、标定模型和处理顺序一致。检查错误并释放资源
- Python
- C
调用失败时抛出异常。结果对象由 Python 管理,无需手动释放。管线及其资源对象应在创建它们的线程中使用。重新处理一段录制时创建新的
pipeline。非法 hand_side 抛出 WujiException。显式 URDF 不可读或解算失败时,通过异常获取原因。