一、QGC 是什么?为什么要学习 QGC 源码?
QGroundControl(简称 QGC)是由 PX4 团队主导开发的开源地面站软件,支持 PX4、ArduPilot 等主流无人机飞控,是无人机地面站开发领域的标杆项目。
学习 QGC 源码的核心价值:
- 掌握Qt+QML大型跨平台项目的工程组织方式;
- 理解无人机地面站与飞控的通信协议(MAVLink)落地实现;
- 基于 QGC 二次开发,快速定制专属无人机地面站功能;
- 学习专业的无人机领域业务逻辑(航点规划、参数配置、实时监控等)。
本文将从源码结构拆解、环境搭建、开发调试到功能开发全流程,带你吃透 QGC 开发的核心要点。
二、QGC 源码结构深度拆解
QGC 基于 Qt 6(最新版)+ QML + C++ 开发,采用模块化设计,源码仓库地址:https://github.com/mavlink/qgroundcontrol
2.1 核心目录结构(重点)
plaintext
qgroundcontrol/ ├── Application/ # 应用程序入口、全局配置 ├── Audio/ # 音频相关功能(告警、提示音) ├── CommLink/ # 通信链路模块(串口/网络/USB/MAVLink) ├── Controls/ # 自定义QML控件(地面站专属UI组件) ├── Docs/ # 文档、注释、开发指南 ├── FirmwarePlugin/ # 飞控固件插件(PX4/ArduPilot适配) ├── FlightMap/ # 飞行地图模块(地图渲染、航点绘制) ├── GroundControl/ # 核心业务逻辑(主界面、飞行控制) ├── Images/ # 图片资源(图标、背景) ├── Installer/ # 安装包制作配置 ├── Location/ # 位置信息、地理坐标处理 ├── Mission/ # 航点任务模块(任务规划、执行) ├── Models/ # 数据模型(MVVM架构的Model层) ├── Parameter/ # 飞控参数管理(参数读取/修改/保存) ├── Plugins/ # 扩展插件系统 ├── Positioning/ # 定位相关(GPS、本地定位) ├── Projects/ # 项目配置(不同平台编译配置) ├── QtQuickControls2/ # QML控件样式定制 ├── Settings/ # 应用设置(界面、通信、系统) ├── Sounds/ # 音频文件资源 ├── src/ # 核心C++源码(大部分业务逻辑) │ ├── qml/ # QML界面文件(UI布局、交互) │ ├── libs/ # 依赖库(MAVLink、地理信息等) │ └── plugins/ # 插件实现 ├── Tests/ # 单元测试、集成测试代码 ├── ThirdParty/ # 第三方依赖库(如OpenSSL、Protobuf) ├── Tools/ # 辅助工具(编译、调试、脚本) ├── Vehicle/ # 无人机载体模块(状态、参数、控制) ├── qgroundcontrol.pro # qmake项目配置文件(核心) └── CMakeLists.txt # CMake编译配置(新版支持)2.2 关键文件说明
| 文件 / 目录 | 核心作用 |
|---|---|
src/qml/main.qml | QGC 主界面入口 QML 文件,定义整个地面站的 UI 布局 |
src/main.cc | C++ 程序入口,初始化 Qt 应用、加载 QML、注册 C++ 类到 QML |
FirmwarePlugin/ | 不同飞控固件的适配层,隔离 PX4 和 ArduPilot 的差异 |
CommLink/MAVLink/ | MAVLink 协议解析、封装、收发,是地面站与飞控通信的核心 |
Vehicle/Vehicle.h/cpp | 无人机载体抽象类,封装无人机状态、参数、控制接口 |
Mission/MissionManager | 航点任务管理,负责任务的上传、下载、编辑、执行 |
2.3 核心架构设计
QGC 采用MVVM(Model-View-ViewModel)架构:
- Model 层:
Models/目录,封装飞控数据、通信数据、配置数据; - View 层:
src/qml/目录,QML 界面,纯展示和交互; - ViewModel 层:C++ 类(如
Vehicle、MissionManager),连接 Model 和 View,处理业务逻辑。
三、QGC 开发环境搭建(Windows/Linux/macOS 通用)
3.1 前置依赖
- Qt 6.5+(必须匹配 QGC 的 Qt 版本,推荐从 QGC 文档确认);
- Git(拉取源码);
- C++ 编译器(Windows:MSVC2019+/MinGW;Linux:gcc/g++;macOS:Clang);
- CMake 3.20+ 或 qmake(编译工具);
- MAVLink 工具链(可选,用于协议调试)。
3.2 源码拉取
bash
运行
# 克隆源码仓库(带子模块,必须加--recursive) git clone --recursive https://github.com/mavlink/qgroundcontrol.git cd qgroundcontrol注意:
--recursive必须加,QGC 依赖多个子模块(如 MAVLink 源码),缺失会导致编译失败。
3.3 Qt 环境配置
- 打开 Qt Creator,导入 QGC 项目:
- 选择
qgroundcontrol.pro或CMakeLists.txt; - Qt Creator 会自动解析项目依赖,等待索引完成。
- 选择
- 配置编译套件:
- 选择对应 Qt 版本(如 Qt 6.5.2 MinGW 64-bit);
- 确认编译器路径正确。
3.4 编译源码
- 点击 Qt Creator 的 “构建” 按钮(锤子图标);
- 首次编译时间较长(需编译第三方库、生成 MAVLink 代码),耐心等待;
- 编译成功后,点击 “运行” 按钮启动 QGC。
3.5 常见编译问题解决
| 问题现象 | 解决方案 |
|---|---|
| 子模块缺失 | 执行git submodule update --init --recursive拉取所有子模块 |
| Qt 版本不匹配 | 安装 QGC 文档指定的 Qt 版本(如 6.5.2),在 Qt Creator 中切换套件 |
| 缺少 OpenSSL | 下载对应平台的 OpenSSL 库,放到 QGC 的ThirdParty/OpenSSL目录 |
| Windows 编译提示缺少 SDK | 安装 Visual Studio 2019+,勾选 “Windows SDK” 组件 |
四、QGC 完整开发流程(以新增功能为例)
以 “新增一个无人机电池电压实时显示控件” 为例,讲解 QGC 二次开发的标准流程:
4.1 步骤 1:分析需求与源码入口
- 需求:在主界面新增一个文本控件,实时显示无人机电池电压;
- 入口:
- 电池数据来源:
Vehicle/VehicleBattery.h/cpp(封装电池状态); - 主界面 QML:
src/qml/MainRootWindow.qml; - 数据绑定:通过 QML 绑定 C++ 的
Vehicle类属性。
- 电池数据来源:
4.2 步骤 2:C++ 层确认数据接口
首先确认Vehicle类已提供电池电压属性:
cpp
运行
// VehicleBattery.h class VehicleBattery : public QObject { Q_OBJECT // 注册属性到QML,允许QML直接访问 Q_PROPERTY(double voltage READ voltage NOTIFY voltageChanged) public: double voltage() const { return _voltage; } // 获取电压值 signals: void voltageChanged(); // 电压变化信号 private: double _voltage = 0.0; // 电池电压 };QGC 中所有供 QML 访问的 C++ 属性,必须用
Q_PROPERTY注册,并提供NOTIFY信号,保证数据实时更新。
4.3 步骤 3:QML 层添加 UI 控件
修改src/qml/MainRootWindow.qml,新增电池电压显示控件:
qml
import QtQuick 2.15 import QtQuick.Controls 2.15 import QGroundControl 1.0 // 导入QGC自定义模块 // 主窗口原有布局 Rectangle { // ... 原有代码 ... // 新增电池电压显示控件 Text { id: batteryVoltageText text: qsTr("电池电压: %1 V").arg( vehicle ? vehicle.battery.voltage.toFixed(1) : "0.0" ) font.pixelSize: 16 color: vehicle && vehicle.battery.voltage < 11.0 ? "red" : "green" anchors.top: parent.top anchors.right: parent.right anchors.margins: 20 } }关键说明:
vehicle是 QGC 全局上下文对象,代表当前连接的无人机;toFixed(1)保留 1 位小数,提升显示友好性;- 电压低于 11.0V 时文字变红,实现告警提示。
4.4 步骤 4:编译调试
- 重新构建项目,确保无语法错误;
- 启动 QGC,连接无人机(或使用 PX4 仿真器);
- 验证功能:
- 未连接无人机时,显示 “电池电压: 0.0 V”;
- 连接后,实时显示当前电池电压;
- 电压过低时文字变红。
4.5 步骤 5:代码提交与测试
- 编写单元测试:在
Tests/目录添加电池电压显示的测试用例; - 提交代码:遵循 QGC 的代码规范(如命名、注释),提交 PR 或本地版本控制。
五、QGC 开发核心技巧
5.1 调试技巧
- QML 调试:Qt Creator 中开启 “QML 调试”,断点调试 QML 代码,查看属性值;
- MAVLink 调试:使用 QGC 内置的 “MAVLink Console”(工具→MAVLink 控制台),查看收发的 MAVLink 消息;
- 日志输出:
- C++ 层:
qDebug() << "电池电压:" << voltage;; - QML 层:
console.log("电池电压:", vehicle.battery.voltage);。
- C++ 层:
5.2 二次开发注意事项
- 尽量基于 QGC 的现有模块扩展,避免修改核心源码(方便后续升级);
- 遵循 QGC 的 MVVM 架构,业务逻辑写在 C++ 层,UI 写在 QML 层;
- 适配不同飞控:通过
FirmwarePlugin隔离 PX4/ArduPilot 的差异; - 测试覆盖:至少测试真实无人机、PX4 仿真器两种场景。
5.3 常用扩展方向
- 新增自定义仪表盘(如风速、高度告警);
- 扩展通信链路(如新增 5G/4G 通信模块);
- 定制航点任务模板(如农业植保任务);
- 集成第三方硬件(如摄像头、避障模块)。
总结
- QGC 采用模块化 + MVVM 架构,核心目录包括
src/(C++ 逻辑)、src/qml/(QML 界面)、Vehicle/(无人机载体)、CommLink/(通信),需重点掌握这几个模块的作用; - QGC 开发环境搭建的核心是 “匹配 Qt 版本 + 拉取完整子模块”,编译失败多因依赖缺失或版本不匹配;
- QGC 二次开发遵循 “确认 C++ 数据接口→QML 绑定显示→编译调试→测试验证” 的流程,核心是利用
Q_PROPERTY实现 C++ 与 QML 的数据双向绑定。