1. ArduPilot 概述:从零到一,认识这个开源飞控巨兽

大家好,我是你们的飞控工程师老张。今天咱们正式开讲《ArduPilot飞行模式切换精讲》的第一章。

说实话,我接触 ArduPilot 快十年了。从最早的 APM 2.0 板子开始,一路看着它从一个小众项目长成今天的庞然大物。你想想看,一个开源飞控能支持无人机、无人车、无人船,甚至潜艇,这本身就够传奇的。

这一章,咱们先不急着写代码。先把 ArduPilot 的来龙去脉、它能跑在什么硬件上、软件到底怎么组织的,捋清楚。嗯,磨刀不误砍柴工嘛。

1.1 ArduPilot 发展史:一个社区驱动的传奇

ArduPilot 的故事,得从 2007 年说起。那时候有个叫 Jordi Muñoz 的墨西哥小伙子,跟 Chris Anderson 一起,在 Arduino 平台上搞出了最早的自动驾驶仪。说白了,就是用 8 位单片机控制航模。

我记得第一次看到 APM 1.0 的代码时,差点没笑出来——就那么几百行,连个像样的卡尔曼滤波都没有。但就是这堆简陋的代码,开启了开源飞控的新纪元。

关键时间节点:

  • 2007年:APM 1.0 诞生,基于 Arduino,仅支持固定翼
  • 2010年:APM 2.0 发布,加入多旋翼支持,社区开始爆发
  • 2013年:Pixhawk 项目启动,硬件升级到 32 位 STM32
  • 2015年:ArduPilot 从 APM 代码库独立,正式成为顶级开源项目
  • 2018年:支持 ChibiOS 实时操作系统,告别裸奔时代
  • 2021年至今:全面拥抱 4.0+ 架构,支持多车辆类型、多传感器融合

这里有个坑,我当年踩过。2014 年那会儿,APM 2.5 板子还在用 8 位单片机,我硬要在上面跑复杂的光流算法。结果呢?CPU 满载,炸机。后来才明白,硬件跟不上,软件再牛也白搭。

1.2 支持的硬件平台:从 8 位到 64 位,总有一款适合你

ArduPilot 能支持的硬件,说实话,比市面上任何商业飞控都多。我个人习惯把硬件平台分成三代:

代际 典型硬件 处理器 RAM 适用场景
第一代 APM 2.x Atmega2560 (8位) 8 KB 教学、简单固定翼
第二代 Pixhawk 1 / Cube STM32F4 (32位) 256 KB 多旋翼、主流无人机
第三代 Pixhawk 4 / Cube Orange+ STM32H7 (32位) 1 MB+ 工业级、自动驾驶

你可能会问:为什么还在支持 8 位机?嗯,这里有个现实问题。很多教育机构和爱好者手里还有大量 APM 板子,ArduPilot 团队一直没放弃它们。我曾经在一个大学实验室里,看到他们用 APM 2.6 带四轴飞了整整两年,虽然功能有限,但稳定得可怕。

我的建议:新手入门直接上 Pixhawk 1 或 Cube 系列。别在 APM 上浪费时间了,那玩意儿连个 SD 卡日志都写不利索。你想想看,调试的时候没有日志,等于瞎子摸象。

除了这些主流板子,ArduPilot 还支持一大堆小众硬件:

  • BeagleBone Blue:适合做无人车,GPIO 多
  • Raspberry Pi + Navio2:适合搞视觉导航
  • STM32F7 系列:适合自己画板子的硬核玩家
  • Linux 平台:直接在 Ubuntu 上跑 SITL 仿真

1.3 软件架构概览:分层设计,各司其职

ArduPilot 的软件架构,说白了就是一套分层系统。我画了张图,你一看就明白:

ArduPilot 软件架构分层图 应用层 (Application Layer) 飞行模式管理 · 任务规划 · 导航逻辑 · 用户交互 核心层 (Core Layer) 姿态估计 (EKF) · 位置控制 · 导航滤波器 · 参数系统 硬件抽象层 (HAL) 传感器驱动 · PWM 输出 · UART/I2C/SPI 总线 · 存储 操作系统层 (OS Layer) ChibiOS / NuttX · 任务调度 · 中断管理 · 内存管理 💡 每一层只通过定义好的接口与上下层通信,更换硬件只需重写 HAL 层 飞行模式切换主要在应用层完成,但依赖核心层的状态估计结果

这张图我画了好几次才满意。你看,从下往上,每一层都只干自己的事。我最喜欢的是 HAL 层——当年为了把 ArduPilot 移植到一块国产 STM32 板子上,我只需要重写 HAL 层的传感器驱动,上层代码一行没改。这就是分层设计的好处。

1.3.1 应用层:飞行模式的老家

应用层里藏着所有飞行模式的逻辑。比如你切到 Loiter 模式,应用层就会调用核心层的定位数据,然后生成位置保持指令。我刚开始学的时候,以为飞行模式是写在核心层的,找了好久才发现全在 ArduCopter/mode.cpp 里。

1.3.2 核心层:飞控的大脑

核心层里最牛的就是 EKF(扩展卡尔曼滤波器)。它把 GPS、IMU、磁力计、气压计的数据揉在一起,输出一个干净的状态估计。嗯,这里有个坑——EKF 参数调不好,飞机在天上就跟喝醉了似的。我曾经在项目里因为 EKF 的噪声参数设错了,导致飞机悬停时左右晃了半米,查了三天才找到原因。

1.3.3 HAL 层:硬件的翻译官

HAL 层把不同硬件的差异藏起来了。你写代码的时候,根本不用管底层是 I2C 还是 SPI,直接调用 hal.analog->read() 就行。我个人习惯在移植新硬件时,先跑一遍 HAL 层的单元测试,确保每个传感器都能正常读数。

1.3.4 操作系统层:让一切有序运行

ArduPilot 早期是裸奔的,所有任务在一个大循环里跑。后来换成 ChibiOS,任务调度才规范起来。现在每个传感器读取、控制计算、通信处理都是独立线程,优先级高的任务不会被阻塞。你想想看,如果 GPS 解析卡住了,飞控还能继续控制电机,这就是操作系统的功劳。

注意:虽然 ArduPilot 支持多平台,但不同硬件上的实时性表现差异很大。我曾经在某个国产 STM32F4 板子上遇到过定时器精度不够的问题,导致 PWM 输出抖动。建议量产前做完整的硬件在环测试。