Skip to content

Simulation Platforms

我们不可能直接就把一个实体机器人拿出来进行测试,往小了说会把机器人弄坏,往大了说你不可能直接让汽车在跑道上自动驾驶,又危险又低效。因此,几乎所有的机器人训练过程都是在Simulation(仿真)平台中完成的。我们把机器人尽可能逼真地复现在虚拟世界中,让虚拟世界尽可能模拟真实世界,来完成训练,然后通过Sim2Real的方式将训练结果迁移到真实世界中。

ROS

ROS并非Simulation,但是经常和Simulation搭配使用,所以这里先单独介绍一下ROS。如果以后有关于ROS这一类别的更多条目,我再把ROS转移过去。

ROS历史

2006年,斯坦福大学人工智能实验室和一家名为Willow Garage的机器人公司合作开发了一个新的机器人软件框架,试图解决机器人软件开发中重复造轮子的问题。第二年,ROS前身Switchyard诞生,这是一个模块化、分布式、跨平台的机器人中间件。

2009年,ROS的第一个正式公开版本发布。虽然叫做Robot Operating System,但ROS并非一个完整的操作系统。ROS运行在Linux上,提供消息通信、包管理、工具链等。

2013年,Willow Garage因资金问题逐渐解散,此时ROS社区已经逐渐成熟,因而ROS的主要开发和维护工作被转交给了OSRF(Open Source Robotics Foundation, 后改名为Open Robotics)。

2017年,社区开始推动ROS2的开发。ROS2采用了基于DDS的通信中间件,支持实时性、安全性、多操作系统、嵌入式系统等。

到2020年,ROS1的最后一个LTS版本Noetic发布,并支持到2025年5月,截止我写这篇文章(2025年9月)时已停止维护。至此,ROS1逐步退出历史舞台。

现在最主要的ROS版本是ROS2 Humble,适配的操作系统平台是Linux Ubuntu 22.04。Humble和Ubuntu 22.04都是LTS长期支持版本,官方维护也都是差不多到2027年5月。由于Humble资料齐全,22.04和其他平台兼容性高,因此现在学习入门使用Humble非常合适。

而现在ROS社区和Ubuntu社区正在主推ROS2 Jazzy和Ubuntu 24.04则将维护到2029年,但现在社区和生态还不是很成熟。个人推荐现在用Humble,然后到2027年再切换到Jazzy。

ROS2 Humble

官方安装指引

安装后每次新开一个终端都要先把ROS2的安装路径告诉terminal,让terminal能识别ROS2的环境变量:

source /opt/ros/humble/setup.bash

如果你下载这个Humble版本后就用这个版本持续开发,而不随时切换ROS1或者其他的不同版本,那么你可以把这句写进.bashrc中:

echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc

ROS2和ROS1有很多架构上的不同,从ROS1过来的人(说的就是我)要注意:在ROS1比如Noetic的时代,我们是直接用ROS进行通信的。但是在ROS2时代,ROS系统做了一个非常重要的改变:专业分工。在ROS1框架中,roscore作为ROS Master,承载了过多的功能,一旦roscore发生故障,那么整个系统都会瘫痪。所以在ROS2时代,整个系统采用了去中心化的自动发现机制,所有的节点都在网络上广播自己的存在,并自动找到其他节点。系统中不再有Master,因此就不再有单点故障,整个系统的robust远高于ROS1。

ROS2时代的ROS系统把所有实际数据比如打包、寻址、加密、发送、接收等脏活都外包给专业的DDS。DDS本身是一套标准,很多公司在此标准基础上开发了自己的DDS实现,Cyclone DDS就是其中一个非常有名的开源DDS,由Eclipse基金会维护。Cyclone DDS和MoveIt等复杂系统配合时非常好用。

DDS架构在使用上看起来和ROS1一样,也是subscribe-publish机制,但我们仔细回想的话,ROS1所有的publisher都要在Master那里注册,而所有的subscriber在启动时都要去Master那里找看有没有自己正在收听的话题。ROS1中的接收者通过Master找到发布者后,两者之间会建立一个点对点的TCP连接,然后从发布者那里向接收者传输数据。然而,在DDS上,并不存在一个中心化的Master,所有的publish-subscribe都是去中心化的、没有任何中央节点的。在DDS网络架构中,每一个发布者和订阅者入场的时候,都会通过UDP多播在公共频道定期发送自己的信息。此外,每当一个新的订阅者或者发布者进入到网络中进行自我介绍时,所有老节点此刻都会重新介绍一边自己。这样一来,节点和节点之间并不通过一个中间人,而是直接握手。

Gazebo

Gazebo最初并非ROS的一部分,但是和ROS紧密集成,所以很多人把Gazebo当作ROS的官方仿真器。这种看法并非没有依据,Gazebo最早也是由OSRF开发维护的。但实际上Gazebo并不需要ROS也能单独运行。

在ROS1时代,Gazebo Classic高度集成。如今在ROS2时代,Gazebo也升级到了Gazebo Sim(在2018-2022年之间也叫做Ignition Gazebo),采用了全新的架构。

Isaac Sim

Isaac Sim/Gym/Lab等都是Nvidia公司推出的和机器人仿真训练相关的东西,我们一起来看一下。

由于Omniverse已经停止维护,没有了 Launcher 的资源库,现在的资产管理主要通过以下面板:

  • Isaac Assets 面板 :在 Isaac Sim 界面下方,直接连接 NVIDIA 的 NGC Catalog
  • SimReady Content :NVIDIA 官方提供的一系列物理精确的家具和场景,直接在软件内搜索“Office”或“Home”即可拖入。

架构与网络配置

我们可以在wsl2 ubuntu22上安装ROS Humble,在windows上按照Isaac Sim和Isaac Lab。

具体要做的事情包括:

  1. 安装nvidia的studio driver
  2. 对于笔记本用户,将显卡修改为dGPU(独显直连)模式
  3. 修改.wslconfig文件,确保wsl2和windows使用同一个IP

在 Windows 用户目录下创建或修改 .wslconfig 文件:

[wsl2]
memory=24GB
swap=0
# 开启镜像网络模式,让 WSL2 和 Windows 共享同一个 IP
networkingMode=mirrored
# 允许 WSL2 访问 Windows 的本地服务
localhostForwarding=true
# 显存优化(可选,针对 4090 建议开启)
guiApplications=true

这会让 WSL2 和 Windows 共享 IP,彻底解决 ROS 2 话题传不过去的问题。

在windows的powershell或cmd中输入ipconfig,然后在wsl2 ubuntu中输入hostname -I,查看是否一致。如果wsl2显示一个以172.开头的地址,就说明设置失败,还在使用默认的NAT模式。

为了保障windows和wsl2的网络传输,还要在wsl2中配置FastDDS:(在 WSL2 的 ~/.bashrc 结尾添加以下三行)

# 强制使用 FastDDS,解决跨系统丢包问题
export RMW_IMPLEMENTATION=rmw_fastrtps_cpp
# 允许非本地节点通信
export ROS_LOCALHOST_ONLY=0
# 确保网卡名称匹配(镜像模式下通常不需要改,但加上更稳)
export ROS_DOMAIN_ID=0

生效配置source ~/.bashrc

安装与环境配置

windows系统上可以按照官方教程快速安装。

安装在~/isaacsim/下后,启动isaac sim:

cd ~/isaacsim/
./isaac-sim.selector.sh

启动界面如下:

1759510607433

启动界面中各个选项的含义:

  • Isaac-sim: 带GUI的版本
  • Isaac-sim Streaming: 没有完整UI,适合远程交互或嵌入式场景
  • Package Path: 就是isaac sim的安装路径
  • Extra Args: 可以添加一些命令行参数,比如强制RTX渲染、无窗口启动等
  • ROS Bridge Extension: 让ROS和isaac sim通信
  • Use Internal ROS2 Lib: 如果本地有ROS2,就不需要勾选了
  • Show startup console: 建议开启,方便排查问题

启动后GUI窗口就会出现:

1759510930165

整个GUI界面主要包括以下区域:

  • 中间的Viewpoint就是操作场景和模型的3D视图区域,右键旋转视角,中键拖动平移,滚轮缩放;上方的RTX-Real-Time是渲染模式,Perspective是视图视角类型。在viewpoint右上角还实时显示FPS,显卡使用情况,内存使用情况等。
  • 右侧上方的Stage面板是场景树,现实当前场景中所有对象的层级结构,当你导入机器人或者物体的时候,他们就会出现在这里
  • 右侧下方的Property区域显示的是当前选中对象的属性,比如Transform, 材质,关节,物理,碰撞等。
  • 底部的Content区域可以浏览本地文件以及英伟达的资源库,在这里可以直接把.usd, .urdf, .fbx的文件拖进来
  • 底部的Console只显示与当前场景和脚本相关的消息,因此程序本身的问题还是要在启动isaac的终端中去看
  • 左侧是工具栏
  • 顶部的菜单栏有一些很关键的功能,比如导入素材、添加几何体、添加灯光、添加摄像机等。

导入机器人

现在isaac sim中是一个虚无的世界,机器人进来后没有地方站着,所以我们需要给机器人创建一个地板。点击 create >> physics >> ground plane创建地板。

然后我们可以导入机器人。你可以直接导入你想导入的机器人,我们先导入一个默认模板试试看:create >> robot >> ... 选一个默认的导入,可以看到场景中出现了一个机器人。

点击左侧菜单栏的启动按钮,机器人就会在模拟重力的影响下摊倒在地面上。如果想要选中机器人,需要在Stage面板中点击该机器人,否则像Humanoid这种多关节的机器人非常难以选中。

1759512190093

上面就是isaac sim内置的波士顿动力狗和Humanoid机器人模型。

如果想导入自己的机器人,比如宇树科技g2,则需要找到其对应的模型。现在常见的模型类型如下:

  • USD:Isaac Sim原生支持格式
  • URDF:ROS生态最常见,isaac官方支持格式转换导入
  • SDF:Gazebo模型,isaac不支持
  • MJCF:MuJoCo模型,isaac不支持,需要通过转换脚本转换

虽然可以自己导入模型自定义,但是一般对于非特殊需求的人,我们还有一个更好用的框架:Isaac Lab.

Isaac Lab

安装

Isaac Lab是基于Isaac Sim的开源模块化框架,集成了高保真模拟,方便研究者进行模仿学习、强化学习等。我们可以直接在GitHub上找到isaac-sim/IsaacLab,clone后就可以开始了。官方的安装说明在这里。

按照教程安装后,测试一下是否能正确训练:python scripts/rl_games/train.py --task=Isaac-Ant-v0,这里也可以加headless参数。不加headless的话可以看到一群小蜘蛛在学习走路。由于isaac sim对模拟进行了优化,可以让模拟直接在GPU上并行运行,因此训练速度在我的RTX4090 laptop上飞快,远比我之前做Atari DQN的项目快的多得多得多。

接着运行一个isaaclab预置的预训练好的脚本:python scripts/rl_games/play.py --task=Isaac-Humanoid-v0 --use_pretrained_checkpoint,然后就能看到一堆小黄人像进击的巨人那样跑步前进:

1759545158031

如此isaaclab就安装好了。

我们可以看到isaaclab和isaacsim并不是一个东西,而且isaaclab也会安装自己的支持依赖等。(目前尚不清楚是否和安装的isaacsim有关联,如果之后这个软件用的比较多可以再研究研究)

新建项目

虽然你可以在 Isaac Lab 的仓库目录下直接写代码,但 这并不是推荐的做法

激活conda环境:(这里取决于你安装的时候起的名字,我起的是isaaclab,请确保后面的操作都是在该conda环境中)

conda activate isaaclab

在 Isaac Lab 根目录下运行:

./isaaclab.sh --new

如果是windows,则运行bat文件:

.\isaaclab.bat --new

在选择时,选项 "External" 会引导你创建一个独立的文件夹(可以在任何位置,比如 ~/my_projects/my_robot_task)。

这里要注意,项目名字最好全都用小写,可以避免一些潜在的麻烦。

1770430578863

接着,如上图所示,项目新建指引会询问项目的架构模式和代理数量。其主要反应了两个内容的分别,首先是direct vs manager-based:

  • Direct Workflow架构师最传统的RL环境写法,类似于OpenAI Gym,你需要继承一个基类,并在一个巨大的 Python 类里亲手写完所有的逻辑:如何观察环境、如何计算奖励、什么时候重置等。
  • Manager-based Workflow是基于管理器的工作流,这种架构是一种新的架构,它将环境拆解成了几个 独立的管理器 (Observation Manager, Reward Manager, Terminate Manager 等)。你不需要写复杂的循环,而是通过配置文件(YAML 或 Python Config)来“声明”你的需求。

其次是数量级的区别:

  • Single Agent就是训练一个策略,控制一台机器人。即便场景里有 1000 台机器人在跑,它们也都共用同一个策略(Policy)。
  • Multi Agent就是训练多个不同的策略,比如有些机器人负责扫地,有些负责倒垃圾,它们需要相互配合或竞争。

这里我们选择现在主流的Manager-based | Single-agent。

接下来安装导引会询问选择哪个rl library:

1770431062415

这几个library都是强化学习后端算法库,封装了强化学习的底层算法:

  • sb3, 即Stable Baselines3, 这个基本相当于RL界的教科书,支持丰富的算法,包括PPO, SAC, DDPG, TD3, DQN...等等,适合各种任务
  • rsl-rl,专门为Isaac Lab设计的PPO算法库,最适合足式机器人、人形机器人等的运动控制。

这里我们选择rsl_rl,因为这个在isaac lab中的适配性是最好的。

创建好后,我们打开项目所在文件夹。如果用vscode打开,会提示推荐安装的插件,按照推荐安装就好。

接着,我们需要在项目根目录下运行命令:

pip install -e .
python -m pip install -e source/{The name of the project}

这一步很重要,必须安装,我们必须让项目变成一个可被导入的包。这个命令不仅会自动安装依赖,还会建立python的快捷链接,并且-e可以保障该链接是软链接。这意味着,我们可以在电脑的任何位置打开终端,运行这个机器人的训练脚本,Python 都能找得到它。并且如果我们修改了这里的代码,下次运行训练时,python会立刻读取到新的修改,不需要重新安装一遍。

我们可以运行命令:

pip list | findstr {the name of the project}

来查看是否完成安装。

至此,新的项目就建好了。

示例脚本:大摆锤

根据安装向导新建好项目后,我们打开项目文件夹。我们先来看一下项目任务名称,打开文件(项目叫cleaning_robot):

source\cleaning_robot\cleaning_robot\tasks\manager_based\cleaning_robot\__init__.py

我们可以看到任务名称是 Template-Cleaning-Robot-v0。在项目的scripts/文件夹下,有一个叫做play.py的示例脚本。我们可以运行这个示例脚本,不过在运行之前,我们需要先了解一下isaaclab的项目文件夹内都有些什么东西,以及我们怎么来使用。

示例任务指向了文件 source/cleaning_robot/cleaning_robot/tasks/manager_based/cleaning_robot/cleaning_robot_env_cfg.py,该文件内部定义了我们训练的任务内容:

  • 机器人:Cartpole 大摆锤
  • 动作与关节:大摆锤的滑块
  • 目标:大摆锤立正
  • 奖励:坚持越久越好,杆子歪了扣分,滑块移动的太快扣分,出界就死亡

所以我们现在可以运行命令:

python scripts/rsl_rl/train.py --task Template-Cleaning-Robot-v0 --num_envs 32

这个命令的意思是:

  • train.py,执行者
  • --task Template-Cleaning-Robot-v0,也就是示例任务
  • --nums_envs 32,创建32个机器人进行同步训练

这里的train.py就相当于是训练流程的启动器和编排者,也可以理解为isaac lab的ai infra,或者说训练脚手架。

现在,我们可以把训练任务视为一个三层汉堡:

  • 上层rsl-rl是负责计算梯度、反向传播、更新网络权重的PPO库
  • 中层train.py是isaac lab,负责把下层数据传给上层,把上层指令传给下层,相当于一个胶水层
  • 下层是环境层,我们在这里定义机器人的身体、物理仿真、奖励等

1770435181073

运行训练任务后,我们可以看到很多大摆锤在训练。

我们可以总结上述工作流程:

  1. ...env_cfg.py中定义环境
  2. 在rewards.py中设置训练策略
  3. ..._ppo_cfg.py里设置学习率、batch size等。
  4. 用脚手架脚本 train.py进行任务
  5. 观察任务训练效果

我们在logs文件夹下可以看到训练好的模型文件,比如 model_149.pt

接着我们可以运行 play.py,这个文件会在logs文件夹里找到最新的模型然后加载。

执行:

python scripts/rsl_rl/play.py --task Template-Cleaning-Robot-v0 --num_envs 32

加载32个大摆锤,并加载最新的模型。1770435639010

之所以加载32个,是为了批量验收,一是测试鲁棒性,二是不同机器人的初始状态设定里有一定的随机性,所以可以看到一些开局很歪的机器人的表现。

至此,我们完成了项目配置。接下来关于项目的更多配置,如场景设置、机器人设置、策略设置、训练、评估等,参见扫地机器人笔记。

MoveIt2

MuJoCo

下面我们来看一下另一个非常常用的仿真模拟器:MuJoCo。(这个任务下周再做吧,今天完成了计划的看到机器人在isaac sim里头跑,休息啦!)


评论 #