3. ArduPilot源码编译与烧录:从GitHub拉取代码、配置编译环境(waf)、编译Copter固件、通过QGC烧录到飞控板

这一章,我们正式进入动手环节。说实话,很多初学者卡在编译这一步,不是因为代码难,而是环境没配好。我见过太多人花了一整天装依赖,最后编译报错,心态直接崩了。

别担心,跟着我的节奏来。我会把每一步拆开讲,包括那些文档里没写的坑。

3.1 从GitHub拉取ArduPilot源码

首先,你得把代码从GitHub上拽下来。我个人习惯用SSH方式,省得每次输密码。

准备工作:确保你已经安装了Git,并且配置好了SSH Key。如果还没配,去GitHub官方文档花5分钟搞定。
# 克隆主仓库(完整版,包含所有飞控类型)
git clone git@github.com:ArduPilot/ardupilot.git

# 进入目录
cd ardupilot

# 查看所有分支
git branch -a

# 切换到稳定版本(我建议用最新稳定版)
git checkout Copter-4.5.7

为什么要切分支?因为master分支是开发版,可能今天能编译,明天就挂了。我在项目里吃过这个亏——早上拉的最新代码,下午编译就报错,查了半天发现是上游刚合入了一个有问题的commit。

所以,生产环境请用稳定分支。学习阶段也一样。

3.2 配置编译环境(waf构建系统)

ArduPilot用的是waf构建系统,不是make,也不是cmake。我第一次接触waf时也觉得别扭,但用顺手后发现,它比makefile清晰多了。

3.2.1 安装依赖

不同的操作系统,依赖包不一样。我以Ubuntu 22.04为例,这也是官方推荐的环境。

# 更新包列表
sudo apt update

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

# 安装waf需要的Python模块
sudo pip3 install future lxml pyserial

# 安装ARM交叉编译工具链(针对Pixhawk等STM32飞控)
sudo apt install -y gcc-arm-none-eabi

# 安装SITL仿真需要的库
sudo apt install -y libtool libtool-bin autoconf automake cmake
注意:不要用系统自带的Python 2.7,ArduPilot已经全面迁移到Python 3。如果你还在用Python 2,编译时会报"ModuleNotFoundError"。

3.2.2 初始化waf

依赖装完后,需要初始化waf。这一步很多人会忘,然后直接编译,结果报错说找不到waf。

# 进入ardupilot根目录
cd ardupilot

# 初始化waf(只需要执行一次)
./waf configure

# 如果一切正常,你会看到类似输出:
# Setting top to                           : /home/user/ardupilot 
# Setting out to                           : /home/user/ardupilot/build 
# Checking for 'gcc' (C compiler)          : /usr/bin/gcc 
# Checking for 'g++' (C++ compiler)        : /usr/bin/g++ 
# ... 
# Build configured successfully

看到"Build configured successfully"就对了。如果报错,99%是依赖没装全。别慌,看报错信息,缺什么装什么。

3.3 编译Copter固件

环境配好了,开始编译。这里要指定飞控板型号和飞控类型。

3.3.1 查看支持的板子

# 列出所有支持的板子
./waf list_boards

# 输出很长,我只截取常用的:
# fmuv2  - Pixhawk 1 (STM32F427)
# fmuv3  - Pixhawk 1 2MB版
# fmuv5  - Pixhawk 4 (STM32F765)
# CubeBlack - Cube Orange/Cube Black
# SITL   - 软件在环仿真

我用得最多的是fmuv3和CubeBlack。如果你用的是Pixhawk 1,选fmuv2;如果是Pixhawk 4,选fmuv5。

3.3.2 执行编译

# 编译Copter固件,目标板为fmuv3
./waf configure --board fmuv3
./waf copter

# 编译过程大概5-15分钟,取决于你的电脑性能
# 编译完成后,固件在 build/fmuv3/bin/ 目录下
# 文件名类似:arducopter.apj
核心知识点:
  • ./waf configure --board <板型>:配置目标板
  • ./waf copter:编译Copter固件
  • 其他飞控类型:./waf plane(固定翼)、./waf rover(地面车)、./waf sub(水下)

编译时,waf会自动检测CPU核心数,并行编译。如果你电脑比较老,可以手动限制并行数:

# 限制为4个并行任务
./waf copter -j4

3.3.3 常见编译错误及解决

错误信息 原因 解决方法
fatal error: mavlink.h: No such file or directory 子模块未更新 git submodule update --init --recursive
arm-none-eabi-gcc: not found 交叉编译工具链未安装 sudo apt install gcc-arm-none-eabi
Python module 'future' not found Python依赖缺失 pip3 install future
configure failed waf配置阶段出错 检查终端输出,定位具体缺失的库

我曾经遇到过一个诡异的错误——编译到一半报"internal compiler error"。折腾了半天,最后发现是内存不够。如果你也遇到类似情况,试试关掉浏览器,或者加个swap分区。

3.4 通过QGC烧录到飞控板

固件编译好了,怎么烧进去?QGroundControl(QGC)是最简单的方式。

3.4.1 准备工作

  • 飞控板通过USB连接到电脑
  • 安装好驱动(Windows需要装驱动,Linux/macOS一般免驱)
  • 下载并安装QGC(从官网下载最新版)

3.4.2 烧录步骤

  1. 打开QGC,点击左上角"Q"图标 → 选择"Vehicle Setup"
  2. 在左侧菜单选择"Firmware"
  3. 点击"Advanced Settings"复选框
  4. 选择"Custom firmware file..."
  5. 找到刚才编译好的 arducopter.apj 文件
  6. QGC会自动识别飞控板,点击"OK"开始烧录
  7. 等待进度条走完,飞控板会自动重启
小技巧:如果QGC识别不到飞控板,试试按住飞控板上的BOOT按钮再插USB。有些板子(如Pixhawk 1)需要进入DFU模式才能烧录。

3.4.3 验证烧录是否成功

烧录完成后,在QGC的"Summary"页面查看固件版本。如果显示的是你编译的版本号(比如4.5.7),说明成功了。

你也可以通过MAVLink终端确认:

# 连接飞控后,在终端输入
param show VERSION

# 输出示例:
# VERSION: 4.5.7 (c5a3f2b1)

3.5 本章知识体系

下面这张图,把整个流程串起来了。你对照着看,每一步都别跳。

ArduPilot源码编译与烧录流程 ArduPilot 源码编译与烧录流程 1. 拉取源码 git clone + checkout 2. 配置编译环境 安装依赖 + waf configure 3. 编译固件 ./waf copter 4. 烧录到飞控 QGC → Custom firmware 5. 验证固件 检查版本号 / 参数 💡 关键提醒 • 每次切换分支后,必须重新执行 ./waf configure • 编译前先 git submodule update,避免头文件缺失 • 烧录前确认飞控板型号与编译目标一致

3.6 避坑指南

最后,分享几个我踩过的坑,你遇到了能少走弯路。

  • 子模块没更新:拉完代码第一件事就是 git submodule update --init --recursive。我有一回忘了这步,编译报错说找不到mavlink.h,查了半小时才发现是子模块没拉下来。
  • Python版本不对:系统自带的Python 2.7和Python 3混装时,pip可能指向Python 2。用 pip3 而不是 pip,或者直接用 python3 -m pip install。
  • 磁盘空间不足:编译一次大概占2-3GB空间。如果你用虚拟机,记得给磁盘留够空间。我见过有人编译到99%报错,一看磁盘满了,白等半小时。
  • USB线质量问题:烧录时断连,90%是USB线的问题。换一根带磁环的线,别用那种几块钱的充电线。

嗯,这一章的内容就这些。你按照流程走一遍,应该能顺利编译出第一个固件。如果卡住了,回头看看流程图,确认每一步都做对了。