diff --git a/四足机器狗训练到实机部署全流程指南.assets/NetworkLayout.png b/四足机器狗训练到实机部署全流程指南.assets/NetworkLayout.png new file mode 100644 index 0000000..b9592b3 Binary files /dev/null and b/四足机器狗训练到实机部署全流程指南.assets/NetworkLayout.png differ diff --git a/四足机器狗训练到实机部署全流程指南.assets/image-20260801191848283.png b/四足机器狗训练到实机部署全流程指南.assets/image-20260801191848283.png new file mode 100644 index 0000000..a6ae96e Binary files /dev/null and b/四足机器狗训练到实机部署全流程指南.assets/image-20260801191848283.png differ diff --git a/四足机器狗训练到实机部署全流程指南.assets/image-20260801192200981.png b/四足机器狗训练到实机部署全流程指南.assets/image-20260801192200981.png new file mode 100644 index 0000000..8bae676 Binary files /dev/null and b/四足机器狗训练到实机部署全流程指南.assets/image-20260801192200981.png differ diff --git a/四足机器狗训练到实机部署全流程指南.assets/image-20260801192620807.png b/四足机器狗训练到实机部署全流程指南.assets/image-20260801192620807.png new file mode 100644 index 0000000..d21a48d Binary files /dev/null and b/四足机器狗训练到实机部署全流程指南.assets/image-20260801192620807.png differ diff --git a/四足机器狗训练到实机部署全流程指南.assets/image-20260801193333084.png b/四足机器狗训练到实机部署全流程指南.assets/image-20260801193333084.png new file mode 100644 index 0000000..6c02d4c Binary files /dev/null and b/四足机器狗训练到实机部署全流程指南.assets/image-20260801193333084.png differ diff --git a/四足机器狗训练到实机部署全流程指南.assets/image-20260801193808916.png b/四足机器狗训练到实机部署全流程指南.assets/image-20260801193808916.png new file mode 100644 index 0000000..0dddd50 Binary files /dev/null and b/四足机器狗训练到实机部署全流程指南.assets/image-20260801193808916.png differ diff --git a/四足机器狗训练到实机部署全流程指南.assets/image-20260801194631847.png b/四足机器狗训练到实机部署全流程指南.assets/image-20260801194631847.png new file mode 100644 index 0000000..59c23df Binary files /dev/null and b/四足机器狗训练到实机部署全流程指南.assets/image-20260801194631847.png differ diff --git a/四足机器狗训练到实机部署全流程指南.assets/image-20260801200427939.png b/四足机器狗训练到实机部署全流程指南.assets/image-20260801200427939.png new file mode 100644 index 0000000..180abe8 Binary files /dev/null and b/四足机器狗训练到实机部署全流程指南.assets/image-20260801200427939.png differ diff --git a/四足机器狗训练到实机部署全流程指南.assets/img_v3_02145_97a765f5-ee43-4437-b264-4555bfb617eg.jpg b/四足机器狗训练到实机部署全流程指南.assets/img_v3_02145_97a765f5-ee43-4437-b264-4555bfb617eg.jpg new file mode 100644 index 0000000..1f608a0 Binary files /dev/null and b/四足机器狗训练到实机部署全流程指南.assets/img_v3_02145_97a765f5-ee43-4437-b264-4555bfb617eg.jpg differ diff --git a/四足机器狗训练到实机部署全流程指南.assets/屏幕截图 2026-08-01 161128.png b/四足机器狗训练到实机部署全流程指南.assets/屏幕截图 2026-08-01 161128.png new file mode 100644 index 0000000..040f720 Binary files /dev/null and b/四足机器狗训练到实机部署全流程指南.assets/屏幕截图 2026-08-01 161128.png differ diff --git a/四足机器狗训练到实机部署全流程指南.assets/屏幕截图 2026-08-01 184526.png b/四足机器狗训练到实机部署全流程指南.assets/屏幕截图 2026-08-01 184526.png new file mode 100644 index 0000000..1a2b780 Binary files /dev/null and b/四足机器狗训练到实机部署全流程指南.assets/屏幕截图 2026-08-01 184526.png differ diff --git a/四足机器狗训练到实机部署全流程指南.assets/屏幕截图 2026-08-01 192536.png b/四足机器狗训练到实机部署全流程指南.assets/屏幕截图 2026-08-01 192536.png new file mode 100644 index 0000000..14624e8 Binary files /dev/null and b/四足机器狗训练到实机部署全流程指南.assets/屏幕截图 2026-08-01 192536.png differ diff --git a/四足机器狗训练到实机部署全流程指南.md b/四足机器狗训练到实机部署全流程指南.md index a2716f2..b06c2a2 100644 --- a/四足机器狗训练到实机部署全流程指南.md +++ b/四足机器狗训练到实机部署全流程指南.md @@ -1,8 +1,7 @@ # 四足机器狗从训练到实机部署全流程指南 -> 本教程基于西安交通大学 RoboGauge 团队的研究成果 [Toward Reliable Sim-to-Real Predictability for MoE-based Robust Quadrupedal Locomotion](https://robogauge.github.io/static/files/arxiv.pdf) 及其[项目主页](https://robogauge.github.io/complete/),将原始 Go2 训练任务适配为 Unitree Go1,并串联 IsaacLab 训练、RoboGauge 评估、MuJoCo sim2sim、ONNX 导出、RDK X5/S100 BPU 量化和 sim2real。 +> 本教程基于西安交通大学 RoboGauge 团队的研究成果 [Toward Reliable Sim-to-Real Predictability for MoE-based Robust Quadrupedal Locomotion](https://robogauge.github.io/static/files/arxiv.pdf) 及其[项目主页](https://robogauge.github.io/complete/),将原始 Go2 训练任务适配为 Unitree Go1,并串联 IsaacLab 训练、RoboGauge 评估、MuJoCo sim2sim、ONNX 导出、RDK X5/S100 BPU 量化和 sim2real > -> 本文依据当前本地仓库代码和本次 Go1 训练记录整理。已验证 1 轮 IsaacLab 训练、ONNX 接口与推理、MuJoCo 采样、RoboGauge 单任务评估,以及使用 ONNX 推理采样数据完成 X5/S100 PTQ 编译的链路。板端数值、延迟和硬件命令仍需在对应设备上逐条复核。不要整段复制后无人值守运行。 ## 1. 教程范围与版本约定 @@ -15,9 +14,9 @@ | 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 仍仅在内部部署机使用,本文不公开协议、密钥和专有接口。 +上述三个 Go1 适配仓库均可从 GitHub 匿名拉取,不再依赖内部 Gitea。官方公开 SDK 可参考 [unitree_legged_sdk](https://github.com/unitreerobotics/unitree_legged_sdk)。 -当前交付镜像只保留 RobotLab 版本,部署目录结构固定为: +当前交付镜像部署目录结构为: ```text /opt/go1_deploy/ @@ -33,14 +32,10 @@ logs/ ``` -已删除的 `deploy_45dim/`、`deploy_wtw/`、`sim2sim_mujoco_example/` 和旧 Gym/旧轮次 ONNX 不属于交付结构,本文不再引用。量化机、训练镜像和板端分别使用 `/opt/go1_deploy` 与 `/root/go1_deploy` 作为仓库根目录,子目录均为 `deploy_rl_lab`。 - 本文有两条使用路径: -- **路径 A,直接使用交付镜像**:不要重新 clone 或重新安装,使用 `/opt` 下的固定目录和解释器。 -- **路径 B,没有镜像**:按 3.4 节拉取仓库并安装,但仓库、虚拟环境、日志和产物仍全部放在 `/opt`。 - -除第 11 至 14 节明确标注的 X5/S100 板端命令外,文中的 `/root/...` 不适用于训练镜像。训练镜像不得把环境或项目放到用户 home 目录。 +- **路径 A,直接使用交付镜像**:不需要重新 clone 或重新安装,使用 `/opt` 下的固定目录和解释器 +- **路径 B,没有镜像**:按 3.4 节拉取仓库并安装 本文以 26000 轮检查点演示导出、评估、量化和部署流程。示例发布名称如下: @@ -52,7 +47,7 @@ X5 模型: policy_robotlab_26000_int16_gemm.bin S100 模型: policy_robotlab_26000_s100_int16_gemm.hbm ``` -训练目录可保留不同课程阶段的 checkpoint 用于比较,但交付目录只保留最终选定的版本。量化脚本使用 `--name policy_robotlab_26000` 时会生成上面的 X5/S100 名称。更换发布 checkpoint 时,应重新导出 ONNX 并完整执行 RoboGauge、MuJoCo 和量化验收,而不是把多个旧 ONNX 一并放入交付目录。 +训练目录可保留不同课程阶段的 checkpoint 用于比较,但交付目录只保留最终选定的版本。量化脚本使用 `--name policy_robotlab_26000` 时会生成上面的 X5/S100 名称 ### 1.2 全流程 @@ -72,13 +67,13 @@ Go1 模型与任务适配 -> 复杂地形测试 ``` -任何阶段不通过,都应退回上一阶段定位问题,不能用放宽真机保护阈值来掩盖观测、关节顺序或模型接口错误。 +任何阶段不通过,都应退回上一阶段定位问题,不能用放宽真机保护阈值来掩盖观测、关节顺序或模型接口错误 ## 2. 研究方法解读 ### 2.1 为什么使用 MoE-CTS -该流程的核心不是只追求仿真中的高回报,而是提高策略在未知动力学和地形上的泛化能力,并用标准化指标提前判断 sim2real 风险。 +该流程的核心不是只追求仿真中的高回报,而是提高策略在未知动力学和地形上的泛化能力,并用标准化指标提前判断 sim2real 风险 - **CTS(Concurrent Teacher-Student)**:teacher 可使用地形高度、接触力、关节力矩等特权信息;student 仅使用真机可获得的本体感知历史。两者在训练期间并行优化,使 student 学会从历史观测中估计隐含环境信息。 - **MoE(Mixture of Experts)**:策略包含多个 expert,由门控网络根据隐变量组合不同 expert。不同 expert 可以分别覆盖平地、坡面、台阶、低摩擦和动力学扰动等状态。 @@ -91,69 +86,40 @@ Go1 模型与任务适配 1. **训练奖励**:判断优化是否收敛、是否发生策略坍塌。 2. **RoboGauge 指标**:在跨地形、跨摩擦、多随机种子下比较跟踪、安全和运动质量。 -3. **真机保护与日志**:判断实时观测、动作、关节目标和硬件状态是否处于允许范围。 +3. **真机保护与日志**:判断实时观测、动作、关节目标和硬件状态是否处于允许范围 -RoboGauge 当前关注的指标包括关节软限位、线/角速度误差、电机功耗、姿态稳定性、力矩平滑度、摩擦裕度和 ZMP 裕度。归一化后均按“越大越好”解释,但任何综合分数都不能替代分项检查。 +RoboGauge 当前关注的指标包括关节软限位、线/角速度误差、电机功耗、姿态稳定性、力矩平滑度、摩擦裕度和 ZMP 裕度。归一化后均按“越大越好”解释,但任何综合分数都不能替代分项检查 ## 3. 两种环境准备方式 ### 3.1 硬件与软件前提 -- NVIDIA GPU 和匹配的驱动。 -- Linux 训练环境;图形界面训练不是必须。 -- Python 3.11。 -- IsaacLab `2.3.2.post1` 和 Isaac Sim `5.1.0.0`。 -- 足够的磁盘空间保存检查点、TensorBoard 日志和导出模型。 +- NVIDIA GPU 和匹配的驱动 +- Linux 训练环境;图形界面训练不是必须 +- Python 3.11 +- IsaacLab `2.3.2.post1` 和 Isaac Sim `5.1.0.0` +- 足够的磁盘空间保存检查点、TensorBoard 日志和导出模型 ### 3.2 路径 A:直接使用交付镜像 -以下信息在当前工作区无法从文件和 Docker 本地缓存推断,属于交付前必须填写的镜像元数据: +我们在地瓜的robogo的云桌面平台--[d-robotics](https://robogo.d-robotics.cc/cloud-desktop) +提供了配置好所有环境开箱即用的镜像 + +![image-20260801194631847](E:/race_save/doge/dog_train_deploy_guide_doc/%E5%9B%9B%E8%B6%B3%E6%9C%BA%E5%99%A8%E7%8B%97%E8%AE%AD%E7%BB%83%E5%88%B0%E5%AE%9E%E6%9C%BA%E9%83%A8%E7%BD%B2%E5%85%A8%E6%B5%81%E7%A8%8B%E6%8C%87%E5%8D%97.assets/image-20260801194631847.png) + +如上创建桌面,选择DOG-MOE-CTS_V1.1的镜像开始创建,选择12g-16c32g的配置 + +进入后我们先把量化的dockerg工具链进行挂载: ```text -交付阻断项(维护者填写) -RoboGo 镜像名称: -镜像拉取命令: -容器启动参数: -训练数据持久化目录: +sudo docker load -i /opt/envs/go2_rl_robotlab/docker-toolchain/images/openexplorer_ai_toolchain_ubuntu_20_x5_cpu_v1.2.8.tar + +sudo docker load -i /opt/envs/go2_rl_robotlab/docker-toolchain/images/ai_toolchain_ubuntu_22_s100_s600_cpu_v3.7.0.tar ``` -量化工具链不依赖交付镜像本身的 CUDA 环境,已单独归档到 `/opt`: +量化时应连接宿主 Docker daemon,先执行 `docker load -i`,再运行第 11 节脚本 -```text -/opt/envs/go2_rl_robotlab/docker-toolchain/images/openexplorer_ai_toolchain_ubuntu_20_x5_cpu_v1.2.8.tar -/opt/envs/go2_rl_robotlab/docker-toolchain/images/ai_toolchain_ubuntu_22_s100_s600_cpu_v3.7.0.tar -``` - -归档内只有 Docker CLI 和工具链镜像,不包含也不应在交付镜像内自行启动 `dockerd`。量化时应连接宿主 Docker daemon,先执行 `docker load -i <归档>`,再运行第 11 节脚本。本次已实际加载并验证两个归档。 - -如果交付镜像本身运行在 Docker 中,需要由宿主在创建容器时挂载 Docker socket: - -```bash -# 以下在宿主执行,放入实际的 docker run 参数中 -docker run ... \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -``` - -进入容器后验收 CLI 和 daemon: - -```bash -sudo /opt/envs/go2_rl_robotlab/docker-toolchain/bin/docker info -sudo /opt/envs/go2_rl_robotlab/docker-toolchain/bin/docker image inspect openexplorer/ai_toolchain_ubuntu_20_x5_cpu:v1.2.8 -sudo /opt/envs/go2_rl_robotlab/docker-toolchain/bin/docker image inspect registry.d-robotics.cc/deliver/ai_toolchain_ubuntu_22_s100_s600_cpu:v3.7.0 -``` - -本次验证 daemon 的 `DockerRootDir` 是宿主 `/var/lib/docker`。交付所需的 CLI、配置和可重新加载的镜像归档都在 `/opt/envs/go2_rl_robotlab/docker-toolchain`;`docker load` 之后的展开层属于宿主 daemon 缓存,不会被保存进 RoboGo 交付镜像。如果专用量化主机要求 Docker 展开层也位于 `/opt`,应由主机管理员在首次 `docker load` 之前设置 daemon,不要在共享 Docker 主机上盲目更改: - -```json -{ - "data-root": "/opt/envs/go2_rl_robotlab/docker-toolchain/docker-data" -} -``` - -上述内容应合并到宿主 `/etc/docker/daemon.json`,然后由管理员重启 Docker 并用 `docker info --format '{{.DockerRootDir}}'` 验收。修改数据根目录会影响该 daemon 管理的所有镜像和容器,不是普通容器内步骤。 - -镜像内目录必须固定如下: +镜像内目录固定如下: ```text /opt/IsaacLab @@ -164,7 +130,7 @@ sudo /opt/envs/go2_rl_robotlab/docker-toolchain/bin/docker image inspect registr /opt/envs/robogauge ``` -直接使用镜像时跳过 3.4 节。首次进入容器先执行验收,不要看到 `/opt/IsaacLab` 存在就默认版本正确: +直接使用镜像时跳过 3.4 节。首次进入容器先执行验收: ```bash export OMNI_KIT_ACCEPT_EULA=YES @@ -184,15 +150,15 @@ git --git-dir=/opt/IsaacLab/.git --work-tree=/opt/IsaacLab describe --tags --alw /opt/envs/go2_rl_robotlab/bin/python -c "import isaaclab, torch; import importlib.metadata as m; print('isaaclab', m.version('isaaclab')); print('isaacsim', m.version('isaacsim')); print('torch', torch.__version__)" ``` -预期为 IsaacLab `v2.3.2`/`2.3.2.post1`、Isaac Sim `5.1.0.0`、PyTorch `2.7.0`。IsaacLab `v2.2.0` 搭配 Isaac Sim `5.0.0` 与当前 `go1` 分支不兼容,不能作为交付镜像发布。本次检查发现原始 `/opt/IsaacLab` 正是该不兼容组合;镜像维护者必须在发布层将 `/opt/IsaacLab` 替换为 `v2.3.2`,不能只在另一个临时目录安装新版后继续交付旧路径。 +预期为 IsaacLab `v2.3.2`/`2.3.2.post1`、Isaac Sim `5.1.0.0`、PyTorch `2.7.0` -Pip 版 Isaac Sim 首次启动必须接受 EULA。建议把下面变量写入镜像运行环境,而不是只写在某个用户的 shell 历史中: +Pip 版 Isaac Sim 首次启动必须接受 EULA。建议把下面变量写入镜像运行环境: ```bash export OMNI_KIT_ACCEPT_EULA=YES ``` -下列目录会在训练或评估时写入,镜像构建阶段必须由 root 预建并授予实际容器用户写权限: +下列目录会在训练或评估时写入: ```text /opt/go2_rl_robotlab/logs @@ -223,25 +189,9 @@ RUN install -d -m 0775 /opt/go2_rl_robotlab/logs /opt/go2_rl_robotlab/outputs \ /opt/envs/go2_rl_robotlab/lib/python3.11/site-packages/isaacsim/kit/logs ``` -运行用户验收: +RoboGauge 环境应指向 `/opt/envs/go2_rl_robotlab/python-runtime`,并把 `/opt/RoboGauge` 和 RoboGauge 自己的 `site-packages` 放入 `PYTHONPATH`。否则第 9 节会在导入前直接报 `No such file or directory` -```bash -test -w /opt/go2_rl_robotlab/logs -test -w /opt/go2_rl_robotlab/outputs -test -w /opt/RoboGauge/logs -test -w /opt/RoboGauge/outputs -test -w /opt/go1_deploy/logs -test -w /opt/envs/go2_rl_robotlab/lib/python3.11/site-packages/isaacsim/kit/cache -test -w /opt/envs/go2_rl_robotlab/lib/python3.11/site-packages/isaacsim/kit/data -test -w /opt/envs/go2_rl_robotlab/lib/python3.11/site-packages/isaacsim/kit/logs -test -w /opt/envs/go2_rl_robotlab/lib/python3.11/site-packages/isaacsim/kit/data/Kit/Isaac-Sim/5.1/user.config.json -``` - -旧 `/opt/IsaacSim` 清理后,RoboGauge 环境的 `bin/python3` 不得继续指向旧路径;应指向 `/opt/envs/go2_rl_robotlab/python-runtime`,并把 `/opt/RoboGauge` 和 RoboGauge 自己的 `site-packages` 放入 `PYTHONPATH`。否则第 9 节会在导入前直接报 `No such file or directory`。 - -本流程以 `/opt/envs/go2_rl_robotlab/lib/python3.11/site-packages/isaacsim` 中的 pip 版 Isaac Sim `5.1.0.0` 为准。旧的独立 `/opt/IsaacSim` `5.0.0` 已从运行环境移除;不要重新挂载它的 `PYTHONPATH` 或 `python.sh`。 - -若仓库由镜像构建用户创建、运行用户不同,普通 `git status` 可能报 `dubious ownership`。镜像应优先统一目录属主;只读检查也可使用 `git --git-dir=/opt//.git --work-tree=/opt/ ...`,不要为省事把所有系统目录加入 Git safe.directory。 +本流程以 `/opt/envs/go2_rl_robotlab/lib/python3.11/site-packages/isaacsim` 中的 pip 版 Isaac Sim `5.1.0.0` 为准 ### 3.3 镜像训练链路自检 @@ -264,11 +214,11 @@ 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 仅用于确认训练链路可运行,不是可部署策略。 +自检生成的 checkpoint 仅用于确认训练链路可运行,不是可部署策略 ### 3.4 路径 B:没有镜像时从零安装 -以下命令假设主机已安装 NVIDIA 驱动、Docker(量化时需要)和 Conda;Conda/Miniforge 本身也应安装在 `/opt`。即使没有镜像,也统一把项目与 Conda prefix 放到 `/opt`: +以下命令假设主机已安装 NVIDIA 驱动、Docker(量化时需要)和 Conda: ```bash sudo install -d -o "$USER" -g "$(id -gn)" /opt/envs /opt/IsaacLab @@ -333,12 +283,12 @@ nvidia-smi 公开仓库的 `go1` 分支已包含 Go1 训练与部署适配。适配不只是替换 URDF,至少包括以下内容: -1. 添加完整的 Go1 URDF、MuJoCo XML 和 mesh。 -2. 定义 Go1 执行器、默认关节角、PD 参数和力矩限制。 -3. 新建 `RobotLab-Go1-v0` 的场景、观测、动作、奖励、随机化和课程配置。 -4. 注册 Go1 任务及 MoE-CTS runner 配置。 -5. 添加 Go1 的 MuJoCo 配置和部署入口。 -6. 在所有模块中统一关节顺序与策略输入输出。 +1. 添加完整的 Go1 URDF、MuJoCo XML 和 mesh +2. 定义 Go1 执行器、默认关节角、PD 参数和力矩限制 +3. 新建 `RobotLab-Go1-v0` 的场景、观测、动作、奖励、随机化和课程配置 +4. 注册 Go1 任务及 MoE-CTS runner 配置 +5. 添加 Go1 的 MuJoCo 配置和部署入口 +6. 在所有模块中统一关节顺序与策略输入输出 ### 4.1 必须固定的策略接口 @@ -376,8 +326,6 @@ RobotLab ONNX 的历史按“观测项分组后堆叠”,不是简单地将 10 关节位置 10 帧, 关节速度 10 帧, 上一动作 10 帧] ``` -不要把旧 RL-Gym 的 5 帧/225 维 ONNX、RobotLab 的 10 帧/450 维 ONNX、内部维护历史的 45 维 TorchScript 混用。即使程序没有立即报错,错误的历史排列也会让输出失去意义。 - ## 5. 奖励函数与环境设计 ### 5.1 奖励项与判断原则 @@ -408,18 +356,18 @@ source/robot_lab/robot_lab/tasks/go1/env_cfg.py | `hip_pos_penalty_l1` | `-0.05` | 约束髋关节偏移 | | `joint_pos_penalty_l1` | `-0.01` | 约束大腿和小腿关节偏移 | -线速度和角速度跟踪项采用指数形式,误差为零时单项接近 1,再乘权重;其余多数为非负代价乘负权重。IsaacLab 奖励管理器还会按环境步长累计,因此不要根据权重直接猜测 TensorBoard 总回报的绝对值。 +线速度和角速度跟踪项采用指数形式,误差为零时单项接近 1,再乘权重;其余多数为非负代价乘负权重。IsaacLab 奖励管理器还会按环境步长累计 奖励判断原则: -- 先看 teacher 和 student 的平均回报是否持续上升并进入平台期。 -- student 长期显著低于 teacher,通常表示历史编码器未学到足够的隐变量信息。 -- 总回报上升时,还要检查关节限制、力矩、功率、动作平滑和 episode length。 -- 单项奖励尺度相差较大,不能要求每条曲线数值接近。 -- 奖励短时波动是 on-policy 训练的正常现象;连续大幅下降、episode length 同时缩短才更值得警惕。 -- 修改奖励后必须新建 run,不能把不同配置的曲线当作同一实验连续比较。 +- 先看 teacher 和 student 的平均回报是否持续上升并进入平台期 +- student 长期显著低于 teacher,通常表示历史编码器未学到足够的隐变量信息 +- 总回报上升时,还要检查关节限制、力矩、功率、动作平滑和 episode length +- 单项奖励尺度相差较大,不能要求每条曲线数值接近 +- 奖励短时波动是 on-policy 训练的正常现象;连续大幅下降、episode length 同时缩短才更值得警惕 +- 修改奖励后必须新建 run,不能把不同配置的曲线当作同一实验连续比较 -环境通过随机初始状态、摩擦/质量等动力学变化、外力扰动、执行器延迟和连续地形难度降低过拟合。Go1 训练中的执行器延迟为 0 到 4 个物理步,即 0 到 20 ms;独立 MuJoCo 部署中的延迟参数按策略步计量,两者单位不同。 +环境通过随机初始状态、摩擦/质量等动力学变化、外力扰动、执行器延迟和连续地形难度降低过拟合。Go1 训练中的执行器延迟为 0 到 4 个物理步,即 0 到 20 ms;独立 MuJoCo 部署中的延迟参数按策略步计量,两者单位不同 ### 5.2 必须单独识别的课程切换 @@ -433,11 +381,11 @@ Go1 当前复用了 `Go2RLGymCommandCfg`。速度指令不是全程保持不变 配置位于 `source/robot_lab/robot_lab/tasks/go2/mdp/commands.py`。命令生成器会在环境重新采样指令时应用切换,并在日志打印 `Command range updated at iter ...`。因此: -- 20000 轮后的奖励断崖首先应按“任务分布突然变难”解释,不能直接判定策略坍塌。 -- `model_20000.pt` 已处于切换边界;当前每 500 轮保存一次,明确属于切换前的最后一个检查点是 `model_19500.pt`。 -- 50000 轮还会发生第二次、更激进的切换。继续训练到该位置前,应预留新的适应区间并单独标注曲线。 +- 20000 轮后的奖励断崖首先应按“任务分布突然变难”解释,不能直接判定策略坍塌 +- `model_20000.pt` 已处于切换边界;当前每 500 轮保存一次,明确属于切换前的最后一个检查点是 `model_19500.pt` +- 50000 轮还会发生第二次、更激进的切换。继续训练到该位置前,应预留新的适应区间并单独标注曲线 -课程切换后,应关注回报是否逐步恢复、非法接触是否下降,而不是要求新课程下的绝对回报回到旧课程水平。另两个固定奖励课程更早结束:`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. 开始训练 @@ -477,7 +425,7 @@ export OMNI_KIT_ACCEPT_EULA=YES watch -n 1 nvidia-smi ``` -选择能稳定运行且留有显存余量的最大环境数。若 OOM,先减小 `num_envs`;只有明确理解 PPO batch 变化后,再修改 `rsl_rl_cfg.py` 中的 `num_steps_per_env`、mini-batch 和 epoch 数。 +选择能稳定运行且留有显存余量的最大环境数。若 OOM,先减小 `num_envs`;只有明确理解 PPO batch 变化后,再修改 `rsl_rl_cfg.py` 中的 `num_steps_per_env`、mini-batch 和 epoch 数 ### 6.2 正式训练并保留候选检查点 @@ -506,7 +454,7 @@ export OMNI_KIT_ACCEPT_EULA=YES find /opt/go2_rl_robotlab/logs/rsl_rl/go1_moe_cts -name 'model_*.pt' -print | sort -V ``` -若训练进程被 `Ctrl+C` 中断,以磁盘上最后一个完整 checkpoint 为准,不要把日志中未保存的轮次标为检查点。 +若训练进程被 `Ctrl+C` 中断,以磁盘上最后一个完整 checkpoint 为准,不要把日志中未保存的轮次标为检查点 ### 6.3 断点续训 @@ -521,7 +469,7 @@ OMNI_KIT_ACCEPT_EULA=YES /opt/envs/go2_rl_robotlab/bin/python /opt/go2_rl_robotl --headless ``` -当前 runner 在恢复训练时将 `--max_iterations` 解释为**额外训练轮数**。例如从 23000 继续到 26000,应填写 `26000 - 23000 = 3000`,若仍填写 26000 会继续训练到约 49000。恢复前先确认 `params/env.yaml` 和 `params/agent.yaml` 与预期一致。加载旧优化器状态后改变网络结构、观测维数或 expert 数量通常不可行。 +当前 runner 在恢复训练时将 `--max_iterations` 解释为**额外训练轮数**。例如从 23000 继续到 26000,应填写 `26000 - 23000 = 3000`,若仍填写 26000 会继续训练到约 49000。恢复前先确认 `params/env.yaml` 和 `params/agent.yaml` 与预期一致。加载旧优化器状态后改变网络结构、观测维数或 expert 数量通常不可行 ## 7. 使用 TensorBoard 观察训练 @@ -531,7 +479,7 @@ OMNI_KIT_ACCEPT_EULA=YES /opt/envs/go2_rl_robotlab/bin/python /opt/go2_rl_robotl /opt/envs/go2_rl_robotlab/bin/python -m tensorboard.main --logdir /opt/go2_rl_robotlab/logs/rsl_rl --port 6006 ``` -从本机通过 SSH 查看远端 TensorBoard: +从本机通过 SSH 查看远端 TensorBoard,或者在远程桌面直接打开火狐浏览器: ```bash ssh -L 6006:127.0.0.1:6006 @ @@ -552,7 +500,8 @@ ssh -L 6006:127.0.0.1:6006 @ | `Curriculum/terrain_levels` | 地形难度是否连续变化 | | `Metrics/base_velocity/max_command_x` | 是否在 20000/50000 轮发生指令课程切换 | -不要跨课程直接比较总回报绝对值,也不要只选平均回报最高或轮次最大的 checkpoint。建议将课程切换前后和训练后期的候选模型同时送入 RoboGauge,比较综合分数和分项指标后再决定。 +![屏幕截图 2026-08-01 184526](E:/race_save/doge/dog_train_deploy_guide_doc/%E5%9B%9B%E8%B6%B3%E6%9C%BA%E5%99%A8%E7%8B%97%E8%AE%AD%E7%BB%83%E5%88%B0%E5%AE%9E%E6%9C%BA%E9%83%A8%E7%BD%B2%E5%85%A8%E6%B5%81%E7%A8%8B%E6%8C%87%E5%8D%97.assets/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-08-01%20184526.png) +不要跨课程直接比较总回报绝对值,也不要只选平均回报最高或轮次最大的 checkpoint。建议将课程切换前后和训练后期的候选模型同时送入 RoboGauge,比较综合分数和分项指标后再决定 ## 8. 评估与导出模型 @@ -583,7 +532,7 @@ cp /exported/policy.onnx /opt/RoboGauge/resources/models/go1/policy_rob cp /exported/policy.pt /opt/RoboGauge/resources/models/go1/policy_robotlab_26000_post_command_curriculum.pt ``` -RoboGauge 当前通过 `torch.jit.load()` 使用 TorchScript `.pt`;ONNX 用于独立 MuJoCo、量化和实机部署。两者不能只靠改后缀互换。 +RoboGauge 当前通过 `torch.jit.load()` 使用 TorchScript `.pt`;ONNX 用于独立 MuJoCo、量化和实机部署。两者不能只靠改后缀互换 ### 8.2 不打断训练的导出原则 @@ -601,9 +550,9 @@ OMNI_KIT_ACCEPT_EULA=YES CUDA_VISIBLE_DEVICES=1 /opt/envs/go2_rl_robotlab/bin/py 注意: - 只处理已经完整写完的 checkpoint,不要复制正在写入的文件。 -- 12 GB 级显卡以 4096 环境训练时通常没有余量再启动 Isaac Sim;不要为了导出挤占训练进程。 -- 若没有第二块 GPU,先复制 checkpoint,待训练停止后离线导出。仓库当前没有正式的 `export-only` 命令,不要把临时 Python 片段写成通用教程入口。 -- `play.py` 导出后仍会进入仿真循环;看到导出文件后用 `Ctrl+C` 结束该独立进程,不会中断训练进程。 +- 12 GB 级显卡以 4096 环境训练时通常没有余量再启动 Isaac Sim;不要为了导出挤占训练进程 +- 若没有第二块 GPU,先复制 checkpoint,待训练停止后离线导出 +- `play.py` 导出后仍会进入仿真循环;看到导出文件后用 `Ctrl+C` 结束该独立进程,不会中断训练进程 ### 8.3 检查 ONNX 接口 @@ -611,13 +560,13 @@ 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`。输入输出不匹配时不要继续 sim2sim 或量化。 +预期 ONNX 输入为 `obs: [1, 450] float32`,输出为 `actions: [1, 12] float32`。输入输出不匹配时不要继续 sim2sim 或量化 ### 8.4 独立 MuJoCo 快速检查 如果你要做的是“和部署链路一致”的快速检查,直接使用部署仓库里的 ONNX 入口。它读取当前 45 维单帧观测,并在脚本内部维护 10 帧历史,适合在进入完整 RoboGauge 评估前核对观测、动作缩放和地形 XML: -Linux 不需要 `mjpython`;它主要用于 macOS 的 MuJoCo 图形启动。镜像中用绝对 ONNX 路径执行非交互采样。该脚本会在加载模型前切换工作目录,相对 ONNX 路径可能因此失效: +镜像中用绝对 ONNX 路径执行非交互采样。该脚本会在加载模型前切换工作目录,相对 ONNX 路径可能因此失效: ```bash cd /opt/go1_deploy/deploy_rl_lab @@ -628,7 +577,7 @@ env -u MUJOCO_GL /opt/envs/robogauge/bin/python deploy_go1_onnx_mujoco_lab.py \ --sample-log-dir /opt/go1_deploy/logs ``` -采样目录名固定以 `mujoco_stairs_sample_` 开头,用于保存独立 MuJoCo ONNX 推理检查日志;PTQ 使用第 11 节的正式 64 样本校验集。 +采样目录名固定以 `mujoco_stairs_sample_` 开头,用于保存独立 MuJoCo ONNX 推理检查日志;PTQ 使用第 11 节的正式 64 样本校验集 楼梯测试同样直接切 terrain: @@ -642,7 +591,7 @@ env -u MUJOCO_GL /opt/envs/robogauge/bin/python deploy_go1_onnx_mujoco_lab.py \ --spawn-z 0.34 ``` -脚本默认 `--clip-actions 100.0`、`--max-target-step 0.0`。如果你要做更保守的起步测试,可以再按日志逐步收紧这些参数;不要把旧版本的示例值当成固定默认。 +脚本默认 `--clip-actions 100.0`、`--max-target-step 0.0`。如果你要做更保守的起步测试,可以再按日志逐步收紧这些参数 ## 9. RoboGauge 自动评估 @@ -670,18 +619,18 @@ cd /opt/RoboGauge python -m pip install -e . ``` -上面的最后一条命令必须在 `/opt/RoboGauge` 中执行。本文需要公开适配仓库 `ChenYouYuan0413/RoboGauge` 的 `go1` 分支,其中包含 `go1_lab.*` 任务;原始上游仓库用于方法参考,不能用 `go2_lab.*` 代替。安装后确认当前 commit 与任务注册,输出中必须出现 `go1_lab.flat`、`go1_lab.stairs_fd` 等任务: +上面的最后一条命令必须在 `/opt/RoboGauge` 中执行。本文需要公开适配仓库 `ChenYouYuan0413/RoboGauge` 的 `go1` 分支,其中包含 `go1_lab.*` 任务;安装后确认当前 commit 与任务注册,输出中必须出现 `go1_lab.flat`、`go1_lab.stairs_fd` 等任务: ```bash git --git-dir=/opt/RoboGauge/.git --work-tree=/opt/RoboGauge rev-parse HEAD /opt/envs/robogauge/bin/python -c "import robogauge.tasks; from robogauge.utils.task_register import task_register; print(*sorted(task_register.pipeline_classes), sep='\n')" ``` -若不存在 `go1_lab.*` 任务,不要用 `go2_lab.*` 代替,应先同步本地 Go1 适配代码。 +若不存在 `go1_lab.*` 任务,应先同步本地 Go1 适配代码 ### 9.2 单模型评估 -直接通过 `--model-path` 指定 26000 对应的部署版 TorchScript。不要传入训练 checkpoint `model_26000.pt`,它是包含优化器等状态的字典,不能被 `torch.jit.load()`。当前平地配置默认启用最大速度和对角速度;命令仍显式传入 `--goals`,以免配置默认值变化后评测范围静默改变: +直接通过 `--model-path` 指定 26000 对应的部署版 TorchScript。不要传入训练 checkpoint `model_26000.pt`,它是包含优化器等状态的字典,不能被 `torch.jit.load()`。当前平地配置默认启用最大速度和对角速度;命令仍显式传入 `--goals`,以免配置默认值变化后评测范围静默改变,不加 **--headless** 则为可视化查看: ```bash cd /opt/RoboGauge @@ -694,6 +643,7 @@ MUJOCO_GL=glfw MPLCONFIGDIR=/tmp/robogauge-matplotlib /opt/envs/robogauge/bin/py --headless ``` +![image-20260801200427939](E:/race_save/doge/dog_train_deploy_guide_doc/%E5%9B%9B%E8%B6%B3%E6%9C%BA%E5%99%A8%E7%8B%97%E8%AE%AD%E7%BB%83%E5%88%B0%E5%AE%9E%E6%9C%BA%E9%83%A8%E7%BD%B2%E5%85%A8%E6%B5%81%E7%A8%8B%E6%8C%87%E5%8D%97.assets/image-20260801200427939.png) 三级楼梯使用目标点任务。`--spawn-type level_eval` 固定评估出生点,避免和搜索最高等级时的出生点混淆: ```bash @@ -716,9 +666,7 @@ MUJOCO_GL=glfw MPLCONFIGDIR=/tmp/robogauge-matplotlib /opt/envs/robogauge/bin/py --headless ``` -`run.py --headless` 在 Linux 默认选择 EGL。本次评估机的 EGL 驱动不支持 `PLATFORM_DEVICE`,所以命令显式设置 `MUJOCO_GL=glfw`;GLFW 可能打印无法打开 X11 的 warning,但无窗口仿真仍可完成。如果目标机 EGL 工作正常,可改回 `MUJOCO_GL=egl`。 - -单任务的 `--task-name` 必须是注册表里的完整名称,例如 `go1_lab.flat` 或 `go1_lab.stairs_fd`,不能写成裸的 `go1_lab`。只有下面的 stress pipeline 把 `go1_lab` 当作机器人任务前缀,再拼接具体地形。 +单任务的 `--task-name` 必须是注册表里的完整名称,例如 `go1_lab.flat` 或 `go1_lab.stairs_fd`,不能写成裸的 `go1_lab`。只有下面的 stress pipeline 把 `go1_lab` 当作机器人任务前缀,再拼接具体地形 ### 9.3 跨地形压力测试 @@ -738,13 +686,13 @@ MUJOCO_GL=glfw MPLCONFIGDIR=/tmp/robogauge-matplotlib /opt/envs/robogauge/bin/py --headless ``` -`--num-processes` 应根据 CPU 核数和内存调整,不宜盲目设为最大逻辑核心数。 +`--num-processes` 应根据 CPU 核数和内存调整,不宜盲目设为最大逻辑核心数 ### 9.4 模型选择原则 -候选 checkpoint 应使用相同的任务、命令目标、地形、随机种子和物理参数评估。同时检查跟踪、安全、运动质量、各地形成功情况和多随机种子波动,不能只按最新轮次或单一综合分数选择发布模型。发布前仍需运行多随机种子、摩擦、质量和地形压力测试,并结合真实电机温度、电流与保护日志做最终判断。 +候选 checkpoint 应使用相同的任务、命令目标、地形、随机种子和物理参数评估。同时检查跟踪、安全、运动质量、各地形成功情况和多随机种子波动,不能只按最新轮次或单一综合分数选择发布模型。使用前仍需运行多随机种子、摩擦、质量和地形压力测试,并结合真实电机温度、电流与保护日志做最终判断 -RoboGauge 的 `dof_power` 是归一化质量分,不是瓦特或电机温度。它可以比较同条件 checkpoint,但不能据此断言真机不会过热。 +RoboGauge 的 `dof_power` 是归一化质量分,不是瓦特或电机温度。它可以比较同条件 checkpoint,但不能据此断言真机不会过热 ### 9.5 训练期间异步评估 @@ -774,21 +722,21 @@ OMNI_KIT_ACCEPT_EULA=YES /opt/envs/go2_rl_robotlab/bin/python scripts/rsl_rl/tra task_name="go1_lab.flat" ``` -检查文件为 `source/rsl_rl/rsl_rl/runners/on_policy_runner_cts.py`。裸的 `go1_lab` 不是单任务注册名,`go2_lab` 也会评估错误的机器人。更合理的长期修复是把评估任务写入训练配置,而不是继续硬编码。完成修复前不要启用 `--robogauge`。异步评估生成的是 `jit_models/policy_jit_.pt`;ONNX 仍需通过 `play.py` 导出。 +检查文件为 `source/rsl_rl/rsl_rl/runners/on_policy_runner_cts.py`。裸的 `go1_lab` 不是单任务注册名,`go2_lab` 也会评估错误的机器人。更合理的长期修复是把评估任务写入训练配置,而不是继续硬编码。完成修复前不要启用 `--robogauge`。异步评估生成的是 `jit_models/policy_jit_.pt`;ONNX 仍需通过 `play.py` 导出 -### 9.6 如何选择发布模型 +### 9.6 如何选择可以部署的模型 至少比较: -- Tracking:线速度、角速度是否准确。 -- Safety:关节范围、功耗、力矩平滑度是否合理。 -- Quality:姿态、急停、运动质量是否稳定。 -- Level:坡面、台阶、波浪和障碍的最高稳定难度。 -- 多 seed 方差:均值高但方差很大的策略不适合直接上机。 +- Tracking:线速度、角速度是否准确 +- Safety:关节范围、功耗、力矩平滑度是否合理 +- Quality:姿态、急停、运动质量是否稳定 +- Level:坡面、台阶、波浪和障碍的最高稳定难度 +- 多 seed 方差:均值高但方差很大的策略不适合直接上机 ## 10. 独立 MuJoCo sim2sim -这里推荐使用 `/opt/go1_deploy/deploy_rl_lab/deploy_go1_onnx_mujoco_lab.py`,因为它与 Lab 的 10 帧/450 维 ONNX 接口一致。 +这里使用 `/opt/go1_deploy/deploy_rl_lab/deploy_go1_onnx_mujoco_lab.py` ```bash cd /opt/go1_deploy/deploy_rl_lab @@ -797,7 +745,7 @@ MUJOCO_GL=glfw /opt/envs/robogauge/bin/python deploy_go1_onnx_mujoco_lab.py \ --onnx /opt/go1_deploy/deploy_rl_lab/policy_robotlab_26000.onnx ``` -这是带窗口和键盘的交互命令,需要可用的 X11/桌面。Linux 使用普通 `python`;只有 macOS 才通常需要 `mjpython`。脚本内部会 `chdir` 到自身目录,因此 `--onnx` 使用绝对路径。无图形环境应使用 8.4 节的 `--sample` 命令。 +这是带窗口和键盘的交互命令,需要可用的 X11/桌面。Linux 使用普通 `python`;只有 macOS 才通常需要 `mjpython`。脚本内部会 `chdir` 到自身目录,因此 `--onnx` 使用绝对路径。无图形环境应使用 8.4 节的 `--sample` 命令 楼梯测试: @@ -809,6 +757,8 @@ MUJOCO_GL=glfw /opt/envs/robogauge/bin/python deploy_go1_onnx_mujoco_lab.py \ --spawn-z 0.34 ``` +![屏幕截图 2026-08-01 161128](E:/race_save/doge/dog_train_deploy_guide_doc/%E5%9B%9B%E8%B6%B3%E6%9C%BA%E5%99%A8%E7%8B%97%E8%AE%AD%E7%BB%83%E5%88%B0%E5%AE%9E%E6%9C%BA%E9%83%A8%E7%BD%B2%E5%85%A8%E6%B5%81%E7%A8%8B%E6%8C%87%E5%8D%97.assets/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-08-01%20161128.png) + 键盘映射: | 按键 | 功能 | @@ -822,12 +772,12 @@ MUJOCO_GL=glfw /opt/envs/robogauge/bin/python deploy_go1_onnx_mujoco_lab.py \ sim2sim 重点检查: -- 初始零历史时是否平稳进入站姿。 -- 四条腿是否对应正确,左右/前后没有交换。 -- 正负 `vx`、`vy`、`wz` 的方向是否正确。 -- 50 Hz 策略周期、PD 参数、默认角和动作缩放是否与训练一致。 -- 平地、急停、转向、侧移、斜坡和台阶是否均无明显动作尖峰。 -- action、关节速度、机身 roll/pitch 是否出现持续增长。 +- 初始零历史时是否平稳进入站姿 +- 四条腿是否对应正确,左右/前后没有交换 +- 正负 `vx`、`vy`、`wz` 的方向是否正确 +- 50 Hz 策略周期、PD 参数、默认角和动作缩放是否与训练一致 +- 平地、急停、转向、侧移、斜坡和台阶是否均无明显动作尖峰 +- action、关节速度、机身 roll/pitch 是否出现持续增长 ## 11. BPU 量化 @@ -835,12 +785,12 @@ sim2sim 重点检查: BPU 量化不是把 ONNX 改一个后缀。至少需要: -1. 已通过接口检查的 `policy_robotlab_26000.onnx`。 -2. 与部署观测构建逻辑一致的 10 帧/450 维 `float32` PTQ 输入样本。 -3. 使用浮点 ONNX 对这批输入执行推理得到的参考输出。 -4. 浮点 ONNX、图变换 ONNX、量化模型三者的逐样本输出对比。 +1. 已通过接口检查的 `policy_robotlab_26000.onnx` +2. 与部署观测构建逻辑一致的 10 帧/450 维 `float32` PTQ 输入样本 +3. 使用浮点 ONNX 对这批输入执行推理得到的参考输出 +4. 浮点 ONNX、图变换 ONNX、量化模型三者的逐样本输出对比 -当前 26000 模型使用 `calibration_data_26000_robotlab_fast64/` 中的 64 个 PTQ 校验样本。这批数据来自 ONNX 推理流程,不是 X5 量化产生的模型 `.bin`。需要重新生成时,先检查供 `make_calibration_data.py` 使用的 ONNX 推理日志: +当前 26000 模型使用 `calibration_data_26000_robotlab_fast64/` 中的 64 个 PTQ 校验样本。这批数据来自 ONNX 推理流程。需要重新生成时,先检查供 `make_calibration_data.py` 使用的 ONNX 推理日志: ```bash find /opt/go1_deploy/logs \ @@ -848,11 +798,11 @@ find /opt/go1_deploy/logs \ -type f -print ``` -`make_calibration_data.py` 读取日志中的 `mode: RL` 和 45 维 `obs_single`,按部署顺序重建 10 帧/450 维历史,并写出工具链所需的 raw float32 校准输入 `.bin`。这里的 `.bin` 是 PTQ 输入文件;X5 编译完成后生成的模型也使用 `.bin` 后缀,但两者用途完全不同。脚本找不到匹配日志或有效样本不足时会中止,不会绕过数据准备继续编译。 +`make_calibration_data.py` 读取日志中的 `mode: RL` 和 45 维 `obs_single`,按部署顺序重建 10 帧/450 维历史,并写出工具链所需的 raw float32 校准输入 `.bin`。这里的 `.bin` 是 PTQ 输入文件;X5 编译完成后生成的模型也使用 `.bin` 后缀,但两者用途完全不同。脚本找不到匹配日志或有效样本不足时会中止,不会绕过数据准备继续编译 -路径 A 已随镜像提供 `calibration_data_26000_robotlab_fast64/`。量化脚本检测到目录中恰好有 64 个 `.bin` 时直接复用;路径 B 或样本数量不匹配时,才从上述 ONNX 推理日志重新生成。 +路径 A 已随镜像提供 `calibration_data_26000_robotlab_fast64/`。量化脚本检测到目录中恰好有 64 个 `.bin` 时直接复用;路径 B 或样本数量不匹配时,才从上述 ONNX 推理日志重新生成 -当前量化脚本会保留 actions 输出、降级 opset、包装为 BPU 需要的 4D 输入,并把 MoE grouped Conv 等价替换为 Gemm,以减少 CPU fallback。中间 norm 节点位于 actor 之前,不能随意删除或移到后处理。 +当前量化脚本会保留 actions 输出、降级 opset、包装为 BPU 需要的 4D 输入,并把 MoE grouped Conv 等价替换为 Gemm,以减少 CPU fallback。中间 norm 节点位于 actor 之前,不能随意删除或移到后处理 量化脚本内部流程如下: @@ -884,7 +834,7 @@ ONNX 推理流程日志 steps.jsonl | `--quant` | 量化策略 | 默认 `int16`,`int8` 仅作对照 | | `--docker-image` | D-Robotics CPU 工具链镜像 | X5/S100 各自不同 | -量化建议在 Mac 或训练机的 Docker 中完成,不在 X5/S100 板端跑 Docker。本文训练/量化主机的仓库固定为 `/opt/go1_deploy`;板端只负责加载产物做离线测速、数值对齐和实机部署。 +量化建议在 Mac 或训练机的 Docker 中完成,不在 X5/S100 板端跑 Docker。本文训练/量化主机的仓库固定为 `/opt/go1_deploy`;板端只负责加载产物做离线测速、数值对齐和实机部署 量化脚本内部直接调用 `docker`。运行 X5/S100 脚本前先验收 daemon: @@ -943,7 +893,7 @@ python3 deploy_rl_lab/bpu_deploy_x5/test_bpu_policy.py \ --repeat 1000 ``` -X5 的 featuremap 模型不要直接改用 `hobot_dnn.pyeasy_dnn.forward()`。当前项目默认通过 C++ DNN API,并按 infer、wait、release 的完整生命周期执行,以保证输出和 `hrt_model_exec infer` 对齐。 +X5 的 featuremap 模型不要直接改用 `hobot_dnn.pyeasy_dnn.forward()`。当前项目默认通过 C++ DNN API,并按 infer、wait、release 的完整生命周期执行,以保证输出和 `hrt_model_exec infer` 对齐 ### 11.3 S100 @@ -1004,27 +954,27 @@ S100 关键配置: 量化验收不能只看平均延迟,还要记录: -- 输入/输出名称、shape 和 dtype。 -- held-out 样本的最大绝对误差、平均绝对误差和余弦相似度。 -- 最大延迟和抖动是否满足 20 ms 控制周期。 -- 是否存在 CPU fallback 或频繁 BPU/CPU 子图切换。 -- 连续推理是否有资源泄漏、错误日志或偶发异常动作。 +- 输入/输出名称、shape 和 dtype +- held-out 样本的最大绝对误差、平均绝对误差和余弦相似度 +- 最大延迟和抖动是否满足 20 ms 控制周期 +- 是否存在 CPU fallback 或频繁 BPU/CPU 子图切换 +- 连续推理是否有资源泄漏、错误日志或偶发异常动作 ## 12. 实机部署边界 -### 12.1 SDK 保密说明 +### 12.1 SDK 说明 -实际部署使用私有 Go1 PRO SDK。本文只描述公开的控制契约和安全设计,不记录私有协议格式、加密材料、逆向过程或专有实现。需要公开复现时,应以 Unitree 官方 `unitree_legged_sdk` 的 `UDP`、`LowState`、`LowCmd` 和 `Safety` 接口为基线重新实现适配层。 +本文只描述公开的控制契约和安全设计,不记录私有协议格式。需要复现时,需要以 Unitree 官方 `unitree_legged_sdk` 的 `UDP`、`LowState`、`LowCmd` 和 `Safety` 接口为基线重新实现适配层 无论 SDK 如何实现,策略层与硬件层之间必须显式完成: -- 状态包有效性、时间戳和丢包检查。 -- 电机顺序到 `FR, FL, RR, RL` 策略顺序的映射。 -- IMU 四元数、角速度坐标系和单位转换。 -- 关节位置、速度、上一动作和指令的缩放。 -- ONNX 历史缓存的初始化、更新和复位。 -- 动作缩放、默认角叠加、目标限幅和变化率限制。 -- PD 控制、安全检查、发送周期和退出阻尼。 +- 状态包有效性、时间戳和丢包检查 +- 电机顺序到 `FR, FL, RR, RL` 策略顺序的映射 +- IMU 四元数、角速度坐标系和单位转换 +- 关节位置、速度、上一动作和指令的缩放 +- ONNX 历史缓存的初始化、更新和复位 +- 动作缩放、默认角叠加、目标限幅和变化率限制 +- PD 控制、安全检查、发送周期和退出阻尼 公开 SDK 可用于核对通用 API、结构体字段和安全调用方式,但不要直接运行带位置目标的官方示例。先只编译: @@ -1034,30 +984,89 @@ cmake -S /opt/unitree_legged_sdk -B /opt/unitree_legged_sdk/build cmake --build /opt/unitree_legged_sdk/build --parallel ``` -本地 `walk-these-ways/go1_gym_deploy/unitree_legged_sdk_bin/lcm_position.cpp` 可作为官方 SDK 接入策略控制环的公开参考。阅读时重点关注 UDP 收发线程、`LowState` 到策略观测的转换、`Safety` 调用和退出流程,不要照搬其网络地址、增益或速度范围到另一台机器人。 +阅读时重点关注 UDP 收发线程、`LowState` 到策略观测的转换、`Safety` 调用和退出流程,不要照搬其网络地址、增益或速度范围到另一台机器人 ### 12.2 硬件、接线与网络 -> 本节按维护者要求留空,由实际设备负责人填写。部署前不得跳过。 +本次部署所使用的是宇树go1 +#### 通信控制 -```text -TODO(维护者填写) +内部通信结构如下: + +![img](E:/race_save/doge/dog_train_deploy_guide_doc/%E5%9B%9B%E8%B6%B3%E6%9C%BA%E5%99%A8%E7%8B%97%E8%AE%AD%E7%BB%83%E5%88%B0%E5%AE%9E%E6%9C%BA%E9%83%A8%E7%BD%B2%E5%85%A8%E6%B5%81%E7%A8%8B%E6%8C%87%E5%8D%97.assets/NetworkLayout.png) + +内部的控制都是通过一台机器狗内部的交换机完成的,通过狗背部暴露出的网口即可完成与它的内部通信(前提是ip需要是统一网段192.168.123.xxx,需要自行修改固定s100和x5的网口的ip,比如配置eth0的ip为192.168.123.222),检验是否连接到内部: -1. Go1 具体型号与固件版本: -2. S100/RDK X5 型号、系统镜像与供电: -3. 机器人、主控、交换机/网卡接线图: -4. 网口名称、静态 IP、子网掩码和路由: -5. 遥控器型号及按键映射: -6. 吊架/保护绳安装方式和承重: -7. 物理急停、断电和现场人员分工: -8. 启停 sport mode 的设备专用步骤: ``` +ping 192.168.123.161 +``` + +下图是网线的连接示意图 + +![image-20260801193808916](E:/race_save/doge/dog_train_deploy_guide_doc/%E5%9B%9B%E8%B6%B3%E6%9C%BA%E5%99%A8%E7%8B%97%E8%AE%AD%E7%BB%83%E5%88%B0%E5%AE%9E%E6%9C%BA%E9%83%A8%E7%BD%B2%E5%85%A8%E6%B5%81%E7%A8%8B%E6%8C%87%E5%8D%97.assets/image-20260801193808916.png) + +![image-20260801191848283](E:/race_save/doge/dog_train_deploy_guide_doc/%E5%9B%9B%E8%B6%B3%E6%9C%BA%E5%99%A8%E7%8B%97%E8%AE%AD%E7%BB%83%E5%88%B0%E5%AE%9E%E6%9C%BA%E9%83%A8%E7%BD%B2%E5%85%A8%E6%B5%81%E7%A8%8B%E6%8C%87%E5%8D%97.assets/image-20260801191848283.png) + + + +之后使用官方的sdk:即可完成对底层的lowlevel电机控制 + +同时建议直接将s100/x5的ssh公钥复制到树莓派(192.168.123.161)上来进行ssh的免密访问 + +``` +# 在机器狗身上的运动控制板树莓派(192.168.123.161)上 +mkdir -p ~/.ssh +chmod 700 ~/.ssh +touch ~/.ssh/authorized_keys +chmod 600 ~/.ssh/authorized_keys +vim ~/.ssh/authorized_keys +# 把公钥粘贴到这里面,vim使用: + wq 退出并保存 +``` + +#### 供电 + +我们使用的s100需要19v的供电,宇树go1的背部有给出对外的接口,如图 + +![image-20260801192200981](E:/race_save/doge/dog_train_deploy_guide_doc/%E5%9B%9B%E8%B6%B3%E6%9C%BA%E5%99%A8%E7%8B%97%E8%AE%AD%E7%BB%83%E5%88%B0%E5%AE%9E%E6%9C%BA%E9%83%A8%E7%BD%B2%E5%85%A8%E6%B5%81%E7%A8%8B%E6%8C%87%E5%8D%97.assets/image-20260801192200981.png) + +是一个24v xt30的接口,我们只需要使用一个24v转19v的降压模块即可(同时注意电流承载大致6A) + +建议接入之前先使用可调电源和万用表测试输入输出电压 + +![屏幕截图 2026-08-01 192536](E:/race_save/doge/dog_train_deploy_guide_doc/%E5%9B%9B%E8%B6%B3%E6%9C%BA%E5%99%A8%E7%8B%97%E8%AE%AD%E7%BB%83%E5%88%B0%E5%AE%9E%E6%9C%BA%E9%83%A8%E7%BD%B2%E5%85%A8%E6%B5%81%E7%A8%8B%E6%8C%87%E5%8D%97.assets/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-08-01%20192536.png) + +![image-20260801192620807](E:/race_save/doge/dog_train_deploy_guide_doc/%E5%9B%9B%E8%B6%B3%E6%9C%BA%E5%99%A8%E7%8B%97%E8%AE%AD%E7%BB%83%E5%88%B0%E5%AE%9E%E6%9C%BA%E9%83%A8%E7%BD%B2%E5%85%A8%E6%B5%81%E7%A8%8B%E6%8C%87%E5%8D%97.assets/image-20260801192620807.png) + +对于s100还需要一根dc的接口 + +如图接线: + +![img_v3_02145_97a765f5-ee43-4437-b264-4555bfb617eg](E:/race_save/doge/dog_train_deploy_guide_doc/%E5%9B%9B%E8%B6%B3%E6%9C%BA%E5%99%A8%E7%8B%97%E8%AE%AD%E7%BB%83%E5%88%B0%E5%AE%9E%E6%9C%BA%E9%83%A8%E7%BD%B2%E5%85%A8%E6%B5%81%E7%A8%8B%E6%8C%87%E5%8D%97.assets/img_v3_02145_97a765f5-ee43-4437-b264-4555bfb617eg.jpg) + +左右两边黄色打印机只是支撑的作用(两个小claude) + +接上go1就是这样: + +![image-20260801193333084](E:/race_save/doge/dog_train_deploy_guide_doc/%E5%9B%9B%E8%B6%B3%E6%9C%BA%E5%99%A8%E7%8B%97%E8%AE%AD%E7%BB%83%E5%88%B0%E5%AE%9E%E6%9C%BA%E9%83%A8%E7%BD%B2%E5%85%A8%E6%B5%81%E7%A8%8B%E6%8C%87%E5%8D%97.assets/image-20260801193333084.png) + +此外建议加一根足够强劲的狗绳来在紧急时候减小对小电脑的冲击,起到保护作用 + + +对于x5就很方便,只需要有支持快充的充电宝和typec线即可完成供电,无需额外的降压 +#### 实际部署效果 + +s100部署: + + +x5部署: + +【溜溜狗~】 https://www.bilibili.com/video/BV1AT3B6GEs2/?share_source=copy_web&vd_source=927818b43cb3455737f81900c0cf8608 ## 13. 软件安全策略 ### 13.1 控制权互斥 -低层控制前必须确认原厂 sport 进程已停止,避免两个控制源同时发送命令。不要在机器人站立或行走时直接停止 sport mode,先让机器人处于受支撑或安全趴卧状态。 +低层控制前必须确认sport 进程已停止,避免两个控制源同时发送命令。不要在机器人站立或行走时直接停止 sport mode,先让机器人处于受支撑或安全趴卧状态 检查示例: @@ -1065,84 +1074,84 @@ TODO(维护者填写) pgrep -fl 'keep_sport_alive|Legged_sport|appTransit' ``` -恢复原厂控制前,先结束自定义低层进程并确认已经发送阻尼停机,再恢复 sport mode。 +恢复原厂控制前,先结束自定义低层进程并确认已经发送阻尼停机,再恢复 sport mode ### 13.2 启动守卫 -- 默认模式只能读取状态,不能发送 RL 关节目标。 -- 必须有显式 `--enable-rl` 才允许进入 RL 状态。 -- 收到第一帧有效、完整且时间连续的 LowState 前,只发送停止哨兵或保持阻尼。 -- 检查电机顺序、模型 shape、NaN/Inf、历史长度和控制频率。 -- RL 刚启用时先预热历史;预热期间保持默认站姿。 -- 从默认站姿向 RL 目标渐变,限制每周期目标变化量。 +- 默认模式只能读取状态,不能发送 RL 关节目标 +- 必须有显式 `--enable-rl` 才允许进入 RL 状态 +- 收到第一帧有效、完整且时间连续的 LowState 前,只发送停止哨兵或保持阻尼 +- 检查电机顺序、模型 shape、NaN/Inf、历史长度和控制频率 +- RL 刚启用时先预热历史;预热期间保持默认站姿 +- 从默认站姿向 RL 目标渐变,限制每周期目标变化量 ### 13.3 每周期保护 每个 20 ms 策略周期至少检查: -- 状态包是否超时、丢失或校验失败。 -- 关节位置是否超硬限位或安全软限位。 -- 关节速度是否超过部署阈值。 -- 估计力矩和命令力矩是否超过电机限制。 -- action 是否有限、是否超过软/硬跳闸阈值。 -- 新关节目标与当前目标、实测位置的差值是否过大。 -- IMU 角速度以及 roll/pitch 是否超过阈值。 -- 推理时间和整个控制循环是否超过 20 ms deadline。 -- 电量、温度、通信状态和错误码是否正常。 +- 状态包是否超时、丢失或校验失败 +- 关节位置是否超硬限位或安全软限位 +- 关节速度是否超过部署阈值 +- 估计力矩和命令力矩是否超过电机限制 +- action 是否有限、是否超过软/硬跳闸阈值 +- 新关节目标与当前目标、实测位置的差值是否过大 +- IMU 角速度以及 roll/pitch 是否超过阈值 +- 推理时间和整个控制循环是否超过 20 ms deadline +- 电量、温度、通信状态和错误码是否正常 -任一关键检查失败应进入 `FAULT` 或 `IDLE damping`,清零历史和上一动作。禁止捕获异常后静默继续运行。 +任一关键检查失败应进入 `FAULT` 或 `IDLE damping`,清零历史和上一动作。禁止捕获异常后静默继续运行 ### 13.4 力矩、速度与位置限制 -训练中的 `33.5 Nm` 是仿真执行器上限,不等于真机调试时应直接允许的命令。首次测试应从官方安全接口允许的保守比例开始,并根据日志逐级放开。 +训练中的 `33.5 Nm` 是仿真执行器上限,不等于真机调试时应直接允许的命令。首次测试应从官方安全接口允许的保守比例开始,并根据日志逐级放开 位置控制命令即使命令前馈力矩为零,也会通过 PD 误差产生实际力矩,因此: -- 增大 `Kp`、目标跳变量或目标与实测位置差都可能造成力矩尖峰。 -- `power_factor` 不能替代实测 `tauEst` 保护。 -- 触发力矩保护时,应优先减小目标变化、速度指令或 PD 增益,不能只提高保护阈值。 -- 关节硬限位、位置偏差保护、速度保护和力矩保护必须同时存在。 +- 增大 `Kp`、目标跳变量或目标与实测位置差都可能造成力矩尖峰 +- `power_factor` 不能替代实测 `tauEst` 保护 +- 触发力矩保护时,应优先减小目标变化、速度指令或 PD 增益,不能只提高保护阈值 +- 关节硬限位、位置偏差保护、速度保护和力矩保护必须同时存在 ### 13.5 停机路径 至少准备三条独立路径: -1. 遥控器软急停:当前状态机使用 `L2` 回到 `IDLE damping`。 -2. `Ctrl+C`:捕获后连续发送多帧阻尼命令再退出。 -3. 物理断电:现场人员随时可以执行,且不依赖已被停止的原厂进程。 +1. 遥控器软急停:当前状态机使用 `L2` 回到 `IDLE damping` +2. `Ctrl+C`:捕获后连续发送多帧阻尼命令再退出 +3. 物理断电:现场人员随时可以执行,且不依赖已被停止的原厂进程 -急停触发后不得自动恢复到 RL。必须重新检查故障原因,从校准或保持状态重新开始。 +急停触发后不得自动恢复到 RL。必须重新检查故障原因,从校准或保持状态重新开始 ## 14. 分级实机测试流程 -以下步骤必须按顺序通过。任何异常都应保存日志并停止,不要连续试错。 +以下步骤必须按顺序通过。任何异常都应保存日志并停止,不要连续试错 ### 14.1 第 0 级:不上电机的离线检查 -- 用相同 450 维输入比较 PyTorch、ONNX 和 BPU 输出。 -- 检查 12 维动作的顺序、符号、范围和有限性。 -- 测量平均、P99 和最大推理时间。 -- 对零输入、PTQ 校验输入和边界输入做回归。 +- 用相同 450 维输入比较 PyTorch、ONNX 和 BPU 输出 +- 检查 12 维动作的顺序、符号、范围和有限性 +- 测量平均、P99 和最大推理时间 +- 对零输入、PTQ 校验输入和边界输入做回归 ### 14.2 第 1 级:只读 LowState -只连接 MCU 并记录 IMU、12 个关节位置/速度/力矩、电量、错误码和遥控器,不发送电机目标。手动缓慢移动悬空的腿,确认索引、符号和单位。 +只连接 MCU 并记录 IMU、12 个关节位置/速度/力矩、电量、错误码和遥控器,不发送电机目标。手动缓慢移动悬空的腿,确认索引、符号和单位 ### 14.3 第 2 级:只构建观测 构建 45 维单帧和 450 维历史,但不运行策略。逐项核对: -- 静止水平时投影重力方向正确。 -- 手动旋转机身时角速度轴和符号正确。 -- 手动移动单腿时仅对应三个关节变化。 -- 零速度命令为 `[0, 0, 0]`。 -- 历史从零初始化,并按正确顺序滑动更新。 +- 静止水平时投影重力方向正确 +- 手动旋转机身时角速度轴和符号正确 +- 手动移动单腿时仅对应三个关节变化 +- 零速度命令为 `[0, 0, 0]` +- 历史从零初始化,并按正确顺序滑动更新 ### 14.4 第 3 级:只推理不发命令 -运行 ONNX/BPU 推理并记录 action,仍不发送电机命令。检查 action 无 NaN/Inf、无持续饱和、静止状态不发散,ONNX 和 BPU 的动作差在离线验收范围内。 +运行 ONNX/BPU 推理并记录 action,仍不发送电机命令。检查 action 无 NaN/Inf、无持续饱和、静止状态不发散,ONNX 和 BPU 的动作差在离线验收范围内 -从这一级开始,命令必须显式保留 `--log-dir logs`;只要要判断板端实时性,就同时加 `--log-timing`。日志目录会在启动时自动创建,终端退出时会打印 `Log saved:` 路径。 +从这一级开始,命令必须显式保留 `--log-dir logs`;只要要判断板端实时性,就同时加 `--log-timing`。日志目录会在启动时自动创建,终端退出时会打印 `Log saved:` 路径 X5 示例: @@ -1178,36 +1187,36 @@ python3 deploy_rl_lab/bpu_deploy_s100/deploy_go1_robotlab_bpu_s100_fastcpp.py \ IDLE -> CALIBRATE -> HOLD -> OBS_TEST -> INFER_TEST ``` -- `R2` 每次只前进一层。 -- `L2` 在任意激活状态回到 `IDLE damping`。 -- 未加 `--enable-rl` 时,`INFER_TEST -> RL` 必须被守卫拒绝。 -- `Ctrl+C` 必须进入阻尼后退出。 +- `R2` 每次只前进一层 +- `L2` 在任意激活状态回到 `IDLE damping` +- 未加 `--enable-rl` 时,`INFER_TEST -> RL` 必须被守卫拒绝 +- `Ctrl+C` 必须进入阻尼后退出 ### 14.6 第 5 级:悬空 RL,零速度命令 -只有前四级通过后才能增加 `--enable-rl`。第一轮禁用摇杆速度输入,只验证站姿、动作方向、关节速度、力矩和急停。观察 5 到 10 秒后主动回到 HOLD,不要长时间连续运行。 +只有前四级通过后才能增加 `--enable-rl`。第一轮禁用摇杆速度输入,只验证站姿、动作方向、关节速度、力矩和急停。观察 5 到 10 秒后主动回到 HOLD,不要长时间连续运行 ### 14.7 第 6 级:悬空 RL,小幅指令 -一次只测试一个方向:小 `vx`、小 `vy`、小 `wz`。每次测试后回零,检查正负方向和动作对称性。逐个参数变化,不要同时修改 PD、action clip、目标变化率和遥控比例。 +一次只测试一个方向:小 `vx`、小 `vy`、小 `wz`。每次测试后回零,检查正负方向和动作对称性。逐个参数变化,不要同时修改 PD、action clip、目标变化率和遥控比例 ### 14.8 第 7 级:平整地面低速 -- 使用保护绳,现场一人操控、一人负责断电。 -- 从零指令站立开始,再给短时小速度。 -- 首轮只测试前进、停止和软急停。 -- 之后再测试后退、侧移和转向。 -- 每轮结束检查电机温度、日志和机械结构。 +- 使用保护绳,现场一人操控、一人负责断电 +- 从零指令站立开始,再给短时小速度 +- 首轮只测试前进、停止和软急停 +- 之后再测试后退、侧移和转向 +- 每轮结束检查电机温度、日志和机械结构 ### 14.9 第 8 级:ONNX/BPU 对照 先用已经通过地面测试的 ONNX 版本确定基线,再在相同软件保护、相同指令、相同场地上测试 BPU。两次测试只替换推理后端。若 BPU 行为异常,回到离线输入逐帧对比,不能通过放宽关节或姿态保护继续测试。 -对照日志至少要能证明三件事:同一段动作里 `commands` 接近一致,`action_raw/action_safe/joint_targets` 的差异在离线验收范围内,`policy_ms/loop_dt_ms/state_age_ms` 没有让 BPU 版本比 ONNX 版本产生额外控制延迟。若 BPU 端 `policy_ms` 很低但 `loop_dt_ms` 仍不稳,应继续查 SDK 收包、构包和系统调度,而不是只看 BPU 占用率。 +对照日志至少要能证明三件事:同一段动作里 `commands` 接近一致,`action_raw/action_safe/joint_targets` 的差异在离线验收范围内,`policy_ms/loop_dt_ms/state_age_ms` 没有让 BPU 版本比 ONNX 版本产生额外控制延迟。若 BPU 端 `policy_ms` 很低但 `loop_dt_ms` 仍不稳,应继续查 SDK 收包、构包和系统调度,而不是只看 BPU 占用率 ### 14.10 第 9 级:坡面、台阶和扰动 -复杂地形是最后阶段。先从低难度、低速度和正向通过开始,再逐步测试侧向、反向、急停和摩擦变化。每次增加难度前必须确认前一级多次可复现。 +复杂地形是最后阶段。先从低难度、低速度和正向通过开始,再逐步测试侧向、反向、急停和摩擦变化。每次增加难度前必须确认前一级多次可复现 ## 15. 日志与验收 @@ -1224,7 +1233,7 @@ steps.jsonl logs/robotlab_go1_deploy_YYYYMMDD_HHMMSS/ ``` -不要关闭日志来“省性能”。实机调试阶段宁可降低打印频率,也要保留 JSONL 日志;后续量化校准、ONNX/BPU 对齐、力矩保护分析和动作异常定位都依赖这些记录。 +不要关闭日志来“省性能”。实机调试阶段宁可降低打印频率,也要保留 JSONL 日志;后续量化校准、ONNX/BPU 对齐、力矩保护分析和动作异常定位都依赖这些记录 `metadata.json` 用来复现实验条件。当前部署脚本会自动写入: @@ -1238,7 +1247,7 @@ history_expected_span_ms 命令行传入的所有标量参数 ``` -发布或多人复现实验时,还应额外记录 Git commit、模型哈希、板端系统版本、BPU runtime 版本、设备型号、测试人员和场景。只给一条 `Log saved:` 路径而没有对应模型与参数,后续无法判断问题来自策略、量化、SDK 还是现场操作。 +发布或多人复现实验时,还应额外记录 Git commit、模型哈希、板端系统版本、BPU runtime 版本、设备型号、测试人员和场景。只给一条 `Log saved:` 路径而没有对应模型与参数,后续无法判断问题来自策略、量化、SDK 还是现场操作 `steps.jsonl` 是逐周期日志。当前脚本每条记录至少包含: @@ -1264,60 +1273,40 @@ loop_dt_ms / recv_ms / policy_ms / work_ms / state_fresh / state_age_ms - `motor_mode`、`motor_reserve`、`motor_temperature`:定位电机是否掉出 servo、是否有错误码或过热。 - `loop_dt_ms`、`recv_ms`、`policy_ms`、`work_ms`、`state_age_ms`:判断慢在推理、收包、构包发送还是系统调度。 -分析日志时不要只看最后一帧。应从 `state_reason` 第一次不为 `ok`、`action_safe` 第一次明显被 clip、`motor_mode` 第一次异常、`tau_est` 第一次接近阈值、`loop_dt_ms` 第一次超过 20 ms 的位置向前回看至少 1 到 2 秒。 +分析日志时不要只看最后一帧。应从 `state_reason` 第一次不为 `ok`、`action_safe` 第一次明显被 clip、`motor_mode` 第一次异常、`tau_est` 第一次接近阈值、`loop_dt_ms` 第一次超过 20 ms 的位置向前回看至少 1 到 2 秒 一次测试通过的最低条件: -- 无 NaN/Inf、状态超时和控制周期持续超期。 -- 电机顺序、坐标系和指令方向全部正确。 -- 无硬限位、速度、力矩、姿态或动作异常跳闸。 -- `L2`、`Ctrl+C` 和物理断电路径均已由现场演练确认。 -- ONNX/BPU 输出差异与离线结果一致。 -- 行为可在相同条件下重复,而不是偶然成功一次。 +- 无 NaN/Inf、状态超时和控制周期持续超期 +- 电机顺序、坐标系和指令方向全部正确 +- 无硬限位、速度、力矩、姿态或动作异常跳闸 +- `L2`、`Ctrl+C` 和物理断电路径均已由现场演练确认 +- ONNX/BPU 输出差异与离线结果一致 +- 行为可在相同条件下重复,而不是偶然成功一次 ## 16. 常见问题 ### 16.1 策略在 IsaacLab 正常,MuJoCo 立即摔倒 -优先检查关节顺序、默认关节角、观测历史排列、IMU 四元数格式、动作缩放、PD 参数和策略周期。不要先调奖励或增加力矩。 +优先检查关节顺序、默认关节角、观测历史排列、IMU 四元数格式、动作缩放、PD 参数和策略周期。不要先调奖励或增加力矩 ### 16.2 ONNX 输出维度正确但动作异常 -检查输入是 450 维按观测项分组的历史,而不是 10 个单帧直接拼接;同时确认输入已经应用训练时的缩放,上一动作使用的是实际送入策略链路的动作定义。 +检查输入是 450 维按观测项分组的历史,而不是 10 个单帧直接拼接;同时确认输入已经应用训练时的缩放,上一动作使用的是实际送入策略链路的动作定义,尤其确认重力方向 ### 16.3 BPU 很快,但真机表现比 ONNX 差 -速度合格不代表数值合格。使用同一批 PTQ 校验输入逐帧比较 ONNX/BPU,重点查 featuremap 输入、量化校准分布、输出 reshape、CPU fallback 和 runtime 调用生命周期。 +速度合格不代表数值合格。使用同一批 PTQ 校验输入逐帧比较 ONNX/BPU,重点查 featuremap 输入、量化校准分布、输出 reshape、CPU fallback 和 runtime 调用生命周期 ### 16.4 TensorBoard 总回报上涨,但 RoboGauge 下降 -先检查是否跨过 20000 或 50000 轮的速度指令课程切换。课程变难后总回报下降、非法接触短时上升是预期现象,旧课程和新课程的绝对回报不能直接比较。若命令范围和地形等级都未变化,才进一步排查训练奖励偏向速度跟踪、牺牲力矩/姿态/关节裕度或后期 checkpoint 对训练域过拟合。无论哪种情况,都应比较分项指标和多个 checkpoint,不要只保留最后一轮。 +先检查是否跨过 20000 或 50000 轮的速度指令课程切换。课程变难后总回报下降、非法接触短时上升是预期现象,旧课程和新课程的绝对回报不能直接比较。若命令范围和地形等级都未变化,才进一步排查训练奖励偏向速度跟踪、牺牲力矩/姿态/关节裕度或后期 checkpoint 对训练域过拟合。无论哪种情况,都应比较分项指标和多个 checkpoint,不要只保留最后一轮 ### 16.5 真机一进入 RL 就力矩保护 -立即停机。依次检查动作方向、目标角、目标单步变化、PD 增益、当前位置偏差、观测缩放和历史初始化。不要把提高 `power_factor` 作为第一反应。 +立即停机。依次检查动作方向、目标角、目标单步变化、PD 增益、当前位置偏差、观测缩放和历史初始化。不要把提高 `power_factor` 作为第一反应 -## 17. 发布前检查清单 - -- [ ] RoboGo 镜像名称、拉取命令、容器启动参数和持久化目录已补全;当前文档中的阻断项不再是 TODO。 -- [ ] `/opt/IsaacLab` 为 `v2.3.2`,pip 环境为 IsaacLab `2.3.2.post1`、Isaac Sim `5.1.0.0`、PyTorch `2.7.0`,且没有重新挂载旧 `/opt/IsaacSim`。 -- [ ] 运行用户可写训练、RoboGauge、MuJoCo 和 Isaac Sim runtime 目录,且 `OMNI_KIT_ACCEPT_EULA=YES` 已注入。 -- [ ] 镜像 1 轮训练自检通过,并保存 `model_0.pt`、日志和参数文件。 -- [ ] 硬件、接线、网络和急停章节已由设备负责人补全。 -- [ ] 所有仓库 commit 和 Python 依赖已记录。 -- [ ] 候选 checkpoint 已注明课程阶段,并完成 TensorBoard 与 RoboGauge 对比。 -- [ ] 最终选定 checkpoint 已完成 IsaacLab play、TorchScript/ONNX 导出及哈希记录。 -- [ ] ONNX 输入 450、输出 12,关节顺序为 `FR, FL, RR, RL`。 -- [ ] RoboGauge 单任务使用完整的 `go1_lab.*` 注册名,而非裸 `go1_lab` 或 `go2_lab`。 -- [ ] MuJoCo 平地、转向、侧移、急停和台阶测试通过。 -- [ ] PTQ 输入、ONNX 参考输出与模型版本一致。 -- [ ] X5/S100 量化模型通过离线精度和延迟验收。 -- [ ] X5/S100 工具链归档已通过 SHA-256 校验,并在具备 Docker daemon 的主机完成 `docker load`。 -- [ ] 私有 SDK 的协议、密钥和专有实现未写入公开文档。 -- [ ] 实机测试严格完成只读、观测、推理、状态机、悬空、地面分级流程。 -- [ ] 每条停机路径均已实际演练。 - -## 18. 参考资料 +## 17. 参考资料 - [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) @@ -1328,5 +1317,6 @@ loop_dt_ms / recv_ms / policy_ms / work_ms / state_fresh / state_age_ms - [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` -- 本地 `RoboGauge/assets/docs/go1_policy_io_zh.md` +- [MAVProxyUser/YushuTechUnitreeGo1: 宇树科技 Yushu Technology (Unitree) go1 development notes](https://github.com/MAVProxyUser/YushuTechUnitreeGo1/tree/main) +- [V3.7.0 | RDK S100/S600 DOC](https://developer.d-robotics.cc/rdk_s_doc/Advanced_development/toolchain_development/algorithm_toolchain/overview?v=4.0.5&p=RDK+S100) +- [7.3.1 简介 | RDK X3/X5 DOC](https://developer.d-robotics.cc/rdk_x_doc/Advanced_development/toolchain_development/overview?v=3.5.0&p=RDK+X5)