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。
具体要做的事情包括:
- 安装nvidia的studio driver
- 对于笔记本用户,将显卡修改为dGPU(独显直连)模式
- 修改.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
启动界面如下:

启动界面中各个选项的含义:
- 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窗口就会出现:

整个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这种多关节的机器人非常难以选中。

上面就是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,然后就能看到一堆小黄人像进击的巨人那样跑步前进:

至此,isaac sim和isaac lab的环境配置和测试就都完成了。
虽然你可以在 Isaac Lab 的仓库目录下直接写代码,但 这并不是推荐的做法 。在 Isaac Lab 根目录下运行:
./isaaclab.sh --new
在选择时,选项 "External" 会引导你创建一个独立的文件夹(可以在任何位置,比如 ~/my_projects/my_robot_task)。这个新项目会通过 pip install -e(编辑模式安装)链接到你的 Python 环境中。这样,你既可以自由地写自己的项目代码,又能随时调用 Isaac Lab 的功能。Once created, navigate to the installed project and run python -m pip install -e source/<given-project-name> to complete the installation process and register the environment. Within the directories created by the template generator, you will find at least one <span class="pre">__init__.py</span> file with something that looks like the following
import gymnasium as gym
gym.register(
id="Template-isaaclabtutorial_env-v0",
entry_point=f"{__name__}.isaaclabtutorial_env:IsaaclabtutorialEnv",
disable_env_checker=True,
kwargs={
"env_cfg_entry_point": f"{__name__}.isaaclabtutorial_env_cfg:IsaaclabtutorialEnvCfg",
"skrl_cfg_entry_point": f"{agents.__name__}.skrl_ppo_cfg:PPORunnerCfg",
},
)
This is the function that actually registers an environment for future use. Notice that the <span class="pre">entry_point</span> is literally just the python module path to the environment definition. This is why we need to install the project as a package: the module path is the entry point for the gymnasium API.
MoveIt2
MuJoCo
下面我们来看一下另一个非常常用的仿真模拟器:MuJoCo。(这个任务下周再做吧,今天完成了计划的看到机器人在isaac sim里头跑,休息啦!)