前置知识:已阅读 HelloWorld 入门。
一、整体流程概览
这个 Notebook 演示了**篮球平衡(Ball Balance)**任务,机器狗需要站在一个篮球上保持不摔倒。
通俗理解:就像让人站在瑜伽球上保持平衡,机器狗需要不断调整关节来维持稳定。
二、逐步骤解读
步骤 1:环境配置
importos os.environ.setdefault("MUJOCO_GL","egl")os.environ.setdefault("OPENBLAS_NUM_THREADS","1")os.environ.setdefault("OMP_NUM_THREADS","4")环境变量解读:
| 环境变量 | 通俗解释 |
|---|---|
MUJOCO_GL=egl | 告诉 MuJoCo 使用 EGL 渲染(无显示器的服务器环境也能渲染画面) |
OPENBLAS_NUM_THREADS=1 | 限制数学计算库使用 1 个线程,避免多线程冲突 |
OMP_NUM_THREADS=4 | 允许 OpenMP 并行计算使用 4 个线程,加速矩阵运算 |
通俗比喻:就像给程序设置"工作模式",告诉它用什么方式画图、用多少 CPU 核心计算。
步骤 2:依赖检查
importimportlib.metadataasmetadataimportmujocoimportonnxruntime gpu_check=subprocess.run([str(MODEL_ENV/"bin/python"),"-c","import torch; ..."])专业库解读:
| 库/工具 | 通俗解释 |
|---|---|
importlib.metadata | 查看已安装 Python 包的版本信息 |
mujoco | 物理仿真引擎,模拟重力、碰撞、关节运动 |
onnxruntime | 运行 ONNX 格式神经网络模型的引擎 |
torch(GPU 检查) | PyTorch 深度学习框架,这里检查是否有 GPU 可用 |
GPU 检查在做什么:
- 尝试导入
torch并检查 CUDA 是否可用 - 如果有 GPU,后续训练会更快
- 没有 GPU 也能运行,只是训练慢一些
步骤 3:加载预训练策略模型
POLICY=prepare_policy()print("策略模型已加载:",POLICY)专业概念解读:
| 概念 | 通俗解释 |
|---|---|
| 预训练模型(Pre-trained Model) | 已经在仿真中训练好的"大脑",可以直接使用,不需要从头训练 |
| prepare_policy() | 自定义函数,下载或加载策略模型文件 |
通俗比喻:就像下载一个已经学会平衡的"老师傅",直接让它教机器狗怎么站篮球。
步骤 4:创建 MuJoCo 仿真环境
sim=BallBalanceSimulation(PLAYGROUND,POLICY)print("模型输入:",[(x.name,x.shape)forxinsim.session.get_inputs()])print("模型输出:",[(x.name,x.shape)forxinsim.session.get_outputs()])专业概念解读:
| 概念 | 通俗解释 |
|---|---|
| BallBalanceSimulation | 自定义封装类,把 MuJoCo 仿真器、篮球、机器狗打包成一个对象 |
| 模型输入 | 机器狗的姿态、篮球的位置、相对速度等信息 |
| 模型输出 | 14 个关节的目标位置,告诉机器狗怎么调整姿势 |
与 HelloWorld 的区别:
- HelloWorld:平地走路,输入是机器狗自身状态
- 篮球平衡:输入还包括篮球的位置和滚动速度,策略需要额外考虑球的动态
步骤 5:单步推理测试
sim.stop()observation=sim.observation()action=sim.session.run([sim.output_name],{sim.input_name:observation})[0]target=sim.apply_action(action)for_inrange(4):mujoco.mj_step(sim.model,sim.data)这段代码在做什么:
- 发送"停止"命令,让机器狗尝试保持静止
- 获取当前观测(机器狗姿态 + 篮球状态)
- 策略模型推理,得到关节目标
- 应用到仿真器
- 推进 4 步物理仿真
通俗比喻:让机器狗站上篮球,看它第一反应怎么调整姿势。
步骤 6:闭环控制循环
VIDEO_PATH=OUTPUT/"ball_balance_demo.mp4"writer=imageio.get_writer(VIDEO_PATH,fps=50,codec="libx264",...)trace=[]defrun_for_seconds(seconds,phase,realtime=False):steps=round(seconds/sim.control_dt)forstepinrange(steps):obs=sim.observation()actions=sim.session.run(...)[0]sim.data.ctrl[:]=sim.default_pose+sim.action_scale*actions[0]for_inrange(4):mujoco.mj_step(sim.model,sim.data)trace.append({...})frame=sim.render()writer.append_data(frame)与 HelloWorld 的区别:
- 控制循环结构相同(观测→推理→执行→仿真)
- 但
trace记录的数据不同:增加了篮球位置、机器狗相对球的偏移等 - 失稳判断更严格:不仅检查高度,还检查是否从球上掉下来
步骤 7:平衡演示
sim.stop()run_for_seconds(1.0,"settle")run_for_seconds(10.0,"balance")演示流程:
- settle(1秒):机器狗站上篮球,调整初始姿势
- balance(10秒):持续保持平衡,篮球可能会滚动,机器狗需要不断调整
通俗比喻:就像看杂技演员站在球上表演,球会滚动,演员要不断调整重心。
步骤 8:数据分析
report=save_report(OUTPUT/"balance_report.json",trace,POLICY)print("累计平衡步数:",report["steps"])print("最大偏移:",report["max_offset_m"])print("最终状态:",report["final_state"])关键指标解读:
| 指标 | 通俗解释 |
|---|---|
steps | 总共执行了多少步控制循环 |
max_offset_m | 机器狗相对篮球中心的最大偏移距离(米) |
final_state | 最终是否成功保持平衡 |
步骤 9:可视化图表
importmatplotlib.pyplotasplt t=np.asarray([row["time_s"]forrowintrace])fig,axes=plt.subplots(3,1,figsize=(9,7),sharex=True)axes[0].plot(t,[row["ball_x"]forrowintrace],label="ball position x")axes[1].plot(t,[row["dog_offset_m"]forrowintrace],label="dog offset from ball")axes[2].plot(t,[row["upright_cos"]forrowintrace],label="uprightness")三张图分别展示:
- 篮球位置:篮球在 X 方向的移动轨迹
- 机器狗偏移:机器狗相对篮球中心的偏移距离
- 直立程度:机器狗身体是否保持竖直(1=完全竖直,0=水平摔倒)
步骤 10:ONNX 模型导出与验证
ONNX_PATH=OUTPUT/"policy.onnx"export_onnx(POLICY,ONNX_PATH)parity=verify_onnx(POLICY,ONNX_PATH)print("ONNX 导出成功,输入输出一致性:",parity)专业概念解读:
| 概念 | 通俗解释 |
|---|---|
| ONNX 导出 | 把 PyTorch 格式的模型转成 ONNX 格式,方便部署到不同硬件 |
| 输入输出一致性验证 | 对比原模型和 ONNX 模型的输出,确保转换后结果一致 |
通俗比喻:就像把 Word 文档转成 PDF,要检查转换后内容是否完全一样。
步骤 11:BPU 板端部署
RUN_BPU=os.getenv("MICRODUCK_RUN_BPU","0")=="1"ifRUN_BPU:# 连接 RDK 开发板,加载 HBM 模型# 运行板端推理,生成视频# 验证模型 SHA 和控制步数专业概念解读:
| 概念 | 通俗解释 |
|---|---|
| BPU | 瑞芯微(Rockchip)的神经网络处理单元,类似 GPU 但专为 AI 推理设计 |
| RDK 开发板 | 瑞芯微的开发板,可以运行部署好的模型 |
| HBM | 板端模型文件格式,经过压缩和优化,适合在 BPU 上运行 |
| MICRODUCK_RUN_BPU=1 | 环境变量,设置为 1 才启用板端推理 |
通俗比喻:把"大脑"从电脑下载到开发板的小芯片里,让机器狗脱离电脑也能自己平衡。
步骤 12:板端验证
ifRUN_BPU:board_report=verify_bpu_report(BPU_VIDEO_OUTPUT,BPU_RUN_ID,[BPU_HBM])print("控制步数:",board_report["steps"])print("重置次数:",board_report.get("resets",0))验证内容:
- 模型 SHA 是否正确(确保用的是正确的模型)
- 控制步数是否达到预期
- 视频是否由板端推理驱动生成
三、核心概念总结
1. 篮球平衡 vs 平地走路
| 维度 | 平地走路 | 篮球平衡 |
|---|---|---|
| 支撑面 | 固定地面 | 滚动的球 |
| 输入维度 | 自身状态 | 自身 + 球的状态 |
| 控制难度 | 低 | 高(需要预测球的滚动) |
| 失稳后果 | 摔倒 | 从球上掉下来 |
2. 什么是 PPO?
PPO(Proximal Policy Optimization)是一种强化学习算法:
- 机器狗在仿真中不断尝试
- 保持平衡就奖励,摔倒就惩罚
- 经过数百万次尝试后学会平衡
- PPO 的特点是"稳定更新",不会因为一次大改动就学坏
3. 为什么需要 ONNX 和 BPU?
| 阶段 | 格式 | 原因 |
|---|---|---|
| 训练 | PyTorch | 灵活,支持自动求导 |
| 导出 | ONNX | 通用格式,跨平台 |
| 部署 | HBM (BPU) | 针对硬件优化,推理速度快 |
四、关键参数速查表
| 参数 | 值 | 含义 |
|---|---|---|
| 策略频率 | 25 Hz | 每秒做 25 次决策 |
| 仿真频率 | 100 Hz | 每秒推进 100 步物理仿真 |
| 关节数 | 14 | MicroDuck 有 14 个可控关节 |
| 平衡时间 | 10 秒 | 演示中保持平衡的时长 |
| BPU 推理 | 可选 | 需要 RDK 开发板 |
总结:篮球平衡比平地走路更难,因为支撑面是动态的。策略模型需要同时考虑机器狗的姿态和球的运动,做出更精细的调整。这展示了具身智能的核心能力:在复杂物理环境中保持稳定。
附:原始 Notebook 参考
- 📓01_篮球平衡_PPO_ONNX_BPU_MuJoCo.ipynb— 在 GitHub 上查看原始 Notebook,可对照代码逐行学习。