This commit is contained in:
MobKBK
2026-08-01 20:13:36 +08:00
parent c8a7718e41
commit e684573c59
13 changed files with 259 additions and 269 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 494 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@@ -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 风险
- **CTSConcurrent Teacher-Student**teacher 可使用地形高度、接触力、关节力矩等特权信息student 仅使用真机可获得的本体感知历史。两者在训练期间并行优化,使 student 学会从历史观测中估计隐含环境信息。
- **MoEMixture 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 \
<RoboGo镜像>
```
进入容器后验收 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/<REPO>/.git --work-tree=/opt/<REPO> ...`,不要为省事把所有系统目录加入 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量化时需要和 CondaConda/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 <USER>@<TRAIN_HOST>
@@ -552,7 +500,8 @@ ssh -L 6006:127.0.0.1:6006 <USER>@<TRAIN_HOST>
| `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 <RUN_DIR>/exported/policy.onnx /opt/RoboGauge/resources/models/go1/policy_rob
cp <RUN_DIR>/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_<ITER>.pt`ONNX 仍需通过 `play.py` 导出
检查文件为 `source/rsl_rl/rsl_rl/runners/on_policy_runner_cts.py`。裸的 `go1_lab` 不是单任务注册名,`go2_lab` 也会评估错误的机器人。更合理的长期修复是把评估任务写入训练配置,而不是继续硬编码。完成修复前不要启用 `--robogauge`。异步评估生成的是 `jit_models/policy_jit_<ITER>.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)