如果你正打算在 Ubuntu 18.04 上搭建 ROS Melodic + Gazebo + PX4 的无人机仿真开发环境,我先说句实话:官网文档写得很工整,但真实安装过程不是照着敲就能一路跑通的。我前后折腾了两天,中间重装过一次系统,最后才把这套环境彻底捋顺。这篇文章就是把我踩过的坑、验证过能用的步骤全部写下来,帮你把这个过程压缩到半天以内。无论你是刚开始接触 PX4 二次开发,还是实验室里想快速跑一个 Gazebo 仿真,都可以按这份流程走一遍。
需要说明的是,这里不讨论新版本 Ubuntu 22.04 + ROS 2 或者 Gazebo Classic 的迁移方案,只讲一套目前仍然在大量无人机项目里服役的组合:Ubuntu 18.04、ROS Melodic、Gazebo 9、PX4 1.12.3。这套组合虽然不新,但胜在资料多、踩坑记录全、和很多老版本开源项目兼容,特别适合入门和复现论文。
1. 为什么 Ubuntu 18.04 + Melodic 是 PX4 开发绕不开的组合
1.1 版本对应关系先理清楚
很多人装环境失败,不是操作问题,而是版本搭配本身就错了。PX4 的仿真体系对 ROS 版本和 Gazebo 版本有对应关系,不是随便拿个 Ubuntu 20.04 + ROS Noetic 就能无脑跑出同样的效果。
Ubuntu 18.04 对应的官方 ROS 版本就是 Melodic,而 Melodic 默认自带的 Gazebo 是 9。PX4 的 SITL 仿真插件从很早就在 Gazebo 9 上做过大量验证,尤其是我下面推荐的 PX4 1.12.3 版本,对 Gazebo 9 的支持非常稳定。三者之间的匹配关系可以简单看作:
| 组件 | 推荐版本 | 说明 |
|---|---|---|
| 操作系统 | Ubuntu 18.04.5 | 长期支持版,生态最成熟 |
| ROS | Melodic | Ubuntu 18.04 官方对应版本 |
| Gazebo | 9.x | ROS Melodic 自带,PX4 1.12 验证充分 |
| PX4 固件 | 1.12.3 | 国内很多教程和开源项目的基础版本 |
如果你去查 PX4 官网,会发现最新固件版本对 Gazebo 版本的要求已经变了,比如 1.14 以后更偏向 Gazebo Classic 甚至新的 Gazebo 版本。但 Ubuntu 18.04 上单独升级 Gazebo 11 会带来一整套依赖冲突,不值得为了追新而无谓消耗时间。新版本可以等环境跑通了以后,再在 Docker 或者新系统下去尝试。
1.2 什么场景下必须用这套环境
我自己遇到最多的是两类需求:一类是跑开源算法,比如目标跟踪、路径规划、视觉 SLAM,很多老项目基于 Melodic 写成,直接给你 launch 文件和环境配置文件,换到 Noetic 就得改一堆依赖和接口;另一类是实验室的 PX4 二次开发,底层仿真链路由学长学姐传下来,用的就是 Gazebo 9 加 PX4 旧版本。
还有一类是课程作业和毕业论文复现。国内不少无人机方向的研究生论文附录里写的都是 Ubuntu 18.04 + Melodic + PX4,你照着搭环境,至少能减少一个“版本环境不一致”带来的变量。
如果你纯粹想尝鲜,用 ROS 2 跑新功能,那 Ubuntu 18.04 这套组合并不适合,可以直接去看 Ubuntu 22.04 + ROS 2 Humble 的方案。但如果你想踏踏实实学 PX4 仿真、把无人机二次开发的基础链路搞明白,这套环境仍然是当前最稳的起点。
1.3 不要被“旧系统”三个字劝退
我在实际使用中最大的感受是:Ubuntu 18.04 看起来老,但好在所有坑都已经被前人踩干净了。你搜任何一个报错信息,几乎都能找到对应的讨论帖。这种“经验的确定性”在开发环境搭建阶段非常宝贵,比追新版本然后自己去踩未知的坑要省心得多。
2. 正式安装前必须搞定的系统配置与依赖清单
2.1 硬件准备和安装方式选择
先说结论:如果条件允许,优先用物理机安装双系统。虚拟机也能跑,但性能和 3D 加速方面会多一些奇怪的问题,比如 Gazebo 界面闪、地面渲染不出来。
内存建议至少 8 GB,编译 PX4 固件的过程中内存不够很容易 OOM,直接编译报错,排查起来很糟心。磁盘预留至少 30 GB,ROS 本体加 PX4 源码加编译产物,实际占用远比你想象的大。
安装 Ubuntu 18.04.5 时要注意几点:
- 不要选最小安装,就选正常安装,因为后续很多开发库在最小安装下缺得厉害。
- 分区时给根目录单独分一个区,不用太在意 /home 单独分,个人开发用根目录一个分区就够。
- 如果安装过程中遇到“执行 grub 安装失败”,通常是引导分区的问题,重装时手动指定 /boot 分区可以解决。
装完系统以后,先执行一遍系统更新:
sudo apt update sudo apt upgrade这里跑一遍很有必要,不少官方软件源里的依赖缓存可能停留在旧版本,后续安装 ROS 时容易碰到依赖版本不满足的怪问题。
2.2 显卡驱动和 OpenGL 检查是重灾区
我折腾了两天,其中至少半天耗在 Gazebo 界面一直闪这个问题上。后来定位到根因是 OpenGL 渲染环境没有准备好,Gazebo 加载图形界面时反复刷新导致闪烁。
先安装 Mesa 工具检查渲染环境:
sudo apt install mesa-utils glxinfo | grep "OpenGL renderer"如果输出的是类似llvmpipe这样的软件渲染设备,说明 OpenGL 没走硬件加速。这种情况在虚拟机里非常常见,在 N 卡闭源驱动没装好的物理机上也偶尔出现。
对应的解决办法分两种情况:
- 虚拟机环境:打开虚拟机的 3D 加速开关。VMware 里在虚拟机设置的显示器选项中勾选“加速 3D 图形”,VirtualBox 则需要在设置里把显存调到 128 MB,并启用 3D 加速。改完以后要重启虚拟机生效。
- 物理机 N 卡:办法是安装合适的闭源驱动,
sudo ubuntu-drivers autoinstall之后重启,或者用“软件和更新”里的额外驱动选项卡手动选一个 recommended 版本。
如果显卡驱动已经装好但渲染还是不稳定,可以临时用软件渲染兜底:
export LIBGL_ALWAYS_SOFTWARE=1 gazebo这个变量只对当前终端生效,测试没问题后再考虑要不要固化到.bashrc。
2.3 提前安装的通用依赖
在装 ROS 之前,先把这些基础工具装好,避免中间被打断:
sudo apt install -y build-essential cmake git python-pip python3-pip \ g++ gdb vim htop net-tools curl wget这里要特别提一下python-pip,Ubuntu 18.04 默认自带的是 Python 2.7 和 Python 3.6,很多 PX4 构建脚本还会依赖 Python 2 生态。虽然官方已经逐步放弃 Python 2,但为了兼容 PX4 1.12.3 的构建流程,把 Python 2 相关工具链保持可用会让你少很多麻烦。
3. ROS Melodic 安装:从软件源到 rosdep 的完整链路
3.1 添加软件源和安装 ROS 本体
ROS Melodic 的软件源在国外的服务器上,直接访问速度不稳定,建议先换成国内镜像。我用的是清华源,实测速度比默认源快了非常多。
sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu bionic main" > /etc/apt/sources.list.d/ros-latest.list'上面这行仍然是官方源。如果你想要清华的 ROS 镜像源,可以改成:
sudo sh -c 'echo "deb https://mirrors.tuna.tsinghua.edu.cn/ros/ubuntu bionic main" > /etc/apt/sources.list.d/ros-latest.list'添加 key:
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654如果加 key 时网络不稳定,多试几次即可。接着:
sudo apt update sudo apt install ros-melodic-desktop-full为什么直接装desktop-full而不是ros-melodic-ros-base?因为 desktop-full 不仅包含 ROS 核心功能,还包含 Gazebo 9、RViz、TF 等一堆后续写代码绕不开的工具库。单独装 base 虽然能省一点空间,但之后你大概率还是要补装,反而多花时间。
安装完成后先验证一下:
source /opt/ros/melodic/setup.bash roscore如果看到started core service的输出,ROS 本体就没问题了。
网上也有很多一键安装 ROS 的脚本,比如鱼香ROS的一键安装工具,确实能省不少时间。但我的看法是:第一次搭建环境还是手动跑一遍比较好,至少你能知道每一步做了什么,之后遇到环境变量问题、软件源问题时,你知道去哪里排查。
3.2 初始化 rosdep 与环境变量
ROS 安装完以后,还有一步是很多人会漏掉甚至直接跳过的:初始化 rosdep。这步不做好,后面编译工作空间时会频繁报依赖缺失,而且有些依赖不是 apt 能直接解决的。
sudo rosdep init rosdep updaterosdep init常见报错是ERROR: cannot download default sources list from github。这不是你操作的问题,而是访问 GitHub 的服务不稳定。解决思路不是一遍遍死磕,而是换一种方式:
- 多试几次,有些时候网络波动是暂时的。
- 如果多次失败,可以搜索国内常用的 rosdep 镜像更新源,修改
/usr/lib/python2.7/dist-packages/rosdep2/sources_list.py或者/etc/ros/rosdep/sources.list.d/20-default.list中的地址,替换成国内可达的镜像。这一步需要一点动手能力,但值得花时间。
rosdep update成功以后,把环境变量写入~/.bashrc,避免每次开终端都要手动 source:
echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc source ~/.bashrc然后初始化 catkin 工作空间:
mkdir -p ~/catkin_ws/src cd ~/catkin_ws catkin_make这里要提醒一下:catkin_make第一次运行时会出现devel和build两个目录,这是正常的。如果这一步出现rosdep相关的报错,说明前面的 rosdep 初始化没做好,回头检查。
3.3 验证 ROS 环境是否完整
打开一个新终端,执行:
echo $ROS_DISTRO如果输出melodic,说明环境变量正常。再执行:
printenv | grep ROS你会看到ROS_MASTER_URI、ROS_PACKAGE_PATH等变量,这是正常的。
到这里,ROS 层面的环境就绪了。接下来才是真正耗时间的部分:Gazebo 和 PX4 的联动。
4. Gazebo 与 PX4 固件编译:最容易翻车的几个环节
4.1 先单独验证 Gazebo 是否能正常启动
ROS Melodic 装完以后,Gazebo 9 已经装好了。不要急着去编译 PX4,先把 Gazebo 单独跑起来确认环境没问题:
gazebo如果一切正常,你会看到一个包含地面、天空和光照的空场景窗口。如果窗口打不开、闪烁、崩溃,那大概率是显卡加速问题,回到第 2.2 节去处理。
这里还有一个高频问题:Gazebo 启动后下面的状态栏一直显示Downloading model...。这是因为 Gazebo 首次启动会从模型库下载一些默认模型,下载速度很慢,甚至卡住。
解决办法是先手动把模型库下载到本地:
cd ~/.gazebo git clone https://github.com/osrf/gazebo_models.git models然后把模型路径写进环境变量:
echo "export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:$HOME/.gazebo/models" >> ~/.bashrc source ~/.bashrc这样 Gazebo 启动时加载的就是本地模型,不会再卡在下载环节。
4.2 获取 PX4 固件并安装依赖
PX4 的源码在 GitHub 上,选对版本是关键。建议使用 1.12.3,而不是直接拉最新主干:
cd ~ git clone -b v1.12.3 https://github.com/PX4/PX4-Autopilot.git --recursive这里必须带--recursive,否则子模块缺失严重,编译到一半会报各种各样的找不到头文件的错误。如果你当时没带--recursive,事后补救命令是:
cd ~/PX4-Autopilot git submodule update --init --recursivePX4 官方提供了一键安装依赖的脚本,位于Tools/setup/ubuntu.sh。在 Ubuntu 18.04 上可以直接执行:
cd ~/PX4-Autopilot bash ./Tools/setup/ubuntu.sh --sim这个脚本会安装大量仿真需要的依赖,包括 Gazebo 相关插件、MAVLink 库、Python 库等等。脚本执行时间取决于网络状况,有时候会卡在某个 apt 包上。
遇到脚本卡住时,我的做法是先 Ctrl+C 停掉,然后手动执行它刚才正在安装的命令,确认是不是网络问题。如果是某个包下载慢,可以多试几次,或者改用国内的 apt 源。
4.3 编译 PX4 SITL 固件
依赖装好以后,开始编译。这一步风险最高,因为耗时可能很长,而且报错信息五花八门。
cd ~/PX4-Autopilot make px4_sitl gazebo第一次编译需要几分钟到十几分钟,取决于你的 CPU 性能。如果内存不足 8 GB,很容易在某个 C++ 文件编译时进程被杀掉。这时候不要慌,先确认是不是 OOM:
dmesg | grep -i oom如果是内存不足,可以通过临时增加 swap 来解决。比如创建一个 8 GB 的 swap 文件:
sudo fallocate -l 8G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile编译成功的标志是终端最后出现类似[100%] Built target gazebo_plane的输出,然后自动弹出 Gazebo 窗口,里面停着一架多旋翼无人机。
如果没有自动弹出窗口,说明环境变量没有正确加载。PX4 的仿真环境需要设置几个关键变量,我把它们统一写进.bashrc里会比较省事:
source ~/PX4-Autopilot/Tools/setup_gazebo.bash ~/PX4-Autopilot ~/PX4-Autopilot/build/px4_sitl_default export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:~/PX4-Autopilot export GAZEBO_PLUGIN_PATH=$GAZEBO_PLUGIN_PATH:~/PX4-Autopilot/build/px4_sitl_default/build_gazebo export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:~/PX4-Autopilot/Tools/sitl_gazebo/models这里的环境变量顺序有讲究。如果先 source 了 ROS 的 setup.bash,再 source PX4 的 setup_gazebo.bash,PX4 自己的 Gazebo 工具会追加到已有路径的后面。如果你反过来了,ROS 的路径会覆盖掉 PX4 的路径,导致 Gazebo 加载不到 PX4 的模型和插件。
4.4 编译过程中的典型报错处理
我遇到过最多的是下面这几类:
| 报错特征 | 真实原因 | 处理办法 |
|---|---|---|
找不到mavlink头文件 | 子模块没有下载完整 | 重新执行git submodule update --init --recursive |
GLIBC_2.XX not found | Python 环境或系统动态库混乱 | 尽量别手动卸载系统自带 Python,使用虚拟环境隔离 |
CMake Error: The source directory does not appear to contain CMakeLists.txt | 目录切换错误或源码路径有中文 | 检查当前目录是否为~/PX4-Autopilot |
| 编译器被 kill | 内存不足 | 增加 swap 或关闭占用内存的浏览器 |
Qt platform plugin xcb相关报错 | Gazebo 图形库依赖残缺 | 安装libqt5gui5和libxcb-xinerama0 |
5. 打通 Ubuntu 18.04 + Melodic + Gazebo + PX4 仿真链路
5.1 从命令行启动一套完整仿真
环境变量配置好以后,启动仿真就变得很简单了:
cd ~/PX4-Autopilot make px4_sitl gazebo这条命令会启动 PX4 SITL 进程,同时拉起 Gazebo。等待十几秒后,你能看到 PX4 终端输出类似[px4] Startup script的日志,紧接着 Gazebo 窗口中出现无人机模型。
如果 Gazebo 窗口有了,但是无人机没有出现,最常见的原因是模型路径没设对。验证方法:
echo $GAZEBO_MODEL_PATH输出里应该包含~/PX4-Autopilot/Tools/sitl_gazebo/models这个路径。
仿真起来以后,PX4 默认会等待地面站连接。你可以用 QGroundControl 连接,协议选择 UDP,端口默认14550。连接成功以后,在 QGC 上能看到无人机的姿态和位置信息,也可以规划任务。
5.2 使用 ROS 话题和 MAVROS 进行交互
如果你需要在自己的 ROS 节点里订阅无人机的位姿、传感器数据,或者给 PX4 发送指令,只靠 QGC 不够,至少还要装 MAVROS:
sudo apt install ros-melodic-mavros ros-melodic-mavros-extras装完以后,在新终端里启动 MAVROS 节点,把 PX4 的 SITL 数据转成 ROS 话题:
source ~/catkin_ws/devel/setup.bash roslaunch mavros px4.launch fcu_url:="udp://:14540@127.0.0.1:14557"这里的fcu_url是 PX4 SITL 默认暴露的 UDP 端口,具体值以你当前 PX4 版本的sitl脚本为准。连接成功后,可以通过:
rostopic echo /mavros/state看到connected: true,就说明 ROS 和 PX4 已经通了。之后你再跑自己的控制节点、SLAM 节点,都可以通过 MAVROS 提供的/mavros/setpoint_position/local或/mavros/rc/override等话题来控制仿真无人机。
这里有个经验:启动顺序很重要。先启动 PX4 SITL 和 Gazebo,等终端稳定输出后再启动 MAVROS,最后启动 QGC。反过来先启动 QGC 再启动仿真,有时候会导致 MAVROS 抢不到数据流端口。
5.3 仿真环境里常见的使用误区
我发现很多初学者会把 Gazebo 当成一个独立工具来调,实际上在 PX4 仿真链路里,Gazebo 只是“传感器仿真器”,PX4 SITL 负责飞控逻辑,QGC 负责地面站,MAVROS 负责 ROS 桥接。三者各司其职,任何一个环节断掉,无人机在 Gazebo 里都会表现异常,但 Gazebo 本身看起来又是正常的。
所以排查问题时,先确认 PX4 终端有没有正常输出EKF syncing之类的日志;再确认 QGC 有没有出现无人机连接;最后才去看 Gazebo 画面。
6. 实测排错:我踩过的坑与快速定位方法
6.1 高频问题排查表
以下这些问题是搜索记录里热度最高、也是我自己实际遇到过的。我整理成一张表,方便你遇到症状时直接对照。
| 症状 | 可能原因 | 快速解决办法 |
|---|---|---|
| Gazebo 界面一直闪 | OpenGL 没有硬件加速 | 检查glxinfo,虚拟机开 3D 加速,或export LIBGL_ALWAYS_SOFTWARE=1 |
| Gazebo 启动慢且一直下载模型 | 模型库没有本地化 | 手动 clonegazebo_models到~/.gazebo/models并设置GAZEBO_MODEL_PATH |
编译make px4_sitl gazebo卡住 | 网络下载依赖失败或内存不足 | 换代理不现实时,就重试;内存不足加 swap |
rosdep update失败 | 访问 GitHub 不稳定 | 多试几次,或把 sources_list 换成国内镜像 |
ROS 找不到px4相关包 | ROS_PACKAGE_PATH没设置 | 确认export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:~/PX4-Autopilot已写入 bashrc |
| QGC 连不上无人机 | 端口被占用或启动顺序不对 | 关掉所有 QGC/MAVROS,先启动 SITL,再启动地面站 |
报错Exception ignored in: <module 'mavlink'... | Python 2/3 模块冲突 | 确认编译和运行时都用同一个 Python 环境 |
6.2 一个更省事的排错思路:日志分期看
不要等 Gazebo 窗口弹出来才去排查问题。启动make px4_sitl gazebo之后,整个启动过程可以分成三个时间段:
- 前 5 秒:PX4 SITL 初始化和 Gazebo 加载。这个阶段报错大多是环境变量、模型路径、子模块缺失。
- 中间 5 到 20 秒:Gazebo 加载世界文件和无人机模型。这个阶段报错一般是模型库缺失、插件路径错误。
- 20 秒以后:PX4 与 Gazebo 握手。如果卡在这里,通常是端口冲突或 QGC 抢占数据流。
按时间段去日志里找关键词,能大幅缩小排查范围。
6.3 我的实际操作体会
这套环境我前前后后配过三台机器,一台物理机加两台虚拟机。物理机用 N 卡闭源驱动,Gazebo 渲染很稳;虚拟机只要把 3D 加速打开,跑 PX4 的简单仿真场景也没问题,但复杂场景下帧率会比较低。
另一个体会是:环境变量这个问题,看起来简单,其实最容易阴沟翻船。每次打开新终端,先用echo $GAZEBO_MODEL_PATH看一眼,不要直接去跑 launch。如果路径是空的,后续所有问题都会表现成“Gazebo 里没有无人机”,但你看 ROS 节点一切正常,容易误判成 PX4 编译失败。
最后再提醒一句:不要用sudo去跑 Gazebo、roscore 或者 roslaunch。一旦用 root 权限跑过,~/.gazebo里的文件所有者和权限会乱掉,后面普通用户启动 Gazebo 时会莫名其妙读不到模型库。遇到这种情况,sudo chown -R $USER:$USER ~/.gazebo可以救回来。
我这些年踩过最大的坑,就是贪图方便用 root 跑完整个仿真,然后花了一个下午处理权限问题。把这套环境手动走一遍之后,你的收获不只是“能跑起来”,而是知道每一条命令背后在干什么。之后换到 Ubuntu 20.04、ROS Noetic,甚至 ROS 2,你都有足够底气去应对新的报错。