right armcup graspspeed 0.3→1.0×HELD = 0
首批实机试验跑完了 14 次(0.3× 九次、1.0× 五次),一次都没抓到。 这一页记录我们怎么把嫌疑一个个排掉、操作者的哪个观察改变了诊断方向、 以及由此学到的「怎么教模型」的四条规则。
更新 · 当晚稍后:重放实验已裁决 —— 硬件几何没变。
操作者重放了一集示范(不加载模型,把录制的关节角原样发给手臂): 手臂到达了正确的低位,把杯子放进了两个爪片之间,动作链完整 —— 唯一的失败原因是夹爪摩擦力不足,杯子被推滑出去。
于是:① 本页的排除链再加一条 —— 机器人几何也还清白,第四节的策略假设成立; ② 暴露出一个此前没被识别的因素 —— 夹爪摩擦力不够,完美动作也抓不住。 操作者已打印摩擦力更大、更长的新夹爪,计划换爪后重录。
换爪的连带影响(重要):旧 50 集的动力学将不再匹配(不能混训);
GRIPPER_LEN = 0.159 m 变长意味着爪尖会在更高的手腕位置触桌,
所以 z_min 必须上调并重跑 measure_table.py。
因此第八节的「定向补录」不要用旧爪做 —— 改为换爪后按新纪律整批重录。
| 嫌疑 | 结论 | 依据 |
|---|---|---|
| 安全包络拦了它 | 排除 | 14 次试验 HELD 全零 —— 没拒过一帧 |
| 步长限速拖住它 | 排除 | 1.0× 下 CLIPPED 仅 3–7%,偏差不变 |
| 头部相机被转过 | 排除 | 训练 (−4.31°, 49.85°) vs 现在 (−3.60°, 50.02°),差 <1° |
| 腕部相机被碰过 | 排除 | 训练帧 vs 实时帧构图一致 |
| 标定漂移 | 排除 | 标定文件 8-16 后未改,早于 8-20 录制 |
| 分块时序(6 秒盲飞) | 已修,非主因 | chunk 按实测频率消费后,重看画面 6s→1.7s,偏差方向不变 |
顺带更正一个流传数日的文档错误:所谓「head_motor_2 = 99.649 超标定 50°」的悖论 不存在 —— 数据集 stats 实为 49.846,换算 2615 counts,在标定上限 2617 之内,差 2 counts。 是当初读错了数。
「手臂轴线对准杯子了 —— 但爪夹是向右侧打开关上的。诀窍是轴线要向左偏, 让左爪贴着杯子左缘。」
「手腕要下沉,爪夹要比杯子边缘低,然后再往杯子方向张开爪夹推进。」
去训练数据里验证:抽出闭爪前一瞬(ep1,全局帧 757)的右腕相机画面 ——
再把全部 50 集的闭爪瞬间拼成一张接触表:
操作者还观察到一条:「杯子放在右臂偏右边时,过高问题更明显」。
一个恒定的偏置不会随位置变化 —— 所以这条值得量化。把 50 集按闭爪时刻的
pan 角聚类(= 杯子摆在哪),再看每组的抓取质量:
| 杯位 (pan 均值) | 集数 | 闭爪高度 z | 组内 σ | 前伸 y |
|---|---|---|---|---|
| −30.5°(最左) | 22 | 0.028(最深) | 0.0063(最一致) | 0.160 |
| −10.2° | 7 | 0.034 | 0.0101 | 0.201 |
| +8.8° | 17 | 0.034 | 0.0118 | 0.142 |
| +22.9°(最右) | 4 | 0.038(最浅) | 0.0141(最散) | 0.157 |
集数 vs 高度 r = −0.88、集数 vs 散布 r = −0.75。
最右那个杯位只有 4 集训练数据,而那 4 集本身就是抓得最浅最散的 ——
模型在那里表现最差,不是因为它笨,是因为在那里教得最少、教得最乱。抓取成败区间只有约 1 cm 宽,而且贴着安全边界。示范闭爪高度
z = 0.032 ± 0.010,而笛卡尔包络的下限是 0.020 ——
示范就压在下限上方 1 cm。任何"保守一点"的倾向都会直接抓空,
这正是回归均值在这个任务上如此致命的原因。
两个没学到的动作,恰好都是轨迹里离均值最远的极端修正。模仿学习对"大路"拟合最好, 对这种又小又晚的关键修正拟合最差 —— 它们在损失函数眼里就像噪声。而一旦第一步略有偏差, 策略就进入示范里没出现过的状态,误差逐帧复合(covariate shift),最后在错误的位置执行 了正确的「闭爪→抬起」剧本 —— 这就是空中抓取。
离线证据相容:留出位评估 0.98× 说明它没在背坐标 —— 它学会了跟着杯子走这条大路, 败在最后三厘米。
这仍是假设。裁决它的实验(重放,见第六节)在写这页时还没跑。
直觉的说法是"告诉模型哪些特征值得学习"。机制上要说准: 你没有渠道"告诉"它 —— 示范数据的分布就是全部课程表。由此:
grasp_sight_check.py把每一集闭爪瞬间的腕部帧自动拼成接触表(上面那张 50 格的图就是它出的)。 闭爪时刻的判法:夹爪开度峰值后首次跌破一半,回退 8 帧。以后每录完一批数据都跑一次, 构图跑偏的集号当场记下 —— 它们在稀释你想教的技巧。
python 03-software/scripts/grasp_sight_check.py # 全部集
python grasp_sight_check.py --episodes 0 1 2 --out /tmp/sheet.jpg
--replay-episode一句话:不跑模型,把训练集里某一集的录制动作原样发给手臂 —— 同一条安全管线、同一套单位,唯一区别是动作来自录制而非推理。 它回答一个模型回答不了的问题:机器人本身还和录数据那天一样吗?
# 先把杯子按面板参考图 1/5 摆回录制位(重放是开环的,杯位越准结论越干净)
python run_policy_trials.py --replay-episode 0 --send --trials 1 \
--speed 1.0 --chunk-rate auto
demo_coverage.py出上面那张表 —— 每个杯位几集、抓多深、多散,以及两个相关系数。 每录完一批就跑一次,覆盖不均衡就补录,别指望训练技巧去弥补。
python 03-software/scripts/demo_coverage.py
trace_vs_demo.py试验轨迹 vs 示范逐点比,输出「下沉不足 1.2 cm」这种可量化结论。
(配套改动:试验现在默认记录每帧动作到 trials/traces/*.npz ——
第一批 14 次只留下三个计数,"它到底降到多低"事后无法回答。)
python 03-software/scripts/trace_vs_demo.py
A 开工前(5 min,不碰硬件)
policy_safety.py 必须 PASS · robot_profile.py 一致
面板 → 头部对准 → 叠参考图 → 套预设 → 快照核对
B 裁决实验(只在怀疑硬件变了时,5 min)
杯子按参考图摆回录制位 → --replay-episode 0 --send
能夹到 = 几何没变,问题在策略 │ 同样偏 = 去查硬件
C 空跑 1 次(面板,手臂不动)
看 device=cuda · 总线认对 · 头部锁定 ≈ (−4.3, 49.8) · HELD=0
D 实跑 10 次(速度 1.0 / 40 s / 动作块 auto)
手放 12V 插头 · 至少 3 次把杯子挪 2–3 cm · 当场判定
E 事后分析(2 min,不靠肉眼)
trace_vs_demo.py → 量化结论
grasp_sight_check.py → 准星构图
F 回填 GOAL-NEXT.md(做完一件事就把边界条件写回去)
一次只改一个变量。速度、时长、chunk、checkpoint、数据 —— 一轮只动一个。 这条在本次调试里被反复验证:先排速度、再排时序,每次单独改、单独看, 才能把六个嫌疑一个个摘干净。
| # | 动作 | 代价 | 预期 |
|---|---|---|---|
| 1 | 重放实验 | 5 min | 裁决硬件 vs 策略,避免后面全白干 |
| 2 | 换 checkpoint 016000 / 018000 各 3 次 | 20 min | 零成本,不同步数对极端段拟合可能差很多 |
| 3 | 定向补录:右侧杯位 4 → 15 集 | 1–2 h | 最高性价比,直击 r=−0.88 |
| 4 | v2 重训:80/20 分层 + 轻量增强 | 3 h+ | 堵死"走到大概那片区域"的捷径 |
| 5 | 调超参 | — | 暂不做 —— 分布问题没解决前只是换种方式过拟合 |
录制时手上要记住的三句话:
轴线向左偏,让左爪贴杯子左缘 · 腕部沉到杯沿以下再推进 · 偏移做夸张,每集都做
仓库内对应文档:03-software/TUNING-PLAYBOOK.md(完整操作手册)·
03-software/TRIALS-2026-08-23-miss-analysis.md(失败分析)·
数据:05-training/trials/trials-20260823-*.json ·
本页由现场分析整理,假设与事实分开标注。