Files
dex_workbench/L20_REFERENCE_DIAGNOSTIC.md
chenlin f5d84e26f6 feat(tracking): 汇总 v0.1.3 回放与 ACT 准备进度
新增专家轨迹诊断、原视频估计相机入口和状态参考ACT数据门禁/训练链路;更新版本与进度文档。

验证:120项CPU/USD回归和4步synthetic CPU smoke通过;1333帧默认GUI历史回放PASS。原视频相机完整回放超时124,策略GPU E2E未执行,完整pre-commit工具缺失。

兼容性:HDF5、Cartpole、USD和控制阈值保持不变。本提交为实验进度快照,不宣称完整发布验收通过;数据、视频和权重不纳入。
2026-09-15 16:29:17 +08:00

315 lines
21 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# L20 专家参考轨迹:离线可执行性诊断
**最新进展(2026-09-14)**:用户另行授权的一次75倍慢放、两轮各30000步动态回放已PASS,
见第7节。第1–6节保留此前CPU审计与当时的NOT_RUN边界,不将数据真实性标为通过。
## 结论
**80 倍慢放主要由腕部平移参考速度门禁决定,而不是已证实的动力学极限。**
对当前这条轨迹,保持现有速度阈值和几何路径时,统一慢放的速度必要下界约为 **69.37266 倍**。
70/75/80 倍在 **0.8 m 对比工作半径**下通过现有 CPU `validate_reference()`;
这不是动力学通过范围,也不授权仿真或真机动作。默认工作半径仍为 0.1 m,没有修改控制参数。
本次不启动 Kit/GPU、不运行训练、不改原始/派生 HDF5、不重绑定资产。当前代码基线
`8e7ab5f`(v0.1.2)加本次诊断模块;工作区原有其他未提交修改保留。
## 1. 输入身份与质量
- 原始输入:`Data/l20_linkerbot_urdf_delivery/demonstrations.hdf5`,右手,
`expert_retargeted`,`demo_000000`,51 帧全有效,50 个源采样区间。
- 本次实际清单校验输入:历史制品目录
`expert-replay-recovery-20260914/recovered-20260914T033624Z/bound.hdf5`。
复核其历史绑定记录;原始文件与该文件的时间、腕位姿、关节、valid、关节顺序及坐标矩阵逐值相同。
80 倍派生文件全部几何样本也逐值相同,时间恰为原时间乘 80。
- 原始交付使用供应方暂定资产摘要,直接配当前清单仍 **FAIL: asset bundle hash mismatch**。
本次没有添加任何 hash override;已有绑定文件通过清单校验不等于重新检查整个 USD 或硬件身份。
- `l20_tracking_v1` schema、有限值、时间严格递增、四元数及清单限位/联动检查:**PASS**。
长度 1.666666667 s,30 Hz;dt 最小/最大 0.033333333333333215 / 0.03333333333333344 s,
没有可见重复时间或异常长采样间隔。四元数最大范数误差约 `3.47e-8`。
- 关节最小限位余量约 `-7.43e-8 rad`,在已有 `1e-6 rad` 浮点容差内;
多个参考关节触及边界,不代表有动态余量。五组联动最大参考残差约 `2.56e-8 rad`,
小于既有 `1e-3 rad` 容差;不能把这些参考等式当作本轮物理联动验收。
- 米制尺度来源明确为 **SLAM 估计**,不是测量控制网。字段正确不证明尺度、腕根转换或重定向正确;
不再次应用 `world_from_source` 或 `scale_to_meters`。
| 输入 | SHA-256 |
| --- | --- |
| 原始 HDF5 | `bd9321096803fbb64f590b4fdeb9056edc11ac446a7e16458c509beedc8b9552` |
| 历史 bound HDF5 | `ad64968150a67f504a7a2a4d18667c5e69bb2ee47f251917f8f9477bd4014c35` |
| 历史 slow80 HDF5 | `8f584c7409698394429737d509924013b8b90700117f8af2fb22465223dc1815` |
| 右手清单文件 | `52419b16d8faedc299f36711b6109b90eeb908e10e1c1b9faec3e16b9eaf37c9` |
## 2. 哪些区间超限
帧号均为 **0-based**,时间为原始秒。速度是相邻参考样本的派生量,不是传感器或仿真速度。
平移/关节使用 float64 差分;旋转使用 shortest-arc 世界旋转向量。
表中百分位按区间等权,关节列先取各区间所有 21 个状态关节的最大绝对速度。
21 个状态关节不等于 21 个独立驱动;JSON 中显式标识模型 follower。
| 量 | 中位数 | P95 | 峰值 | 现有参考上限 | 超限区间数 | 单项慢放下界 |
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
| 腕平移 m/s | 0.988018 | 2.203842 | **3.468633** | 0.05 | **50/50** | **69.372659** |
| 腕旋转 rad/s | 2.893062 | 6.756863 | **8.999576** | 0.5 | 49/50 | 17.999153 |
| 最大关节 rad/s | 1.263341 | 2.640378 | **2.935250** | 0.5 | 46/50 | 5.870501 |
优先核查的原始片段:
1. **帧 49→50,1.633333→1.666667 s**:平移峰值,约 0.11562 m / 帧。
帧 47→48、48→49 的平移速度分别为 1.967910、2.696393 m/s,末段速度连续上升。
应回看原视频/SLAM/腕根重定向;不能仅凭高速就判为离群并删除尾帧。
2. **帧 28→29,0.933333→0.966667 s**:旋转峰值 8.999576 rad/s。
3. **帧 29→30,0.966667→1.0 s**:`ring_mcp_pitch` 速度峰值 2.935250 rad/s。
4. **帧 0→1** 已有平移 1.684308 m/s、旋转 4.293173 rad/s。
当前 replay reset 清零速度;参考并非从静止平滑起步,启动瞬态需运行时验证。
整条腕路径长度约 **1.872604 m**,相对起点最大距离 **0.651218 m(帧 15)**。
帧 **2–50** 超过默认 0.1 m 半径;任何慢放都不改变这一点。
历史使用的 0.8 m 半径可包含该几何路径,但不是碰撞、可达性或硬件工作空间证明。
附加的中点差分加速度峰值:平移 33.683240 m/s²、旋转 99.073881 rad/s²、
各区间最大关节 62.699264 rad/s²。它们仅用于定位参考粗糙程度,**不是物理加速度上界**。
现有线性/SLERP 插值在节点速度可能跳变,不能据此估算真实力矩、认定饱和或保证平滑性。
独立的归一化四元数 dot/acos 算法与报告旋转速度的最大差约 `1.06e-12 rad/s`。
## 3. 慢放候选:仅 CPU 门禁结果
对原始 bound 样本在内存中使用现有 `stretch_time()`,再实际调用 `validate_reference()`;
没有生成新的慢放 HDF5。报告中的派生速度提升到 float64 计算,门禁仍使用既有实现,未改精度或容差。
| 慢放倍数 | 单轮时长 s | 平移峰值 m/s | 0.8 m 半径下参考门禁 | 本次动力学 |
| --- | ---: | ---: | --- | --- |
| 1 | 1.666667 | 3.468633 | FAIL:平移过快 | NOT_RUN |
| 60 | 100 | 0.057811 | FAIL:平移过快 | NOT_RUN |
| 69 | 115 | 0.050270 | FAIL:平移过快 | NOT_RUN |
| 70 | 116.666667 | 0.049552 | PASS | NOT_RUN |
| 75 | 125 | 0.046248 | PASS | NOT_RUN |
| 80 | 133.333333 | 0.043358 | PASS | NOT_RUN |
默认 0.1 m 半径下,这六档全部 FAIL(较慢档仍违反工作半径)。
70 倍的平移速度余量仅约 **0.90%**,75 倍约 **7.50%**,80 倍约 **13.28%**。
因此不建议先盲试 40/20 倍,也不把 69.37266 倍数学边界直接当作可执行速度。
历史 80 倍动力学 PASS 及误差见 [`L20_TRACKING.md` 第5节](L20_TRACKING.md#5-显式扩范围与完整专家参考回放)。
本次重新核对历史原始日志 SHA,但没有重跑;不能把历史 PASS 扩展到70/75倍或当前GUI入口。
## 4. 控制器归因与下一步
源码核查 `control.py` / `scripts/tracking/track_l20.py`:
- 腕 PD 为 `Kp*(p_ref-p)-Kd*v_measured`,角速度同理,**没有参考速度前馈**;
手指位置目标的 velocity target 也保持0。移动目标需要误差抵消阻尼,存在跟踪滞后机制。
忽略惯性、重力残差和耦合的恒速近似下,腕滞后时间 `Kd/Kp=0.1 s`;这只是定性诊断,
不能当作全轨迹误差预测或改变增益的依据。
- 当前目标在 step 开始时发送,step 后与下一参考点比较,另有离散采样因素。
- 20 N / 1 N·m 总 wrench 限制、0.2 N·m finger effort、0.5 rad/s finger velocity
都是未标定的仿真配置。仅凭参考数据无法知道实际执行是否饱和。
- 默认参考速度门禁、物理 drive cap、运行时速度安全断言及误差断言是不同层次;
不能拿较宽的实测速度安全界限替代较窄的参考门禁。
**建议顺序:**
1. 先请数据方核查上述关键帧、SLAM 米制尺度与腕根变换,保留原文件与版本;
当前证据不能区分真实高速动作与重建/重定向误差,不擅自平滑、裁剪、缩放或重居中。
2. 若几何确认无误且继续使用现有控制器,可另行授权一次 **75 倍、两轮各30000步、单环境、
240 Hz、工作半径0.8 m、外部上限600秒**的完整回放;保持阈值,先记录误差及饱和信息。
本轮未运行,也未增加运行时日志字段。75倍通过后才考虑70倍。
3. 若目标是接近原速,这类慢放提速收益很有限。需单独设计经确认的参考速度前馈/启动过渡
与控制带宽实验,而不是直接放宽门禁;随后再接入任务、示教基线与RL。
## 5. 复现与验证
新增入口 `source/dex_workbench/dex_workbench_tracking/diagnostic.py` 仅依赖已有 numpy/h5py,
不导入 pxr、torch、isaaclab 或 Kit。JSON 包含每关节统计、全部区间、超限位置、mimic残差、
输入/清单哈希、未标定默认参数和候选实际门禁结果。拒绝无效帧间隙、不匹配身份、覆盖输出。
`status=PASS` 仅表示报告成功生成;候选的 `reference_gate` 单独报告,`dynamic_replay=NOT_RUN`。
从仓库根目录执行,`BOUND` 必须指向已有独立核验的同清单文件;**不是原始交付的 hash 替换开关**。
`EVIDENCE` 指向已存在的仓库外制品目录,新输出路径不得已存在。
```bash
export PYTHONPATH="$PWD/source/dex_workbench${PYTHONPATH:+:$PYTHONPATH}"
MANIFEST=assets/robots/dex_hand/linkerhand_g20_right/tracking_manifest.json
~/isaacsim/python.sh -m dex_workbench_tracking.diagnostic "$BOUND" \
--manifest "$MANIFEST" --output "$EVIDENCE/default-workspace.json"
~/isaacsim/python.sh -m dex_workbench_tracking.diagnostic "$BOUND" \
--manifest "$MANIFEST" --workspace-radius 0.8 --output "$EVIDENCE/extended-workspace.json"
~/isaacsim/python.sh -m unittest discover -s source/dex_workbench/tests -p 'test_tracking_*.py' -v
~/isaacsim/python.sh -m ruff check source/dex_workbench/dex_workbench_tracking/diagnostic.py \
source/dex_workbench/tests/test_tracking_diagnostic.py
~/isaacsim/python.sh -m ruff format --check source/dex_workbench/dex_workbench_tracking/diagnostic.py \
source/dex_workbench/tests/test_tracking_diagnostic.py
git diff --check
```
实际 CPU 环境:Python 3.12.13、numpy 2.5.1、h5py 3.16.0;未安装/升级依赖。
本机制品目录(相对仓库根):`../dex_workbench-evidence/l20-reference-9Q2Cbs/`,不随源码分发。
含两份JSON、输入审计脚本/结果、测试日志及实际命令记录;干净克隆不自带 bound/右USD/专家数据。
- **PASS**:新诊断10项回归;全部tracking CPU/USD回归 **98项,无跳过**。
首次诊断测试因合成测试清单缺少右手必需身份字段失败;补全测试夹具后全量重跑。
没有放宽生产身份门禁。初次Ruff行宽失败,经格式化后复检。
- **PASS**:原始/bound/slow80身份与样本保留审计,独立旋转数值交叉核对。
- **NOT_RUN**:GPU仿真、GUI、70/75倍动力学、碰撞/接触、训练及硬件;本任务限定CPU诊断。
- 完整 pre-commit 工具不可用,不将局部Ruff与单测代替全量发布门禁。
- 新增只读诊断,不改变既有数据schema、运行控制器、资产、Cartpole任务、checkpoint或包版本。
没有提交/推送。
## 6. 继续核查:关键帧与导出链路
本节为后续 CPU 审计,不新增运行时验收。使用交付中的 `retarget/right_qpos.npz` 与
`demo_000000_triple_0_50.mp4`,没有重新拟合、修复或发布数据。
### 已排除:关节导出列错位与时间轴不一致
- NPZ 有121帧、21列,HDF5交付前51帧;两者关节列顺序不同。
**按名称显式重排**后,NPZ前51帧转为float32,与HDF5的全部关节样本逐值完全一致。
原float64到HDF5 float32的最大差仅 `5.88378966e-8 rad`。
- `ring_mcp_pitch` 的帧29→30峰值在NPZ中已经存在,约 `2.93524959 rad/s`。
因而该峰值不是本次HDF5序列化或关节列错位制造的;仍不证明重定向结果等于真实关节运动。
- HDF5时间逐值等于 `arange(51)/30`,NPZ声明fps=30。
预览按顺序解码得到51帧、30fps;帧28/29/30/49/50的媒体时间与对应HDF5时间一致。
这只核对交付内部时间索引,不能证明与原始相机/SLAM真实同步。
### 尚未闭合:相机系腕位姿到世界系的变换
NPZ声明 `view=ego_cam`,其 `wrist_pos` 不能直接与世界系HDF5位置相减后当作误差。
NPZ本身也没有显式腕位置单位字段;交付说明暗示米制,但仍应由数据方确认。
| 帧49→50 | NPZ相机系(原单位) | HDF5世界系(m) |
| --- | ---: | ---: |
| 位移范数 | 0.013635702 | 0.115621099 |
| 位移范数 / dt | 0.409071067 | 3.468632970 |
**若双方长度单位确认为米**,此差异不能由一个固定刚体坐标变换单独解释:
固定旋转/平移不会改变相邻点间距离。交付声明另外应用了逐帧SLAM相机运动,
因此需要复算的是这一步的旋转、平移、方向、帧对齐与尺度,不能认定世界系高速就是错误。
不以逆向拟合出来的相机轨迹代替缺失的独立SLAM证据。
预览关键帧0、28、29、30、47、48、49、50已实际抽帧并查看:
末段桌椅在画面中明显移动,画面模糊,手/叠加模型接近下边缘;
这与视角变化相容,但单目叠加预览没有独立米制依据,既不能证实也不能否定3.47 m/s世界速度。
帧28–30的叠加显示也不足以验证8.9996 rad/s世界系腕角速度。
另有待确认字段:NPZ的 `hand_scale` 前51帧范围为 **0.678304–0.845200**;
帧49→50从0.720546降到0.681751(约 **−5.38%**)。它的估计方法及应用位置未随NPZ提供,
**不能把它等同于HDF5的 `scale_to_meters=1.0`**,也不能据此直接重新缩放轨迹。
它可能与手模型拟合有关,是否影响腕根平移需查看上游代码,而不是从字段名推断。
### 给数据方的最小补充清单
> 请补充同一 `video_0`、至少覆盖帧0–51(包含交付末帧后的一个邻帧)的以下材料;
> 最好提供已有完整121帧,不必重新采集:
>
> 1. `hawor_slam_w_scale_0_121.npz` 或等价逐帧相机SE3,附帧ID、秒时间戳、
> 变换方向(camera→world还是world→camera)、轴向、位置单位及四元数顺序。
> 2. 同版本 `export_l20_tracking_hdf5.py` 与 `retarget_mano_to_g20_mujoco.py`,
> 或相关变换/尺度计算片段,附版本/提交及实际参数。
> 3. 明确 `right_qpos.npz` 的腕位置单位、四元数顺序、`hand_scale` 的含义、
> 每帧变化是否应用于腕根平移,以及SLAM米制尺度来自何种估计/标定。
> 4. 原始 `video_0.mp4` 的对应短片及原帧号/时间映射;说明重定向、视频、SLAM是否存在偏移或丢帧。
>
> 优先解释帧49→50的世界位移0.115621 m及帧28→29的世界旋转峰值。
> 请保留当前交付,任何修正另出版本与哈希,不原地替换样本或静默裁剪。
当前交付与本仓库 `Data/`、`scripts/` 中未找到上述SLAM文件、原始视频或两份上游脚本。
因此 **世界腕位姿导出复算为BLOCKED(缺独立输入)**,不是仿真或训练失败。
先补齐此接口,再判断是否需要修正数据或开展75倍受限回放。
### 本轮证据与边界
本机制品目录:`../dex_workbench-evidence/l20-keyframes-ANfXqd/`,不随代码提交。
包含 `audit_keyframes.py`、`keyframe-audit.json`、`audit.log`、
`keyframes-video-mano.jpg` 和完整三联帧49/50图片。
审计使用 `np.load(..., allow_pickle=False)`;OpenCV 4.13.0软件解码既有预览,不调用Kit或GPU仿真。
环境PATH无ffmpeg/ffprobe,本轮使用已有OpenCV,未安装依赖。
实际命令(仓库根;`KEYFRAME_EVIDENCE`指上述仓库外目录):
```bash
PYTHONPATH=source/dex_workbench ~/isaacsim/python.sh "$KEYFRAME_EVIDENCE/audit_keyframes.py"
git diff --check
```
- **PASS**:脚本退出0;命名关节映射/float32样本一致、时间一致、51帧预览解码断言,
对交付目录全部文件的运行前后SHA-256相等;原始数据没有改变。
- **BLOCKED**:世界系腕位姿独立复算,缺逐帧相机SE3/导出源码/尺度说明。
- **NOT_RUN**:新GPU回放、GUI、训练、硬件;本轮没有启动,也未授权扩大默认资源预算。
- 本轮仅追加本文及仓库外诊断制品;未改变应用代码、控制参数、资产、schema或包版本。
不重复把上一轮98项回归当作本轮新运行;本轮文档变更的仿真E2E为N/A。
未暂存、提交或推送。
## 7. 单次授权75倍慢放动态回放:PASS(2026-09-14)
用户明确确认GPU预算后,只执行一次:单环境、seed42、240Hz、两轮各30000步、
每轮125秒完整参考,工作半径0.8m,headless,外部timeout600秒(终止宽限15秒)。
未重试、未启动70倍或其他实验;未调增益、限速、力/力矩上限或验收断言。
### 准备与真实验收结果
- 以历史已核验的 `bound.hdf5` 为输入,使用已有 `stretch-time --factor 75` 生成仓库外新文件。
原始交付不改写、不重新绑定;原始/bound样本完全一致,slow75几何/valid/坐标元数据保持,
时间恰为原始时间乘75。派生文件通过清单及现有参考速度/工作半径检查。
- 注册现有PhysX/Newton schema后的prepared检查通过,覆盖层包SHA保持
`3e2071a60496b23bed252f4e2fc6e1d4540eecc8098578506419b5eb594f7da0`。
- 本轮新运行全部tracking CPU/USD回归:**98项PASS,无跳过**。
- GPU运行 **364秒、退出0**,日志唯一的 `bounded_experimental_dynamic_tracking` 结果为PASS;
确认HDF5哈希、全覆盖125秒、两轮各30000步、浮动根、1个有效articulation root、21个状态关节。
原入口的有限值、速度安全界限、限位、非零被动联动、reset、逐步位姿及速度重复性断言全部执行通过。
- 每轮的max/RMS汇总相同,但不承诺跨运行GPU位级确定性。下列关节/联动统计沿用运行入口语义:
每步先取各关节最大绝对误差/残差,再对时间汇总。
| 误差 | 最大值 | RMS |
| --- | ---: | ---: |
| 腕位置 m | **0.004526687** | 0.001701794 |
| 腕姿态 rad | **0.014233187** | 0.007083100 |
| 各步最大关节误差 rad | **0.011136770** | 0.007015317 |
| 各步最大mimic残差 rad | **0.000231415** | 0.000100018 |
历史80倍的最大腕位置/姿态误差分别为0.004234530m / 0.013369173rad;
本次75倍略大,但均在既有门禁内。这是两个指定轨迹速度的结果对照,不是收敛、性能或全速度区间保证。
### 执行环境、命令与证据
Isaac Sim安装版本 `6.0.1-rc.7+release.42383.32955d8d.gl`,运行时PhysX `110.1.13`;
RTX5080,驱动595.84,Python3.12.13、numpy2.5.1、h5py3.16.0。
Isaac Lab基线 `6a7acb0320a0bdc15b13e44e83b575e00797faf4`,其本机工作区有既有
`source/isaaclab/isaaclab/cloner/cloner_utils.py` 修改:本任务未改该文件,已另存patch,
不能将本次结果当作干净上游Lab环境验收。项目运行源码仍为 `8e7ab5f` 对应控制入口,
另有前几轮新增的独立CPU诊断和文档;本次未改应用代码。
实际运行命令(仓库根目录;`EVIDENCE`指下方本机制品目录):
```bash
export PYTHONPATH="$PWD/source/dex_workbench${PYTHONPATH:+:$PYTHONPATH}"
RIGHT=assets/robots/dex_hand/linkerhand_g20_right
# 仅复现记录,不是再次启动授权。
timeout --kill-after=15s 600s ~/isaacsim/python.sh scripts/tracking/track_l20.py \
"$RIGHT/tracking.usda" --manifest "$RIGHT/tracking_manifest.json" \
--hdf5 "$EVIDENCE/slow75.hdf5" --steps 30000 --full-episode \
--workspace-radius 0.8 --execute-experimental --headless
```
本机制品目录:`../dex_workbench-evidence/l20-slow75-DeXIEX/`,不随源码提交。
包含精确展开命令 `exact-command.txt`、单次启动脚本 `run-once.sh`、`LAUNCH-CONSUMED`、
`replay.log`、`result.txt`、`metrics.json`、`acceptance.json`、输入预检/样本保留检查、
`source-before.json`、CPU测试日志、前后GPU/进程快照及既有Lab patch。
- slow75 HDF5 SHA256:`6133e58499e3eb4739bed4b70f3147c9361c445dc97d32ba4f03a60c74afe8f9`。
- replay.log SHA256:`794c5a95b3176285ca2852febacd295a701c4ea846e916008d582397271cf75d`。
- 接受脚本另外核验退出0、预算、唯一PASS、步数/轮数/身份、参数、有限指标及阈值;
在更新本文前,93个被快照的源码/文档/资产/交付文件SHA与运行前相同。
- 启动前后无Kit或GPU计算进程;运行后显存633MiB,仍有正常桌面图形进程。
没有停止其他用户进程,不据此保证所有资源位级恢复。
### 剩余边界
- 保留了现有headless参数弃用/重复提示、protobuf重复注册诊断、visualizer配置缺失、
MaterialX/usdrt及TGS外力迭代警告。16/21 actuator提示对应5个有意被动关节,未关闭警告或放宽检查。
- 当前入口只保存汇总误差,未导出逐步wrench/力矩饱和统计;**不能声称无控制饱和**。
要做带宽或前馈归因,应另行增加可审计的遥测,而不是仅靠本次PASS推断。
- 上游相机SE3、尺度和原视频的独立核查依旧BLOCKED;本次只是把给定参考在仿真中受限跟踪。
- 原速、70倍、GUI整合、接触/物体任务、多环境、训练与硬件本轮均NOT_RUN。
不自动启动下一档;不把75/80倍两个离散PASS泛化为整个区间可执行。
- 本轮仅更新验收文档、变更记录及仓库外制品;资产/控制器/schema/版本不变。
完整pre-commit仍未具备,测试通过不等于完整Release就绪。未暂存、提交或推送。