Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
12 KiB
L20 左手专家轨迹 HDF5 交付要求
接口版本:l20_tracking_v1
交付对象:视频重定向/示教数据同事
当前用途:浮动腕部与全部手指参考关节的轨迹回放,后续用于学习策略。
本文是可独立分享的数据交付说明,与当前仓库校验器一致。它不是通用 HDF5 标准,也不是完整 DexSchema。 请先交付 1 条短样例,确认坐标、尺度、关节映射后再批量导出。
1. 要交什么
交付重定向后的 L20 左手机器人参考状态轨迹:
- 腕部/手根的三维位置与姿态。
- 约定模型的全部手指关节角,包括从动关节。
- 同步时间戳与逐帧有效标记。
- 模型身份、坐标变换、尺度和数据来源说明。
不是原始人手关键点、MANO 参数或电机实测指令。关节状态不能直接等同于执行器控制命令。 本阶段不要求图像、物体位姿、奖励、接触标签、速度、加速度、电流或力矩;缺少这些内容不需要补零伪造。
2. 文件结构(必填)
文件扩展名建议使用 .hdf5;HDF5 根属性通过 file.attrs 保存,不要创建名为 attrs 的 group。
demonstrations.hdf5
├── 根属性:schema_version、embodiment、hand_side、asset_sha256、root_link、
│ provenance、source_description、metric_scale_provenance、scale_to_meters
├── metadata/
│ ├── joint_names UTF-8 [J]
│ └── world_from_source float64 [4, 4]
└── episodes/
├── demo_000000/
│ ├── time float64 [T]
│ ├── wrist_position float32 [T, 3]
│ ├── wrist_quaternion float32 [T, 4]
│ ├── joint_position float32 [T, J]
│ └── valid bool [T]
└── demo_000001/
└── 同样结构,可以有不同帧数 T
- 至少一个 episode;名称必须为
demo_加六位数字,如demo_000012。 - 每条 episode 至少两帧;各字段的 T 必须相同。
- 一个文件共享模型、关节顺序及源世界标定;标定、模型或关节布局改变时另建文件。
- 当前约定资产的 J=21,不是从“L20”名称推断出的自由度。21 个状态关节不代表 21 个独立执行器。
3. 根属性
除 scale_to_meters 外,下列属性均为非空 UTF-8 字符串。
| 属性 | 内容与要求 |
|---|---|
schema_version |
固定为 l20_tracking_v1 |
embodiment |
固定为 L20 |
hand_side |
固定为 left |
asset_sha256 |
双方约定的原始模型依赖包哈希,64 位小写十六进制;见第 6 节 |
root_link |
固定为当前模型的 hand_base_link |
provenance |
实际专家重定向数据填 expert_retargeted;程序生成的测试数据填 synthetic |
source_description |
视频/轨迹标识、重定向工具及版本、世界原点与 X/Y 朝向、源坐标约定、腕点到机器人根部的映射依据、质量限制 |
metric_scale_provenance |
米制尺度如何获得,标定方法/版本或估算方法、可信程度与已知误差;不得把估算写成实测 |
scale_to_meters |
有限正浮点标量,记录已应用的源位置尺度系数;不是要求读取方再缩放 |
例:源位置以毫米表示,则 scale_to_meters=0.001;输出位置仍须已经是米。
源数据已经是米时可填 1.0,但必须有实际依据,不能仅为通过校验填写。
4. 字段与坐标语义
| 路径 | 类型 / shape | 单位及语义 |
|---|---|---|
metadata/joint_names |
HDF5 UTF-8 string [J] |
joint_position 每列对应的模型关节名称,严格使用第 5 节顺序 |
metadata/world_from_source |
float64 [4,4] |
已应用的源世界系到交付世界系刚体变换;矩阵平移部分单位 m |
episodes/.../time |
float64 [T] |
秒;每条轨迹从 0 开始,严格递增 |
episodes/.../wrist_position |
float32 [T,3] |
hand_base_link 的 link 原点在交付世界系中的 [x,y,z],单位 m |
episodes/.../wrist_quaternion |
float32 [T,4] |
[w,x,y,z];将根 link 局部向量主动旋转到交付世界系 |
episodes/.../joint_position |
float32 [T,J] |
参考关节角,单位 rad;零位和正方向与约定模型一致 |
episodes/.../valid |
bool [T] |
整帧是否有效;不是每关节标记,不使用 0/1 整数数组代替 bool |
坐标与姿态
-
交付世界系采用 右手系、Z 向上,在一个 episode 内固定,不随腕部移动。
-
根部位姿不是人手腕点、机器人质心或 USD default prim 位姿。重定向端必须先完成到
hand_base_link坐标系的映射,并说明映射依据。 -
记录的尺度和刚体变换满足:
p_world = R_world_from_source @ (scale_to_meters * p_source) + t_world_from_source此式用于源位置点;人手腕点到机器人根部的额外映射仍须由重定向端完成。 导出的
wrist_position和wrist_quaternion已经在交付世界系。 接收端不会再次应用该矩阵或尺度。 -
world_from_source最后一行为[0,0,0,1],旋转部分正交且行列式为 +1,不能混入尺度或镜像。 已统一世界系时可以使用单位矩阵,但不能用单位矩阵掩盖未知标定。 -
有效四元数必须单位化,范数容差
1e-4;相邻两帧都有效时,四元数点积必须非负。q与-q表示同一旋转,导出时应统一相邻符号;不能混用xyzw或欧拉角。 -
不要为了适配当前合成测试而把真实轨迹自动平移到
z=0.4,或把起始姿态强制设为单位四元数。 场景对齐必须有明确、可追溯的坐标约定。
5. 关节顺序与联动
当前 joint_names 必须严格等于下列列表;这是数据清单顺序,不是仿真运行时 DOF 顺序。
joint_names = [
"index_dip", "index_mcp_pitch", "index_mcp_roll", "index_pip",
"middle_dip", "middle_mcp_pitch", "middle_mcp_roll", "middle_pip",
"pinky_dip", "pinky_mcp_pitch", "pinky_mcp_roll", "pinky_pip",
"ring_dip", "ring_mcp_pitch", "ring_mcp_roll", "ring_pip",
"thumb_cmc_pitch", "thumb_cmc_roll", "thumb_cmc_yaw", "thumb_ip", "thumb_mcp",
]
-
不允许重名、缺列、多列、静默重排或用其他手型的关节代替。
-
每个有效帧必须满足清单
joints[].lower_rad/upper_rad,校验容差为1e-6 rad。 精确限位以随交付约定的 JSON 清单为准,避免使用文档四舍五入值作为限位。 -
当前源模型定义以下联动;数据中仍须包含这些从动关节列:
thumb_ip = 1.02 * thumb_mcp index_dip = 0.89 * index_pip middle_dip = 0.89 * middle_pip ring_dip = 0.89 * ring_pip pinky_dip = 0.89 * pinky_pip偏置均为 0 rad,有效帧等式残差绝对值不得超过
1e-3 rad。 -
联动关系和各关节限位必须同时满足;不能单独裁剪从动关节而破坏联动。
-
这些是约定模型的约束,不是已经核实的硬件电机协议。重定向映射有疑问时先确认,不要擅自独立控制从动关节。
6. 模型身份与随附清单
本仓库当前清单:
assets/robots/dex_hand/linkerhand_g20_left/tracking_manifest.json
当前原始模型依赖包 asset_sha256:
6c8f35358f481cf604ee802588017f30c1661c0f38e1187c49e5340db3830538
这是当前版本快照。请由仿真方提供同版 tracking_manifest.json 与约定模型,数据方确认使用该模型后填写哈希。
不得把上述哈希复制到实际使用了其他模型的数据中。
- 哈希不是 HDF5 文件自身哈希,不是仅入口 USD 的哈希,也不是浮动控制覆盖层的哈希。
- 它由完整解析资源包的相对路径与各文件 SHA-256 汇总生成,使用仓库工具获取,不自行猜测算法。
- 模型依赖内容或名称变化时必须重新对齐。分享本文给同事时,请同时附上同版清单,不要只发送失效的仓库相对链接。
7. 时间同步、无效帧与缺失数据
time[0]必须精确等于0.0,之后严格递增;不得有重复、倒序时间戳。- 允许非均匀采样,不强制视频帧率等于仿真控制频率。保留实际时间间隔,不通过伪造时间戳“拉齐”数据。
- 同一帧腕部、姿态和关节角必须已经同步;异步数据须由交付方先明确对齐方式。
- 任一必需部分缺失或不可信,整帧
valid=false。至少一帧有效;全部无效的 episode 会被拒绝。 - 所有数值都必须有限,包括无效帧,不能出现 NaN/Inf。 无效帧可以用明确的有限占位值,
但必须保留
valid=false,并在来源说明中解释。无效帧四元数不要求单位化。 - 必填 dataset 不能省略;禁止把缺失帧补零后标成有效,或把插值/估算值冒充测量。
- 当前重采样 CLI 只接受全有效 episode,不跨无效片段插值。建议交付方将连续有效片段显式切成 独立 episode,并为每段重新设置从 0 开始的时间;原片段来源需可追溯。
8. 导出注意事项
使用 h5py 时,字符串必须显式声明 UTF-8,数值类型按契约转换:
# 仅展示 dtype 写法;不是完整数据生成器,不包含真实轨迹。
import h5py
import numpy as np
utf8 = h5py.string_dtype(encoding="utf-8")
# metadata.create_dataset("joint_names", data=joint_names, dtype=utf8)
# group.create_dataset("time", data=np.asarray(time, dtype=np.float64))
# group.create_dataset("wrist_position", data=np.asarray(position, dtype=np.float32))
# group.create_dataset("wrist_quaternion", data=np.asarray(quaternion_wxyz, dtype=np.float32))
# group.create_dataset("joint_position", data=np.asarray(q, dtype=np.float32))
# group.create_dataset("valid", data=np.asarray(valid, dtype=np.bool_))
不要用 dtype="S" 或普通 ASCII bytes 数组写 joint_names。不要用 float64 替代契约中的 float32,
也不要用整数时间戳或整数 valid 代替约定类型。
9. 交付及验收流程
数据方交付
- 一份包含一条短轨迹的
.hdf5样例,优先选择连续、全有效、缓慢运动的片段。 - 对应模型清单/版本确认。
- 明确的标定与重定向说明;写入根属性,也可附独立说明文件。
- 可选:对应原视频片段或可视化,便于人工核对方向、尺度与动作,不是本格式必填字段。
仿真方校验
从仓库根目录运行:
export PYTHONPATH="$PWD/source/dex_workbench${PYTHONPATH:+:$PYTHONPATH}"
~/isaacsim/python.sh -m dex_workbench_tracking.cli validate /path/to/demonstrations.hdf5 \
--manifest assets/robots/dex_hand/linkerhand_g20_left/tracking_manifest.json
该校验不启动仿真。仿真方本地的 python.sh 路径不是数据文件的依赖;具备项目模块、NumPy、h5py
的普通 Python 环境也可执行同一 -m 命令。
- PASS:schema、模型身份、关节顺序、限位和已记录联动一致。
- FAIL:修正具体报错后重新交付,不绕过校验器或放宽断言。
- 不加
--manifest只检查格式,不能证明模型/关节兼容。 - 校验通过后仍需人工核对坐标和标定,再做受限动力学回放。格式通过不等于重定向正确、动力学可执行、 策略已经可训练或真机可运行。
注意: 当前诊断脚本要求腕部及全部五组联动都有足够运动,用于发现失效约束;这是诊断用例要求, 不是 HDF5 格式要求。合法的静止或局部手指轨迹不应为了满足诊断而添加伪造动作。
仿真实现与已有验证结果另见 L20_TRACKING.md。本文只约定数据交付,不要求数据方运行 Isaac Sim。