EXP-04 · 8 学时

真机推理与鲁棒性评估

把训练好的 ACT checkpoint 部署回真机:三终端跑通「硬件层 → 推理节点 → 服务开关」,先 DRY_RUN 干跑再接真机复现开盖-取物-入罐-盖盖闭环,最后用摆放偏移检验策略的鲁棒性。

机房实训ROS2 推理节点鲁棒性评估

00课程节奏:五星学习法 · 8 段微课(每段 ≤ 15 min)

本实验按五星学习法组织:先用"checkpoint 部署回真机却猛甩臂"的真实故障聚焦问题,再用「开车眼手脚循环」激活旧知,接着示证新知(ROS2 接口 + 安全机制 + 双线程节拍动画),然后动手应用新知完成三终端启动与真机复现,最后借排障与拓展融会贯通。全程切成 8 段微课、每段不超过 15 分钟,段间停顿 1~2 分钟消化;纯讲授合计约 100 分钟,其余课时用于动手实操与个别辅导。

① 聚焦问题
课段 1 · 12 min
"checkpoint 部署后猛甩臂"故障引入
② 激活旧知
课段 2 · 8 min
开车眼手脚 · 双线程 · 三层平滑
③ 示证新知
课段 3~4 · 27 min
ROS2 接口安全 + 摆放偏移动画
④ 应用新知
课段 5~7 · 40 min
三终端启动 + 真机复现 + 鲁棒性评估
⑤ 融会贯通
课段 8 · 13 min
排障口诀 · 拓展 · 思考题
课段五星阶段时长对应章节本段任务
课段 1聚焦问题12 min§01 + §02 前半抛出"checkpoint 部署后猛甩臂"的故障,明确推理部署目标
课段 2激活旧知8 min§02 后半用"开车眼手脚循环"旧知解释双线程推理与三层平滑
课段 3示证新知15 min§03认识 ROS2 接口(订阅/发布/服务)与 DRY_RUN 等安全机制
课段 4示证新知12 min§06看摆放偏移容忍带与双线程节拍动画
课段 5应用新知15 min§04 + §05 前半三终端启动、DRY_RUN=True 干跑验证动作合理性
课段 6应用新知15 min§05 后半切 DRY_RUN=False、SetBool 启停、真机复现开盖入罐闭环
课段 7应用新知10 min§07用摆放偏移鲁棒性评估台预判复现表现
课段 8融会贯通13 min§08~§10排障口诀收口,拓展阅读与思考题拔高迁移

讲课提示:课段 1/2 以讲授 + 提问为主;课段 3~4 用接口表 + 动画;课段 5~6 边讲边演(先干跑再真机);课段 7 学员独立完成;课段 8 答疑拔高。段间停顿 1~2 分钟。

01学习目标课段 1 · 聚焦问题 · 12 min

  • 读懂推理节点的双线程结构:50Hz 推理线程出目标、100Hz 发布线程经限速平滑后发指令。
  • 掌握三终端启动法与 /model_ifrun 服务开关,理解 DRY_RUN 安全开关的干跑验证流程。
  • 能按案例步骤完成家庭收纳闭环真机复现,并记录成功/失败现象。
  • 理解「摆放偏移鲁棒性」评估的意义:数据覆盖范围决定策略能容忍多大的场景变化。
安全第一(案例原文):确保推理开始之前,机械臂附近没有人活动;抓取范围内不能站人,桌面做适当保护。

02原理:双线程推理与三层平滑课段 1 收尾 + 课段 2 · 激活旧知 · 8 min

❓ 聚焦问题(课段 1)checkpoint 部署回真机,机械臂却猛地一甩——一查发现忘了先 DRY_RUN 干跑,Ramp 起步也没等。问题出在哪?带着这个故障听完全课——到课段 5 你会亲手跑通三终端安全启动。

推理节点像一位「边看边喊话的指挥」:推理线程每 20ms(50Hz)看一眼三路相机 + 16 维关节状态,让 ACT 算出「接下来该怎么动」;但机器人不能听完就猛动——发布线程每 10ms(100Hz)把目标动作先「磨平」再发出去。为什么要磨平?网络输出偶尔会抖,直接执行等于手臂突然哆嗦。平滑分三层:① 滑动窗口平均(取最近 5 个目标求均值,抹平单点毛刺)、② EMA 平滑(α=0.15,每次只朝目标挪一小步,像轻推弹簧)、③ 硬性限速(臂关节每拍最多变 0.003 rad、夹爪 0.02,物理上封顶)。三层过滤后,动作既跟得上策略又稳如人手。

动作块 chunk
ACT 一次预测未来 100 步动作,存进 FIFO 队列逐步弹出,队列空了再重新推理——动作天然连贯不碎蹦。
恒等映射
fixed 版转换脚本已修复列偏移 bug,数据集 16 维顺序 = ROS 物理顺序,部署侧不做任何循环移位。
Ramp 起步
首次推理从「当前实测关节角」出发逼近目标,避免从零位突然跳变——上电不甩臂。
鲁棒性
行为克隆只认「画面→动作」映射;摆放超出采集覆盖范围,画面陌生化,策略就会露怯。
↺ 激活旧知(课段 2)回忆开车:眼睛看路(感知)、大脑判断(决策)、手脚操作(执行),三者不停循环。推理节点也是这样:50Hz 看一眼算目标、100Hz 磨平后发指令,三层平滑保证手臂不哆嗦。
一句话原理:推理管「想什么」,发布管「怎么动」——想得快(50Hz)、动得稳(100Hz + 限速),真机才既灵敏又安全。

03硬件与环境:ROS2 接口与安全机制课段 3 · 示证新知 · 15 min

三路相机
/dev/cam_head、/dev/cam_left、/dev/cam_right,720×1280 输入策略。
订阅(输入)
/cerebellum_sdk/arm/joint_states(双臂 14 关节实时)+ /slave/gripper/{left,right}/states(夹爪位置 q)。
发布(输出)
joint_commands 与左右夹爪 cmds 均 100Hz:14 关节目标位置段 + 左右夹爪目标 q。
服务(开关)
/model_ifrun(SetBool:true 启动 / false 停止推理)、joint_mode(MotorMode:切从动臂位置控制模式)。
🧯 关机三项安全开关接真机前先把这三道保险关上,出错也不会砸手:① DRY_RUN=True 只打印动作不发布到机械臂——测新模型必开;② 硬性限速 臂 0.003 rad/tick、夹爪 0.02/tick,防止动作突变;③ Ramp 准备 从当前实际位置起手,不跳变。此外节点启动前会做消息就绪检查(所有关节/夹爪/相机就绪才放行),并用双线程分离保证推理 50Hz 偶尔卡顿时发布仍保持 100Hz。

04操作步骤:从干跑到真机复现课段 5~6 · 应用新知 · 2×15 min

S1部署模型
回传 checkpoint,改 MODEL_PATH 指向 pretrained_model
→
S2DRY_RUN=True 干跑
三终端启动,只打印动作验证合理性
→
S3DRY_RUN=False 真机
确认无异常后改 False,服务开关启动执行
→
S4复现与鲁棒性评估
恢复采集场景跑闭环,再平移摆放测偏移
  1. 环境准备:把 lerobot_inference_node_act.py 放入 /home/lindenbot/lerobot-0.4.1/,修改 MODEL_PATH 指向本任务 checkpoint。
  2. 终端 1 硬件层:运行 01start_robot_act.sh(臂 SDK + 夹爪 + 碰撞检测)。
  3. 终端 2 推理节点:运行 run_act_node.sh,看到「节点初始化完成,等待 /model_ifrun 启动指令」。
  4. 终端 3 干跑:先保持 DRY_RUN=True,SetBool true 启动,查看打印的 L_arm/R_arm 动作序列是否合理。
  5. 切真机:改 DRY_RUN=False 重启节点,SetBool true,机械臂自主完成开盖-取物-入罐-盖盖;SetBool false 停止。
  6. 鲁棒性评估:环境恢复至采集阶段先跑通闭环;随后将罐子/芒果平移少量位置重复测试,记录成功与失败边界。
🧭 真机判据(复现是否成功)把环境按采集阶段恢复——芒果放桌面、不锈钢收纳盒带盖摆好(对应实拍图 order:左洞芒果、右盒带盖)——点 SetBool true 后,机械臂应自主完成「开盖 → 取芒果 → 入盒 → 盖盖」。判据就一句话:机械臂能自主把芒果放进不锈钢盒,即任务完成。
🔍 失败排查(照这个顺序)万一机械臂没完成任务,别急着重跑——按序看三级原因:① 环境没对上(桌面布景、相机视角与采集阶段不一致);② 数据不够(简单任务一般建议采集 200 组左右);③ 训练不充分(训练步数建议 500000 步以上)。前两项都能复现、只是集/训不足时,才考虑补数据重训。

05关键命令(三终端)随课段 5 / 6 对照使用

# ──终端1:机器人硬件层(臂 SDK + 夹爪 + 碰撞检测,无 CamerasNode)──
bash /home/lindenbot/iflytek_armtele_project/start_bash/04model_run_demo/01start_robot_act.sh

# ──终端2:ACT 推理节点(首次测新模型务必先 DRY_RUN=True)──
bash /home/lindenbot/lerobot-0.4.1/run_act_node.sh

# ──终端3:启动 / 停止推理──
source /home/lindenbot/iflytek_armtele_project/install/setup.bash
ros2 service call /model_ifrun std_srvs/srv/SetBool "{data: true}"   # 启动
ros2 service call /model_ifrun std_srvs/srv/SetBool "{data: false}"  # 停止
干跑判读:终端 2 打印 DRY_RUN=True:只打印动作,不发布到机械臂,step=0/10/20… 的 L_arm/R_arm 数列应连续缓变;若出现跳变或方向明显反常,先回 EXP-03 查数据与训练,不要急着接真机。
🖥️ 启动日志对照(DRY_RUN=True 干跑,原文 04-推理)
🚀 LeRobot ACT 推理节点启动
⚠️  DRY_RUN=True:只打印动作,不发布到机械臂
   ✓ 相机设备: /dev/cam_head
   ✓ 相机设备: /dev/cam_left
   ✓ 相机设备: /dev/cam_right
📦 加载 ACT 模型 ...
🖥️  设备: cuda
✅ ACT 模型/处理器加载成功 (chunk_size=100)
📡 创建订阅者 ...
   ✓ 机械臂状态: /cerebellum_sdk/arm/joint_states
   ✓ 夹爪状态: /slave/gripper/{left,right}/states
📤 创建发布者 ...
   ✓ 臂命令 /cerebellum_sdk/arm/joint_commands + 夹爪命令
✅ 节点初始化完成,等待 /model_ifrun 启动指令
🎬 启动推理
🔎 /joint_states 实际关节名(14): [left_shoulder_pitch_joint, left_shoulder_roll_joint, ...]
🪜 ramp 起点(ROS顺序) L_pitch=+0.123 R_pitch=-0.456 -> 目标 L_pitch=+0.130 R_pitch=-0.450
🔄 推理循环启动 (50 Hz)
📡 发布线程启动 (100 Hz, slew限速)
step=0 L_arm[+0.130 -0.200 +0.100 -0.050 +0.300 +0.010 -0.150] L_grip=0.750 ...
step=10 L_arm[+0.135 -0.205 +0.098 -0.048 +0.305 +0.012 -0.148] L_grip=0.752 ...
🔧 DRY_RUN=False 真机切换把 `DRY_RUN` 改为 False 后重启节点,启动日记多一行 🔴 DRY_RUN=False:将真正发布命令到机械臂!,开始推理后会出现 ✅ 已切换臂控制模式 mode=1;停止时打印 ⏸️ 停止推理 / 🛑 推理循环结束 / 🛑 发布线程结束。
MODEL_PATH 指哪
家庭任务指向 …/output/put_fruit_in_box/last/pretrained_model(文档默认示例为 …/act_fac/050000/pretrained_model)。
怎么确认就绪
相机三路 ✓、模型 chunk_size=100 ✓、订阅/发布者 ✓、等待 /model_ifrun 指令——四连 ✓ 才可继续。
切换真机后
启动会打印「已切换臂控制模式 mode=1」与 ramp 起点→目标,再进入 50Hz 推理循环。
怎么收工
SetBool false 打印「推理循环结束 / 发布线程结束」,硬件层终端随后关闭。

06动画:摆放偏移容忍带与双线程节拍课段 4 · 示证新知 · 12 min

桌面俯视 · 罐子摆放偏移 小范围变动可复现(采集覆盖的容忍带) 基准位 罐子 超出容忍带 → 画面陌生 → 易失败 推理 50Hz → 目标动作 → 发布 100Hz(限速平滑) 推理线程 · 50Hz 看三路相机 → ACT 算出目标 发布线程 · 100Hz 滑窗 5 帧均值 → EMA(0.15) → 硬限速
动画:上半部分罐子在采集形成的容忍带内往复平移表示「小范围摆放变动仍可复现」,越过红线区域画面变陌生则易失败;下半部分 50Hz 推理黄点较慢、100Hz 发布蓝点更密,绿点表示磨平后的指令持续送往双臂。
观察推理点稀、发布点密——即使某一帧推理稍慢,发布线程仍按 100Hz 把现有目标限速平滑地送出去,手臂不会「卡一下抖一下」。鲁棒性的本质:容忍带不是画出来的,是采集时用足够多、覆盖足够宽的示范「铺」出来的。

07互动:摆放偏移鲁棒性评估台课段 7 · 应用新知 · 10 min

调节场景变化,预判复现表现(滑杆分档为教学示意,文档未给出具体厘米阈值)
等待评估……

判读依据均来自案例原文:桌面到机械臂的距离要尽可能保持一致,否则复现效果较差;方位粗略测量、采集数量足够大时场景小范围变动也可以复现;简单任务建议采集 200 次左右、训练步数 500000 步以上。

08常见问题课段 8 · 融会贯通 · 13 min

Q 节点起不来 / 报相机找不到?
先确认硬件层终端已启动、三路 /dev/cam_* 在线;日志出现「✓相机设备」三连才继续。
Q 调用 /model_ifrun 无响应?
前提「所有 ROS 话题已就绪」:joint_states、夹爪 states 有数据、MODEL_PATH 有效、终端3 记得 source install/setup.bash。
Q 动作幅度小、像慢动作?
正常现象:三层平滑硬限速封顶(臂 0.003 rad/tick、夹爪 0.02/tick),这是安全设计不是故障。
Q 闭环总在某步失败?
按案例排查顺序:先恢复桌面环境参数与预设一致,再核对采集是否 200 次左右、训练是否 500000 步以上。
Q 忘了 DRY_RUN 就启动?
默认 DRY_RUN=True 只打印;改 False 后切换真机会打印「已切换臂控制模式 mode=1」——手放在急停旁再启动。
Q 换了 checkpoint 要改什么?
只改 MODEL_PATH 指向新的 pretrained_model;DRY_RUN 先改回 True 走一遍干跑再接真机。

09拓展阅读课段 8 · 融会贯通

  • 《04-聆动机器人推理》:推理源码逐层解析(1.1–1.4)、恒等映射与 cyclic-shift 历史溯源。
  • 《聆动机器人案例-家庭场景》第 5 章「复现效果评估」:排查顺序与成功判据原文。
  • LeRobot 官方文档:ACTPolicy.select_action 的 FIFO 动作块机制与推理示例。
  • 数据增广思路:若希望容忍更大的摆放偏移,可从采集端扩大示范位置覆盖面(回 EXP-02 规划采集)。
  • 对照 IND-03 分拣案例:同一套三终端启动与 /model_ifrun 开关,仅换 checkpoint 与场景布设。

10思考题 · 自测课段 8 · 融会贯通

✅ 完成成果
干跑日志 + 真机闭环成功记录 + 一张摆放偏移评估表(至少 3 个偏移档位)。
🧠 原理收获
讲清 50Hz/100Hz 双线程分工,以及三层平滑各自防的是什么问题。
🛠 技能收获
独立完成三终端启动、DRY_RUN 切换、SetBool 启停与 MODEL_PATH 配置。
📐 评分速览
真机复现 40% + 鲁棒性评估表 30% + 原理与排查论述 30%。
思考 1摆放偏移加大后失败率上升,为什么「加训步数」往往不如「补采不同位置的示范」有效?(提示:模型缺的是经验覆盖,不是参数量。)
思考 2如果允许罐子任意摆放,采集时应该怎样设计示范(位置分层?随机撒点?)才能铺出足够宽的「容忍带」?