Isaac Lab 强化学习实战:从 Cartpole 训练到推理验证

本文记录第一次在 Isaac Lab 中完成强化学习训练、查看训练曲线、加载 checkpoint 推理、观察仿真效果,以及修改奖励函数做对照实验的完整过程。

这次学习的重点不是背诵算法公式,而是先打通以下闭环:

理解任务 → 启动训练 → 判断是否学会 → 找到模型
→ 加载模型推理 → 观察行为 → 修改一个变量 → 对照实验

实践目标与运行环境

远程服务器和 Isaac Lab 工作目录可按实际环境填写:

服务器:<username>@<server-host>
Isaac Lab:<isaac-lab-root>/IsaacLab

当前环境已经验证了以下能力:

  • Isaac Lab 可以正常启动强化学习任务。
  • RSL-RL 可以完成策略训练并保存模型。
  • Newton/MJWarp 可以作为物理后端运行已验证任务。
  • TensorBoard 可以显示奖励、回合长度和成功率等指标。
  • Viser 可以把远程服务器上的仿真画面显示在局域网浏览器中。
  • 训练和可视化进程可以分别启动、检查和停止。

局域网访问地址的格式如下:

Viser 仿真:http://<server-host>:8080
TensorBoard:http://<server-host>:6006

这些端口只应在可信局域网中开放,不建议直接暴露到公网。

核心概念:训练、推理与仿真

这三个概念最容易混淆。

训练

训练时,智能体在仿真环境中不断试错:

观察状态 → 策略产生动作 → 物理仿真执行动作
→ 获得奖励和下一状态 → 更新神经网络参数

训练的特点是:

  • 需要物理仿真。
  • 会不断采集新的经验。
  • 会更新模型参数。
  • 会定期保存 checkpoint。

推理

推理时加载已经训练好的 checkpoint,让策略根据当前观察产生动作:

加载 checkpoint → 获得观察 → 策略产生动作
→ 物理仿真执行动作 → 显示行为

推理不会继续更新参数。因此,model_9.ptplay 过程中不会自己变得更好。

仿真

仿真是虚拟世界中的物理运行过程。训练和推理都需要仿真:

  • 训练:在仿真中大量试错并学习。
  • 推理:在仿真中验证已经学到的策略。

Viser 展示的是仿真画面,不是训练本身。

Cartpole 任务结构

Cartpole 是强化学习的经典入门任务:

  • 小车可以在轨道上左右移动。
  • 杆通过转轴连接在小车上。
  • 策略需要控制小车移动,使杆尽量保持竖直。

它虽然简单,但包含了机器人强化学习最重要的组成部分:

观察 Observation
动作 Action
奖励 Reward
终止条件 Done
重置 Reset
策略 Policy

任务代码位置

任务配置:
source/isaaclab_tasks/isaaclab_tasks/direct/cartpole/cartpole_env_cfg.py

任务逻辑:
source/isaaclab_tasks/isaaclab_tasks/direct/cartpole/cartpole_env.py

任务逻辑中四个关键函数:

_get_observations()  # 获取策略看到的观察
_get_rewards()       # 计算本步奖励
_get_dones()         # 判断回合是否结束
_reset_idx()         # 重置已经结束的环境

观察空间

Cartpole 的策略每一步看到 4 个数:

[杆角度, 杆角速度, 小车位置, 小车速度]

对应代码的核心形式:

obs = torch.cat(
    (
        pole_position,
        pole_velocity,
        cart_position,
        cart_velocity,
    ),
    dim=-1,
)

这里只有位置和速度,这是因为对这个任务来说,它们已经足以描述当前运动状态。

动作空间

动作空间只有 1 维,策略输出一个数,用于控制小车沿轨道左右运动。

配置中的:

action_scale = 100.0

表示策略输出还要乘以动作缩放系数,转换为施加给小车的力。它不是“小车每次移动 100 米”。

奖励函数

该任务的奖励可以概括为:

总奖励
= 存活奖励
+ 失败惩罚
+ 杆倾斜惩罚
+ 小车速度惩罚
+ 杆角速度惩罚

近似写成:

r = 1
    - 杆角度²
    - 0.01 × |小车速度|
    - 0.005 × |杆角速度|

若任务失败,还会增加终止惩罚。

例如,杆角度为 0.5,两项速度都是 0,本步没有失败:

r = 1 - 0.5² = 0.75

这说明奖励函数不是直接告诉智能体“向左”还是“向右”,而是给行为打分。策略通过大量试错,逐渐发现哪些动作更容易获得高分。

终止、超时与重置

Cartpole 回合结束有两类原因:

  • 失败终止:小车越界,或者杆倾斜过大。
  • 时间用完:已经坚持到一个回合的最大时长。

当前主要终止阈值包括:

小车最大位置:3.0 m
杆最大倾角:90°
回合时长:5 s

仿真步长为 1/120 s,每两个物理步执行一次策略,所以策略频率约为 60 Hz

5 s × 60 步/s = 300 个策略步

因此,平均回合长度接近 300,通常意味着杆能够坚持完整个回合。回合成功后也会重置,并不代表所有重置都是失败。

重置时会随机化初始杆角度。这样训练出的策略不只会处理一个固定姿态,而能适应一定范围内的初始状态。

首次训练与 Checkpoint

训练配置与结果

第一次独立训练使用了较短的 10 轮实验:

CUDA_VISIBLE_DEVICES=0 ./isaaclab.sh train \
  --rl_library rsl_rl \
  --task=Isaac-Cartpole-Direct-v0 \
  --num_envs=128 \
  --max_iterations=10 \
  --run_name=student_first_train \
  --seed=7 \
  physics=newton_mjwarp

训练结果:

reward:35.26
mean episode length:61.72

这说明策略已经开始学习,但还没有稳定掌握任务。此时平均每回合只能坚持约 62 步,距离最大 300 步还有明显差距。

查找 Checkpoint

find logs/rsl_rl/cartpole_direct \
  -type f \
  -path '*student_first_train*' \
  -name 'model_*.pt'

找到了:

model_0.pt
model_9.pt

10 轮训练按 0~9 编号,因此本次最后一个 checkpoint 是 model_9.pt

需要修正一个容易产生的误解:

  • model_0.pt 不是严格意义上的“完全没有训练”。
  • 它通常是在第 0 次迭代完成后保存的早期状态。
  • model_9.pt 经过了更多轮参数更新,一般比 model_0.pt 更成熟。

Checkpoint 的含义

Checkpoint 是训练过程在某个时刻保存的“模型快照”。

它主要包含:

  • 神经网络已经学到的参数。
  • 继续训练或恢复训练所需的状态。
  • 与本次训练相关的部分配置和统计信息。

Checkpoint 不是仿真场景,也不是视频。可以把它理解为策略当时已经形成的“技能记忆”。

Checkpoint 有两个主要用途:

  • 推理:加载它,直接验证已经学到的行为。
  • 续训:从它的状态继续训练,使策略进一步改善。

模型推理与仿真可视化

CUDA_VISIBLE_DEVICES=0 ./isaaclab.sh play \
  --rl_library rsl_rl \
  --task=Isaac-Cartpole-Direct-v0 \
  --checkpoint logs/rsl_rl/cartpole_direct/2026-07-25_14-13-46_student_first_train/model_9.pt \
  --num_envs=1 \
  --viz viser \
  --max_visible_envs=1 \
  --real-time \
  physics=newton_mjwarp

在浏览器中打开:

http://<server-host>:8080

观察到小车左右移动,杆没有立即倒下,说明:

  • checkpoint 加载成功。
  • 策略确实在根据观察输出动作。
  • 物理仿真和局域网可视化链路正常。

停止推理时在服务器终端按:

Ctrl+C

终端出现 server stopped,一般表示 Viser 服务被正常停止,不代表模型损坏。

TensorBoard 与收敛判断

启动 TensorBoard:

./isaaclab.sh -p -m tensorboard.main \
  --logdir logs/rsl_rl/cartpole_direct \
  --host 0.0.0.0 \
  --port 6006

浏览器打开:

http://<server-host>:6006

20 轮实验

day1_first_train 的结果大致为:

reward:-0.95 → 136.44
mean episode length:13 → 149.86

判断:模型明显在学习,但还未完全收敛。

100 轮实验

day2_convergence 的最终结果大致为:

reward:294.07
mean episode length:299
success rate:1.0
最终 checkpoint:model_99.pt

判断:该任务已经基本收敛。

多指标判断方法

较可靠的收敛判断需要同时考虑:

  • 奖励总体上升,并在较高水平形成平台。
  • 平均回合长度接近任务最大值。
  • 成功率接近 1.0
  • 多轮之间波动较小。
  • 加载 checkpoint 后,实际动作表现稳定。

对于这次 Cartpole 实验:

平均回合长度接近 300
+ 成功率接近 1.0
+ 奖励曲线已经平稳
= 可以停止训练并保存当前模型

继续训练不一定有明显收益,还会继续消耗计算资源。

并行环境与经验采集

--num_envs=128 表示一次并行运行 128 个独立的仿真环境。

它不是训练 128 个不同模型,而是:

1 个共享策略
同时控制 128 个 Cartpole 环境
快速采集大量不同经验
共同用于更新这 1 个策略

若观察维度为 4,128 个环境的观察张量形状通常类似:

[128, 4]

动作维度为 1,则动作张量形状类似:

[128, 1]

如果每个环境每轮采集 16 步:

128 个环境 × 16 步 = 2048 条经验

若使用 256 个环境:

256 个环境 × 16 步 = 4096 条经验

增加并行环境通常能更快收集数据,但也会占用更多显存和计算资源。它不会自动保证策略更好,还要结合每轮步数、批大小、学习率等参数理解。

奖励参数对照实验

实验目标:增大小车速度惩罚,观察是否能让小车移动得更慢。

实验设计

基准参数:

rew_scale_cart_vel = -0.01

修改后:

rew_scale_cart_vel = -0.05

为了使比较尽量公平,保持以下条件一致:

任务:Isaac-Cartpole-Direct-v0
并行环境数:256
训练轮数:100
随机种子:42

训练命令:

CUDA_VISIBLE_DEVICES=0 ./isaaclab.sh train \
  --rl_library rsl_rl \
  --task=Isaac-Cartpole-Direct-v0 \
  --num_envs=256 \
  --max_iterations=100 \
  --run_name=student_cart_vel_penalty \
  --seed=42 \
  physics=newton_mjwarp \
  env.rew_scale_cart_vel=-0.05

最终 checkpoint:

logs/rsl_rl/cartpole_direct/2026-07-25_15-40-14_student_cart_vel_penalty/model_99.pt

实验结果

平均奖励:287.98
平均回合长度:299
成功率:1.0
主观观察:小车移动速度与基准模型差不多

实验结论

可以确定:

  • 将速度惩罚从 -0.01 增强到 -0.05,没有破坏模型完成 Cartpole 任务的能力。
  • 修改后的模型仍然达到回合长度约 299、成功率 1.0。

暂时不能确定:

  • 小车的实际平均速度是否降低。
  • 动作是否变得更加平滑。

原因是本次没有记录速度和动作变化的量化指标,仅凭肉眼看“差不多”,证据还不够。

另外,修改奖励公式后,两个实验的奖励绝对值不能直接作完全等价的横向比较,因为它们使用的“计分尺”已经不同。

速度与动作平滑性的区别

判断速度是否降低,可以记录:

平均 |cart_velocity|
最大 |cart_velocity|

判断控制是否平滑,可以记录:

相邻动作变化:|action(t) - action(t-1)|
小车加速度
动作或加速度的最大值、均值和方差

策略可能移动速度不快,但频繁左右抖动;这种行为并不平滑。因此,后续实验必须让评价指标与实验目标一致。

强化学习实验方法

以后修改任务时,使用下面的模板。

明确实验问题

实验问题:
只修改哪个变量:
预期会出现什么变化:
可能带来什么副作用:

控制实验变量

除研究变量外,尽量保持以下设置一致:

任务
算法
并行环境数
训练轮数
随机种子
其他环境和算法参数

记录实验结果

训练是否成功:
平均奖励:
平均回合长度:
成功率:
目标指标:
仿真现象:
能确定的结论:
还不能确定的部分:

建立证据与结论的对应关系

例如:

“成功率为 1.0”
可以支持“模型能够完成任务”。

“肉眼看速度差不多”
不能支持“平均速度一定没有改变”。

这一区分是从“会运行命令”走向“会做强化学习实验”的关键。

参考资料

参考资料检索日期:2026-07-25。

评论