diff --git a/四足机器狗训练到实机部署全流程指南.md b/四足机器狗训练到实机部署全流程指南.md index d1e0e0d..a2716f2 100644 --- a/四足机器狗训练到实机部署全流程指南.md +++ b/四足机器狗训练到实机部署全流程指南.md @@ -8,14 +8,14 @@ ### 1.1 仓库 -| 用途 | 镜像内目录 | 本次验证版本 | -| --- | --- | --- | -| IsaacLab 源码 | `/opt/IsaacLab` | `v2.3.2` | -| IsaacLab 训练与自带 MuJoCo 部署 | `/opt/go2_rl_robotlab` 的 `go1` 分支 | `f40874bc90c72264dbf46989d90e15a9715c1393` | -| 自动化 sim2sim 评估 | `/opt/RoboGauge` 的 `go1` 分支 | `66d0eb9010dabc501c52a8b9e5ffb2149dbcb82b` | -| 独立 MuJoCo、ONNX、X5/S100 BPU 部署 | `/opt/go1_deploy/deploy_rl_lab` | `22a13d6659c59e2793b08c767ab69d8fcc0a406b` | -| 官方公开 SDK | [unitree_legged_sdk](https://github.com/unitreerobotics/unitree_legged_sdk) | -| 私有 Go1 PRO SDK | 仅在内部部署机使用,本文不公开协议、密钥和专有接口 | +| 用途 | 公开仓库 | 分支/版本 | 镜像内目录 | 本次验证 commit | +| --- | --- | --- | --- | --- | +| IsaacLab 源码 | [isaac-sim/IsaacLab](https://github.com/isaac-sim/IsaacLab) | `v2.3.2` | `/opt/IsaacLab` | `37ddf626871758333d6ed89cf64ad702aef127d0` | +| Go1 训练与 IsaacLab 部署 | [ChenYouYuan0413/go2_rl_robotlab](https://github.com/ChenYouYuan0413/go2_rl_robotlab) | `go1` | `/opt/go2_rl_robotlab` | `f40874bc90c72264dbf46989d90e15a9715c1393` | +| Go1 RoboGauge 评估 | [ChenYouYuan0413/RoboGauge](https://github.com/ChenYouYuan0413/RoboGauge) | `go1` | `/opt/RoboGauge` | `a1665511267bca6f66c41224a113595f0abd3051` | +| Go1 MuJoCo、ONNX 与 BPU 部署 | [ChenYouYuan0413/go1_deploy](https://github.com/ChenYouYuan0413/go1_deploy) | `main` | `/opt/go1_deploy/deploy_rl_lab` | `cc7864aa605df0d6f533c463ddf930d2ace8aed8` | + +上述三个 Go1 适配仓库均可从 GitHub 匿名拉取,不再依赖内部 Gitea。官方公开 SDK 可参考 [unitree_legged_sdk](https://github.com/unitreerobotics/unitree_legged_sdk);私有 Go1 PRO SDK 仍仅在内部部署机使用,本文不公开协议、密钥和专有接口。 当前交付镜像只保留 RobotLab 版本,部署目录结构固定为: @@ -42,7 +42,7 @@ 除第 11 至 14 节明确标注的 X5/S100 板端命令外,文中的 `/root/...` 不适用于训练镜像。训练镜像不得把环境或项目放到用户 home 目录。 -本次训练在约 33540 轮手动停止,最后一个完整保存的检查点是 `model_33500.pt`。综合当前单 seed RoboGauge 结果,本文仍用 **26000 轮检查点**作为平地与三级楼梯之间较均衡的部署基线;33500 是最新候选,而不是无条件替代 26000。示例发布名称如下: +本文以 26000 轮检查点演示导出、评估、量化和部署流程。示例发布名称如下: ```text 训练检查点: model_26000.pt @@ -52,7 +52,7 @@ X5 模型: policy_robotlab_26000_int16_gemm.bin S100 模型: policy_robotlab_26000_s100_int16_gemm.hbm ``` -训练目录仍可保留不同课程阶段的 checkpoint 用于比较,但交付目录只保留最终选定的 26000 版本。量化脚本使用 `--name policy_robotlab_26000` 时会生成上面的 X5/S100 名称。26000 只是当前均衡基线,不表示轮数越大一定越好;更换发布 checkpoint 时,应重新导出 ONNX 并完整执行 RoboGauge、MuJoCo 和量化验收,而不是把多个旧 ONNX 一并放入交付目录。 +训练目录可保留不同课程阶段的 checkpoint 用于比较,但交付目录只保留最终选定的版本。量化脚本使用 `--name policy_robotlab_26000` 时会生成上面的 X5/S100 名称。更换发布 checkpoint 时,应重新导出 ONNX 并完整执行 RoboGauge、MuJoCo 和量化验收,而不是把多个旧 ONNX 一并放入交付目录。 ### 1.2 全流程 @@ -245,7 +245,7 @@ test -w /opt/envs/go2_rl_robotlab/lib/python3.11/site-packages/isaacsim/kit/data ### 3.3 镜像训练链路自检 -正式训练前先跑 1 轮。以下命令已在目标镜像运行环境中以 16 个环境验证,完成 384 个 transition,用时约 5.23 秒;发布镜像仍必须先通过 3.2 节的版本和写权限验收: +正式训练前先跑 1 轮。发布镜像必须先通过 3.2 节的版本和写权限验收: ```bash cd /opt/go2_rl_robotlab @@ -264,7 +264,7 @@ OMNI_KIT_ACCEPT_EULA=YES /opt/envs/go2_rl_robotlab/bin/python scripts/rsl_rl/tra find /opt/go2_rl_robotlab/logs/rsl_rl/go1_moe_cts -path '*image_direct_1iter*' -type f -print ``` -本次自检 checkpoint 的 SHA-256 为 `14589a131b09680bbbd10427ad6d5f90dd4cf3a0cc57b6f516c4de2ef1b0cbe3`。该文件仅证明训练链路可运行,不是可部署策略。 +自检生成的 checkpoint 仅用于确认训练链路可运行,不是可部署策略。 ### 3.4 路径 B:没有镜像时从零安装 @@ -282,13 +282,18 @@ python -m pip install "isaaclab[isaacsim,all]==2.3.2.post1" --extra-index-url ht python -m pip install torch==2.7.0 torchvision==0.22.0 --index-url https://download.pytorch.org/whl/cu128 ``` -拉取固定分支。内部 Gitea 地址需要相应读取权限;没有权限时应向交付方获取源码归档及 commit 校验,不能退回公开仓库的不同分支假装等价: +从公开 GitHub 仓库拉取固定分支。`go2_rl_robotlab` 和 `RoboGauge` 使用 `go1` 分支,`go1_deploy` 使用 `main` 分支: ```bash git clone --branch v2.3.2 --depth 1 https://github.com/isaac-sim/IsaacLab.git /opt/IsaacLab -git clone --branch go1 --single-branch https://gitea.qingruxu.xyz/cyy/go2_rl_robotlab.git /opt/go2_rl_robotlab -git clone --branch go1 --single-branch https://gitea.qingruxu.xyz/cyy/RoboGauge.git /opt/RoboGauge -git clone --branch main --single-branch https://gitea.qingruxu.xyz/cyy/go1_pro_deploy.git /opt/go1_deploy +git clone --branch go1 --single-branch https://github.com/ChenYouYuan0413/go2_rl_robotlab.git /opt/go2_rl_robotlab +git clone --branch go1 --single-branch https://github.com/ChenYouYuan0413/RoboGauge.git /opt/RoboGauge +git clone --branch main --single-branch https://github.com/ChenYouYuan0413/go1_deploy.git /opt/go1_deploy + +git -C /opt/IsaacLab rev-parse HEAD +git -C /opt/go2_rl_robotlab rev-parse HEAD +git -C /opt/RoboGauge rev-parse HEAD +git -C /opt/go1_deploy rev-parse HEAD cd /opt/go2_rl_robotlab @@ -326,7 +331,7 @@ nvidia-smi ## 4. 从 Go2 适配到 Go1 -本地 `go1` 分支的关键提交为 `0d2afbf feat: add Go1 training and MuJoCo deployment`。适配不只是替换 URDF,至少包括以下内容: +公开仓库的 `go1` 分支已包含 Go1 训练与部署适配。适配不只是替换 URDF,至少包括以下内容: 1. 添加完整的 Go1 URDF、MuJoCo XML 和 mesh。 2. 定义 Go1 执行器、默认关节角、PD 参数和力矩限制。 @@ -335,16 +340,6 @@ nvidia-smi 5. 添加 Go1 的 MuJoCo 配置和部署入口。 6. 在所有模块中统一关节顺序与策略输入输出。 -可用下面的命令查看完整改动: - -```bash -git show --stat 0d2afbf -git show 0d2afbf -- source/robot_lab/robot_lab/tasks/go1 -git show 0d2afbf -- source/robot_lab/robot_lab/assets/unitree.py -git show 0d2afbf -- source/robot_lab/robot_lab/assets/unitree_actuator.py -git show 0d2afbf -- deploy/deploy_mujoco -``` - ### 4.1 必须固定的策略接口 | 项目 | RobotLab Go1 约定 | @@ -442,17 +437,7 @@ Go1 当前复用了 `Go2RLGymCommandCfg`。速度指令不是全程保持不变 - `model_20000.pt` 已处于切换边界;当前每 500 轮保存一次,明确属于切换前的最后一个检查点是 `model_19500.pt`。 - 50000 轮还会发生第二次、更激进的切换。继续训练到该位置前,应预留新的适应区间并单独标注曲线。 -本次训练在 19900 到 20100 附近的代表性数据如下: - -| 指标 | 19900 | 20100 | -| --- | ---: | ---: | -| Teacher reward | 55.64 | 38.35 | -| Student reward | 54.08 | 36.33 | -| 非法接触终止比例 | 6.64% | 18.05% | -| 平均地形等级 | 5.687 | 5.735 | -| 最大 X 速度指令 | 0.5 | 1.0 | - -地形等级在切换点附近没有同步跳变,奖励下降与速度指令范围扩大相吻合。后续判断重点是回报是否逐步恢复、非法接触是否下降,而不是要求新课程下的绝对回报回到旧课程水平。另两个固定奖励课程更早结束:`lin_vel_z_l2` 在 0 到 1500 轮由 `-2` 变为 0,`base_height_l2` 在 0 到 5000 轮由 `-1` 变为 `-10`,都不是 20000 轮断崖的原因。 +课程切换后,应关注回报是否逐步恢复、非法接触是否下降,而不是要求新课程下的绝对回报回到旧课程水平。另两个固定奖励课程更早结束:`lin_vel_z_l2` 在 0 到 1500 轮由 `-2` 变为 0,`base_height_l2` 在 0 到 5000 轮由 `-1` 变为 `-10`,都不是 20000 轮断崖的原因。 ## 6. 开始训练 @@ -521,7 +506,7 @@ export OMNI_KIT_ACCEPT_EULA=YES find /opt/go2_rl_robotlab/logs/rsl_rl/go1_moe_cts -name 'model_*.pt' -print | sort -V ``` -本次实际 run 保留了 `model_15000.pt`、`model_19500.pt`、`model_26000.pt` 和 `model_33500.pt`。若训练进程被 `Ctrl+C` 中断,以磁盘上最后一个完整 checkpoint 为准;本次停止日志到 33540 左右,但 33540 没有保存,不能把 33500 标成 33540。 +若训练进程被 `Ctrl+C` 中断,以磁盘上最后一个完整 checkpoint 为准,不要把日志中未保存的轮次标为检查点。 ### 6.3 断点续训 @@ -567,7 +552,7 @@ ssh -L 6006:127.0.0.1:6006 @ | `Curriculum/terrain_levels` | 地形难度是否连续变化 | | `Metrics/base_velocity/max_command_x` | 是否在 20000/50000 轮发生指令课程切换 | -不要跨课程直接比较总回报绝对值,也不要只选平均回报最高或轮次最大的 checkpoint。建议将 15000、19500、26000、33500 等候选同时送入 RoboGauge,比较综合分数和分项指标后再决定。 +不要跨课程直接比较总回报绝对值,也不要只选平均回报最高或轮次最大的 checkpoint。建议将课程切换前后和训练后期的候选模型同时送入 RoboGauge,比较综合分数和分项指标后再决定。 ## 8. 评估与导出模型 @@ -626,7 +611,7 @@ OMNI_KIT_ACCEPT_EULA=YES CUDA_VISIBLE_DEVICES=1 /opt/envs/go2_rl_robotlab/bin/py /opt/envs/go2_rl_robotlab/bin/python -c "import onnx, onnxruntime as ort; p='/opt/go1_deploy/deploy_rl_lab/policy_robotlab_26000.onnx'; onnx.checker.check_model(onnx.load(p)); s=ort.InferenceSession(p, providers=['CPUExecutionProvider']); print([(x.name,x.shape,x.type) for x in s.get_inputs()]); print([(x.name,x.shape,x.type) for x in s.get_outputs()])" ``` -预期 ONNX 输入为 `obs: [1, 450] float32`,输出为 `actions: [1, 12] float32`。当前交付的 26000 ONNX 已通过 `onnx.checker.check_model()`。输入输出不匹配时不要继续 sim2sim 或量化。 +预期 ONNX 输入为 `obs: [1, 450] float32`,输出为 `actions: [1, 12] float32`。输入输出不匹配时不要继续 sim2sim 或量化。 ### 8.4 独立 MuJoCo 快速检查 @@ -685,7 +670,7 @@ cd /opt/RoboGauge python -m pip install -e . ``` -上面的最后一条命令必须在 `/opt/RoboGauge` 中执行。本文需要 Gitea `go1` 分支中的 `go1_lab.*` 任务;公开上游仓库只能作为参考,不能用 `go2_lab.*` 代替。安装后确认当前 commit 与任务注册,输出中必须出现 `go1_lab.flat`、`go1_lab.stairs_fd` 等任务: +上面的最后一条命令必须在 `/opt/RoboGauge` 中执行。本文需要公开适配仓库 `ChenYouYuan0413/RoboGauge` 的 `go1` 分支,其中包含 `go1_lab.*` 任务;原始上游仓库用于方法参考,不能用 `go2_lab.*` 代替。安装后确认当前 commit 与任务注册,输出中必须出现 `go1_lab.flat`、`go1_lab.stairs_fd` 等任务: ```bash git --git-dir=/opt/RoboGauge/.git --work-tree=/opt/RoboGauge rev-parse HEAD @@ -733,8 +718,6 @@ MUJOCO_GL=glfw MPLCONFIGDIR=/tmp/robogauge-matplotlib /opt/envs/robogauge/bin/py `run.py --headless` 在 Linux 默认选择 EGL。本次评估机的 EGL 驱动不支持 `PLATFORM_DEVICE`,所以命令显式设置 `MUJOCO_GL=glfw`;GLFW 可能打印无法打开 X11 的 warning,但无窗口仿真仍可完成。如果目标机 EGL 工作正常,可改回 `MUJOCO_GL=egl`。 -本次镜像自检只启用 `--goals max_velocity`,6 个速度子任务约 12 秒完成,`quality_score.mean=0.8402`,证明 TorchScript 加载、Go1 XML、MuJoCo 和指标落盘链路可用。该数值不是发布验收阈值,也不能替代下文完整的多目标、多 seed 评估。 - 单任务的 `--task-name` 必须是注册表里的完整名称,例如 `go1_lab.flat` 或 `go1_lab.stairs_fd`,不能写成裸的 `go1_lab`。只有下面的 stress pipeline 把 `go1_lab` 当作机器人任务前缀,再拼接具体地形。 ### 9.3 跨地形压力测试 @@ -757,23 +740,9 @@ MUJOCO_GL=glfw MPLCONFIGDIR=/tmp/robogauge-matplotlib /opt/envs/robogauge/bin/py `--num-processes` 应根据 CPU 核数和内存调整,不宜盲目设为最大逻辑核心数。 -### 9.4 本次同条件评估结果 +### 9.4 模型选择原则 -下表来自同一 Go1 MuJoCo 模型、`go1_lab.*` 配置、seed 42 和上述目标参数。所有分数都已归一化为越大越好;楼梯的 `success` 均为 1。15000 的平地对角速度序列曾发生一次翻倒,pipeline 恢复后继续了其余目标。 - -| Checkpoint | 平地综合 | 对角速度 | 最大速度 | 三级楼梯前向 | 三级楼梯后向 | -| --- | ---: | ---: | ---: | ---: | ---: | -| 15000 | 0.7072 | 0.5878 | 0.8265 | **0.6477** | 0.6536 | -| 19500,20k 课程前最后一版 | 0.7246 | 0.6209 | 0.8283 | 0.6311 | 0.5774 | -| 26000 | 0.7933 | 0.7540 | 0.8326 | 0.6410 | 0.6904 | -| 33500,最新完整保存版 | **0.8030** | **0.7558** | **0.8502** | 0.6135 | **0.7009** | - -这组结果说明: - -- 26000 比 19500 更适应扩大后的速度指令,平地和后向楼梯均明显恢复,整体最均衡。 -- 33500 的平地最大速度和后向楼梯最好,但前向上楼梯继续下降,不适合只按最新轮次替换 26000。 -- 15000 的前向上楼梯分数最高,但存在一次平地对角命令翻倒,不能仅凭楼梯单项直接上机。 -- 这些是单 seed 筛选结果,只用于缩小候选范围。发布前仍需运行多 seed、摩擦、质量和地形压力测试,并结合真实电机温度、电流与保护日志。 +候选 checkpoint 应使用相同的任务、命令目标、地形、随机种子和物理参数评估。同时检查跟踪、安全、运动质量、各地形成功情况和多随机种子波动,不能只按最新轮次或单一综合分数选择发布模型。发布前仍需运行多随机种子、摩擦、质量和地形压力测试,并结合真实电机温度、电流与保护日志做最终判断。 RoboGauge 的 `dof_power` 是归一化质量分,不是瓦特或电机温度。它可以比较同条件 checkpoint,但不能据此断言真机不会过热。 @@ -1336,7 +1305,7 @@ loop_dt_ms / recv_ms / policy_ms / work_ms / state_fresh / state_age_ms - [ ] 镜像 1 轮训练自检通过,并保存 `model_0.pt`、日志和参数文件。 - [ ] 硬件、接线、网络和急停章节已由设备负责人补全。 - [ ] 所有仓库 commit 和 Python 依赖已记录。 -- [ ] 15000、19500、26000、33500 候选已注明课程阶段,并完成 TensorBoard 与 RoboGauge 对比。 +- [ ] 候选 checkpoint 已注明课程阶段,并完成 TensorBoard 与 RoboGauge 对比。 - [ ] 最终选定 checkpoint 已完成 IsaacLab play、TorchScript/ONNX 导出及哈希记录。 - [ ] ONNX 输入 450、输出 12,关节顺序为 `FR, FL, RR, RL`。 - [ ] RoboGauge 单任务使用完整的 `go1_lab.*` 注册名,而非裸 `go1_lab` 或 `go2_lab`。 @@ -1352,8 +1321,11 @@ loop_dt_ms / recv_ms / policy_ms / work_ms / state_fresh / state_age_ms - [RoboGauge 项目主页](https://robogauge.github.io/complete/) - [Toward Reliable Sim-to-Real Predictability for MoE-based Robust Quadrupedal Locomotion](https://robogauge.github.io/static/files/arxiv.pdf) -- [RoboGauge](https://github.com/wty-yy/RoboGauge) -- [go2_rl_robotlab](https://github.com/wertyuilife2/go2_rl_robotlab) +- [Go1 训练适配:ChenYouYuan0413/go2_rl_robotlab,go1 分支](https://github.com/ChenYouYuan0413/go2_rl_robotlab/tree/go1) +- [Go1 RoboGauge 适配:ChenYouYuan0413/RoboGauge,go1 分支](https://github.com/ChenYouYuan0413/RoboGauge/tree/go1) +- [Go1 部署:ChenYouYuan0413/go1_deploy,main 分支](https://github.com/ChenYouYuan0413/go1_deploy/tree/main) +- [RoboGauge 原始上游](https://github.com/wty-yy/RoboGauge) +- [go2_rl_robotlab 原始上游](https://github.com/wertyuilife2/go2_rl_robotlab) - [IsaacLab 2.3.2 安装文档](https://isaac-sim.github.io/IsaacLab/v2.3.2/source/setup/installation/isaaclab_pip_installation.html) - [Unitree unitree_legged_sdk](https://github.com/unitreerobotics/unitree_legged_sdk) - 本地 `go2_rl_robotlab/docs/go1.md`