在飞控开发这条路上,环境搭建往往是劝退率最高的第一道坎。我在Ubuntu 24.04刚发布没多久就开始把PX4开发环境往新版本上迁移,前后因为网络、依赖冲突和串口权限问题重装过三次系统,也算把常见的坑都踩了一遍。这篇教程是我“飞控入门前期准备”系列的第一篇,核心目标很简单:带你从零开始,在一台装着Ubuntu 24.04的机器上把PX4固件编译环境、Gazebo仿真器和QGroundControl地面站全部跑通,让你第一次执行模拟飞行之前,系统是干干净净、明明白白的。
这篇文章适合完全没接触过Linux的新手,也适合已经装过PX4但被Ubuntu版本升级搞得焦头烂额的老手。我会把每一步背后的为什么讲清楚,不光是“敲什么命令”,而是让你知道这条命令在干什么、失败时怎么看日志。只要跟着走一遍,后续玩仿真、接真机、写飞行控制算法,就不会在环境问题上消耗太多精力。
1. 为什么偏偏选Ubuntu 24.04来跑PX4?环境选型的真实考量
很多人一上来就纠结“到底用哪个Ubuntu版本”,这其实是个好问题,因为飞控工具链对操作系统的依赖程度远高于普通软件开发。我先说结论:现在装PX4,Ubuntu 24.04 LTS完全可以用,而且从长期维护的角度看,它是比老版本更省心的选择。
1.1 版本适配:LTS生命周期和工具链兼容性
Ubuntu 24.04 LTS(Noble Numbat)于2024年4月发布,官方提供5年安全更新支持。这对飞控开发意味着什么?你不需要频繁担心系统组件的安全补丁问题,整个开发周期里系统层面的变化会非常小,环境是稳定可控的。
PX4官方文档当前对Ubuntu的支持范围已经涵盖了22.04和24.04。24.04默认自带的关键工具链版本是:GCC 13.2、CMake 3.28、Python 3.12、Git 2.43。这几个版本和PX4固件的编译需求是匹配的。有一些老教程会提醒你“不要用太新的Ubuntu,因为工具链版本太新会编译失败”,这主要是针对20.04往22.04过渡那段时间的问题。到了24.04这个节点,PX4主分支和新版本Gazebo仿真器已经做了大量适配,默认的Python 3.12环境下,pip安装依赖时需要注意PEP 668的限制,后面我会专门讲。
1.2 双系统、虚拟机还是WSL?我给新手的明确建议
这是个高频问题。我直接给结论:
- 首选:双系统,独立安装Ubuntu 24.04。飞控开发会涉及串口设备直连、USB设备识别、网络端口监听、图形化仿真界面,双系统能让你完全避开虚拟化层的各种兼容性问题。
- 次选:虚拟机。如果你只想先体验一下PX4的SITL仿真,不碰真实飞控硬件,那么VMware或VirtualBox里跑Ubuntu 24.04完全够用,性能损失对纯仿真场景影响不大。但你一旦要接USB下载器、数传模块、飞控板,虚拟机的USB设备透传经常会折腾人。
- 不推荐:WSL2。虽然WSL2支持GUI应用和串口映射,但PX4和QGroundControl这类需要实时访问硬件设备、处理多网络端口的软件,在WSL2的网络模型下会冒出很多莫名其妙的问题,排查成本极高。
我自己的经历是第一次图省事装了虚拟机,结果插上CUAV V5+飞控后USB设备一直无法稳定识别,折腾两个晚上后果断改成双系统,问题直接消失。所以如果你确定要长期走飞控这条路线,请直接分配一块独立硬盘装双系统,把麻烦前置。
1.3 磁盘与硬件配置的最低标准
PX4全量clone源码加编译中间文件,体积不小。我建议系统安装时给Ubuntu至少分配100GB磁盘空间。编译时GCC会吃满所有CPU核心,8GB内存是起步配置,16GB更稳。每次执行make命令时,build目录里的中间文件短时间就能膨胀到20GB以上,磁盘空间不足是编译失败的头号隐形杀手。
2. 系统装完别急着重启三次,先做这三件基础配置
很多教程直接跳到PX4工具链安装,但忽略了三件影响全局的基础配置。这些配置不做好,后面每一步都会遇到怪问题。
2.1 换源和系统更新:第一件事永远是这件事
Ubuntu 24.04默认的软件源服务器在国外,国内网络环境下apt下载速度慢到怀疑人生。装完系统第一件事,把源换成国内镜像。
编辑源列表文件:
sudo sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list sudo sed -i 's/security.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list注意Ubuntu 24.04开始使用了新的源格式,包含components字段,上面这个sed替换命令对传统格式有效,如果发现替换后apt报错,直接编辑文件手动把archive.ubuntu.com和security.ubuntu.com替换成mirrors.aliyun.com或mirrors.tuna.tsinghua.edu.cn即可。
然后执行系统更新:
sudo apt update && sudo apt upgrade -y这里的逻辑很直白:PX4工具链依赖大量系统库,如果不先把系统本身升到最新,后续apt安装依赖时可能出现部分包版本冲突。官方工具链脚本可不会帮你排查系统包冲突。
2.2 安装基础软件包:装工具链之前的铺垫
PX4官方脚本会自动安装绝大多数依赖,但有一些基础包我建议手动先装好:
sudo apt install -y git curl wget vim build-essential \ zlib1g-dev libncurses-dev libgdbm-dev libnss3-dev \ libssl-dev libreadline-dev libffi-dev cmake ninja-buildgit和vim属于必备,不用多解释。build-essential提供GCC和make。cmake和ninja-build是PX4编译系统的核心,官方脚本虽然也会装,但先装一份最新版能确保后续工具链检测环节不卡壳。
2.3 中文输入法配置:一个容易被忽略的痛点
Ubuntu 24.04默认桌面环境是GNOME,中文输入法默认支持了iBus框架,但很多从Windows转过来的用户习惯用fcitx5。如果你需要中文输入,建议装fcitx5:
sudo apt install -y fcitx5 fcitx5-chinese-addons然后打开“设置-系统-区域与语言”,把输入法框架切换为fcitx5,注销重新登录即可生效。这个配置和PX4没有直接关系,但它直接影响你后续查资料、写注释的效率。我见过太多人因为输入法问题分心,最后环境装到一半放弃了。
另外提醒一句:整个开发环境的用户目录请保持英文路径,不要用中文用户名。PX4的编译脚本和Python虚拟环境对路径中的非ASCII字符支持并不完善,中文路径会导致一些莫名其妙的编译错误。
3. PX4工具链安装全流程:从git clone到串口权限
这一步是整个教程的核心,也是最多人出问题的环节。我会先讲原理再讲操作,确保你理解每一步的意义。
3.1 下载PX4源码:理解--recursive的含义
PX4使用Git子模块来管理大量第三方库,比如NuttX实时操作系统、mavlink协议库、eigen数学库等。如果你漏掉了这些子模块,编译时会报“找不到头文件”之类的错误。
获取源码的命令:
mkdir -p ~/src && cd ~/src git clone --recursive https://github.com/PX4/PX4-Autopilot.git这里有几个要点:
--recursive参数会在clone主仓库的同时初始化并拉取所有子模块,这个过程依赖网络,耗时可能很长。国内网络环境下,GitHub访问不稳定,建议使用代理或镜像站。我这里提供一个备选方案:使用gitee镜像仓库(在很多飞控社区里有人维护),或者定时在低峰期重试。- 如果中途clone失败,不要直接重来,进入仓库目录后反复执行以下命令补全子模块:
cd ~/src/PX4-Autopilot git submodule update --init --recursive- 分支选择:默认当前在
main分支,这是开发版。不想追新的话,可以切到稳定分支。PX4的稳定分支和Tag命名方式与很多软件不同,建议查看官方发布页确认最新稳定版,然后:
git checkout v1.15.4 # 这里以你查到的版本号为准 git submodule update --init --recursive3.2 运行官方工具链脚本:搞清楚它在干什么
PX4提供了一个自动化脚本,位于PX4-Autopilot/Tools/setup/ubuntu.sh。首次运行需要安装所有依赖,执行:
cd ~/src/PX4-Autopilot bash ./Tools/setup/ubuntu.sh这个脚本做了很多事,包括:
- 更新apt软件包列表并升级系统
- 安装Python3的各种开发头文件和pip
- 安装cmake、ninja、gstreamer等编译和仿真库
- 安装NuttX交叉编译工具链
- 设置用户串口访问权限
脚本运行过程中会打印大量输出,如果中途失败,不要忽略。最常见的失败原因是网络问题导致某个apt包或pip包下载超时。脚本本身支持断点续跑,修好网络后重新执行即可。
需要特别说明的是,Ubuntu 24.04自带的Python 3.12引入了PEP 668机制,限制了使用系统pip直接安装包,这是为了防止pip包覆盖系统包管理器。PX4官方脚本处理了这个限制,但如果你在脚本运行后手动执行pip install时报错,请使用虚拟环境或在pip命令前加--break-system-packages参数。更推荐的做法是让脚本自己管理Python依赖。
大部分用户只需要做SITL仿真开发,不需要真机编译,这种情况下运行脚本时可以跳过NuttX工具链安装:
bash ./Tools/setup/ubuntu.sh --no-nuttx这个参数能帮你省下不少下载时间和磁盘空间。如果你以后要编译真实飞控固件,再重新完整运行一次脚本即可,没有副作用。
3.3 串口权限:接真机之前的必要配置
PX4飞控通过USB串口与电脑通信,Ubuntu默认情况下普通用户没有权限访问串口设备。官方脚本会在最后提示你将当前用户加入dialout和plugdev组:
sudo usermod -a -G dialout $USER sudo usermod -a -G plugdev $USER关键点:执行完这个命令后,必须注销重新登录或重启,用户组变更才会生效。很多人在这一步偷懒,用su切换用户,或者直接以root身份运行,导致后面串口设备无权限问题反复出现。正确做法是重启一次系统,然后用普通用户身份继续操作。
4. 编译PX4固件:第一次跑通的完整过程
工具链装完,下一步是编译固件,验证整个环境是否真的可用。这个环节最容易让人崩溃,我把我的经验完整写出来。
4.1 选择编译目标:理解PX4的构建系统
PX4使用CMake作为构建系统,通过make命令调用。编译目标的命名格式是:
make <板卡目标> <特定配置>- 板卡目标:比如
px4_fmu-v5(Pixhawk 4)、px4_fmu-v6x(Pixhawk 6X)、sitl(仿真) - 特定配置:比如
gz_x500、gazebo-classic等,用于配置仿真环境
首次入门,我建议先编译仿真目标:
cd ~/src/PX4-Autopilot make px4_sitl gz_x500这个命令会编译PX4飞控栈的x500多旋翼模型,并在Gazebo仿真器中启动。如果一切顺利,你会看到终端输出大量编译日志,最后出现Starting gazebo...之类的字样。
如果只是验证工具链完整性,也可以先编译不带仿真器的纯固件:
make px4_sitl这个目标不会启动仿真器,但会编译出SITL仿真固件,可以用来验证工具链是否正确。我建议第一次跑这个,失败时日志短,排查容易。
4.2 编译日志怎么看:常见报错与定位方法
编译出问题是最正常的。关键是你要知道怎么从日志里找到真正的原因。
报错一:找不到头文件或库文件。
这种错误通常是依赖没装全。日志中会明确提示缺失的文件名,比如FATAL_ERROR: "opencv2/opencv.hpp" not found,那就说明OpenCV开发包未安装。执行sudo apt install libopencv-dev补上再重新编译。
报错二:submodule未更新。
日志会提示类似于Directory ... does not exist或fatal: No such file or directory,这类问题基本是子模块缺失。回到源码目录,执行:
git submodule update --init --recursive再重新编译。这类报错在clone中断后特别常见。
报错三:内存不足或进程被杀死。
编译过程中终端输出Killed字样,同时系统变得卡顿,这是内存或磁盘空间不够。检查内存:free -h;检查磁盘:df -h。如果磁盘不足,清理build目录:
make clean然后可以限制编译并行度,避免内存爆炸:
make px4_sitl -j4-j参数是编译线程数,默认情况下Make会用满所有CPU核心,16线程编译8GB内存很容易把内存耗尽。保守起见,第一次编译用-j4。
4.3 编译产物在哪?构建目录的认知
编译完成后,产物在build目录下。例如:
build/px4_sitl_default/bin/px4这是SITL仿真固件的可执行文件。在Gazebo环境下,实际启动流程是:make命令先编译固件,然后读取ROMFS/px4fmu_common/init.d-posix/rcS启动脚本,该脚本负责启动飞控主进程和仿真通信模块。
理解这个启动流程能帮你在仿真异常时定位问题:如果你是手动启动px4而不是通过make命令,需要额外设置环境变量:
export PX4_SIM_MODEL=gz_x500 export PX4_GZ_MODEL=x500 ./build/px4_sitl_default/bin/px4很多新手直接把这一步省略,然后发现仿真器启动不了,就是环境变量没有带过去。
5. 搭建Gazebo仿真环境:第一次起飞前必须检查的环节
编译通过不代表仿真能跑起来。PX4的SITL仿真是一个非常复杂的三方协作:PX4飞控栈(C++)作为飞行逻辑核心,Gazebo作为物理引擎和传感器仿真器,两者通过uORB消息和MAVLink协议通信。这个环节我要把背后的连接关系讲透。
5.1 仿真器选型:Gazebo Classic还是新版本Gazebo
PX4在24.04下默认使用新版Gazebo(即Garden或Harmonic),构建目标名称是gz_x500。旧版本Ubuntu常用的Gazebo Classic(gazebo-classic)在24.04上也能装,但我建议直接用新版,因为新版是PX4官方重点维护的对象,功能更多。
新版本Gazebo默认不会自动安装,PX4的make px4_sitl gz_x500命令会检查并提示你安装缺少的gazebo相关包。你也可以手动安装:
sudo apt install -y gazebo安装完成后确认版本:
gz sim --version运行仿真时你可能会遇到图形环境问题。在虚拟机里首次运行Gazebo,渲染速度慢甚至黑屏是正常的,这是因为虚拟机没有独立GPU。试一次以后心里有底就行,真机场景不受此影响。
5.2 检查MAVLink连接和终端输出
仿真器启动完整后,终端会持续滚动PX4的启动日志,其中包括:
INFO [logger] logger started. INFO [mavlink] mode: Normal, data rate: 4000000 B/s on udp port 14550 remote port 14550 INFO [mavlink] mode: Onboard, data rate: 4000000 B/s on udp port 14540 remote port 14030重点是第一行:udp port 14550。这是PX4向地面站发送MAVLink数据的端口。QGroundControl启动后会自动监听本地的14550端口,连接成功才能显示飞机状态。
验证连接是否就绪的具体操作:启动QGroundControl,左上角应显示“关联”和飞行器型号(x500)。如果没有,检查防火墙:
sudo ufw status如果防火墙是开启的,需要允许UDP 14550端口访问,或者直接关闭防火墙:
sudo ufw disable仅限开发机调试用,生产环境不建议直接关闭防火墙,但飞控开发领域大部分场景是物理隔离的实验室环境,问题不大。
5.3 遥控器和手动控制:没有遥控器也能玩吗
很多入门用户没有遥控器,但仿真时想验证手动飞行。PX4提供了几种方案:
第一种:使用QGroundControl的虚拟摇杆。在QGroundControl的“设置-虚拟摇杆”里可以开启屏幕摇杆,通过鼠标拖动控制飞机。
第二种:使用游戏手柄。Xbox手柄接上后,QGroundControl里配置一下通道映射就能用。注意默认配置是RC遥控器的通道定义,游戏手柄需要做Channel Mapping,这个映射过程建议参照QGroundControl官方文档。
第三种:也是我最推荐的入门方式——先用指令控制。在SITL模式下,可以用make px4_sitl gz_x500启动后,来到终端执行一些地面站命令。比如:
commander takeoff这是PX4 SITL环境下的官方入门测试。前提是飞行模式已经设置为Offboard,这个前期配置比手柄映射简单得多。等你理解了PX4模式切换的原理,再研究遥控器映射会顺利得多。
6. 我在部署中踩过的坑:三张清单帮你一步到位
这一节是我个人经验的直接总结,没有官方文档会这样写。假如你时间有限,可以直接拿这三张清单排查。
6.1 网络相关坑:最常见的头号杀手
PX4源码、子模块、Gazebo安装包、pip依赖,全都需要从外部下载。国内网络环境下,主体clone失败率极高。我的做法是:
- 下载大仓库时,使用每日低峰时段或使用可靠的镜像加速服务。
- 如果某个子模块反复下载失败,用
git config --global url."https://gitclone.com/github.com/".insteadOf "https://github.com/"来做前置替换,下载完成后记得取消替换:git config --global --unset url."https://gitclone.com/github.com/".insteadOf
这个方法只适用于clone阶段,编译阶段不影响。还有一个小技巧:git支持断点续传,中断后重新执行相同的clone或submodule update命令即可,不需要删掉重来。
6.2 权限相关坑:root、串口、sudo的边界
- 不要在root用户下运行PX4编译和仿真。PX4的很多脚本会检测用户身份,root环境下模拟器网络端口绑定行为会异常。
- 加入dialout组后必须注销重登,这个我前面反复强调了。
- 运行QGroundControl时如果提示无法打开设备,检查一下当前用户是否在dialout组里,而不是急着给AppImage加sudo执行权限。
- 虚拟机的USB设备透传问题:如果你确实在虚拟机里做开发,USB设备映射时要选对设备,不要选成USB Hub根设备。插上设备后,在VMware菜单栏的“虚拟机-可移动设备”里手动选择飞控对应的USB设备。
6.3 版本相关坑:不要盲目追新也不要死守老版本
- PX4的main分支更新非常频繁,Daily Build可能随时引入破坏性变更。如果你需要稳定学习,务必切换tag版本,比如v1.15.x,不要一直留在main分支。
- Ubuntu 24.04的Python是3.12,某些老教程中提到的
python3-pip安装方式会导致pip安装依赖时出现“externally-managed-environment”错误。遇到这个错误就说明系统PEP 668机制在起作用,不要强装,改用--break-system-packages参数或使用虚拟环境。 - GCC 13对比老版本更严格,针对老版本GCC编写的代码在编译时可能出现“uninitialized variable”这类警告,PX4官方代码库里大部分已修复,但如果自己写的代码遇到这类问题,先检查是否有未初始化变量,而不是第一时间怀疑工具链有问题。
6.4 给新手的最终检查清单
按照这个顺序逐项确认,环境就基本没问题了:
# 1. 确认系统版本 lsb_release -a # 2. 确认git、cmake、gcc版本 git --version cmake --version gcc --version # 3. 确认Python版本 python3 --version # 4. 确认与编译相关的环境变量 which ninja which pip3 # 5. 确认串口权限 groups # 6. 确认PX4源码及子模块完整 cd ~/src/PX4-Autopilot && git submodule status # 7. 编译验证 make px4_sitl gz_x500最后再分享两个我自己的体会。
第一,环境搭建过程中,日志是最好的老师。不管报什么错,先把日志从头看到尾,找第一个error,而不是在CSDN上盲搜报错片段。很多时候Python包安装失败的真实原因是在日志的前半段网络连接超时,后半段只是连带反应。
第二,不要小看“先跑通一个最简单的例子”这件事。很多新手觉得仿真环境跑起来不算什么,非得直接上真机,结果在飞控地面站连接、传感器校准、解锁起飞这些环节被打回原形。SITL仿真跑顺了,你的后续开发效率比那些一上来就买真机的人高得多。就冲这一点,今天这一连串安装配置,值了。