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
注意: 如果你用的是 Ubuntu 22.04 或更新版本,脚本可能会报 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 本章知识体系

为了让你对整个流程有个全局印象,我画了一张图。你可以把它当作一个检查清单,每完成一步就打个勾。

ArduPilot 编译环境搭建流程 1. 获取源码 2. 安装依赖库 3. waf configure 4. waf build 5. 验证固件文件 提示:每一步完成后,建议用表格中的验证命令确认状态,避免问题累积到下一步

这张图把整个流程串起来了。你想想看,从源码到可烧录的固件,其实就这五步。每一步都有对应的命令和验证方法,只要按顺序来,基本不会出大问题。

4.6 小结

这一章我们完成了 ArduPilot 编译环境的搭建。核心要点就三个:

  • 源码获取:用 git clone 拉取,注意分支选择
  • 依赖安装:自动脚本 + 手动补装,交叉编译器是关键
  • waf 编译:configure 指定板卡,build 生成固件