当前位置: 首页 > news >正文

一、QGroundControl地面站:开发教程(2)

从自定义MAVLink消息到UI界面显示

在实际项目中,我们经常会遇到一个需求:飞控侧新增了某些自定义数据(例如算法输出、传感器融合状态、设备健康度、识别目标信息等),希望通过 MAVLink 实时传输到 QGroundControl,并在 UI 界面中显示出来。

QGC 默认只支持标准 MAVLink 消息,如果我们想实现“飞控发送自定义消息 → QGC 接收解析 → QML 界面显示”,就必须完整走通 MAVLink 消息扩展链路。

本文将详细讲解完整流程,包括:

  • MAVLink 库源码获取
  • MAVLink 消息 XML 自定义
  • 使用 mavgen 生成 C/C++ 头文件
  • QGC 工程中集成自定义消息头文件
  • QGC 中解析消息并转换为 UI 可用数据
  • QML 中实时显示自定义消息数据

1. MAVLink 简介:为什么要自定义消息?

MAVLink 本质是一个“消息协议”,消息的结构由 XML 文件定义,例如常见的:

  • HEARTBEAT
  • SYS_STATUS
  • ATTITUDE
  • GPS_RAW_INT

飞控与地面站之间的通信,本质就是发送/接收这些消息。

当标准消息无法满足业务需求时,就需要在 MAVLink XML 中新增消息定义,例如:

  • VISION_RESULT
  • OBSTACLE_INFO
  • ALGO_STATUS

QGC 和飞控双方只要都基于同一套 XML 生成代码,就能完成通信。


2. 获取 MAVLink 库源码(官方方式)

MAVLink 的生成工具和 XML 定义文件主要在官方仓库中维护。

常用仓库地址:

  • MAVLink 主仓库(含 XML 与生成脚本):mavlink/mavlink

建议使用 Git 拉取:

git clone https://github.com/mavlink/mavlink.git cd mavlink

仓库中最重要的目录:

  • message_definitions/v1.0/标准 XML 消息定义
  • pymavlink/:Python 生成工具(mavgen 在这里)

3. 准备 MAVLink 生成环境

MAVLink 消息生成依赖 Python,推荐 Python3.8+。

安装依赖:

pip install -r pymavlink/requirements.txt

或直接安装 pymavlink:

pip install pymavlink

验证 mavgen 是否可用:

python -m pymavlink.tools.mavgen --help

如果能正常输出 help 信息,说明环境正常。


4. 自定义 MAVLink 消息(XML 添加 message)

自定义消息通常有两种方式:

  • 修改已有 dialect(如 ardupilotmega.xml)
  • 创建自己的 dialect(推荐)

建议创建一个独立 XML,例如:

message_definitions/v1.0/my_custom.xml

内容示例:

<?xml version="1.0"?> <mavlink> <version>3</version> <dialect>0</dialect> <messages> <message id="42000" name="ALGO_STATUS"> <description>Algorithm output status</description> <field type="uint32_t" name="timestamp_ms">Timestamp in ms</field> <field type="float" name="target_x">Target X position</field> <field type="float" name="target_y">Target Y position</field> <field type="uint8_t" name="state">Algorithm state</field> </message> </messages> </mavlink>

或者修改已有 ardupilotmega.xml,

  • 默认路径:通常位于 MAVLink 仓库的/message_definitions/v1.0/目录下
  • 建议创建备份副本:cp ardupilotmega.xml ardupilotmega.xml.bak
  1. 关键修改区域
    <messages> <message id="42000" name="ALGO_STATUS"> <description>Algorithm output status</description> <field type="uint32_t" name="timestamp_ms">Timestamp in ms</field> <field type="float" name="target_x">Target X position</field> <field type="float" name="target_y">Target Y position</field> <field type="uint8_t" name="state">Algorithm state</field> </message> </messages>

4.1 Message ID 如何选择?

MAVLink 官方规定:
自定义消息 ID 建议使用 42000~42999(避免与官方冲突)。

如果你项目里还有多个消息,可以统一规划:

  • 42000:ALGO_STATUS
  • 42001:VISION_RESULT
  • 42002:OBSTACLE_INFO

5. 使用 mavgen 生成头文件(关键步骤)

生成 C 语言头文件:

python -m pymavlink.tools.mavgen \ --lang=C \ --wire-protocol=2.0 \ --output=generated/my_custom \ message_definitions/v1.0/my_custom.xml

生成后会输出目录:

generated/my_custom/ mavlink.h my_custom.h mavlink_msg_algo_status.h

其中最关键的是mavlink_msg_algo_status.h,里面包含:

  • message struct
  • pack/unpack 函数
  • CRC 校验信息

6. 飞控端如何使用自定义消息(简单说明)

飞控侧一般是 C/C++ 项目,只要包含生成的头文件即可使用。

例如发送消息:

mavlink_message_t msg;
mavlink_msg_algo_status_pack(
sysid, compid, &msg,
timestamp_ms,
target_x,
target_y,
state
);

send_mavlink_message(&msg);

飞控端只要能发送出去,地面站就可以接收解析。


7. QGC 中集成自定义 MAVLink 消息

QGroundControl 内部自带 MAVLink 头文件,但默认来自官方 dialect(common、ardupilotmega 等)。

要让 QGC 支持自定义消息,有两种方式:

方式 A:直接替换 QGC 的 MAVLink 生成目录(简单粗暴)

QGC 通常在:

libs/mavlink/include/mavlink/v2.0/

你可以把生成的my_customdialect 复制进去,例如:

libs/mavlink/include/mavlink/v2.0/my_custom/

然后确保 QGC 的 mavlink include path 能找到它。

方式 B:修改 QGC 构建流程,让它自动生成(更规范)

这种方式适合长期维护项目:
你可以在 QGC 的构建脚本里添加 dialect,使其构建时自动调用 mavgen。

如果你只是快速实现功能,方式 A 更直接。


8. QGC C++ 端接收与解析自定义消息

QGC 接收 MAVLink 消息的入口通常在MAVLinkProtocolVehicle相关模块中。

常见处理逻辑:

  • MAVLinkProtocol 收到 raw bytes
  • 解包为mavlink_message_t
  • 分发给 Vehicle / FactGroup / 插件模块处理

你可以在 Vehicle 层监听消息,例如:

void Vehicle::_mavlinkMessageReceived(const mavlink_message_t& message)
{
switch (message.msgid) {
case MAVLINK_MSG_ID_ALGO_STATUS:
_handleAlgoStatus(message);
break;
default:
break;
}
}

然后实现解析函数:

void Vehicle::_handleAlgoStatus(const mavlink_message_t& message)
{
mavlink_algo_status_t algo;
mavlink_msg_algo_status_decode(&message, &algo);

_targetX = algo.target_x;
_targetY = algo.target_y;
_algoState = algo.state;

emit algoStatusChanged();
}


9. 把数据暴露给 QML(Qt 属性绑定)

要在 QML 界面显示,必须让 QML 能访问 C++ 数据。

一般做法是在Vehicle类中增加Q_PROPERTY

Q_PROPERTY(float targetX READ targetX NOTIFY algoStatusChanged)
Q_PROPERTY(float targetY READ targetY NOTIFY algoStatusChanged)
Q_PROPERTY(int algoState READ algoState NOTIFY algoStatusChanged)

并实现 getter:

float Vehicle::targetX() const { return _targetX; }
float Vehicle::targetY() const { return _targetY; }
int Vehicle::algoState() const { return _algoState; }

这样 QML 就能通过activeVehicle.targetX访问。


10. QML 界面显示自定义消息数据

QGC UI 一般在src/FlightDisplaysrc/QmlControls

例如我们想在 Flight View 叠加显示算法输出:

import QtQuick
import QtQuick.Controls
import QGroundControl

Rectangle {
width: 240
height: 120
radius: 8
color: "#66000000"

Column {
anchors.centerIn: parent
spacing: 6

Text {
text: "Algo State: " + QGroundControl.multiVehicleManager.activeVehicle.algoState
color: "white"
}

Text {
text: "Target X: " + QGroundControl.multiVehicleManager.activeVehicle.targetX.toFixed(2)
color: "white"
}

Text {
text: "Target Y: " + QGroundControl.multiVehicleManager.activeVehicle.targetY.toFixed(2)
color: "white"
}
}
}

只要消息持续从飞控发送,界面数值就会实时刷新。


11. 常见问题与踩坑总结

11.1 QGC 编译报找不到mavlink_msg_xxx.h

原因通常是 include path 没配置正确。
确保 dialect 文件夹路径在:

libs/mavlink/include/mavlink/v2.0/

并且 CMake/qmake include path 包含该目录。


11.2 msgid 冲突导致解析异常

如果你使用的 msgid 与 common.xml 或 ardupilotmega.xml 中已有的 ID 重复,可能导致解析错误甚至 CRC 校验失败。

必须保证自定义 ID 在官方推荐范围内。


11.3 飞控发送了但 QGC 收不到

重点检查:

  • MAVLink 通信链路是否正常(心跳是否正常)
  • 飞控发送的 sysid/compid 是否正确
  • 消息是否被 stream rate 限制(某些飞控需要配置发送频率)

11.4 QML 显示不刷新

如果 Q_PROPERTY 绑定值不更新,通常是:

  • 你更新了变量但没有 emit 信号
  • Q_PROPERTY 的 NOTIFY 信号未触发

解决方法就是每次 decode 后 emit 对应 notify。


12. 总结:完整链路已经打通

到这里,我们已经实现了完整闭环:

  1. MAVLink XML 自定义消息
  2. mavgen 生成头文件
  3. 飞控发送自定义消息
  4. QGC 集成 dialect
  5. QGC C++ 解包并存储数据
  6. Q_PROPERTY 暴露给 QML
  7. Flight View 界面实时显示

这个流程一旦跑通,你就可以无限扩展更多消息类型,例如:

  • AI 识别目标框
  • 避障距离阵列
  • 电机状态、温度、电流
  • RTK 精度信息
  • 视觉定位误差
http://www.jsqmd.com/news/711983/

相关文章:

  • Gemma-4开源模型效果展示:原生图像理解能力在技术截图分析中的真实表现
  • 知名壁画品牌与源头工厂推荐:ENGLONG英仑家居新中式、酒店背景墙、刺绣软硬包定制厂家一站式选型 - 栗子测评
  • 一场关于AI面试精准度的真实较量:三大梯队主流工具深度测评!
  • 2026园艺喷壶哪家好?洒水壶生产厂家/塑料喷壶源头厂家精选推荐 - 栗子测评
  • Hermes vs OpenClaw:社区真实体验对比,谁更适合你?
  • ensp- ACL 综合配置实验(附拓扑与完整步骤)
  • 如何在OBS Studio中免费使用VST插件:提升直播音频质量的完整指南
  • LM文生图参数详解:CFG Scale 4.5–6.5对人像质感的影响实测
  • 2026西宁铝镁锰板厂家怎么选:青海仿古瓦/青海冷库板/青海岩棉板/青海彩钢厂/青海彩钢岩棉夹心板/青海彩钢岩棉板/选择指南 - 优质品牌商家
  • 2026年3月头部熟食礼盒定制厂家推荐,蘑菇木耳礼盒/熟食礼盒/牛羊肉礼盒/蛋类礼盒/大闸蟹礼盒,熟食礼盒品牌推荐 - 品牌推荐师
  • 天赐范式第24天:我们的研究发现,究竟有什么深层次的历史意义吗?文心如是说:~
  • 2026年AI面试软件深度测评:谁能真正实现“精准初面替代”!
  • FinFET技术如何革新FPGA设计与性能
  • 跨模型AI协作平台:架构设计与性能优化实践
  • 基于Node.js与SQLite构建命令行面试知识库管理工具
  • 兰州钢塑波纹管技术解析:兰州孔网钢带塑料复合管/兰州孔网钢带复合管/兰州孔网钢带管/兰州孔网钢带聚乙烯复合管/兰州孔网钢骨架塑料复合管/选择指南 - 优质品牌商家
  • AI入门者的思维方式:如何像AI工程师一样思考 | 避开90%新手都会踩的思维陷阱
  • DeepSeek的484天:从“557万训练成本“到腾讯阿里争相投资!
  • 告别Mac自带终端:iTerm2 + Oh My Zsh 保姆级配置指南(含国内镜像源)
  • JavaScript编排小型语言模型实战指南
  • 主流 AI Agent 框架大比拼:Hermes、OpenClaw、Cognithor、Thoth、Gaia 深度对比
  • 各种算法的适用场景
  • 10大在线多人编辑文件工具盘点:提升团队协作效率的秘密武器
  • 终极怀旧游戏复活指南:在Windows 11上轻松启用IPX/SPX协议支持
  • NE2281 1000W PFC芯片,主要应用于boost PFC变换器
  • LLM自我验证新突破:Gnosis机制解析与应用
  • Phi-3.5-mini-instruct镜像免配置:预置多语言测试用例一键验证
  • RS-485故障安全偏置技术演进与工程实践
  • 哔哩下载姬:专业B站视频下载工具,支持8K与批量下载
  • 02 | AI Agent 架构设计:工具系统设计 ——OpenClaw、Claude Code、Hermes Agent对比