一、ArduPilot概述与环境搭建

大家好,我是你们的讲师。今天咱们正式开始《ArduPilot自定义飞控模式开发实战》的第一课。

说实话,ArduPilot这个项目我接触了快十年了。从最早的APM 2.0板子开始,一路看着它从一个小众的开源飞控,成长为现在支持无人机、无人车、无人船甚至潜艇的全能型选手。嗯,这里我得先给你泼盆冷水——想玩转自定义飞控模式,你得先把这个大家伙的骨架摸清楚。

ArduPilot到底是什么?

说白了,ArduPilot就是一个开源的自动驾驶软件栈。它运行在硬件上,负责读取传感器数据、执行控制算法、输出PWM信号给电机和舵机。你想想看,一架四轴飞行器从起飞到悬停再到降落,背后是成千上万行C++代码在实时运算。

我个人习惯把ArduPilot分成三层:

  • 硬件抽象层(HAL):负责跟具体的硬件打交道,比如I2C、SPI、UART这些总线
  • 核心库(AP_* 系列):数学工具、滤波器、坐标系变换,这些是飞控的"肌肉"
  • 飞行模式层:就是我们今天要讲的重点——各种飞行模式,比如Stabilize、Loiter、Auto

核心观点:自定义飞控模式,本质上就是在飞行模式层里添加一个新的"行为逻辑",然后把它挂接到遥控器的某个通道上。

我在项目中遇到过不少新手,一上来就想改飞控的核心算法。其实没必要。ArduPilot的架构设计得相当模块化,你只需要关注自己需要改的那一块就行。

源码获取——从哪里开始?

ArduPilot的源码托管在GitHub上。我个人建议你直接克隆主仓库,而不是下载ZIP包。为什么?因为后续你要频繁地拉取更新、切换分支,用Git管理会方便得多。

# 克隆主仓库(完整版,包含所有子模块)
git clone --recursive https://github.com/ArduPilot/ardupilot.git

# 如果你网络不好,可以先克隆主仓库再单独拉子模块
git clone https://github.com/ArduPilot/ardupilot.git
cd ardupilot
git submodule update --init --recursive

注意:--recursive 参数一定要加。ArduPilot依赖很多第三方库(比如mavlink、uavcan),这些都以子模块形式存在。我曾经有一次忘了拉子模块,编译报错找了半天,结果发现是缺少一个头文件。

克隆完成后,你会看到这样的目录结构:

目录/文件 说明
ArduCopter/ 多旋翼飞控代码(我们主要关注这个)
ArduPlane/ 固定翼飞控代码
ArduRover/ 无人车/船代码
libraries/ 核心库,所有飞行器共用
Tools/ 调试工具、自动测试脚本
mk/ 编译系统(Makefile相关)

Linux开发环境搭建

我强烈建议你在Ubuntu 20.04或22.04上开发。Windows虽然也能用WSL,但我在项目中遇到过USB设备映射的问题,折腾起来挺烦的。

环境搭建其实就三步:

  1. 安装依赖包
  2. 配置工具链
  3. 验证环境

ArduPilot官方提供了一个一键安装脚本,但我不建议你直接用。为什么?因为那个脚本会装很多你可能用不到的包。我个人习惯手动安装,这样心里有数。

# 更新系统
sudo apt update
sudo apt upgrade -y

# 安装基础编译工具
sudo apt install -y git build-essential g++ python3 python3-pip

# 安装ARM交叉编译工具链(编译Pixhawk固件用)
sudo apt install -y gcc-arm-none-eabi gdb-arm-none-eabi

# 安装SITL仿真需要的库
sudo apt install -y libtool libltdl-dev libsdl2-dev libsdl2-image-dev

# Python依赖
pip3 install --user pyserial empy mavproxy

小技巧:装完交叉编译工具链后,运行 arm-none-eabi-gcc --version 检查版本。如果显示"command not found",说明环境变量没配好。我一般直接加到 ~/.bashrc 里:export PATH=$PATH:/usr/bin

编译第一个固件

环境搭好了,咱们来编译一个固件试试手。以Pixhawk 1为例:

# 进入ArduCopter目录
cd ardupilot/ArduCopter

# 配置编译目标
./waf configure --board=Pixhawk1

# 开始编译(-j4表示用4个线程并行编译)
./waf build -j4

第一次编译会比较慢,大概5-10分钟。趁这个时间,我跟你聊聊编译系统。ArduPilot用的是Waf构建系统,不是传统的Makefile。Waf的好处是跨平台、支持并行编译,而且配置起来更灵活。

编译完成后,你会看到这样的输出:

Waf: Entering directory `/home/user/ardupilot/build/Pixhawk1'
[ 98/128] Compiling libraries/AP_Motors/AP_MotorsMatrix.cpp
[ 99/128] Compiling ArduCopter/system.cpp
[100/128] Linking build/Pixhawk1/bin/arducopter.elf
Build successful

生成的固件在 build/Pixhawk1/bin/ 目录下,主要有两个文件:

  • arducopter.elf:带调试信息的固件(用于GDB调试)
  • arducopter.hex:可以直接烧录的固件

避坑指南:我曾经在编译时遇到"undefined reference"错误,折腾了半天才发现是子模块没更新。如果你也遇到类似问题,试试 git submodule update --init --recursive,然后重新编译。

知识体系总览

下面这张图帮你理清本章的知识脉络:

ArduPilot概述与环境搭建 ArduPilot简介 开源自动驾驶软件栈 三层架构:HAL/核心库/模式层 支持多旋翼/固定翼/无人车 源码获取 git clone --recursive 子模块管理 目录结构:ArduCopter/libraries等 Linux环境搭建 Ubuntu 20.04/22.04 安装依赖包 ARM交叉编译工具链 编译第一个固件 ./waf configure --board=Pixhawk1 ./waf build -j4 生成 .elf 和 .hex 文件 常见问题与避坑 子模块未更新导致编译失败 工具链版本不匹配 USB设备映射问题(WSL)

这张图把咱们今天讲的内容串起来了。从ArduPilot的整体架构,到源码获取,再到环境搭建和编译,每一步都是后续开发的基础。你想想看,如果连固件都编译不过,后面怎么改代码?

我的建议:第一次编译成功后,别急着关终端。试试改一行代码再编译一次,感受一下增量编译的速度。比如在 ArduCopter/system.cpp 里加个打印语句,然后重新编译——你会发现第二次快得多,因为Waf只重新编译改动的文件。

好了,第一课就到这里。环境搭好了,源码也编译通过了,接下来你就可以开始真正接触飞控模式的代码了。记住,动手是最好的学习方式——别光看,自己敲一遍。


公众号:蓝海资料掘金营,微信deep3321