原始数据转换
Wuji SDK 的原始数据转换让你在采集时只保存轻量的原始数据,事后再把它们复算成完整的后处理产物——指尖位姿、关节角度、手骨架、IMU 融合姿态。离线复算结果与在线实时计算完全一致。
何时使用
实时逆向运动学解算对 CPU 消耗较高。如果采集时只想录数据、之后再分析,全程跑解算是浪费。原始数据转换适合:
- 采集时只订阅轻量的
emf_poses和原始 IMU,降低 CPU 占用 - 事后再决定需要哪些后处理产物
- 用任意自选格式保存原始数据,不绑定特定文件格式
工作流
- 在线采集:只订阅
emf_poses和原始 IMU 数据 - 保存:用任意格式保存原始数据帧
- 离线复算:用
WujiGlove.offline_pipeline()把保存的帧复算成后处理产物
离线复算与在线实时计算结果一致:相同的输入加相同的标定,得到相同的输出。
创建离线 pipeline
WujiGlove.offline_pipeline() 创建一条不依赖真实设备连接的 pipeline。
from wuji_sdk import WujiGlove
pipeline = WujiGlove.offline_pipeline(
sn="WujiGlove-12345", # 必填,按序列号加载该设备的标定
hand_side="right", # 必填,"left" 或 "right"
urdf_path=None, # 可选,指定标定手部模型文件
)| 参数 | 说明 |
|---|---|
sn | 设备序列号,用于加载对应设备的标定模型 |
hand_side | 手别,"left" 或 "right";非法值抛 ValueError |
urdf_path | 可选,显式指定 URDF 手部模型路径 |
pipeline 创建后可查询实际使用的标定来源:
print(pipeline.sn) # "WujiGlove-12345"
print(pipeline.hand_side) # "right"
print(pipeline.urdf_source) # "override" | "calibration_file" | "builtin_default"
print(pipeline.urdf_source_path) # 实际 URDF 路径,或 None标定查找顺序
手部产物依赖标定的手部模型。pipeline 按以下顺序查找 URDF:
urdf_path:显式传入则直接使用该文件- 标定文件:未传
urdf_path时,按sn在~/.wuji/sdk/params/中查找该设备的标定 - 内置默认模型:以上都没有时回退到内置默认 URDF,并打印 warning
回退到内置默认模型(urdf_source 为 builtin_default)时,手部产物可能不准确。请确认使用的是采集该数据的手套的标定模型。IMU 融合产物不依赖 URDF,不受影响。
复算手部产物
手部链以 emf_poses 帧为输入,复算出三种产物。三者共享同一次解算,结果与在线一致。
for emf_poses in my_recording_reader(): # 自定义读取器,逐帧返回 EmfPoseArray
angles = pipeline.hand_joint_angles().compute(emf_poses)
tips = pipeline.tip_poses().compute(emf_poses)
skeleton = pipeline.hand_skeleton().compute(emf_poses)
save(angles, tips, skeleton) # 自定义写入器| 资源 | 返回类型 | 内容 |
|---|---|---|
pipeline.hand_joint_angles() | HandJointAngles | 21 DoF 手部关节角 |
pipeline.tip_poses() | FingertipPoses | 5 指指尖位姿 |
pipeline.hand_skeleton() | HandSkeleton | 21 个 MediaPipe 关键点骨架 |
产物的完整字段定义见 SDK 数据参考。
复算 IMU 融合
IMU 链以原始 IMU 帧为输入,复算出融合姿态。手套手背 IMU 用 imu_data_palm()。
for raw_frame in my_imu_reader(): # 逐帧返回原始 ImuData
fused = pipeline.imu_data_palm().compute(raw_frame)
save(fused) # 自定义写入器原始 IMU 帧用 ImuData.raw() 构造,orientation_covariance[0] 自动标记为 -1(未融合)。IMU 融合产物不依赖标定 URDF。
构造输入帧
用 schema 构造器在内存中构造输入帧:
from wuji_sdk import (
EmfPose, EmfPoseArray, FrameHeader, ImuData,
Pose, Quaternion, Vector3F64,
)
emf = EmfPoseArray(
header=FrameHeader(seq=1, timestamp_us=0, frame_id="r_hand_emf_tx"),
poses=[
EmfPose(
pose=Pose(position=[0.05, 0.0, 0.0],
orientation=Quaternion(0.0, 0.0, 0.0, 1.0)),
confidence=1.0,
)
for _ in range(5)
],
)
raw_imu = ImuData.raw(
header=FrameHeader(seq=1, timestamp_us=0, frame_id="imu_raw/palm"),
angular_velocity=Vector3F64(0.0, 0.0, 0.0),
linear_acceleration=Vector3F64(0.0, 0.0, 9.8),
)完整可运行示例见 SDK 安装包中的 examples/3.offline_pipeline.py。