← reports index
数据体检 · 2026-09-07

左臂 sep3 训练集的抓取位点图 —— 以及它暴露的一件没人知道的事

这张接触表本来只是上机前的例行体检:把 54 集里「闭爪前一瞬」的画面拼在一起,看构图散不散。表本身是干净的。但把每集第 0 帧的颜色量出来之后,发现这份被当作一份数据的集子,其实是两批不同光照下录的,28 / 26 对半劈,而且分界是一个台阶不是渐变。更麻烦的是:09-06 实测的现场光照,两批都不像。

一句话结论:xlerobot-left-pick-cup-sep3-clean-20260905 的 54 集在视觉上不是一个分布。 ep0–ep27 绿红比中位 1.28,ep28–ep53 中位 0.98,中间没有过渡。 之前报告里记的「这份集是 1.21」是双峰分布的平均数 —— 两半都不长这样。

一、先看表本身:构图是好的

54 集成对接触表:每集左格是第 0 帧头相机(杯子起始位置),右格是闭爪前一瞬的左腕相机
左格=第 0 帧头部相机,杯子起始在哪;右格=闭爪前一瞬的左腕相机,实际抓到哪。一行一集,共 54 集。 生成:grasp_sight_check.py --dataset xlerobot-team/xlerobot-left-pick-cup-sep3-clean-20260905,48 秒。

先说这张表可信的依据,不是「看着挺好」:

第二条是这次真正的防呆。同一段代码在修好之前写死用右臂夹爪那一维(dim 11),拿这份左臂集跑的结果是:54 集全部落在第 0 帧,而且不报错 —— 拼出来是一张「手臂还在起点」的表,看上去像张正常的表。左臂夹爪是 dim 5。

对照实测 · 2026-09-07
左臂集 + dim 5(对):闭爪时刻中位 131/246,落在第 0 帧 0/54
左臂集 + dim 11(错):54/54 落在第 0 帧,全程无报错

二、真正的发现:这份集是两批光照

把每集第 0 帧头相机整幅画面的平均 R、G、B 算出来,取绿红比 G/R。1.0 = 绿红相等(中性),所以基线画在 1.0,柱子往上=偏绿。

ep0–ep27 · 偏绿批 ep28–ep53 · 中性批 09-06 实测现场光照 1.58
09-06 实测头相机 1.58 — 比两批都绿 ep0 · G/R 1.239 · 亮度 100.5ep1 · G/R 1.213 · 亮度 102.4ep2 · G/R 1.196 · 亮度 102.3ep3 · G/R 1.227 · 亮度 104.2ep4 · G/R 1.220 · 亮度 102.3ep5 · G/R 1.179 · 亮度 103.0ep6 · G/R 1.363 · 亮度 102.7ep7 · G/R 1.260 · 亮度 103.2ep8 · G/R 1.202 · 亮度 101.6ep9 · G/R 1.205 · 亮度 98.8ep10 · G/R 1.277 · 亮度 105.8ep11 · G/R 1.311 · 亮度 106.0ep12 · G/R 1.320 · 亮度 99.9ep13 · G/R 1.298 · 亮度 99.9ep14 · G/R 1.314 · 亮度 100.4ep15 · G/R 1.291 · 亮度 102.0ep16 · G/R 1.264 · 亮度 100.9ep17 · G/R 1.296 · 亮度 101.7ep18 · G/R 1.306 · 亮度 102.5ep19 · G/R 1.324 · 亮度 98.3ep20 · G/R 1.328 · 亮度 101.7ep21 · G/R 1.337 · 亮度 104.1ep22 · G/R 1.322 · 亮度 104.3ep23 · G/R 1.311 · 亮度 100.1ep24 · G/R 1.278 · 亮度 105.6ep25 · G/R 1.282 · 亮度 101.1ep26 · G/R 1.259 · 亮度 106.0ep27 · G/R 1.271 · 亮度 102.7ep28 · G/R 0.978 · 亮度 109.3ep29 · G/R 0.975 · 亮度 109.5ep30 · G/R 0.975 · 亮度 107.4ep31 · G/R 0.972 · 亮度 107.4ep32 · G/R 0.975 · 亮度 108.0ep33 · G/R 0.977 · 亮度 107.1ep34 · G/R 0.978 · 亮度 109.6ep35 · G/R 0.976 · 亮度 109.1ep36 · G/R 0.976 · 亮度 108.6ep37 · G/R 0.977 · 亮度 106.4ep38 · G/R 0.973 · 亮度 106.6ep39 · G/R 0.978 · 亮度 105.4ep40 · G/R 0.976 · 亮度 108.7ep41 · G/R 0.970 · 亮度 107.8ep42 · G/R 0.983 · 亮度 106.6ep43 · G/R 0.983 · 亮度 106.9ep44 · G/R 0.982 · 亮度 106.9ep45 · G/R 0.982 · 亮度 108.3ep46 · G/R 0.978 · 亮度 108.2ep47 · G/R 0.979 · 亮度 107.5ep48 · G/R 0.978 · 亮度 108.8ep49 · G/R 0.976 · 亮度 103.2ep50 · G/R 0.979 · 亮度 107.8ep51 · G/R 0.978 · 亮度 108.9ep52 · G/R 0.974 · 亮度 107.7ep53 · G/R 0.974 · 亮度 108.4 ep0–ep27 · 偏绿 · 28 集 ep28–ep53 · 中性 · 26 集 1.01.21.41.60612182430364248G/R

每集第 0 帧头相机全幅均值,PyAV 顺序解码,2026-09-07 实测。悬停看单集数值。

批集号集数G/R 范围中位亮度中位
偏绿ep0–ep27281.179 – 1.3631.28102.3
中性ep28–ep53260.970 – 0.9830.98108.9

分界是台阶,不是渐变:ep27 = 1.271,ep28 = 0.978。相邻两集之间掉了 0.29,而各批内部的全部波动加起来也没这么大。这不是灯慢慢变了,是中间换过一次光(或者开了灯 / 天亮了 / 换了房间)。

展开 54 集逐集数值(表格视图)
集G/R亮度批
ep01.239100.5偏绿
ep11.213102.4偏绿
ep21.196102.3偏绿
ep31.227104.2偏绿
ep41.220102.3偏绿
ep51.179103.0偏绿
ep61.363102.7偏绿
ep71.260103.2偏绿
ep81.202101.6偏绿
ep91.20598.8偏绿
ep101.277105.8偏绿
ep111.311106.0偏绿
ep121.32099.9偏绿
ep131.29899.9偏绿
ep141.314100.4偏绿
ep151.291102.0偏绿
ep161.264100.9偏绿
ep171.296101.7偏绿
ep181.306102.5偏绿
ep191.32498.3偏绿
ep201.328101.7偏绿
ep211.337104.1偏绿
ep221.322104.3偏绿
ep231.311100.1偏绿
ep241.278105.6偏绿
ep251.282101.1偏绿
ep261.259106.0偏绿
ep271.271102.7偏绿
ep280.978109.3中性
ep290.975109.5中性
ep300.975107.4中性
ep310.972107.4中性
ep320.975108.0中性
ep330.977107.1中性
ep340.978109.6中性
ep350.976109.1中性
ep360.976108.6中性
ep370.977106.4中性
ep380.973106.6中性
ep390.978105.4中性
ep400.976108.7中性
ep410.970107.8中性
ep420.983106.6中性
ep430.983106.9中性
ep440.982106.9中性
ep450.982108.3中性
ep460.978108.2中性
ep470.979107.5中性
ep480.978108.8中性
ep490.976103.2中性
ep500.979107.8中性
ep510.978108.9中性
ep520.974107.7中性
ep530.974108.4中性

三、为什么这件事重要

train-left-2026-09-06.html 里记过两个数,现在要一起重读:

这不构成「0/6 是光照造成的」这个结论。它只是把光照从「没量过的怀疑」变成「量过的、确实存在的分布外因素」。要证明因果必须做实验:同一个 checkpoint、同一杯位,只改光照跑两批。在没跑之前,它和控制频率、起始位姿、只有成功样本这几条一样,都还只是嫌疑人。

四、接下来做什么

  1. 上机时把现场 G/R 量出来记进试验记录。现在这个数只在有人专门去量的时候才存在,事后无法追溯 —— 和 08-23 那批只留了 OK/CLIPPED/HELD 三个计数是同一类问题。
  2. 试跑时把两批分开看。如果失败集中在某一批的杯位上,那是信号。
  3. Demo Day 的光照现在是已知风险。机器人要被搬到会场,光照必然和这两批都不同。这条已经写进 CURRENT-STATUS.md 的开放风险。

五、后续:模型侧的实测(2026-09-08 追加,当日两次修正)

本节曾经写错,两小时内修正两次,原文如下保留说明。
第一版写着这个左臂模型「全场最差 / 对图像几乎没有任何可测的响应」,依据是 state_regime_sweep.py 测出的 pan 斜率 +0.006、elbow 斜率 −0.004。 那个测法有缺陷:它只取动作块的第一步,而且只在起手位测 —— 手臂停在 home 位时第一步本来就只挪一点点,杯子在哪都差不多,于是任何模型测出来都接近 0。 同样的缺陷当天已经在右臂上被发现并修正,我却把带着它的数字先发布到了这一页。

改用整条动作块 + 分阶段测量之后

工具改成 chunk_sweep.py:reset 一次连抽 50 步拿到整条计划,用计划终点对杯位回归; 并在够取过程的 phase 0.35 / 0.70 各测一次(起手位斜率天然 ≈ 0,没有分辨力)。 同时把 sep3-clean 的两批光照分开各测一次(ep0–27 / ep28–53,分界见第三节):

批次phase杯位跨度pan 斜率pan relbow 斜率
A:ep0–270.3543.8°+0.538+0.618−0.057
A:ep0–270.7043.8°+0.990+0.998+0.364
B:ep28–530.3558.7°+0.955+0.995−0.370
B:ep28–530.7058.7°+0.949+0.995+0.220
这个模型瞄得很准。到接近段(phase 0.70),杯子横移多少它的计划终点就跟多少 —— 斜率 0.95 / 0.99,相关系数 0.995 以上,两批光照下都是如此。 和右臂最好的那个 checkpoint(1.02)是同一档。
光照双峰在这个测试里不构成信号。 判据是事先定好的:差异要在两个 phase 上一致出现才算数。 phase 0.70 两半几乎相同(0.990 vs 0.949);phase 0.35 差得多(0.538 vs 0.955),但只在一个 phase 上出现。 elbow 那一列四个数正负乱跳,也没有一致性。
所以:本节不能作为「光照导致模型学不会」的证据。第四节把光照列为嫌疑人的判断保持不变 —— 它既没有被证实,也没有被这次测试排除;真正的对照实验(同 checkpoint、同杯位、只改光照)依然要做。

顺带纠正一处配方差异

核对 train_config.json 时发现,这一轮左臂训练的图像增强是关着的 (image_transforms.enable = False),而同期右臂那一轮是开着的 (ColorJitter 亮度/对比度/饱和度/色相 + 仿射)。
这一条此前没人记录,而它正好落在光照这个话题上:一份本来就有两种光照的数据,训练时不做任何颜色扰动。 下一轮左臂训练应当 AUG=1,理由不是"修数据",而是光照本来就是要泛化的东西 —— 机器人会被搬到会场,现场光照和这两批都不同。按这个角度看,双峰不是要消除的杂质, 是仅有的一点光照多样性;去"清洗"成单一光照反而会让泛化更差。

六、一个新发现的雷:9 个恒定维(2026-09-08 追加)

同一次横扫顺带查出来的,和光照无关,但影响所有左臂模型的实机表现:

sep3-left/020000 的恒定维(训练集里 std == 0)共 9 个:
  right_arm_shoulder_pan / shoulder_lift / elbow_flex / wrist_flex / wrist_roll / gripper
  x.vel / y.vel / theta.vel

录左臂数据时右臂不动、底盘不动,所以这九维在 13,693 帧里是常数,训练统计量的标准差恰好是 0。 而 lerobot 的归一化是 processor/normalize_processor.py:359:

denom = std + self.eps          # eps = 1e-8,std==0 没有任何保护
return (tensor - mean) / denom
真机上右臂是连着的、报真实角度 —— 那六维会被放大约 1e8 倍灌进 state token,底盘三维同理。
这个效应在右臂模型上已经实测过(镜像的同一个问题,那边是左臂六维恒零):同一张图、同一右臂状态下, 另一条臂偏 0.1°,输出就变 64°;而 0.1° / 5° / 几十度给出的结果几乎一样 —— state token 已经饱和。

推理端已修(run_policy_trials.py 的 install_state_guard(),2026-09-08):从 checkpoint 自己的统计量推出所有 std==0 的维度,喂给策略前钉回训练均值。不硬编码哪条臂,左右通用。 跑左臂模型之前确认日志里有这一行:

== state 恒定维保护【已启用】: 9 维在训练集里恒定(std==0),喂给策略前钉回训练均值

看不到这一行就是没生效,那一批数据不作数。下次录左臂数据时不该再留这个雷 —— 要么让不动的那条臂真的报数,要么明确不把它放进 state。

七、左臂补录要按哪份指南(2026-09-08 追加)

09-08 从右臂数据里量出来的四条要求,对左臂一模一样成立,见 Recording guide(英文,可直接发给队友):

  1. 杯位覆盖 —— 右臂那份 40 集的覆盖差了 16 倍,最疏一档只有 1 集,而那一档正是操作者标的 hard zone。左臂 54 集的覆盖分布还没有量过,应当先量再决定补哪儿。
  2. 打散节奏 —— 右臂示范里「跑到全程 63.2% 闭爪」的标准差只有 4.6%,模型数拍子就能压低 loss、完全不用看杯子。左臂这个数同样没量过,值得先算一遍。
  3. 补「先偏再修正」的集 —— 右臂 40 集全是一次成功,左臂 54 集大概率也是。
  4. 每集记录杯子真实位置 —— 今天所有分析都卡在没有真值上。
现实约束(2026-09-08 傍晚):左臂现在断电了。 `check_arms` 只读扫描显示左肩抬 66°C(右肩抬 39°C,其余全部 30–40°C,电压全线 12.1–12.3 V 正常), 超过我们自己定的 60°C 停机线,操作者已让队员断开左总线降温。 左臂的补录和实机验证要等它凉下来, 并且等现场确认过机械阻力 —— 那个位置已经换过一次舵机,额外的机械阻力软件修不了。

八、这一页答不了什么(诚实标注)

生成于 2026-09-07,2026-09-08 追加第五~七节 · Jetson 本机实测 · 数据集 xlerobot-team/xlerobot-left-pick-cup-sep3-clean-20260905(54 集 / 13,693 帧)
接触表脚本 03-software/scripts/grasp_sight_check.py(左右臂判定来自 dataset_dims.py,取自提交 522cf2a)