1. ArduPilot 生态全景:从历史到实战环境搭建

各位同学好,我是你们这门课的老朋友。在正式开始折腾性能优化之前,我觉得有必要先带大家把 ArduPilot 的整个家底摸清楚。你想想看,要调优一辆车,总得先知道发动机在哪、方向盘连着什么、轮胎是什么规格吧?

ArduPilot 这个项目,我从 2015 年开始接触,那时候它还是个“飞控界的 Linux”,现在已经成了无人机、无人车、无人船甚至潜艇的通用大脑。我个人习惯把它的生态分成三块看:历史脉络、核心架构、硬件与工具链。咱们一个一个来。

1.1 发展历史:从学生项目到行业标准

ArduPilot 的故事,说白了就是一个“玩着玩着就搞大了”的典型。2007 年,一个叫 Jordi Muñoz 的墨西哥小伙,跟 DIY Drones 社区的 Chris Anderson 一起,把 Arduino 和 IMU 传感器焊在一起,做出了最早的 ArduPilot。

我记得第一次看到 ArduPilot Mega(APM 1.0)的板子时,差点笑出声——那玩意儿用的是 8 位 AVR 单片机,16MHz 主频,2KB RAM。放在今天,连个智能灯泡的算力都比它强。但就是这块板子,奠定了整个项目的根基。

关键里程碑:

  • 2007-2010:APM 1.0/2.0,基于 Arduino,8 位 MCU,只能做简单的四轴自稳
  • 2011-2013:APM 2.5/2.6,加入 GPS 和气压计,开始支持航线飞行
  • 2014-2016:Pixhawk 诞生,32 位 STM32F4 处理器,ArduPilot 进入“现代”阶段
  • 2017-2020:支持 Cube、CUAV 等硬件,加入 EKF2/3、Lua 脚本、UAVCAN
  • 2021-至今:ChibiOS 成为默认 RTOS,支持 SITL 硬件在环仿真,性能优化成为核心议题

这里有个坑,我当年踩过。APM 2.5 时代,很多人把 ArduPilot 和 APM 硬件划等号。其实 ArduPilot 是软件,APM 只是最早跑它的那块板子。现在你可以在 Pixhawk、Cube、CUAV、甚至树莓派上跑 ArduPilot。千万别搞混了。

1.2 核心架构:四层结构,各司其职

ArduPilot 的架构,我习惯用“四层蛋糕”来理解。每一层只跟上下层打交道,互不干扰。这种设计,说白了就是为了跨平台——换一块 MCU,只需要改最底层,上面的逻辑代码纹丝不动。

ArduPilot 四层架构图 GCS 地面站层 Mission Planner / QGroundControl / MAVProxy Vehicle 飞行器层 ArduCopter / ArduPlane / ArduRover / ArduSub / ArduBoat Libraries 核心库层 AP_InertialNav / AP_Math / EKF / AC_AttitudeControl / AP_GPS AP_HAL 硬件抽象层 HAL_ChibiOS / HAL_Linux / HAL_ESP32 / HAL_Empty 数据流方向:GCS ↔ Vehicle ↔ Libraries ↔ HAL ↔ 硬件 换硬件只需重写 AP_HAL 层,上层代码完全复用

咱们从下往上说:

  • AP_HAL(硬件抽象层):这是最底层,负责跟 MCU 的寄存器、外设打交道。比如你要读一个 GPIO 电平,在 HAL_ChibiOS 里调的是 ChibiOS 的 API,在 HAL_Linux 里调的是 sysfs。上层代码根本不知道底下是什么芯片。
  • Libraries(核心库):这是 ArduPilot 的“工具箱”。EKF 姿态估计、惯性导航、PID 控制器、GPS 解析……所有跟硬件无关的算法都在这里。我优化性能时,80% 的精力都花在这个层。
  • Vehicle(飞行器层):每种载具类型对应一个顶层目录。ArduCopter 管四轴/六轴/八轴,ArduPlane 管固定翼,ArduRover 管车。它们共享 Libraries 的代码,但有自己的状态机和模式逻辑。
  • GCS(地面站):地面站不是飞控上跑的,是电脑或手机上的软件。Mission Planner 是 Windows 上的老大哥,QGroundControl 跨平台,MAVProxy 是命令行神器。它们通过 MAVLink 协议跟飞控通信。

我的经验:刚开始学 ArduPilot 源码时,别一头扎进 Vehicle 层。先读 Libraries 里的 AP_Math 和 AP_InertialNav,这两个库是所有算法的基石。我当年就是先啃完 EKF 的论文,再回来看代码,豁然开朗。

1.3 支持的硬件平台:选对板子,少走弯路

ArduPilot 支持的硬件,我按“血统”分成三大家族。嗯,这里要注意,不是所有板子都能跑最新固件——Flash 和 RAM 是硬门槛。

家族 代表型号 MCU RAM Flash 适合场景
Pixhawk 系列 Pixhawk 1 / 4 / 6C STM32F4/F7/H7 256KB - 2MB 1MB - 2MB 入门、教育、轻量级无人机
Cube 系列 Cube Orange / Black / Yellow STM32H7 / F7 1MB - 2MB 2MB 工业级、高可靠性、冗余传感器
CUAV 系列 CUAV V5+ / X7+ / Nora STM32F7 / H7 512KB - 2MB 2MB 高性价比、开源硬件、开发者友好
其他 ESP32 / Linux (RPi / Jetson) ESP32 / ARM Cortex-A 512KB+ / 1GB+ 4MB+ / 外部存储 实验、边缘计算、AI 集成

避坑指南:我曾经在 Pixhawk 1(256KB RAM)上尝试开启 EKF3 + GPS 双天线 + 光流 + 激光雷达测距,结果编译完固件 230KB,运行时 RAM 直接爆了,飞控反复重启。后来换成 Cube Orange 才搞定。选硬件时,先算算你的功能需要多少 RAM——EKF3 大约占 80KB,Lua 脚本每 100 行约 5KB,心里要有数。

1.4 固件编译环境搭建:WSL 和 Linux 两条路

编译 ArduPilot 固件,我强烈建议用 Linux 原生环境。Windows 上虽然能用 Cygwin 或 MSYS2,但坑太多——路径分隔符、换行符、权限问题,随便一个就能让你折腾半天。

我个人习惯用 WSL2(Windows Subsystem for Linux 2)。它跑的是真正的 Linux 内核,跟 Ubuntu 虚拟机几乎没区别,但文件系统跟 Windows 互通。下面是我的标准操作流程:

方案一:WSL2(推荐 Windows 用户)

  1. 安装 WSL2 和 Ubuntu 22.04 LTS
  2. 更新系统:sudo apt update && sudo apt upgrade -y
  3. 安装编译工具链:
sudo apt install -y git python3 python3-pip python3-venv \
  gcc-arm-none-eabi binutils-arm-none-eabi \
  g++-arm-linux-gnueabihf gcc-arm-linux-gnueabihf \
  libc6-armhf-cross libc6-dev-armhf-cross \
  libtool pkg-config autoconf automake
  1. 克隆 ArduPilot 源码:
git clone https://github.com/ArduPilot/ardupilot.git
cd ardupilot
git submodule update --init --recursive
  1. 安装 Python 依赖:
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
  1. 编译测试(以 Cube Orange 为例):
./waf configure --board CubeOrange
./waf copter

编译完成后,固件在 build/CubeOrange/bin/ 目录下,文件名是 arducopter.apj。

方案二:原生 Linux(Ubuntu 22.04)

步骤跟 WSL2 几乎一样,只是不需要装 WSL。如果你用的是 Ubuntu 桌面版,我建议直接装 gcc-arm-none-eabi 和 g++-arm-linux-gnueabihf 这两个交叉编译器。注意不要用 Ubuntu 源里的旧版本——我踩过坑,gcc-arm-none-eabi 版本低于 10 会导致某些 C++17 特性编译失败。

小技巧:第一次编译时,加上 -j$(nproc) 参数能大幅提速:./waf copter -j$(nproc)。nproc 返回你的 CPU 核心数,比如 8 核就是 8 个并行任务。我自己的工作站 16 核,编译一次 ArduCopter 只要 40 秒。

1.5 第一个固件:验证你的环境

环境搭好后,我建议你编译一个最简单的固件来验证——SITL(Software In The Loop)。它不烧录到真实硬件,而是在你的电脑上模拟一个飞控。

# 编译 SITL 版本
./waf configure --board sitl
./waf copter -j$(nproc)

# 启动仿真
cd Tools/autotest
python3 sim_vehicle.py -v ArduCopter --map --console

如果一切顺利,你会看到一个 MAVProxy 控制台和一个地图窗口。输入 arm throttle 然后 takeoff 10,虚拟无人机就会起飞到 10 米高度。嗯,看到这个画面,你的环境就算彻底搭好了。

环境验证清单:

  • ✅ git clone 成功,子模块完整
  • ✅ Python 虚拟环境激活,依赖安装无报错
  • ✅ waf configure 通过,没有“missing toolchain”错误
  • ✅ waf copter 编译成功,生成 .apj 文件
  • ✅ SITL 启动,MAVProxy 控制台无异常