1. 飞控固件概述:PX4与ArduPilot的区别、固件架构、编译环境概览

大家好,欢迎来到第一节课。

做飞控开发这么多年,我经常被问到同一个问题:「PX4 和 ArduPilot 到底选哪个?」说实话,这个问题没有标准答案。但如果你理解了它们的本质区别,选型就变得很简单了。

1.1 PX4 与 ArduPilot:两个流派,两种哲学

先说说我的个人经历。我最早接触的是 ArduPilot,那时候它叫 ArduCopter,代码风格非常「Arduino」—— 一个 setup 加一个 loop,看起来特别亲切。后来转到 PX4,第一反应是:「这什么玩意儿?怎么这么多文件夹?」

嗯,这就是它们最核心的区别。

核心差异速览:

维度 PX4 ArduPilot
架构风格 微内核 + 模块化 宏内核 + 单进程
调度方式 uORB 消息总线 主循环 + 定时器
代码语言 C++ (现代风格) C++ (Arduino 风格)
实时性 强 (基于 RTOS) 中等 (基于调度器)
扩展难度 中等 (需理解模块机制) 较低 (直接改主循环)
社区生态 学术/工业界 爱好者/商业应用

说白了,PX4 更像一个「操作系统」,每个模块都是独立的任务,通过消息队列通信。ArduPilot 更像一个「大循环」,所有功能都在一个线程里轮询。

为什么会这样?

这跟它们的出身有关。PX4 最初来自苏黎世联邦理工,学术背景决定了它追求架构的优雅和可扩展性。ArduPilot 来自 DIY 社区,更注重「拿来就能用」和「好改」。我个人觉得,如果你要做产品级开发,PX4 的架构更靠谱;如果你只是改改参数、加个简单功能,ArduPilot 上手更快。

我的建议: 初学者可以先从 ArduPilot 入手,理解飞控的基本逻辑。等需要做复杂功能时,再切换到 PX4。我自己就是这么过来的。

1.2 固件架构:PX4 的模块化 vs ArduPilot 的扁平化

咱们深入看看架构。这里我重点讲 PX4,因为它的设计思想更值得学习。

PX4 架构:三层结构

  1. 底层:NuttX RTOS —— 提供任务调度、文件系统、驱动框架。说白了就是飞控的「操作系统内核」。
  2. 中间层:uORB 消息总线 —— 所有模块之间不直接调用,而是通过发布/订阅消息来通信。比如传感器模块发布「传感器数据」消息,姿态估计模块订阅它。
  3. 应用层:各种模块 —— 姿态估计、位置控制、导航、GPS 处理等。每个模块都是一个独立的任务。

我记得第一次看 PX4 的代码时,最让我困惑的就是 uORB。你想想看,一个传感器数据,从驱动读到发布,再到被其他模块订阅,中间绕了一大圈。但后来我明白了,这种设计的好处是:任何一个模块崩溃了,系统不会挂。这在无人机上太重要了。

避坑指南: 我曾经在项目中遇到过一个 bug —— 某个自定义模块订阅了错误的 uORB 主题,导致姿态数据一直不对。排查了整整两天才发现是主题名拼写错了。所以,uORB 主题名一定要仔细核对,大小写敏感!

ArduPilot 架构:单进程大循环

ArduPilot 的架构简单得多。整个固件就是一个大循环,按固定频率执行:

void loop() {
    // 1. 读取传感器
    // 2. 姿态估计
    // 3. 控制计算
    // 4. 输出 PWM
    // 5. 处理遥控器信号
    // 6. 日志记录
    // ...
}

这种架构的好处是:代码逻辑一目了然,改起来也方便。坏处是:如果某个任务卡住了,整个系统都会受影响。比如你加了一个耗时的传感器处理,飞控可能就「抖」了。

1.3 编译环境概览:从零搭建你的开发环境

好,理论说完了,咱们来点实际的。编译环境怎么搭?

我个人习惯用 Ubuntu 20.04/22.04,因为官方支持最好。Windows 也能搞,但坑比较多,我不建议新手尝试。

PX4 编译环境搭建

官方提供了一个一键安装脚本,但我不建议直接用。为什么呢?因为网络问题,经常下载失败。我推荐分步安装:

  1. 安装基础工具:
sudo apt update
sudo apt install git zip cmake build-essential genromfs ninja-build exiftool -y
  1. 安装 ARM 交叉编译器:
sudo apt install gcc-arm-none-eabi gdb-multiarch -y
  1. 安装 PX4 工具链:
git clone https://github.com/PX4/PX4-Autopilot.git --recursive
cd PX4-Autopilot
make px4_fmu-v5_default

小技巧: 第一次编译会很慢,因为要下载很多依赖。我建议用 make px4_fmu-v5_default -j4 来加速,-j4 表示用 4 个线程并行编译。如果你的电脑性能好,可以试试 -j8。

ArduPilot 编译环境搭建

ArduPilot 的编译环境相对简单,因为它依赖的库更少:

git clone https://github.com/ArduPilot/ardupilot.git
cd ardupilot
git submodule update --init --recursive
./waf configure --board Pixhawk1
./waf copter

嗯,这里要注意:ArduPilot 使用 waf 作为构建系统,而不是 CMake。我第一次用的时候也愣了一下,但用习惯了其实挺顺手的。

1.4 我的开发环境推荐

最后,分享一个我现在的开发环境配置,供你参考:

工具 推荐 备注
操作系统 Ubuntu 22.04 WSL2 也可以,但 USB 透传有点麻烦
编辑器 VS Code 配合 C/C++ 插件、GitLens
调试工具 J-Link / ST-Link 配合 Ozone 或命令行 GDB
版本管理 Git + GitHub 建议用 SSH 方式,省去输密码的麻烦
模拟器 Gazebo (PX4) / SITL (ArduPilot) 没有硬件也能调试代码

好了,第一节课就到这里。你可能会觉得内容有点多,但这些都是基础中的基础。下一节课,我们会真正开始动手编译固件,并加入第一个自定义功能。

记住:飞控开发没有捷径,但理解架构能让你少走弯路。我当年就是没搞懂 uORB,白白浪费了一个月。希望你能比我顺利。

课后思考: 如果你现在要做一个「自定义传感器驱动」,你觉得在 PX4 和 ArduPilot 上分别应该怎么做?下一节课我会揭晓答案。