1. 通信协议总览:MAVLink协议简介、uORB消息总线、QGC地面站架构、通信链路拓扑图
好,咱们开始第一章。这一章说白了就是给整个课程搭个骨架。你得先知道PX4飞控和QGC地面站之间到底是怎么说话的,用了什么“语言”,走了什么“路”。我见过不少新手,上来就调参、改代码,结果通信断了抓瞎半天——其实就是没搞懂底层这几条链路。
核心一句话:PX4内部用uORB总线传消息,对外用MAVLink协议打包,通过串口或UDP发给QGC。QGC收到后解包,再通过内部插件分发显示。
1.1 MAVLink协议简介
MAVLink,全称Micro Air Vehicle Link。说白了就是无人机界的“普通话”。它定义了飞控和地面站之间所有消息的格式——心跳、姿态、GPS坐标、遥控指令,全得按这个规矩来。
我个人习惯把MAVLink分成两代:
- MAVLink v1: 消息长度8字节,简单粗暴,适合老式8位单片机。但扩展性差,现在基本淘汰了。
- MAVLink v2: 消息长度最大255字节,支持签名认证、消息扩展。PX4和QGC现在默认都用v2。
一个典型的MAVLink数据包长这样:
| 起始标志(0xFD) | 长度 | 不兼容标志 | 兼容标志 | 序列号 | 系统ID | 组件ID | 消息ID | 载荷 | 校验和 |
嗯,这里要注意:系统ID和组件ID是区分设备的关键。飞控的系统ID通常是1,QGC是255。组件ID则区分飞控内部的GPS、IMU等模块。我在项目中遇到过两台飞控同时连一个地面站,结果指令串了——就是因为系统ID没改。
避坑指南:我曾经调试时发现QGC收不到心跳包,折腾半天发现是串口波特率设成了9600,而飞控默认是57600。MAVLink的波特率必须两端一致,否则连不上。
1.2 uORB消息总线
uORB是PX4内部的消息总线。你可以把它想象成飞控的“内部快递系统”。传感器数据、控制指令、状态信息,全通过uORB在模块之间传递。
为什么要有uORB?你想想看,PX4里有几十个模块——姿态估计、位置控制、GPS驱动、RC输入……如果每个模块都直接调用对方的函数,代码就乱成一锅粥了。uORB让它们解耦:发布者只管发,订阅者只管收,谁都不认识谁。
常用的uORB消息主题:
| 主题名称 | 发布者 | 订阅者 | 内容 |
|---|---|---|---|
sensor_accel |
加速度计驱动 | 姿态估计、EKF | 三轴加速度数据 |
vehicle_attitude |
姿态估计模块 | 位置控制、QGC | 四元数、欧拉角 |
vehicle_gps_position |
GPS驱动 | 位置估计、导航 | 经纬度、海拔、速度 |
actuator_controls |
混控器 | PWM输出驱动 | 电机/舵机控制量 |
uORB的工作流程很简单:
- 发布者调用
orb_advertise()注册主题 - 发布者循环调用
orb_publish()发送数据 - 订阅者调用
orb_subscribe()订阅主题 - 订阅者调用
orb_copy()获取最新数据
注意:uORB是飞控内部机制,QGC完全看不到它。飞控内部把uORB消息转换成MAVLink包后,才发到外部。反过来,QGC发来的MAVLink指令,飞控也要先解包,再通过uORB投递给对应模块。
1.3 QGC地面站架构
QGC(QGroundControl)不是个简单的显示界面。它的架构分三层:
- 通信层: 负责收发MAVLink包。支持串口、UDP、TCP。我建议调试时用UDP,方便抓包分析。
- 核心层: 解析MAVLink消息,维护无人机状态。比如心跳超时检测、参数同步、航点管理。
- UI层: 用Qt Quick写的界面。显示地图、仪表盘、参数表。说白了就是给人看的。
QGC内部有个MAVLink协议栈,它维护着所有连接设备的状态。每个设备有一个Vehicle对象,里面存着它的系统ID、组件列表、当前模式、电池电量等等。
我记得有一次,QGC显示“连接已断开”,但飞控明明还在飞。后来发现是QGC的心跳超时阈值默认设了5秒,而飞控因为CPU负载高,心跳偶尔延迟到6秒。把阈值调到10秒就解决了。
1.4 通信链路拓扑图
下面这张图展示了从传感器到地面站的完整数据流。我特意把uORB和MAVLink的分界画清楚了。
从图上你能看到:数据从传感器驱动出发,经过uORB总线分发给各个飞控模块,模块处理完后交给MAVLink层打包,再通过串口或UDP发出去。QGC那边反过来:物理层收到数据,MAVLink协议栈解包,核心层更新无人机状态,UI层刷新显示。
这个链路里最容易出问题的环节,我个人经验是物理链路和MAVLink版本不匹配。串口线太长、USB转串口芯片质量差、或者飞控用v2而QGC配置成v1,都会导致通信失败。
调试小技巧:用mavlink-router或者mavproxy抓包看原始MAVLink数据。我习惯在飞控和QGC之间串一个mavproxy,既能转发又能录日志。出问题时回放日志,一眼就能看出是飞控没发数据,还是QGC没解析对。
好了,这一章把整个通信骨架搭起来了。后面我们会深入每个环节——MAVLink消息怎么定义、uORB怎么用代码发布订阅、QGC的插件怎么开发。有了这个总览图,后面学起来就不会迷路。