
做机器人开发这行有句老话别拿真机练手先把仿真跑通。尤其是刚接触 ROS 的朋友手里可能连一块开发板都没有但一个靠谱的仿真平台能让你同时体验到激光雷达、里程计、导航算法甚至机械臂运动规划的全部流程。这篇文章我想认真聊聊 ROS 生态里最常见的三个仿真平台——Webots、Gazebo、Stage它们各自的定位完全不同用错了场景会让你多走很多弯路。我尽量不写那种泛泛而谈的对比表而是把我在实际项目里踩过的坑、验证过的流程、以及不同任务应该怎么选平台的经验一次性讲清楚。1. 先搞明白仿真平台在ROS开发里到底扮演什么角色1.1 没有机器人的时候仿真就是你的试验田很多新手一上来就纠结要不要买真机我的建议很直接先别买。真机不仅贵而且调试效率极低一个参数改错了可能就得重新上电、复位、等传感器预热。仿真平台解决的是算法逻辑是否正确这件事你的导航栈、SLAM 建图、路径规划、机械臂运动规划在仿真里跑通之后移植到真机上只需要处理传感器噪声和机械误差即可。这里要区分一个概念ROS 本身的底层通信机制话题、服务、动作与仿真器是解耦的。也就是说你在仿真里写的 ROS 节点放到真机上基本不用改。这是仿真平台最大的价值——它不是玩具而是开发流程里的一环。另一个容易被忽略的点是仿真平台能让你同时跑多套传感器配置。比如你想对比单线激光雷达和深度相机对导航效果的影响在真机上你得换硬件、改驱动、重新标定在仿真里只需要改一个传感器 tag 的参数。这种快速试错能力在项目初期比什么都重要。1.2 三个平台的本质差异物理精度、视觉真实度、运行速度怎么取舍这三个平台的差异本质上是在三个维度上做取舍物理引擎的真实程度、传感器渲染的逼真度、以及运算开销。Gazebo 是 ROS 社区里最常见的选择默认用 ODE 物理引擎支持多种传感器插件历史资料最多Webots 是一个独立发展了很多年的专业机器人仿真软件后来和 ROS 深度集成它的物理引擎和渲染器做的非常好而且官方维护了一批高质量的机器人模型Stage 则是极简主义的 2D 仿真器几乎所有计算都在二维平面完成速度极快。我见过太多人一上来就无脑选 Gazebo结果卡在安装和环境配置上最后连一个 TurtleBot 模型都没跑起来。其实完全可以根据你的任务来选如果你做的是两轮差速小车导航、SLAMStage 完全够用如果你要跑机械臂的运动规划、视觉抓取Webots 的体验比 Gazebo 顺滑不少如果你要复现一个复杂的多传感器融合场景或者要模拟真实环境下的传感器噪声那 Gazebo 的生态最成熟。2. GazeboROS圈子里的老大哥但别被它惯坏了2.1 为什么大多数教程都在用GazeboGazebo 之所以成为 ROS 教程里的默认选择是因为它和 ROS 的集成历史最长官方文档、社区问答、论文开源代码里大量使用了 Gazebo。你搜ros小车自主导航仿真十有八九出来的教程都是 Gazebo 环境。这种生态优势带来的直接好处是遇到问题很容易搜到答案而且几乎所有 ROS 功能包都带至少有 gazebo 的 launch 文件。Gazebo 的核心工作机制是插件。传感器、控制器、物理属性全部通过插件的形式挂载到模型上。比如你要给小车加一个激光雷达需要在一个 urdf 文件里声明gazebo标签指定 sensor 类型、topic 名、帧率、分辨率等参数然后由 gazebo_ros 插件把仿真数据转成 ROS 话题发布出来。这种设计非常灵活但也带来了学习成本——你得搞清楚 URDF 和 SDF 的区别。URDF 是 ROS 里的机器人描述格式能表达运动学、惯性、碰撞属性SDF 是 Gazebo 原生的世界描述格式能表达灯光、地形、传感器。两者之间可以通过工具转换但实际使用中经常出现 URDF 在 Rviz 里显示正常、加载进 Gazebo 就崩的情况。这个问题后面我会专门讲。2.2 Gazebo安装与ROS版本匹配的坑安装 Gazebo 最大的问题不是命令复杂而是版本匹配。我见过不少人在 Ubuntu 24 上折腾 ROS 2 Jazzy 加 Gazebo Harmonic结果被依赖问题折磨到卸载重装三遍。如果你刚入门我给的建议是Ubuntu 20.04 ROS Noetic Gazebo 11或者Ubuntu 22.04 ROS 2 Humble Gazebo Classic 11这两套组合是我目前折腾下来最稳定的。Humble 是 ROS 2 里资料最全的版本绝大多数支持 ROS 2 的仿真包都会优先适配它。至于 Noetic虽然 ROS 1 已经停止官方维护但大量的教学代码、论文开源项目还停留在 ROS 1如果你主要想学基础概念Noetic 反而更省心。如果你不想手动改环境变量我强烈推荐直接用鱼香ROS的一键安装脚本实测下来对新手非常友好。它能帮你处理好 apt 源、rosdep、以及基础功能包的安装尤其在国内网络环境下能省掉很多折腾时间。但注意一键安装不等于一劳永逸装完 Gazebo 之后最好跑一下gazebo --version确认版本再跑一个最简单的 empty world 测试有没有缺库。2.3 上手案例让TurtleBot在Gazebo里跑起来我以 TurtleBot3 为例给你一套实测可用的流程。先装功能包sudo apt install ros-noetic-turtlebot3-* echo export TURTLEBOT3_MODELburger ~/.bashrc source ~/.bashrc然后启动Gazebo仿真环境roslaunch turtlebot3_gazebo turtlebot3_world.launch这时候你应该是能看到一个带围墙的室内场景小车停在中间。下一步验证传感器数据通不通roslaunch turtlebot3_gazebo turtlebot3_slam.launch roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch用键盘控制小车在环境里转一圈在 Rviz 里应该能看到点云地图在实时增长。这整个过程不需要真机却完整覆盖了底盘驱动雷达数据SLAM建图三个核心模块。这套流程之所以推荐是因为 TurtleBot3 的模型文件、传感器参数、控制器插件都已经官方调好了。新手不需要关心 Gazebo 的模型配置细节先跑通再拆解比我当初从零写 URDF 要高效得多。如果你后续要换自己的车模可以把官方的 burger.urdf 拿过来改改完一个传感器就测试一次别一次性全改完再启动出错了根本定位不到问题。3. Webots被低估的全能选手尤其适合机械臂和教学3.1 Webots的设计哲学物理引擎和渲染做得比想象中好和 Gazebo 相比Webots 在国内的讨论热度没那么高但它在国际上其实是一个非常老牌的专业仿真软件由 EPFL 开发2018 年开源后与 ROS 的集成度越来越高。它使用 ODE 作为物理引擎但渲染器是自己实现的画质比 Gazebo 默认的 OpenGL 渲染好一截最直观的感受是Gazebo 里看地面是灰蒙蒙的平面Webots 里能看到地板纹理、阴影和反射。但画质好不是重点重点是 Webots 的建模思想。它有一套自己的.wbt世界文件和基于 PROTO 的模型定义方式你可以用图形界面拖拽物体、设置Joint属性也可以直接用文本编辑器改模型参数。这种所见即所得的设计对于做机械臂仿真特别友好——你不需要像在 Gazebo 里那样反复调整 SDF 的坐标节点直接在界面上拖动机械臂末端控制器节点就能实时反馈关节角变化。另一个我觉得很良心的点是Webots 官方维护了一大批高质量机器人模型从 TurtleBot3、Pioneer、NAO 到 Franka Emika Panda、UR 系列机械臂都有而且都配好了传感器和 ROS 接口。你如果想做 panda 机械臂的 Gazebo 仿真得自己找包、配 MoveIt、调控制器插件但在 Webots 里可以直接从项目向导里创建一个带 Panda 的场景。3.2 ROS2与Webots的连接方式Webots 对 ROS 2 的支持非常到位。它有一个核心包叫webots_ros2提供了 driver 节点负责 Webots 和 ROS 2 之间的桥接。你只需要在 Webots 里加载一个带 ROS 接口的机器人模型然后启动对应的 ROS 2 节点两者就会通过webots_ros2_driver自动建立连接。我最常用的启动方式有两种。第一种是纯命令行# 启动一个带TurtleBot3的Webots世界 ros2 launch webots_ros2_turtlebot robot_launch.py第二种是在 Webots 图形界面里手动加载世界文件再单独启动 ROS 2 节点。这种方式适合调试单个传感器或者控制算法因为你可以边看仿真画面边在终端里看 topic 数据。Webots 对 micro-ROS 的集成也是一个亮点。你可以在 Webots 里模拟一个微控制器节点跑 micro-ROS 的发布订阅程序验证嵌入式端代码逻辑。比如我想测试一个急停按钮是否能在极端时间内阻塞电机控制指令在 Webots 里可以直接配置控制器的计算周期模拟 MCU 的实时性这在 Gazebo 里实现起来要麻烦得多。3.3 实操案例基于Webots的多机械臂智能分拣系统原型做基于 Webots 的多机械臂智能分拣系统这类项目我建议的路径是先搭静态环境再写感知逻辑最后才做抓取控制。第一步在 Webots 里建立一个传送带加视觉相机的场景。传送带可以用ConveyorBelt这个 PROTO 定义设置带速和摩擦系数相机可以用Camera节点配置分辨率、视场角和位置。然后在传送带上放几个不同颜色的小方块作为待分拣物体。第二步写一个 ROS 2 节点订阅相机图像用 OpenCV 做颜色阈值分割输出目标物体的像素坐标和类别。这里要注意一个坑Webots 的相机默认输出的是 RGB 图像顺序是 RGB而 OpenCV 默认是 BGR直接拿过来显示会出现颜色通道对调的问题颜色检测会全部错乱。第三步把像素坐标通过简单的针孔相机模型或者 tf 变换转换到机械臂基坐标系下然后调用 MoveIt 的规划接口生成抓取路径。Webots 里可以使用自身的 Inverse Kinematics 插件来让机械臂末端到达目标位置这一点比 Gazebo 里需要额外配置gazebo_ros_control要轻量很多。我这里强调一下做多机械臂系统时Webots 最大的优势是——你可以轻松地在同一个世界文件里加载两个以上的机械臂模型为每个机械臂配置独立的控制器节点并通过 ROS 命名空间隔离各自的 topic。在 Gazebo 里做多机械臂你需要手动处理刚体碰撞、模型命名、控制插件初始化顺序等问题光是把两个一样的 URDF 加载进同一个世界就可能报一堆错。4. Stage轻量级2D仿真SLAM和导航调试的极速通道4.1 Stage的定位2D激光雷达算法验证如果你只是想做 SLAM 建图、路径规划、多机器人编队这些算法层面的验证Stage 是效率最高的选择。它不是 3D 仿真器它只跑 2D 平面没有重力、没有碰撞物理、没有视觉渲染本质上是在一个二维格栅地图上模拟激光雷达扫描和移动机器人位姿。Stage 快在哪里我举个实际数据在我的笔记本上Gazebo 跑一个 TurtleBot3 带激光雷达的场景CPU 占用大概在 60% 到 80%风扇直接起飞Stage 跑同样的 SLAM 算法CPU 占用不到 10%一个 100 平方米的地图环境建图过程几秒钟就能完成几乎感觉不到延迟。这背后的原因是Stage 使用射线投影直接计算激光雷达的 hit 点而不是像 Gazebo 那样通过 GPU 渲染深度图再转成激光数据。它不需要渲染任何 3D 模型内存占用极小因此可以非常轻松地跑多机器人仿真。如果你在做多机器人协同探索或集群编队Gazebo 跑 3 个以上机器人就会掉帧Stage 跑 10 个机器人依然流畅。4.2 用Stage做TurtleBot SLAM测试的实操流程Stage 在 ROS 里的使用方式非常简单。以 TurtleBot 为例先安装sudo apt install ros-noetic-turtlebot-simulator然后启动 Stage 仿真环境roslaunch turtlebot_stage turtlebot_stage.launch这时会出现一个二维地图窗口里面可以看到小车的平面轮廓和激光扫描线。接着启动 SLAM 算法比如 gmappingroslaunch turtlebot_navigation gmapping_demo.launch再用键盘控制节点让小车移动地图会实时更新。整个过程几乎不消耗显卡资源非常适合在学生机、虚拟机、老旧的开发环境中跑。Stage 还支持编写自定义的.world文件用简单的地理图元矩形、圆形、多边形来构建环境。比如你可以画一个 U 型走廊来测试回环检测算法这套世界文件语法比 Gazebo 的 SDF 简单太多半小时就能上手。4.3 Stage的局限性虽然 Stage 很快但它的功能也就到此为止了。它无法模拟3D传感器比如深度相机、三维激光雷达不处理机器人之间的碰撞物理没有关节控制能力更别说机械臂运动规划了。如果你做的是视觉SLAM、机械臂抓取、地形适应等需要3D物理交互的任务Stage 完全不适用。另外需要注意的是Stage 的激光雷达模型是理想化的没有加入足够的噪声和误差因此你在 Stage 里调试好的算法直接上真机往往会发现地图质量明显下降。我自己的习惯是算法层面先在 Stage 里快速迭代逻辑验证通过后再到 Gazebo 或 Webots 里加入传感器噪声重新测试最后才上真机。这样既保证了速度也能在接近真实的仿真环境中发现传感器误差带来的问题。5. 选型决策表不同需求对应不同平台5.1 按任务场景选平台任务类型推荐平台原因2D SLAM 算法学习Stage轻量、快速、开箱即用3D 导航/多传感器融合Gazebo生态成熟传感器插件多机械臂运动规划与抓取Webots官方模型质量高MoveIt 集成顺滑视觉算法开发深度相机/目标检测Gazebo 或 Webots两者都支持 RGB-D 相机但 Gazebo 教程更多多机器人编队Stage性能开销低能跑到 10 机器人嵌入式/微控制器逻辑验证Webots对 micro-ROS 支持好物理反馈稳精确的动力学研究Gazebo支持多种物理引擎和控制器插件5.2 按硬件配置选平台如果你的电脑是低配轻薄本或虚拟机我建议直接放弃 Gazebo从 Stage 开始。Stage 的占用极低任何能跑 ROS 的设备都能流畅运行。你要真想上 3D 仿真Webots 对显卡的要求比 Gazebo 低一些因为 Webots 的渲染管线优化得更好但需要下载它的 AppImage 版本并手动安装。Gazebo 对硬件要求最高尤其当你加载复杂世界模型时GPU 显存不足会导致渲染异常甚至启动崩溃。5.3 按学习阶段选平台刚入门 ROS 时我的建议是 Stage 和 Webots 二选一。Stage 帮你快速理解话题/服务的通信机制不会陷入模型配置的泥潭Webots 则适合你想看3D效果、做机械臂项目时使用。当你对 ROS 的机制有了基本概念后再切换到 Gazebo因为大部分开源项目的仿真模块还是基于 Gazebo 写的脱离它意味着你无法复现很多论文或开源代码。6. 常见问题与排查技巧实录6.1 Gazebo界面一直在闪这个问题可以进我见过的高频问题前三名了。大多数情况下是因为 OpenGL 兼容问题。解决办法export LIBGL_ALWAYS_SOFTWARE1 gazebo强制使用软件渲染能缓解闪烁问题代价是渲染速度会下降。如果是 NVIDIA 显卡优先更新显卡驱动并在系统设置里切换到 NVIDIA 显卡输出。还有一个容易被忽略的原因多显卡环境如笔记本的 Intel NVIDIA 双显卡Gazebo 默认搭载的 GL 库选错了渲染设备这时候可以在启动命令前加__gl:x强制指定或者去安装mesa-utils后用glxinfo查看渲染器列表。6.2 模型加载不出来或显示成黑色方块这是新手最崩溃的时刻世界文件启动了但所有模型都是空的或者黑色。一般有三个原因一是模型数据库没下载下来Gazebo 默认从 models.gazebosim.org 在线拉取模型网络不稳定时会卡住。解决方法是提前设置模型路径export GAZEBO_MODEL_PATH$GAZEBO_MODEL_PATH:/path/to/your/models或者干脆下载好常用模型库放到本地。第二个原因是模型自带材质文件缺失SDF 引用了不存在的纹理贴图路径。第三个原因是显卡驱动对某些 shader 支持不好导致渲染异常这种情况也可以先用软件渲染救急。6.3 ROS版本兼容性问题我见过太多人死在版本不匹配上。记住一个基本原则主流的版本组合就那几套不要自由发挥。Ubuntu 20.04 用 ROS NoeticUbuntu 22.04 用 ROS 2 HumbleUbuntu 24.04 用 ROS 2 Jazzy。不要试图在没有官方支持的情况下强行安装 unix 版本的 ROS 包。另外ROS 1 的包不能直接在 ROS 2 里跑需要做端口映射或使用ros1_bridge这一点新手经常混淆。如果安装时提示要 Python 版本、CMake 版本或 Gazebo 版本不匹配最好的办法不是硬着头皮调而是查一下你当前 Ubuntu 版本对应的官方推荐版本换源后重新安装。鱼香ROS一键安装脚本在版本匹配上已经帮你处理过一轮但装完还是要跑roscore或ros2 doctor验证一下核心功能。6.4 仿真速度太慢Gazebo 跑起来像幻灯片这几乎是每个人都会遇到的。优先降低摄像头的发布频率和分辨率把激光雷达的 rays 数调低把世界里的物理步长调大比如把max_step_size从 0.001 改成 0.002但注意这会降低物理精度。如果你只需要传感器数据流和位姿可以关掉可视化窗口只保留 headless 模式运行速度能提升不少。Webots 里配置无限速选项可以加速仿真Stage 则基本不存在卡顿问题。6.5 从Blender导出模型到Gazebo的注意事项很多设计用 Blender 建好模型后想导进 Gazebo这里有个等级分明的坑。Blender 导出.daeCollada格式比.stl好很多因为.stl没有颜色信息导进去全是灰色模型。如果你搞到的是.dae文件但材质不显示大概率是 Blender 里的颜色通道和 Gazebo 的 shader 不兼容。建议导出时选择包含UV纹理并且在 Gazebo 的 SDF 文件里手动指定一个material标签。更稳妥的方式是先在 Blender 里把模型拆成多个部件给每个运动部件单独设置原点使用 Blender 的 URDF 导出插件生成 urdf 文件。注意所有碰撞体和视觉体的原点必须相对准确否则 Gazebo 加载后关节位置会完全不对。写在最后的个人经验从我自己的经历来看平台选型这件事没有最好用的仿真器只有最适合当前阶段的仿真器。我在做的导航项目里算法的快速验证几乎都在 Stage 完成真实纹理环境的传感器测试会放到 Gazebo而机械臂相关的实验我更倾向于 Webots。折腾这么多年后我最大的体会是别在一个仿真器里钻牛角尖熟练掌握两个平台的基本流程遇到具体问题时再根据需求切换这才是最高效的方式。如果你现在还在纠结选哪个我的建议是——选那个你当前的项目最需要覆盖的那个功能先装好跑通再评估是否要切换经验是在踩坑中积累的光看对比文章永远选不出答案。