QGroundControl二次开发:从源码编译到自定义功能实战
2026/9/21 21:59:07 网站建设 项目流程

1. 为什么值得折腾QGC二次开发

QGC地面站(QGroundControl)在无人机圈子里基本是绕不开的工具。不管你是飞PX4还是ArduPilot固件,QGC都是最主流的航线规划、参数调试、固件烧录平台。但很多人用着用着就会发现,官方版本虽然稳定,可总有些地方不趁手——比如想加一个自定义的遥测数据面板、想改一下航线规划的逻辑、想接入自己公司的私有协议,这时候就不得不走上二次开发这条路。

我自己第一次编译QGC的时候,踩了不少坑。网上教程要么太老,要么跳步严重,要么默认你已经是个Qt老手。实际上,一个做飞控算法的工程师和一个做前端出身的开发者,面对QGC源码时的困惑点完全不同。这篇内容就是把我自己从零编译QGC的完整过程拆开来讲,包括环境怎么搭、源码怎么拉、Qt Creator怎么配、编译报错怎么查,以及那些教程里不会写的坑。

适合谁看?如果你已经会用QGC地面站的基本功能,想改点东西但不知道从哪下手;或者你是嵌入式/飞控方向的学生,课程项目需要定制一个地面站;再或者你只是好奇QGC内部长什么样,想编译一份自己玩玩——这篇都能给你一条能走通的路。不需要你是Qt专家,但至少得知道C++的基本语法和命令行怎么用。

QGC的代码量不小,整个工程编译下来,中间文件加上最终产物,轻松吃掉几十个G的磁盘空间。所以开始之前,先确认你的机器至少有100G以上的空闲空间,内存建议16G起步,8G也能编但会很痛苦。操作系统方面,Windows和Ubuntu都可以,我下面会以Ubuntu为主来写,因为QGC在Linux下的编译体验明显更顺,依赖管理也简单得多。Windows下不是不能编,但光是Qt版本和编译器版本的匹配就够你喝一壶的。

2. 编译前的环境准备与工具选型

2.1 操作系统与硬件的最低要求

先说清楚硬件和系统的底线,免得你编到一半发现机器扛不住。QGC的源码仓库拉下来大概2到3个G,但编译过程中产生的中间文件会膨胀到20G以上,如果开了调试符号,30G也正常。所以磁盘空间我给的建议是至少预留80G,最好100G以上。内存方面,链接阶段是吃内存大户,16G是比较舒服的配置,8G的话建议把并行编译的线程数降下来,不然容易卡死。

操作系统我推荐Ubuntu 20.04或者22.04,这两个版本我都实际编过,依赖库的版本比较合适。Ubuntu 18.04也能用,但有些库的版本偏老,需要手动升级。Windows 10/11也可以,但你需要装Visual Studio 2019或者2022,再加上Qt Creator,整个工具链的配置复杂度比Linux高不少。如果你是第一次编译QGC,我强烈建议先在Ubuntu下走通一遍,理解了整个流程之后,再考虑在Windows下折腾。

注意:不要用太新的Ubuntu版本,比如刚发布的非LTS版本,Qt的某些依赖可能还没跟上,会出现一些莫名其妙的链接错误。

2.2 Qt版本的选择与安装

QGC对Qt版本是有明确要求的。不同版本的QGC源码对应的Qt版本不一样,这个必须匹配,否则编译必挂。一般来说,QGC 4.2以上的版本需要Qt 5.15.2或者Qt 6.5以上的版本。我个人的建议是,先去QGC的官方GitHub仓库看一下你准备编译的那个分支的README或者CI配置文件,里面会写清楚需要的Qt版本。

安装Qt的时候,不要用系统自带的apt版本,那个版本通常缺少QGC需要的某些模块。正确的做法是去Qt官网下载在线安装器,选择自定义安装,勾选以下组件:

  • Qt 5.15.2(或者你需要的版本)下的Desktop gcc 64-bit
  • Qt Charts
  • Qt Quick Controls 2
  • Qt Location
  • Qt Multimedia
  • Qt Serial Port
  • Qt SVG
  • Qt Network Authorization

这些模块缺一不可,特别是Qt Location和Qt Charts,QGC的地图和仪表盘都依赖它们。安装路径建议用默认的,不要带空格和中文,不然后面配置Kit的时候容易出问题。

2.3 编译工具链与依赖库

Ubuntu下需要安装的基础工具包括build-essential、cmake、git、ninja-build。其中ninja-build是我强烈推荐的,它比make快很多,特别是在多核机器上。安装命令很简单:

sudo apt update sudo apt install build-essential cmake git ninja-build

除了这些基础工具,QGC还依赖一些系统库,比如libssl-dev、libasound2-dev、libudev-dev、libsdl2-dev等。这些库如果不装,编译到一半就会报找不到头文件的错误。我建议一次性把这些都装上:

sudo apt install libssl-dev libasound2-dev libudev-dev libsdl2-dev libxcb-xinerama0-dev

还有一个容易漏掉的是GStreamer相关的库,QGC的视频流功能依赖它。如果你不需要视频功能,可以在编译时关掉,但默认是开的,所以还是装上比较省事:

sudo apt install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev

2.4 源码获取与分支选择

QGC的源码托管在GitHub上,直接clone就行。但要注意,不要直接clone master分支,master分支是开发版,可能随时处于不可编译的状态。如果你只是想稳定使用,建议checkout到最新的稳定tag。比如:

git clone https://github.com/mavlink/qgroundcontrol.git cd qgroundcontrol git checkout v4.2.8

分支的选择取决于你的需求。如果你要跟着PX4的最新固件走,那就用比较新的稳定版;如果你要兼容老版本的ArduPilot,可能需要用旧一点的QGC版本。我个人的经验是,QGC 4.2.x系列比较成熟,社区资料也多,适合入门。

拉源码的时候还有一个坑:submodule。QGC依赖一些第三方库作为submodule,如果你clone的时候没有加--recursive参数,后面编译会报缺文件。补救方法是:

git submodule update --init --recursive

这一步会下载不少东西,网络不好的话可能要等一会儿。如果中途断了,重新执行一次就行,git会接着下载。

3. Qt Creator的配置与工程加载

3.1 Qt Creator的安装与Kit配置

Qt Creator在你安装Qt的时候会一起装上,不需要单独下载。打开Qt Creator之后,第一件事是检查Kit配置。所谓Kit,就是Qt Creator用来编译工程的一套工具组合,包括编译器、Qt版本、调试器等。

进入Tools -> Options -> Kits,你应该能看到一个自动检测到的Desktop Kit。点进去检查几个关键项:Compiler应该是GCC 64bit,Qt version应该是你安装的Qt 5.15.2,Debugger应该是系统的gdb。如果Qt version那一栏是空的或者显示错误,说明Qt Creator没有自动检测到你的Qt安装路径,需要手动添加。

手动添加的方法是,在Qt Versions标签页里点Add,然后找到你Qt安装目录下的qmake可执行文件。比如~/Qt/5.15.2/gcc_64/bin/qmake。添加完之后回到Kits页面,把Qt version选成你刚添加的这个。

提示:如果你在Ubuntu下用apt装了qtcreator,它可能会用系统自带的Qt版本,和你手动安装的Qt冲突。建议直接用Qt官方安装器里的Qt Creator,避免版本混乱。

3.2 打开QGC工程与首次配置

在Qt Creator里选择File -> Open File or Project,然后找到QGC源码根目录下的qgroundcontrol.pro文件。Qt Creator会问你用哪个Kit来配置这个工程,选你刚才配好的Desktop Kit就行。

首次打开工程的时候,Qt Creator会解析整个.pro文件,这个过程可能需要几分钟,因为QGC的工程结构比较复杂,有很多子项目和条件编译。解析完成之后,你会看到左侧的项目树里有很多子项目,比如libssrctest等。

在正式编译之前,还需要做一件事:配置构建目录。默认情况下,Qt Creator会在源码目录旁边创建一个build目录,这个没问题。但如果你之前编译过,建议先清理一下,避免旧的中间文件干扰。Build -> Clean All,然后再Build -> Run qmake,最后再Build -> Build All。

3.3 编译参数的调整与优化

QGC默认的编译配置是Debug模式,这个模式编译出来的程序体积大、运行慢,但调试方便。如果你只是想跑起来看看,建议切换到Release模式。在Qt Creator左下角的构建套件选择器那里,点一下,选择Release。

Release模式下,编译时间会短一些,但链接阶段仍然很吃资源。如果你机器核多,可以在.pro文件或者Qt Creator的构建设置里加上-j8或者更高的并行数。不过要注意,并行数太高可能导致内存不够,特别是链接的时候。我一般用-j4或者-j6,比较稳。

还有一个编译选项是CONFIG+=debugCONFIG+=release,这两个不要同时加,会冲突。另外,如果你不需要单元测试,可以在.pro文件里把test子项目注释掉,能省不少编译时间。

4. 编译过程中的常见报错与排查

4.1 依赖库缺失导致的编译中断

这是最常见的报错类型。症状是编译到某个文件时,提示fatal error: xxx.h: No such file or directory。这种问题一般是因为系统缺少对应的开发库。解决办法是根据报错的头文件名,反查它属于哪个库,然后apt安装对应的-dev包。

比如报错说找不到openssl/ssl.h,那就是缺libssl-dev;找不到alsa/asoundlib.h,那就是缺libasound2-dev。我前面列的那些库基本覆盖了大部分情况,但如果你开了额外的功能,可能还需要装别的。

有一个比较隐蔽的情况是,库装了但版本不对。比如QGC需要OpenSSL 1.1,但你的系统装的是OpenSSL 3.0,这时候编译能过,但运行时会报符号找不到。这种情况在Ubuntu 22.04上比较常见,因为22.04默认的OpenSSL就是3.0。解决办法是手动编译一个OpenSSL 1.1放到工程里,或者用QGC提供的脚本去下载预编译的版本。

4.2 Qt模块找不到的解决方法

另一种常见的报错是Unknown module(s) in QT: xxx。这说明你安装的Qt缺少某个模块。比如报错说Unknown module(s) in QT: location,那就是你装Qt的时候没有勾选Qt Location模块。

解决办法是重新运行Qt的在线安装器,找到你安装的那个Qt版本,把缺少的模块勾上。不需要卸载重装,安装器会自动补上缺的模块。

还有一种情况是,模块装了但Qt Creator找不到。这时候检查一下Kit配置里的Qt version路径是否正确,以及.pro文件里的QT +=语句是否写对了。有时候QGC的.pro文件里会根据平台条件添加模块,如果你在Windows下编译,可能某些Linux特有的模块就不会被添加,这是正常的。

4.3 链接阶段的符号冲突与内存不足

链接阶段最常遇到的两个问题是符号冲突和内存不足。符号冲突的表现是multiple definition of xxx或者undefined reference to xxx。前者通常是因为同一个符号在多个地方定义了,后者是因为某个库没有链接进来。

QGC的工程里有一些第三方库是静态链接的,如果这些库之间有不兼容的符号,就会报冲突。这种情况比较难排查,一般需要看完整的链接命令,找到冲突的符号来自哪个库,然后调整链接顺序或者去掉重复的库。

内存不足的表现是链接器被系统kill掉,报错信息可能是collect2: fatal error: ld terminated with signal 9。这就是典型的OOM(Out Of Memory)。解决办法是降低并行编译数,或者增加swap空间。我一般会临时加一个8G的swap文件:

sudo fallocate -l 8G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile

编译完之后可以关掉,不影响系统。

4.4 编译成功但运行闪退的排查思路

有时候编译能过,但一运行就闪退,或者界面出不来。这种情况一般是运行时依赖的问题。首先检查是不是缺动态库,用ldd命令看一下可执行文件依赖的库有没有找不到的:

ldd ./QGroundControl | grep "not found"

如果有not found的,根据库名安装对应的包就行。

另一个常见原因是Qt插件路径不对。QGC运行时需要加载Qt的平台插件,比如libqxcb.so。如果Qt Creator的运行环境没有正确设置QT_PLUGIN_PATH,就会报This application failed to start because no Qt platform plugin could be initialized。解决办法是在Qt Creator的Projects -> Run -> Environment里加上:

QT_PLUGIN_PATH=/home/你的用户名/Qt/5.15.2/gcc_64/plugins

或者直接在命令行里export这个变量再运行。

5. 二次开发的切入点与实操建议

5.1 从修改界面开始练手

编译跑通之后,下一步就是试着改点东西。我建议从界面入手,因为QGC的界面是用QML写的,改起来比较直观,不容易搞崩核心逻辑。比如你可以试着改一下主界面的标题文字,或者调整某个按钮的位置。

QML文件主要在src/UI目录下,比如MainWindow.qmlMainRootWindow.qml这些。用Qt Creator打开这些文件,改完之后重新编译,就能看到效果。这个过程能帮你熟悉QGC的工程结构和编译流程,而且风险很低。

提示:改QML的时候,Qt Creator有实时预览功能,但QGC的QML依赖一些C++注册的类型,预览可能不完整。最靠谱的方式还是编译后运行看效果。

5.2 添加自定义遥测数据面板

如果你想让QGC显示一些官方没有的遥测数据,比如自定义传感器的读数,那就需要动C++代码了。QGC的遥测数据流是从MAVLink消息解析出来的,解析后的数据会存到Vehicle对象里。你可以找到src/Vehicle/Vehicle.hVehicle.cc,在里面添加新的属性,然后在QML里绑定显示。

具体步骤是:先在Vehicle类里加一个Q_PROPERTY,然后在MAVLink消息处理的地方更新这个属性的值,最后在QML里用vehicle.你的属性名来显示。这个过程涉及到Qt的属性系统和信号槽机制,如果你不熟悉,建议先补一下这方面的基础。

MAVLink消息的定义在src/comm/MAVLinkProtocollibs/mavlink里。如果你想解析自定义的MAVLink消息,需要在MAVLink的消息定义文件里加上你的消息ID和字段,然后重新生成MAVLink库。这一步稍微复杂一点,但QGC的文档里有说明,跟着做就行。

5.3 修改航线规划逻辑的注意事项

航线规划是QGC的核心功能之一,相关代码主要在src/MissionManager目录下。如果你想改航线的生成逻辑,比如自动添加航点、修改航点间距等,需要仔细阅读MissionControllerPlanManager这两个类。

修改这部分代码的风险比较高,因为航线规划涉及到与飞控的通信协议,改错了可能导致飞控执行异常。我的建议是,先在模拟环境下测试,用PX4的SITL(软件在环仿真)配合QGC,确认逻辑没问题之后再上真机。

另外,QGC的航线规划支持多种协议,比如MAVLink的Mission协议和Survey协议。如果你要加新的规划模式,需要同时改UI和后台逻辑,工作量不小。建议先从简单的修改开始,比如调整默认的航点高度、修改航线的默认速度等。

6. 实操心得与避坑清单

6.1 版本匹配是最大的坑

我踩过的最大的坑就是版本不匹配。QGC的源码版本、Qt版本、编译器版本、MAVLink版本,这几个东西必须互相兼容。我曾经用Qt 5.12去编译QGC 4.2,结果报了一堆莫名其妙的错误,折腾了一整天,最后换成Qt 5.15.2,十分钟就编过了。

所以我的建议是,在开始编译之前,先去QGC的GitHub仓库看一下你那个分支的CI配置文件(一般在.github/workflows或者.travis.yml里),里面会写清楚用的什么版本的Qt、什么版本的编译器。照着那个配置来,能省掉90%的版本问题。

6.2 磁盘空间和内存要留足

前面提过,QGC编译很吃资源。我再强调一遍,磁盘至少留80G,内存至少16G。如果你用虚拟机编译,记得把虚拟磁盘设成动态扩展,并且给足初始空间。我曾经在一个50G的虚拟机上编译,编到一半磁盘满了,清理了半天才继续。

内存不足的问题在链接阶段特别明显。如果你看到链接器被kill,不要怀疑代码有问题,就是内存不够。加swap或者降低并行数都能解决。

6.3 不要轻易改核心通信代码

QGC的核心通信代码在src/comm目录下,包括MAVLink协议解析、串口通信、UDP/TCP通信等。这部分代码非常敏感,改错一个字节就可能导致通信失败。如果你只是想加功能,尽量在应用层做,不要动底层通信。

如果确实需要改通信协议,比如加自定义的MAVLink消息,建议先在MAVLink的XML定义文件里加,然后用官方的生成工具重新生成代码,而不是手动改生成的C++文件。手动改的话,下次重新生成就被覆盖了。

6.4 善用日志和调试工具

QGC内置了日志系统,可以在运行时输出调试信息。你可以在代码里用qDebug()qWarning()qCritical()来打日志,然后在Qt Creator的Application Output窗口里看。如果是在命令行运行,日志会直接打到终端。

另外,QGC支持MAVLink Inspector功能,可以实时查看飞控发过来的MAVLink消息。这个功能在调试通信问题时非常有用。你可以在QGC的设置里打开它,或者直接在代码里加断点调试。

6.5 常见问题速查表

问题现象可能原因解决办法
编译报错找不到头文件缺少开发库apt安装对应的-dev包
Unknown module in QTQt模块未安装用Qt安装器补装模块
链接时报undefined reference库未链接或链接顺序不对检查.pro文件里的LIBS配置
链接器被kill内存不足加swap或降低并行编译数
运行闪退,无界面Qt插件路径不对设置QT_PLUGIN_PATH环境变量
运行报OpenSSL符号错误OpenSSL版本不匹配使用QGC自带的OpenSSL或手动编译1.1版本
QML界面不更新编译缓存未清理Clean All后重新Run qmake和Build
飞控连接不上QGC串口权限或波特率不对检查用户是否在dialout组,确认波特率设置

6.6 关于代码对齐和编辑器的小技巧

有人提到Qt Creator的代码对齐快捷键不好用,这个我也有同感。Qt Creator默认的格式化快捷键是Ctrl+I,但它只对选中的代码生效,而且格式化规则比较保守。如果你想要更强大的格式化功能,可以装一个ClangFormat插件,在Beautifier设置里配置。QGC的源码里自带了一个.clang-format文件,你可以直接用这个配置来格式化,保持和官方代码风格一致。

另外,Qt Creator的代码补全有时候会卡,特别是在大工程里。你可以在Options -> C++ -> Code Model里把“Indexing”相关的选项调一下,比如关掉后台索引,或者增加索引的线程数。不过这些调整因机器而异,自己试一下找到最顺手的配置就行。

7. 编译之后的下一步

编译跑通只是第一步,真正的二次开发才刚刚开始。我的建议是,先花点时间把QGC的工程结构摸清楚,知道哪个目录放什么代码,哪个类负责什么功能。然后找一个你感兴趣的小功能,试着改一改,跑一跑,看看效果。这个过程比看文档学得快得多。

QGC的社区比较活跃,遇到问题可以去GitHub的Issues里搜一搜,大概率有人遇到过类似的问题。另外,QGC的开发者文档虽然不算特别详细,但关键部分都有说明,值得一读。

最后再分享一个小技巧:如果你在编译过程中遇到了奇怪的错误,先别急着改代码,试试删掉整个build目录,重新Run qmake和Build。很多时候问题只是编译缓存不一致导致的,清理一下就好了。这个习惯帮我省了很多无谓的调试时间。

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

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

立即咨询