4、ArduPilot固件编译环境搭建:源码获取、依赖安装与首次编译
好,咱们进入正题。上一章我们把 PX4 的环境搞定了,这一章轮到 ArduPilot。说实话,ArduPilot 的编译环境比 PX4 要「古典」一些——它用的是自家的 waf 编译系统,而不是 CMake。我第一次接触的时候也觉得有点别扭,但用顺手之后会发现,waf 在嵌入式交叉编译的场景下其实非常灵活。
别急,咱们一步步来。从源码获取,到依赖库安装,再到第一次跑编译,我会把我在项目中踩过的坑都告诉你。
4.1 获取 ArduPilot 源码
源码托管在 GitHub 上,和 PX4 一样,我们直接用 git clone 拉下来。我个人习惯把飞控源码统一放在 ~/src 目录下,方便管理。
cd ~/src
git clone https://github.com/ArduPilot/ardupilot.git
cd ardupilot
这里有个小细节——ArduPilot 的代码库非常大,因为它包含了所有载具类型(Copter、Plane、Rover、Sub 等)的固件。如果你只想下载最新稳定分支,可以加个 --depth=1 参数,只拉取最新一次提交,能省不少时间。
git bisect 定位问题。但如果只是编译测试,--depth=1 完全够用。
拉完之后,记得切换到你想用的分支。比如我们教程基于最新的稳定版,我会用 Copter-4.5.x 分支:
git checkout Copter-4.5.7
嗯,这里要注意:分支名会随版本更新变化,建议去 ArduPilot 官网确认当前最新稳定版。
4.2 安装依赖库
ArduPilot 的依赖管理比 PX4 稍微「手工」一点。它提供了一个自动化脚本,但我在 Ubuntu 22.04 上跑的时候发现有些包会漏装。所以我建议你按下面的步骤来,稳一点。
4.2.1 基础工具链
先装编译器和一些基础工具:
sudo apt update
sudo apt install git build-essential python3 python3-pip python3-dev
ArduPilot 的编译依赖 Python 3,而且对 pip 包的版本比较敏感。我曾经因为 future 库版本不对,卡在编译报错上折腾了半天。
4.2.2 运行自动安装脚本
ArduPilot 官方提供了一个 install-prereqs-ubuntu.sh 脚本,位于 Tools/environment_install 目录下。运行它:
cd ~/src/ardupilot
Tools/environment_install/install-prereqs-ubuntu.sh -y
这个脚本会安装 ARM 交叉编译器、MAVLink 头文件、以及一堆 Python 依赖包。跑完之后,记得重新加载一下 ~/.profile,让环境变量生效:
source ~/.profile
g++-arm-linux-gnueabihf 安装失败。这是因为新版仓库里交叉编译器包名变了。解决办法是手动安装:sudo apt install g++-arm-linux-gnueabihf。
4.2.3 手动补装关键依赖
跑完脚本后,我建议你再手动确认一下这几个关键组件:
| 组件 | 用途 | 验证命令 |
|---|---|---|
| ARM GCC 交叉编译器 | 编译 Pixhawk 等 ARM 目标固件 | arm-none-eabi-gcc --version |
| Python3 + pip | 运行 waf 编译系统 | python3 --version |
| MAVLink | 生成 MAVLink 协议头文件 | python3 -c "import mavlink" |
| future 库 | Python 2/3 兼容层 | pip3 show future |
如果 arm-none-eabi-gcc 找不到,说明交叉编译器没装好。你可以从 ARM 官网下载,但我更推荐直接用 apt 装:
sudo apt install gcc-arm-none-eabi
4.3 waf 编译系统入门
好,依赖装完了,咱们来聊聊 waf。ArduPilot 选择 waf 而不是 CMake,说白了是因为 waf 对嵌入式交叉编译的支持更原生。你不需要写复杂的 toolchain 文件,waf 自己就能搞定。
waf 的核心命令就几个,我列出来你感受一下:
./waf configure—— 配置编译目标(板卡类型、调试选项等)./waf build—— 执行编译./waf clean—— 清理编译产物./waf list_boards—— 列出所有支持的板卡
我个人觉得 waf 最爽的一点是:你不需要手动创建 build 目录,它自动管理。而且增量编译做得很好,改一行代码重新编译,通常只需要几秒钟。
4.3.1 配置编译目标
以 Pixhawk 1 为例,配置命令是:
./waf configure --board=Pixhawk1
这里 --board 参数指定了目标硬件。ArduPilot 支持几十种板卡,从 Pixhawk 系列到 Cube、Here、乃至 Linux 板子。你可以用 list_boards 查看完整列表。
--board 参数,结果 waf 默认用 Linux 本地编译,生成的是 x86 的可执行文件,烧到 Pixhawk 上当然跑不起来。所以每次配置前,先确认板卡名写对了。
4.3.2 执行编译
配置成功后,直接 build:
./waf build
第一次编译会比较慢,因为要生成 MAVLink 头文件、编译所有模块。我的机器(i7-12700H)大概需要 5-8 分钟。你可以趁这个时间去泡杯咖啡。
编译完成后,固件文件会生成在 build/<board>/bin 目录下。比如 Pixhawk1 的固件是 arducopter.apj。
4.4 首次编译测试:验证环境
理论说完了,咱们实操一把。我建议你第一次编译用 fmuv3 板卡(兼容 Pixhawk 1),因为这是最常用的目标之一,社区支持最好。
4.4.1 完整编译流程
cd ~/src/ardupilot
./waf configure --board=fmuv3
./waf build
如果一切顺利,你会看到类似这样的输出:
Waf: Entering directory `/home/user/src/ardupilot/build/fmuv3'
[ 1/512] Compiling libraries/AP_Common/AP_Common.cpp
[ 2/512] Compiling libraries/AP_Math/AP_Math.cpp
...
[512/512] Linking build/fmuv3/bin/arducopter
Build complete.
看到 Build complete 就说明成功了。这时候去 build/fmuv3/bin 目录下,你应该能看到 arducopter.apj 文件。
4.4.2 常见编译错误及对策
第一次编译很少一帆风顺。我把最常见的几个问题列出来,你遇到了直接对照解决:
| 错误现象 | 可能原因 | 解决办法 |
|---|---|---|
Python.h: No such file or directory |
缺少 Python 开发头文件 | sudo apt install python3-dev |
arm-none-eabi-gcc: command not found |
交叉编译器未安装 | sudo apt install gcc-arm-none-eabi |
ModuleNotFoundError: No module named 'future' |
Python future 库缺失 | pip3 install future |
waf: error: no such option: --board |
waf 版本不对或未在 ardupilot 根目录执行 | 确认在 ~/src/ardupilot 目录下执行 |
build/<board>/config.log 这个文件。里面记录了详细的配置日志,90% 的问题都能在那里找到线索。
4.5 本章知识体系
为了让你对整个流程有个全局印象,我画了一张图。你可以把它当作一个检查清单,每完成一步就打个勾。
这张图把整个流程串起来了。你想想看,从源码到可烧录的固件,其实就这五步。每一步都有对应的命令和验证方法,只要按顺序来,基本不会出大问题。
4.6 小结
这一章我们完成了 ArduPilot 编译环境的搭建。核心要点就三个:
- 源码获取:用 git clone 拉取,注意分支选择
- 依赖安装:自动脚本 + 手动补装,交叉编译器是关键
- waf 编译:configure 指定板卡,build 生成固件