1. ArduPilot概述:从开源飞控到自动驾驶生态

各位同学,欢迎来到《ArduPilot无人机系统原理解析》的第一章。

说实话,我接触ArduPilot快十年了。从最早的APM 2.0板子开始,一路看着它从一个小众爱好者的玩具,成长为今天能飞固定翼、多旋翼、直升机、无人车甚至潜艇的庞然大物。这中间踩过的坑、烧过的板子,嗯,够写一本小册子了。

今天我们先从宏观上认识一下ArduPilot——它从哪来,现在长什么样,以及它的骨架是怎么搭起来的。

1.1 项目起源:一个想飞的念头

ArduPilot的故事,得从2007年说起。

当时有个叫Chris Anderson的哥们,他搞了个叫DIY Drones的社区。大家聚在一起,就想做一件事:让无人机飞控不再神秘,不再昂贵。那时候市面上的飞控要么是军工级的黑盒子,要么是玩具级的陀螺仪,想自己写个算法?门都没有。

后来他们找到了一个叫ArduPilot的开源项目——注意,这个ArduPilot最初是Arduino上的一个固件,用AVR单片机跑的。说白了,就是一块几十块钱的Arduino板子,加上一个MPU6050惯性传感器,就能让飞机保持平衡。

核心转折点:2010年,3D Robotics公司成立,ArduPilot正式从个人项目走向社区化、专业化。2012年,Pixhawk项目启动,硬件平台从8位AVR升级到32位ARM Cortex-M4,飞控能力直接上了一个台阶。

我个人觉得,ArduPilot能活下来并且活得这么好,核心原因就一个:它把“飞控”这件事从黑盒变成了白盒。你不仅能飞,还能看代码,还能改代码。这种自由度,在2010年前后是难以想象的。

1.2 发展历程:四个关键阶段

我习惯把ArduPilot的发展分成四个阶段,这样比较好记:

阶段 时间 标志性事件 我的个人记忆
萌芽期 2007-2010 ArduPilot 1.0发布,基于Arduino 那时候我还在用8位单片机做平衡车,看到ArduPilot能飞,简直惊为天人
成长期 2010-2014 APM 2.x系列硬件,Pixhawk诞生 我买的第一块APM 2.5,焊接质量感人,但飞起来的那一刻,值了
成熟期 2014-2018 Pixhawk 1成为事实标准,ArduPilot分家(PX4独立) 分家那段时间社区很动荡,但ArduPilot坚持了“全平台支持”的路线,现在看来是对的
生态期 2018-至今 Cube系列、ChibiOS迁移、自动驾驶车辆支持 现在ArduPilot已经不只是飞控了,它是个完整的机器人操作系统

一个小提示:如果你在网上看到“APM”和“ArduPilot”两个词混用,别慌。APM是早期的硬件代号,现在ArduPilot是软件项目的总称。但老玩家还是习惯叫“APM固件”。

1.3 主要特点:凭什么选它?

市面上开源飞控不少,PX4、Cleanflight、Betaflight……为什么ArduPilot能成为工业级和科研级的主流?我总结了几点:

  • 全平台支持:多旋翼、固定翼、直升机、无人车、无人船、潜艇,一套代码全搞定。你想想看,同样的姿态估计算法,换个参数就能从天上用到水里,这复用性有多强。
  • 成熟度极高:代码库从2007年迭代到现在,超过15年。我在项目中遇到过很多边缘情况——比如GPS丢星、磁罗盘干扰、电机堵转——ArduPilot的故障处理逻辑基本都覆盖了。
  • 硬件无关性:ArduPilot的硬件抽象层(HAL)做得非常好。同样的固件,可以跑在STM32F4上,也可以跑在STM32H7上,甚至能跑在Linux上。我曾经把ArduPilot移植到一块国产MCU上,只改了底层驱动,上层算法一行没动。
  • 社区生态:Mission Planner地面站、MAVLink协议、DroneKit SDK……这些配套工具链,让ArduPilot不只是一个飞控,而是一整套开发平台。

避坑指南:我曾经因为贪便宜买了一块山寨Pixhawk,结果飞了十分钟,IMU数据就开始漂移。后来拆开一看,传感器是翻新件,晶振也是次品。做项目时,硬件可靠性永远是第一位的,尤其是飞控这种关乎安全的东西。

1.4 支持的硬件平台

ArduPilot支持的硬件平台很多,但主流就几个。我按使用场景给你排个序:

硬件平台 处理器 适用场景 我的评价
Pixhawk 1 STM32F427 入门、教学、轻量级无人机 经典款,资料最多,但性能已经有点吃力了
Pixhawk 4 / 4 Mini STM32F765 中高端多旋翼、固定翼 性能够用,接口丰富,我目前的主力平台
Cube系列(Cube Orange / Cube Black) STM32H7 / STM32F4 工业级、科研级、自动驾驶 可靠性极高,带冗余设计,适合长时间飞行
Here系列 STM32F4 高精度RTK定位场景 自带RTK模块,省去外接的麻烦
Linux平台(Navio2、Raspberry Pi) ARM Cortex-A系列 视觉导航、深度学习、复杂任务 适合做计算密集型任务,但实时性不如MCU

选型建议:如果你刚开始学,买个Pixhawk 4 Mini就够了,便宜、够用、资料多。如果你要做工业项目,直接上Cube Orange,多花几百块钱买的是可靠性。别问我怎么知道的——我有一架飞机因为Cube的硬件看门狗救回来三次。

1.5 软件架构概览

好了,重头戏来了。ArduPilot的软件架构,说白了就是一套分层+模块化的设计。我画了一张图,你看完就明白了:

ArduPilot 软件架构概览 应用层(Vehicle Code) ArduCopter / ArduPlane / ArduRover / ArduSub / AntennaTracker 核心库(Libraries) AP_InertialSensor | AP_GPS | AP_Baro | AP_Compass | AP_AHRS | AP_NavEKF AP_Motors | AC_AttitudeControl | AC_PosControl | AP_Mission | AP_Notify 硬件抽象层(HAL) HAL_ChibiOS | HAL_PX4 | HAL_Linux | HAL_ESP32 实时操作系统(RTOS) ChibiOS / NuttX / Linux PREEMPT_RT 硬件层(Hardware) STM32 MCU | IMU | GPS | Barometer | Magnetometer | PWM输出 | UART/I2C/SPI 用户直接选择机型 编译时确定 核心算法库 跨平台复用 适配不同MCU 移植的关键层

这张图你得记住。以后我们讲每一章,都会回到这个架构图上,找到对应的模块。

从上往下看:

  • 应用层:就是ArduCopter、ArduPlane这些。说白了,它们是一套参数配置和任务逻辑的集合。你选Copter,它就加载多旋翼的控制律;你选Plane,它就加载固定翼的逻辑。我刚开始学的时候,以为每个机型是独立的代码,后来才发现它们共享了90%的核心库。
  • 核心库:这是ArduPilot的灵魂。IMU驱动、GPS解析、姿态估计(EKF)、位置控制、电机混控……全在这里。每个库都是一个独立的模块,用C++类封装,接口清晰。你想想看,AP_InertialSensor这个库,不管底层是SPI还是I2C,不管传感器是BMI088还是MPU9250,上层调用的接口完全一样。这就是抽象的力量。
  • 硬件抽象层(HAL):这是ArduPilot能跑在不同硬件上的关键。HAL定义了一套标准接口——比如“读一个GPIO引脚”“发一条I2C数据”“设置一个PWM占空比”——然后针对不同的RTOS和MCU去实现。我做过一次HAL移植,说实话,工作量不小,但一旦做完,上层代码完全不用改。
  • RTOS:现在主流是ChibiOS。它负责任务调度、中断管理、时间同步。ArduPilot的主循环跑在1kHz(也就是1毫秒一次),所有实时任务都靠RTOS来保证时序。
  • 硬件层:就是你的板子、传感器、执行器。嗯,这里最容易出问题——我曾经因为一个电容虚焊,导致飞控在高振动环境下频繁重启,排查了整整两天。

一个实用的视角:当你拿到一份ArduPilot的代码,别急着看细节。先找到libraries/AP_InertialSensor和libraries/AP_NavEKF这两个目录。理解了IMU数据怎么进来、EKF怎么融合,你就理解了飞控的一半。

1.6 代码结构速览

最后,我们看一眼ArduPilot的代码目录结构。你不需要记住所有文件夹,但要知道它们大概在干什么:

ardupilot/
├── libraries/          # 核心库(上面讲的那一堆)
│   ├── AP_InertialSensor/
│   ├── AP_GPS/
│   ├── AP_NavEKF/
│   ├── AP_Motors/
│   ├── AC_AttitudeControl/
│   └── ...
├── ArduCopter/         # 多旋翼应用层
├── ArduPlane/          # 固定翼应用层
├── ArduRover/          # 无人车应用层
├── ArduSub/            # 潜艇应用层
├── AntennaTracker/     # 天线跟踪器
├── Tools/              # 调试工具、参数说明
├── mk/                 # 编译脚本
└── config/             # 板级配置文件

你看,结构非常清晰。应用层和核心库完全分离。这意味着什么?意味着如果你想给多旋翼加一个新功能,你只需要改ArduCopter/下面的代码,核心库不用动。反过来,如果你要优化EKF算法,你改libraries/AP_NavEKF/,所有机型都能受益。

总结一下:ArduPilot不是一个“飞控固件”,它是一个机器人操作系统框架。它的架构设计让开发者可以专注于算法本身,而不是每次都要从零开始写底层驱动。这也是为什么它能从无人机扩展到无人车、无人船、甚至潜艇——因为核心的导航、控制、任务管理逻辑,本质上是一样的。