Robotics
LeRobot
Safetensors
pi05
bimanual
arx
spikefly's picture
Add files using upload-large-folder tool
4c4a210 verified
|
Raw History Blame Contribute Delete
5.9 kB

π0.5 · ARX Lift2S「stack three cups」部署契约(一页)

训练:LeRobot π0.5,上游 huggingface/lerobot 提交 89236ea0f4f81a81ca566081e20dd1ff5f823cbe(训练时另有两个只管存档的本地开关,与推理无关);底座 lerobot/pi05_base;数据 yaoxianze/arx_external_cam_cups(版本 2d87a09)转 LeRobot v3.0(转换与分位数统计脚本见 tools/);全局批 32、3 万步(前 2 万步就是 1 万 / 2 万步档那次训练,学习率按 2 万步余弦衰减到 2.5e-6;之后从第 2 万步的完整训练状态(优化器、调度器、随机数、步数)接着训 1 万步,调度器的衰减终点改为 3 万步,所以续训开始时学习率回到约 8.1e-6,再余弦衰减到 2.5e-6);绝对关节;分位数归一化。 仓根 = 训练落盘的 pretrained_model/,PI05Policy.from_pretrained(<仓名或本地目录>) 直接可用。前后处理器(policy_preprocessor*、policy_postprocessor*)已经含相机改名和分位数归一化 / 反归一化参数,客户端不要自己归一化。 推理代码:上游 lerobot 提交 89236ea 即可(clone 后 git checkout 89236ea && pip install -e ".[pi,dataset]";[dataset] 是复现检查和数据转换要用的 PyAV、jsonlines 等)。

输入(每次推理一帧)

键 内容 形状 / 类型 注意
observation.images.camera_h 头部相机 640×480,RGB 和采集同一台相机、同样设置
observation.images.camera_l 左腕相机 640×480,RGB
observation.images.camera_r 右腕相机 640×480,RGB
observation.state 当前关节读数 float32 (14,) 顺序 [左 j0…j5, 左夹爪, 右 j0…j5, 右夹爪];关节为弧度,夹爪为原始读数(全开约 −3.34 / −3.39(左 / 右)、抓住杯子时约 −2.0,都是数据实测;按数据集约定 0 为全闭,请以你们机器人的实际读数为准)
task 提示词 字符串 逐字 stack three cups
  • 图像转换:torch.from_numpy(rgb_uint8_HxWx3).permute(2,0,1).float() / 255,不要自己缩放(预处理器内部 resize-pad 到 224)。
  • 颜色:OpenCV 取图是 BGR,必须先转 RGB。deploy/fit_check_pi05.py 里的客户端路径测试会抓这个错。
  • 外部相机(camera_external)不参与训练和推理。

输出

  • 一块 50 步 × 14 维绝对关节目标,顺序与 state 相同 [左 6, 左夹爪, 右 6, 右夹爪],单位同 state(已反归一化)。
  • 数据里 action ≡ 当前状态 → 第 0 步 ≈「现在在哪」,部署从第 1 步开始执行。

执行

  • 控制频率 20 Hz(和采集一致)。
  • 同步重规划:推理 → 执行第 1…25 步 → 再推理(执行步数可调,默认 25)。
  • 块起点渐入:默认开,前 5 步(k 可调)从实测关节线性过渡到预测轨迹,缓解每次重推的起点跳变;开 / 关效果在真机上对比。
  • 夹爪:直接下发模型输出值,不做特殊处理。
  • 推理显存约 9 GB(bf16),RTX 5090 够用。

上真机前

  1. 先做回放测试(与模型无关,任何策略之前):python deploy/replay_demo.py export --dataset-root <数据目录> --episode 0 --out replay_ep000_commands.csv(数据目录 = 按 README 第 3 节用 tools/prep_pi05_data.sh 转换出来的目录;本仓不含数据),按第 0 局的布局摆好杯子,机械臂慢速移到第 0 行,再按 20 Hz 逐行下发,记录实测关节(RolloutLogger.state 或 CSV)和视频;然后 python deploy/replay_demo.py analyze --commands … --measured …。它回答三件事:「拿实测位置当指令」能否复现示教;夹爪停在约 −2.0 时夹不夹得住杯子(看视频);控制器跟踪滞后几帧(作为真机执行段跟踪的基线)。回放都做不成,先查硬件 / 指令语义。
  2. 在部署机上跑 deploy/fit_check_pi05.py(命令见 deploy/TOLERANCE.md;--dataset-root 用你自己转换出来的目录,--compare-to deploy/expected/action_fit_summary_bf16.json),对照 deploy/TOLERANCE.md(脚本读 deploy/tolerance.json,末尾打印 TOLERANCE_CHECK PASS/FAIL):期望块最大差(全部 14 维和只看关节两项)、聚合拟合误差相对差都要在容差内;client_path_test.pass 必须为 true(判据:每帧图像差 ≤ 1/255;两条路径的块差只作提示,部分显卡上两次前向不逐位相同)。
  3. 必须用你自己机器人端的「相机取图 → 张量」代码跑一遍客户端路径测试:--client-fn 你的模块:函数 --client-frame-format bgr|rgb(函数收相机原样交出的 uint8 HxWx3 帧,返回进模型的 float (3,H,W) [0,1];客户端 / 服务端分开的话把两段拼起来)。模板见 deploy/example_client_fn.py。BGR、缩放、裁剪这类错只有这样才抓得到。
  4. 第一次上机先悬空或低速,只打印一块 50 步动作,核对关节范围、顺序、夹爪方向都对了再正式执行;确认急停可用。

真机上查训推不一致(上真机后)

  • 客户端用 deploy/rollout_consistency.py 里的 RolloutLogger 记每次推理(当前关节状态 + 预测块 + 执行区间)和每个控制步的实测关节,一局一个 jsonl。
  • 跑完执行 python deploy/rollout_consistency.py run_*.jsonl --reference deploy/expected/action_fit_summary_bf16.json,得到和离线同口径的两个数:
    • 块起点偏移 |â0 − s_t|(模型估计「手臂现在在哪」与实测关节之差,不需要标注):离线基准见 deploy/TOLERANCE.md;真机上超过离线 3 倍会给出排错提示(只是提示、不是关卡),先查相机机位 / 曝光、光照、取图转换、相机顺序;
    • 执行段跟踪 |â_k − s_{t+k}|:含控制器跟踪滞后,离线没有这部分,应当和回放测试测出的跟踪误差比,而不是和离线拟合误差比。