4、飞控系统核心:飞控硬件架构、实时操作系统与软件架构概览

飞控系统,说白了就是无人机的大脑。我见过不少新手,上来就调参数、改代码,结果飞机在天上乱飘,最后发现是硬件选型出了问题。嗯,这一章我们就把飞控的底牌翻出来看看。

4.1 飞控硬件架构:MCU、传感器接口与PWM输出

一块典型的飞控板,核心就三块:大脑(MCU)、感知器官(传感器接口)、肌肉驱动(PWM输出)。我习惯把飞控硬件拆成这几个模块来看,选型时心里才有底。

4.1.1 MCU——飞控的算力核心

MCU 决定了飞控能跑多复杂的算法,能接多少传感器。目前主流飞控的 MCU 分两大阵营:

参数 STM32F4/F7(Pixhawk 系) STM32H7(高端飞控)
主频 168–216 MHz 400–480 MHz
浮点运算 单精度 FPU 双精度 FPU
典型型号 STM32F427, STM32F765 STM32H743, STM32H750
适用场景 多旋翼、固定翼、车船 视觉导航、复杂滤波、冗余系统
我的经验: 做物流无人机时,我选了 STM32H7。因为要同时跑 EKF 融合、光流和避障算法,F4 的 CPU 占用率飙到 85% 以上,换成 H7 后直接降到 40%。算力留余量,后期迭代才不慌。

4.1.2 传感器接口——飞控的感官神经

飞控需要感知姿态、位置、空速、高度。传感器接口通常通过 SPI、I2C、UART 连接。我个人习惯把传感器接口分成三类:

  • IMU(惯性测量单元):加速度计 + 陀螺仪,通常用 SPI 连接,速率高、延迟低。我遇到过 SPI 线序接反导致数据全乱的情况,嗯,后来老老实实对着 datasheet 一根一根对。
  • 气压计/磁力计:I2C 接口为主,速率要求不高,但容易受干扰。我曾经在机臂上走 I2C 线,结果磁力计读数跳得跟心电图似的——后来把线绕开电机磁场区域就好了。
  • 外部传感器(GPS、光流、激光雷达):UART 或 SPI,注意波特率匹配和协议兼容性。
避坑指南: 我曾经在项目里同时接了 3 个 I2C 传感器,结果总线冲突导致飞控反复重启。后来加了 I2C 多路复用器(如 TCA9548A)才解决。多传感器共线时,一定要算总负载电容和地址冲突。

4.1.3 PWM 输出——飞控的肌肉驱动

飞控通过 PWM 信号控制电调(ESC)和舵机。标准 PWM 频率是 50 Hz(周期 20 ms),脉宽 1–2 ms。但现代电调支持更高频率,比如 400 Hz 甚至 1 kHz。

我建议你注意两点:

  • PWM 分辨率:16 位定时器比 8 位细腻得多,尤其在做精确悬停时,低分辨率会导致电机抖动。
  • 输出通道数:四旋翼至少 4 路,六旋翼 6 路,固定翼还要加舵机通道。Pixhawk 通常有 8–14 路 PWM 输出。

4.2 实时操作系统(RTOS)与任务调度

飞控不能像手机那样“等一会再响应”。无人机每秒要执行几百次姿态解算和 PID 控制,延迟超过 1 毫秒就可能炸机。所以必须用 RTOS。

4.2.1 为什么飞控必须用 RTOS?

你想想看,飞控要同时做这些事:

  • 读取 IMU 数据(1 kHz)
  • 运行姿态解算(500 Hz)
  • 执行 PID 控制(400 Hz)
  • 处理遥控器信号(50 Hz)
  • 记录日志(10 Hz)

如果用裸机轮询,高优先级任务会被低优先级任务阻塞。RTOS 通过抢占式调度保证:高优先级任务来了,低优先级任务立刻让路。

核心概念: RTOS 的任务调度策略主要有两种:

  • 抢占式调度(Preemptive):高优先级任务随时打断低优先级任务。飞控主循环必须用这个。
  • 时间片轮转(Round-Robin):同等优先级任务轮流执行。适合日志记录、状态上报等非紧急任务。

4.2.2 飞控中常用的 RTOS

RTOS 特点 典型应用
NuttX POSIX 兼容,支持动态加载模块 PX4 官方推荐
FreeRTOS 轻量、易移植、生态成熟 ArduPilot(部分平台)
ChibiOS 极低延迟、适合资源受限 MCU Betaflight、INAV

我个人更倾向 NuttX。为什么?因为它支持文件系统和动态模块加载。我在做一款需要热插拔传感器的飞控时,NuttX 的模块化设计让我省了不少事——不用每次改硬件都重新编译整个固件。

4.2.3 任务调度实例

以 PX4 为例,它的任务调度大概是这样的:

// 伪代码示意:PX4 主任务调度
void px4_main_task(void)
{
    while(1)
    {
        // 最高优先级:传感器数据采集(1 kHz)
        sensor_imu_update();

        // 高优先级:姿态估计(500 Hz)
        attitude_estimator_update();

        // 中优先级:位置控制(250 Hz)
        position_controller_update();

        // 低优先级:日志记录(10 Hz)
        logger_update();

        // 空闲时执行:参数检查、状态上报
        idle_tasks();
    }
}
我的建议: 设计任务优先级时,把“传感器读取”和“控制输出”放在最高级。日志、通信、参数管理可以放低优先级。我曾经把日志优先级设高了,结果 IMU 数据被延迟,飞机在高机动时直接失控——教训深刻。

4.3 PX4 / ArduPilot 软件架构概览

现在主流的开源飞控软件就两个:PX4 和 ArduPilot。它们架构不同,但核心思想一致:模块化、可配置、支持多旋翼/固定翼/车船。

4.3.1 PX4 架构:基于发布/订阅的模块化设计

PX4 的核心是 uORB(微对象请求代理)。说白了,就是一个消息总线。各个模块(传感器、导航、控制)通过 uORB 发布和订阅消息,互不直接调用。

PX4 软件架构(基于 uORB 消息总线) 传感器驱动 IMU / GPS / 气压计 状态估计 EKF / 姿态解算 控制器 PID / 位置控制 uORB 消息总线 混控器 & 输出 PWM / DShot 说明:各模块通过 uORB 总线解耦 传感器 -> 估计 -> 控制 -> 输出,数据流清晰可追踪 新增模块只需订阅/发布对应消息,无需修改其他模块

这种架构的好处是模块解耦。你想换一个姿态估计算法?只要新模块发布同样的 uORB 消息就行,其他模块完全不受影响。我在做定制飞控时,就自己写了一个视觉里程计模块,直接订阅 IMU 消息,发布位置估计消息,无缝接入 PX4。

4.3.2 ArduPilot 架构:基于调度器的分层设计

ArduPilot 的架构更传统一些。它有一个主调度器(Scheduler),按固定频率轮询各个任务。任务分四层:

  • 快速循环(1 kHz):IMU 读取、姿态控制
  • 中速循环(400 Hz):位置控制、导航
  • 慢速循环(50 Hz):遥控器处理、通信
  • 极慢循环(10 Hz):日志、参数管理

PX4 vs ArduPilot 架构对比:

维度 PX4 ArduPilot
通信机制 uORB 发布/订阅 全局变量 + 调度器轮询
模块化程度 高(动态加载模块) 中(编译时静态链接)
实时性保障 RTOS 任务优先级 调度器固定时间片
学习曲线 较陡(需理解 uORB) 较平缓(代码结构直观)
典型用户 研究机构、定制化开发 爱好者、商业应用

4.3.3 如何选择?

我个人建议:

  • 如果你要做深度定制(比如加新传感器、改控制算法),选 PX4。uORB 的模块化设计让你改一处不影响全局。
  • 如果你要快速部署、做成熟产品,选 ArduPilot。它的参数体系非常完善,很多功能开箱即用。
  • 如果你刚入门,两个都试试。我最初从 ArduPilot 入手,后来转 PX4,发现理解 uORB 后,调试效率反而更高。
注意: 不管选哪个,硬件兼容性是第一位的。我曾经在某个国产飞控上强行刷 PX4,结果传感器驱动不匹配,IMU 数据全是乱码。选型前一定去官网查硬件支持列表。

好了,这一章我们把飞控的硬件架构、RTOS 调度、以及两大开源软件的架构都过了一遍。你想想看,这些底层逻辑搞清楚了,后面调参、改代码、甚至自己写飞控,都会顺手很多。