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

至此,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里头跑,休息啦!)


评论 #