一、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设备映射的问题,折腾起来挺烦的。
环境搭建其实就三步:
- 安装依赖包
- 配置工具链
- 验证环境
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的整体架构,到源码获取,再到环境搭建和编译,每一步都是后续开发的基础。你想想看,如果连固件都编译不过,后面怎么改代码?
我的建议:第一次编译成功后,别急着关终端。试试改一行代码再编译一次,感受一下增量编译的速度。比如在 ArduCopter/system.cpp 里加个打印语句,然后重新编译——你会发现第二次快得多,因为Waf只重新编译改动的文件。
好了,第一课就到这里。环境搭好了,源码也编译通过了,接下来你就可以开始真正接触飞控模式的代码了。记住,动手是最好的学习方式——别光看,自己敲一遍。
公众号:蓝海资料掘金营,微信deep3321