ROS 2 Gazebo从安装到自建世界:版本选型与高频坑解析
2026/9/18 21:04:42 网站建设 项目流程

做ROS 2机器人开发,几乎绕不开Gazebo这个话题。无论是调导航、测SLAM,还是验证机械臂运动规划,先在仿真环境里跑通逻辑再上真机,能省下大量调试时间。但很多初学者第一次接触Gazebo时,卡住的往往不是机器人模型本身,而是最基础的安装和世界构建。这篇文章围绕ROS 2中Gazebo的版本选型、安装步骤、自定义世界文件编写、模型与传感器接入这几个核心环节展开,把我实际踩过的高频坑也一并整理出来。内容相当于教材6.4.1节的扩展版,适合刚装好ROS 2还没跑通第一个仿真场景的读者,也适合那些已经在用Gazebo但想彻底搞懂.world文件结构的开发者。

1. 版本选择是第一个坎:Classic和Modern两条线怎么选

1.1 Gazebo 11和Gazebo Harmonic到底差在哪

很多人搞不清楚为什么有"两个Gazebo"。这得从Gazebo的改名历史说起。老的Gazebo 7、9、11系列现在被官方称作Gazebo Classic,采用的是ROS 1时代延续下来的gazebo_ros_pkgs集成方式。这条线非常成熟,网上的教程、论文复现、开源的仿真案例,绝大多数都基于它。Ubuntu 22.04搭配ROS 2 Humble时,默认源里的Gazebo就是Classic 11,这也是目前资料最多、最不容易卡住的环境组合。

另一条线是新一代仿真器,曾经叫Ignition Gazebo,后来改名成Gazebo Sim,再后来直接叫Gz Sim。它从架构上做了大量重构,渲染引擎、物理引擎、插件系统都变了,模型格式依然是SDF,但启动命令从gazebo变成了gz sim,集成ROS 2的依赖包也从gazebo_ros_pkgs换成了ros_gz。Gazebo Harmonic是当前长期支持版,对应Ubuntu 24.04和ROS 2 Jazzy是最常见的组合。

从功能上讲,新旧两代都在持续维护,Gazebo Classic短期内也不会消失。但你要明白一件事:新封装和老封装的话题接口、launch文件写法、环境变量名都不一样,混着用容易出各种诡异问题。

1.2 ROS 2发行版和Gazebo版本的匹配对照

装机前先对着自己的环境确定版本组合,这是最重要的一步。我曾经见过有人用ROS 2 Humble却强行去跑只支持gz sim的launch文件,折腾一晚上没跑起来,最后发现是版本配错了。

ROS 2发行版Ubuntu版本推荐仿真器集成包
Humble22.04Gazebo Classic 11ros-humble-gazebo-ros-pkgs
Iron22.04Gazebo Classic 11或Gazebo Fortressros-iron-gazebo-ros-pkgs
Jazzy24.04Gazebo Harmonicros-jazzy-ros-gz

这里有个关键区别:Humble的官方源里默认装的是Gazebo Classic,对应包名是gazebo_ros_pkgs,启动launch文件用的是ros2 launch gazebo_ros gazebo.launch.py。而Jazzy的源里默认没有Gazebo Classic,只有新架构的gz-harmonic,对应的ROS 2集成包是ros_gz_sim,启动方式完全不同。

如果你在Ubuntu 22.04上非要跑Gazebo Harmonic,也不是不行,需要额外添加OSRF软件源,同时ROS 2侧的ros_gz包得从源码编译指定harmonic版本,这部分操作比较折腾,新手不推荐一上来就这么干。先用系统默认的组合把基础流程跑通,后面再研究进阶切换会从容得多。

1.3 按照你的实际场景做选择

怎么判断自己应该用哪条线?我给自己定了几条选择标准,可以供你参考:

  • 如果你要复现学术代码、跑开源SLAM/导航项目,优先选Gazebo Classic 11。开源生态里大部分仓库都在这条线上验证过。
  • 如果你是Ubuntu 24.04新装系统,别想办法去装老版Gazebo,直接顺应默认,用Gazebo Harmonic。Jazzy集成它已经是官方推荐路径,硬件加速和渲染效果也更好。
  • 如果你要做视觉或雷达仿真,新架构的传感器插件更规范,Humble环境里也建议提前尝试Harmonic。

基于这些判断,后面我会把Humble+Classic和Jazzy+Harmonic两套安装流程都讲清楚。

2. 安装实操:Ubuntu 22.04与24.04两条完整路径

2.1 Humble搭配Gazebo Classic 11的安装步骤

Ubuntu 22.04上安装这一套非常省心,ROS 2 Humble装好之后,一行命令就能把Gazebo本体和ROS 2集成包一起搞定。

sudo apt update sudo apt install ros-humble-gazebo-ros-pkgs

这个包会把gazebolibgazebo11gazebo_ros_pkgs一起拉进来。装完确认版本:

gazebo --version

如果终端能打印出类似Gazebo multi-robot simulator, version 11.x.x的信息,说明本体没问题。接着确认ROS 2集成是否正常:

ros2 pkg list | grep gazebo

正常情况下能看到gazebo_rosgazebo_ros_pkgsgazebo_plugins等包。这里有个容易忽略的点:gazebo_ros_pkgs是个元包,真正负责ROS 2节点的是gazebo_ros,负责话题桥接和gazebo插件的是gazebo_plugins。如果只装了元包而不确认子包,后面编译自己的模型插件时会报找不到头文件的错。

然后是环境变量。虽然gazebo_ros_pkgs安装时会设置一部分路径,但你的自定义模型目录一定要手动加进GAZEBO_MODEL_PATH。这个我建议写进~/.bashrc里:

echo 'export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:$HOME/gazebo_models' >> ~/.bashrc source ~/.bashrc

如果没有这个变量,后续用model://引用自己下载或导出的模型时,Gazebo会一直提示找不到模型。

2.2 Jazzy搭配Gazebo Harmonic的安装步骤

Ubuntu 24.04上的路径完全不同。先安装Gazebo Harmonic本体:

sudo apt install gz-harmonic

然后安装ROS 2 Jazzy侧的集成包:

sudo apt install ros-jazzy-ros-gz

这个元包会拉入ros_gz_simros_gz_bridge等关键组件。ros_gz_sim负责在仿真里生成实体、管理世界,ros_gz_bridge负责在ROS 2话题和gz传输话题之间搭桥。验证安装时注意,启动命令不是gazebo了:

gz sim --version

正常会打印Gazebo Sim, version 8.x.x之类的信息,这里的版本号对应的是Harmonic的Sim核心版本,不是Gazebo Classic的11。

环境变量也和Classic不一样,新架构用的是GZ_SIM_RESOURCE_PATH,设置自定义模型目录时别写错了:

echo 'export GZ_SIM_RESOURCE_PATH=$GZ_SIM_RESOURCE_PATH:$HOME/gz_models' >> ~/.bashrc source ~/.bashrc

2.3 装完怎么判断能不能用

每次装完工具,我喜欢用最小化验证来确认配置是真的通的,而不是等到后面写launch文件时才发现环境有问题。

先做GUI启动测试。Humble环境执行:

ros2 launch gazebo_ros gazebo.launch.py

Jazzy环境执行:

ros2 launch ros_gz_sim gz_sim.launch.py gz_args:=empty.sdf

正常会弹出一个空世界窗口,里面有地面网格和天空背景。看到这个窗口还不算完,再开一个终端确认ROS 2侧能看到仿真器节点:

ros2 node list

Humble下能看到/gazebo,Jazzy下能看到/gzserver/gz_sim这类节点名。如果节点列表是空的,说明ROS 2和Gazebo之间的桥没建立起来,后面spawn实体肯定失败,需要先排查这一步。

3. 写world文件前必须整明白的SDF骨架

3.1 world文件到底是个什么格式

Gazebo描述仿真世界用的是SDF格式,全称Simulation Description Format。你可能听过URDF,那是描述单个机器人的,SDF则更宏观,不仅描述机器人本身,还描述整个世界的组成:地面、光照、物理参数、静态物体、动态物体。

一个.world文件的最外层是sdf标签,里面通常包含一个world标签。看一个最小世界的骨架:

<?xml version="1.0" ?> <sdf version="1.6"> <world name="my_first_world"> <include> <uri>model://sun</uri> </include> <include> <uri>model://ground_plane</uri> </include> </world> </sdf>

model://sunmodel://ground_plane是Gazebo内置的模型引用,sun提供全局光照,ground_plane提供地面。这个文件虽然简单,但已经是能跑的合法世界了。

SDF特别讲究版本号。<sdf version="1.6">对应Gazebo 9+的基本语法,到了Harmonic,版本号推荐用1.101.11,因为新版本里部分标签结构有调整。跨版本解析时,老版本写法的文件基本都能被新版本读取,但反过来不行。我见过有人把新版world文件拿到Gazebo Classic 11里跑,报出一堆XML解析错误,多半就是这个原因。

3.2 scene、light、physics三个全局配置

除了include模型,world里最常用的是三个配置块:scene控制画面表现,light控制光照,physics控制物理仿真参数。

<scene> <background>0.8 0.8 0.9 1.0</background> <ambient>0.4 0.4 0.4 1.0</ambient> <sky> <clouds> <speed>5</speed> </clouds> </sky> </scene>

background是RGB加透明度的背景色,ambient是环境光强度。这两个值调不好,世界会看起来一片漆黑或者惨白刺眼。新架构里sky的云层速度用了<speed>,旧架构里则是<wind><humidity>这些不同字段,这也是跨版本兼容要注意的地方。

光照配置以方向光为例,模拟太阳光最合适:

<light type="directional" name="sun"> <cast_shadows>true</cast_shadows> <pose>0 0 10 0 0 0</pose> <diffuse>1 1 1 1</diffuse> <specular>0.5 0.5 0.5 1</specular> <direction>-0.5 0.1 -0.9</direction> </light>

direction的取值很多人调整不好。光线的方向是光源照射的方向向量,-0.5 0.1 -0.9表示从右上方向后方照射,阴影会投到地面偏后侧。如果你发现阴影方向诡异,第一件事不是去调pose,而是调direction

物理参数是仿真重力的关键:

<physics type="ode"> <max_step_size>0.001</max_step_size> <real_time_factor>1</real_time_factor> <gravity>0 0 -9.8</gravity> </physics>

max_step_size是每一步物理求解的时间步长,默认0.001秒,精度高但计算量大。如果仿真卡顿严重,可以放宽到0.002或0.005,但机械臂这类高精度场景不建议放宽太多。real_time_factor控制仿真速度和真实时间的比例,保持1就代表和真实时间一样快,跑仿真机器人视觉感知时这个值很重要,真机部署前就是靠这个参数确认算力够不够。

3.3 用include还是自己建model

构建世界时,摆在面前的有两条路:引用现成模型,或者在world文件里直接写死一个model

引用现成模型用includeuri

<include> <uri>model://cafe_table</uri> <pose>2.0 -1.5 0 0 0 0.8</pose> </include>

这种方式的好处是代码简洁,Gazebo会自动从模型数据库加载。但缺点也很明显,首次加载需要联网下载,下载不成功就卡住。在离线环境或网络不稳的场合,大量model://引用会导致世界加载时间长得让人崩溃。

直接在world里写model则完全依赖本地SDF描述,不涉及网络,更适合那些需要精确定制的墙、柱子、坡道。写法举例如下:

<model name="wall_1"> <static>true</static> <pose>0 2.0 0.5 0 0 0</pose> <link name="link"> <collision name="collision"> <geometry> <box> <size>3.0 0.2 1.0</size> </box> </geometry> </collision> <visual name="visual"> <geometry> <box> <size>3.0 0.2 1.0</size> </box> </geometry> <material> <ambient>0.8 0.2 0.2 1</ambient> <diffuse>0.8 0.2 0.2 1</diffuse> </material> </visual> </link> </model>

没有写<static>默认是false,也就是动态物体,会有重力作用往下掉。做环境墙体时一定要显式写static>true,否则启动后会看到墙体轰然倒下的名场面。

4. 零基础搭出一个能跑的世界文件

4.1 完整案例:带围栏和障碍物的导航测试场

纸上谈兵没有意义,直接给一个能跑的world文件,这个场景我经常用来测试导航算法,包含地面、四周围墙、两个障碍物和一盏方向光。

<?xml version="1.0" ?> <sdf version="1.6"> <world name="nav_test_world"> <include> <uri>model://sun</uri> </include> <include> <uri>model://ground_plane</uri> </include> <physics type="ode"> <max_step_size>0.001</max_step_size> <real_time_factor>1</real_time_factor> <gravity>0 0 -9.8</gravity> </physics> <model name="wall_left"> <static>true</static> <pose>-5.0 0 0.5 0 0 0</pose> <link name="link"> <collision name="collision"> <geometry> <box><size>0.2 10.0 1.0</size></box> </geometry> </collision> <visual name="visual"> <geometry> <box><size>0.2 10.0 1.0</size></box> </geometry> <material> <ambient>0.5 0.5 0.5 1</ambient> <diffuse>0.5 0.5 0.5 1</diffuse> </material> </visual> </link> </model> <model name="wall_right"> <static>true</static> <pose>5.0 0 0.5 0 0 0</pose> <link name="link"> <collision name="collision"> <geometry> <box><size>0.2 10.0 1.0</size></box> </geometry> </collision> <visual name="visual"> <geometry> <box><size>0.2 10.0 1.0</size></box> </geometry> <material> <ambient>0.5 0.5 0.5 1</ambient> <diffuse>0.5 0.5 0.5 1</diffuse> </material> </visual> </link> </model> <model name="wall_back"> <static>true</static> <pose>0 -5.0 0.5 0 0 0</pose> <link name="link"> <collision name="collision"> <geometry> <box><size>10.0 0.2 1.0</size></box> </geometry> </collision> <visual name="visual"> <geometry> <box><size>10.0 0.2 1.0</size></box> </geometry> <material> <ambient>0.5 0.5 0.5 1</ambient> <diffuse>0.5 0.5 0.5 1</diffuse> </material> </visual> </link> </model> <model name="obstacle_box"> <static>true</static> <pose>1.5 0 0.3 0 0 0.4</pose> <link name="link"> <collision name="collision"> <geometry> <box><size>0.6 0.6 0.6</size></box> </geometry> </collision> <visual name="visual"> <geometry> <box><size>0.6 0.6 0.6</size></box> </geometry> <material> <ambient>0.1 0.6 0.1 1</ambient> <diffuse>0.1 0.6 0.1 1</diffuse> </material> </visual> </link> </model> <model name="obstacle_cylinder"> <static>true</static> <pose>-1.8 1.8 0.5 0 0 0</pose> <link name="link"> <collision name="collision"> <geometry> <cylinder><radius>0.4</radius><length>1.0</length></cylinder> </geometry> </collision> <visual name="visual"> <geometry> <cylinder><radius>0.4</radius><length>1.0</length></cylinder> </geometry> <material> <ambient>0.9 0.6 0.1 1</ambient> <diffuse>0.9 0.6 0.1 1</diffuse> </material> </visual> </link> </model> </world> </sdf>

保存为nav_test.world。启动之前注意一点,<pose>里的四个墙和障碍物的z坐标,都是"半个高度偏移量",比如墙体高度1米,所以z设置了0.5,让底部刚好贴地。这个偏移算错了,看起来会像悬浮或者穿模。

4.2 启动你自己的世界

Humble环境下,启动自定义world文件:

ros2 launch gazebo_ros gazebo.launch.py world:=/path/to/nav_test.world

注意,world:=后面要用绝对路径,用相对路径偶尔会因为launch文件的工作目录不同而找不到文件。如果你不想每次敲这么长的路径,可以把world文件统一放在一个目录里,然后在launch文件里用pkg-relative方式引用。但对初学者,我建议先直接用绝对路径,先把流程跑通。

如果你在Jazzy环境,启动方式有变化,而且支持直接在gz_args里传世界文件路径:

ros2 launch ros_gz_sim gz_sim.launch.py gz_args:=/path/to/nav_test.world

启动后,应该能看到一个带灰色地面、四面围墙、两个障碍物的三维场景。视角操作上,Shift+鼠标中键拖动是平移,鼠标左键拖动是旋转视角,鼠标滚轮是缩放。很多人第一次跑起来后不知道怎么调整视角,这里先记一下。

4.3 启动后必做的三个自检

世界加载成功不等于一切正常,我通常会在刚打开场景后立刻做三个自检。

第一,物理引擎的静置检查。视线盯着障碍物和墙面,确认没有任何模型在下落或滑动。如果出现墙体倾倒,检查<static>是否为true。

第二,光照方向检查。看地面上的阴影是否自然,如果整个场景惨白或者完全漆黑,检查sun模型是否加载成功。sun加载失败时场景会有光源缺失感,此时在Gazebo左侧模型面板里手动拖一个sun进去也能临时解决。

第三,用户界面里的模型列表。在左侧插入面板可以看到当前世界的树结构,里面应有wall_leftobstacle_box等模型节点。如果某个模型没有出现,多半是XML里有标签拼写错误,终端也会同步打印SDF解析报错。终端里没有错误输出、模型却没显示的情况极少,一旦出现基本是图形渲染层面的显示问题,可以试着关闭重开或调整渲染引擎。

5. ROS 2与Gazebo的交接:生成实体与传感器接入

5.1 spawn实体命令在不同版本间的差异

世界文件准备好了,机器人怎么放进去?两种方式,一是在world文件里直接通过include引入机器人模型,二是在启动仿真后动态生成实体。动态生成在实际开发中更常用,因为可以在launch文件里灵活控制位置、参数和数量。

Humble环境,经典做法是用gazebo_ros包里的spawn_entity.py脚本:

ros2 run gazebo_ros spawn_entity.py \ -entity my_robot \ -file /path/to/my_robot.sdf \ -x 0.0 -y 0.0 -z 0.1

实体名-entity必须唯一,重复生成同名实体会报错。-file参数指向URDF或SDF文件,URDF也能用但推荐转成SDF,SDF对Gazebo的支持更完整。

Jazzy环境,命令换成了ros_gz_sim的create命令:

ros2 run ros_gz_sim create \ -name my_robot \ -file /path/to/my_robot.sdf \ -x 0.0 -y 0.0 -z 0.1

注意选项从-entity变成了-name,其他坐标参数保持一致。如果你在Humble里强行用gz sim --spawnros_gz_sim create,会因为版本不对打出奇怪的eigen3库报错,当年我排查了一晚上后发现只是命令用混了。

5.2 差速驱动机器人接入仿真

假设你已经有一个差速驱动机器人的URDF模型,想接入Gazebo进行导航测试。URDF直接给Gazebo用会缺少一些关键信息,建议先用gazebo_ros2_control插件包把URDF转成SDF,或者在URDF里附带Gazebo插件标签。

一个最简的差速驱动Gazebo插件配置长这样:

<gazebo> <plugin name="diff_drive" filename="libgazebo_ros_diff_drive.so"> <ros> <namespace>/robot</namespace> </ros> <left_joint>left_wheel_joint</left_joint> <right_joint>right_wheel_joint</right_joint> <wheel_separation>0.35</wheel_separation> <wheel_diameter>0.2</wheel_diameter> <command_topic>cmd_vel</command_topic> <odom_topic>odom</odom_topic> </plugin> </gazebo>

这些配置写入URDF文件的末尾,再用spawn命令把它加载进仿真。Gazebo会解析插件,创建cmd_velodom话题,这时你可以从终端发一个速度指令验证:

ros2 topic pub -1 /robot/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 0.5}, angular: {z: 0.0}}"

同时监听里程计话题:

ros2 topic echo /robot/odom

如果机器人动了、里程计也在持续更新,说明闭环建立成功。这一步没反应时,优先检查插件是否真的被加载,在启动仿真时的终端里搜索diff_drive相关日志,找不到基本就是插件路径或命名空间配置问题。

5.3 激光雷达和相机传感器怎么放进来

Gazebo里的激光雷达一般用gpu_ray插件模拟,网络上有大量现成配置。以Humble为例,一个gpu_lidar插件的URDF片段长这样:

<gazebo reference="lidar_link"> <sensor type="gpu_ray" name="lidar_sensor"> <pose>0 0 0.1 0 0 0</pose> <always_on>true</always_on> <update_rate>10</update_rate> <visualize>true</visualize> <plugin name="lidar_plugin" filename="libgazebo_ros_ray_sensor.so"> <ros> <namespace>/robot</namespace> <remapping>scan:=scan</remapping> </ros> <output_type>sensor_msgs/LaserScan</output_type> <min_range>0.1</min_range> <max_range>10.0</max_range> <horizontal_samples>360</horizontal_samples> <horizontal_resolution>1.0</horizontal_resolution> </plugin> </sensor> </gazebo>

相机传感器同样用插件方式接入,常用libgazebo_ros_camera.so。相机接入后能产生image_rawcamera_info话题,供视觉SLAM或者目标检测做测试。这类传感器在Harmonic上有对应替代配置,接口字段和插件名字会有差别。

这里提醒一句:雷达的update_ratehorizontal_samples两个参数非常影响CPU占用。把水平采样设为720、更新率设为20时,一颗高仿雷达就能烧掉不少算力,做多机器人仿真时要特别注意,别让一颗虚拟雷达拖垮整台电脑。

6. 高频异常排查:闪烁、白屏、加载失败的现场还原

6.1 界面一直在闪:图形渲染问题排查

网上关于"为什么gazebo界面一直在闪"的提问特别多。我在虚拟机里遇到过一次,真机上也遇到过。

先判断环境。如果运行在VMware或者VirtualBox虚拟机里,闪烁大概率是OpenGL渲染不兼容导致的。虚拟机默认的3D加速能力和Gazebo要求的OpenGL版本经常对不上。简单的解决办法是强制软件渲染,启动前设置环境变量:

export LIBGL_ALWAYS_SOFTWARE=1

设置后Gazebo界面闪烁会显著减少,代价是渲染帧率下降,稍微复杂的场景旋转视角时会感觉卡顿。如果是真机出现闪烁,优先排查显卡驱动,关闭快捷键切换导致的渲染异常,再尝试升级mesa驱动。

第二个常见原因是窗口聚焦问题,Gazebo的渲染循环在高DPI缩放或多显示器环境下会异常刷新。可以尝试把外部GUI渲染选项关掉,用headless模式跑服务器端仿真,界面只用来做可视化调试:

export GAZEBO_HEADLESS=1

6.2 模型加载不出来或显示白模:资源路径设置

Gazebo模型加载的问题分两种。第一种是model://引用找不到,终端会打印Unable to find uri[model://xxx]。这时候检查GAZEBO_MODEL_PATHGZ_SIM_RESOURCE_PATH是否包含了目标模型所在目录。注意,环境变量要在启动Gazebo的同一个终端里生效,改了.bashrc记得source或者重开终端。

第二种是模型能加载但显示全白,大概率是模型文件里没有定义<material>,或者材质贴图路径缺失。Gazebo White Model是一个常见现象,特别是用Blender导出的模型最容易出现。因为Blender导出时纹理贴图的相对路径没有正确带到模型目录里,Gazebo找不到贴图文件,只能显示白色材质。

处理方法是把贴图文件和模型文件放在同一目录,确保SDF里的<uri>是相对路径,不要写成file:///home/user/...这样的绝对路径。跨机器拷贝模型包时,绝对路径几乎必坏,这是很多人踩过的坑。

6.3 用Blender导出的模型怎么正确进Gazebo

热词里有人搜"blender导出gazebo模型",说明这条路确实很多人都走。Blender默认导出格式里没有直接对应Gazebo的选项,通常路径是Blender导出.dae,再通过gz sdf工具转换成.sdf

Humble环境下的转换命令:

gz sdf -p model.dae > model.sdf

转换完成后,需要在SDF里补上材质信息,Blender导出的材质在转换后经常丢失或者变成默认白色。转换出来的SDF文件里往往是一堆<visual><collision>块,你需要确认碰撞体积是不是和视觉模型一致。很多人在这一步偷懒,写一个简化的长方体碰撞盒,导致仿真里机器人明明看起来离障碍物还远,却已经撞上去了。

如果只是想在world里放一个装饰性物体,可以把整个模型包放到GAZEBO_MODEL_PATH目录中,目录结构应该是model_name/model.configmodel_name/model.sdf。Gazebo通过model.config识别模型名称和描述信息,缺少这个文件时模型面板里不会显示你的模型。

6.4 版本混杂导致的链接错误与话题缺失

最后一种高频异常,是Humble环境里装了一堆gz sim相关包,导致gazebo_ros_pkgs插件加载时报找不到符号或版本不匹配。

一个典型场景:你先安装了ros-humble-ros-gz,又在同一环境里用gazebo_ros_pkgs启动Classic仿真,可能会出现libignition-common相关的so文件冲突。原因是两个版本的集成包依赖了不同版本的底层库,动态链接时优先加载了不对应的库文件。

遇到这种问题,检查两件事。第一,用ldd确认实际加载的库路径:

ldd /opt/ros/humble/lib/libgazebo_ros_diff_drive.so | grep ignition

看到多个不同版本的ignition库时,考虑在启动前用LD_LIBRARY_PATH指定优先路径,或者干脆清理掉不需要的gz sim相关包。第二,检查当前环境变量里是不是混入了多个AMENT_PREFIX_PATH。如果养成每装一个包就手动往环境里加路径的习惯,很容易导致ROS 2包解析错乱,这时用printenv | grep ROS检查一下,把重复路径清理干净。

从我自己折腾Gazebo这些年的经验看,绝大多数启动失败、界面异常、模型加载问题,根因都不是复杂的技术难题,而是环境不纯、版本混用、路径错误这三件事。所以每次搭建新环境时我都会写个备忘,明确记录当前ROS 2版本、Gazebo版本、模型资源路径,避免几天后回过头来忘了自己配过什么。遇到奇怪问题,先降级处理:把自定义的东西全部停掉,跑官方示例,跑通了再逐步加回自己的模型,这个排查思路虽然笨,但效率往往最高。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询