3. 源码获取与编译:从GitHub克隆ArduPilot主仓库,配置编译环境,编译Copter固件,验证编译产物(.px4文件)

好,到了真正动手的环节了。前面两章我们把环境搭好、工具链装齐,现在终于可以拉代码、编译固件了。这一章我会带你走完整个流程:从GitHub上把ArduPilot源码拿下来,配置好编译环境,然后编译出Copter固件,最后验证那个.px4文件是不是对的。

说实话,我第一次编译ArduPilot的时候,踩了不少坑。那时候文档还没现在这么全,光一个依赖库装错版本就折腾了半天。嗯,现在好多了,但有些细节还是得注意。跟着我来,别跳步。

本章核心目标:从零开始,在本地获得一个可用的Copter固件(.px4文件),并验证其完整性。

源码获取与编译全流程 1. 克隆主仓库 2. 切换稳定分支 3. 更新子模块 4. 配置编译环境 5. 编译Copter固件 6. 验证.px4文件 整个流程大约需要15-30分钟,取决于网络和机器性能。第一次编译会慢一些。

3.1 从GitHub克隆ArduPilot主仓库

先打开终端,找个你习惯放代码的目录。我个人习惯在 ~/workspace 下面放所有项目,你随意,别放桌面就行。

克隆命令很简单:

cd ~/workspace
git clone https://github.com/ArduPilot/ardupilot.git
cd ardupilot

这里有个小细节——不要用SSH方式克隆,除非你配好了GitHub SSH Key。HTTPS方式最省事,输一次密码就行。我见过不少新手卡在这一步,明明配了Key但权限不对,折腾半天。

小技巧:如果你网络不好,可以加个 --depth=1 参数只克隆最新版本,省流量也省时间。不过后续更新子模块时可能要多跑一次 git fetch --unshallow。

3.2 切换分支与更新子模块

克隆下来后,默认在 master 分支。但说实话,master分支有时候不太稳定,我建议你切到最新的稳定版。写这篇文章时,稳定版是 Copter-4.5.x。

git checkout Copter-4.5.7

然后是最关键的一步——更新子模块。ArduPilot依赖很多第三方库,比如AP_Param、AP_Math这些,都是以子模块形式管理的。不更新子模块,编译必报错。

git submodule update --init --recursive

这个过程会下载所有依赖库,大概几百兆。我第一次跑的时候等了快十分钟,还以为卡死了。其实它在后台拉东西,耐心等就好。

注意:子模块更新失败是最常见的坑。如果你遇到网络超时,可以试试 git submodule update --init --recursive --depth=1,或者换个时间段再试。我曾经在下午三点怎么都拉不下来,换到晚上十点一次成功——你想想看,GitHub的CDN有时候就是这么玄学。

3.3 配置编译环境

子模块更新完后,需要安装一些Python依赖。ArduPilot的编译脚本依赖 future、pyserial 这些库。

pip install --user future pyserial
python Tools/environment_install/install-prereqs-ubuntu.py -y

这个脚本会自动检测你的系统,安装必要的工具链。如果你用的是Ubuntu 20.04或22.04,基本一路绿灯。但如果你跟我一样用Ubuntu 24.04,可能会遇到Python版本兼容问题——别慌,后面我会讲怎么处理。

装完之后,记得重新加载一下环境变量:

. ~/.profile

这一步很多人会忘,然后发现 arm-none-eabi-gcc 找不到。嗯,我也忘过。

3.4 编译Copter固件

环境配好了,终于可以编译了。ArduPilot的编译系统基于waf,用法很简洁。

先配置目标板型。以Pixhawk1为例:

./waf configure --board Pixhawk1

配置成功后,开始编译Copter:

./waf copter

第一次编译会下载工具链并编译所有依赖,大概需要10-20分钟。后面再编译就快多了,只编译改动的文件。

常用板型对照表:

板型名称 适用硬件 Flash大小 RAM大小
Pixhawk1 Pixhawk 1/2.4.x 1MB 256KB
Pixhawk4 Pixhawk 4 / FMUv5 2MB 512KB
CubeOrange Cube Orange / FMUv5 2MB 512KB
sitl 软件在环仿真 N/A N/A

编译过程中,你会看到终端刷刷地滚日志。如果一切正常,最后会显示 Build complete 或者类似信息。如果报错,别慌——90%的情况是子模块没更新全,或者Python依赖没装对。

3.5 验证编译产物(.px4文件)

编译成功后,固件文件在哪?在 build/Pixhawk1/bin/ 目录下。你会看到类似这样的文件:

ls -la build/Pixhawk1/bin/
# 输出示例:
# arducopter.apj
# arducopter.px4
# arducopter.hex

我们要验证的是 .px4 文件。这个文件是Pixhawk系列飞控的标准固件格式,包含了引导加载器和固件镜像。

怎么验证它是不是对的?我一般做三步检查:

  1. 检查文件大小:正常编译出来的.px4文件应该在500KB-1.5MB之间。如果只有几KB,那肯定有问题。
  2. 检查文件头:用 hexdump 或 xxd 看一眼文件头,应该能看到 PX4 或 APJ 魔数。
  3. 检查编译时间戳:用 stat 命令看文件修改时间,确认是你刚才编译的时间。
# 检查文件大小
ls -lh build/Pixhawk1/bin/arducopter.px4

# 检查文件头(前4个字节)
xxd -l 4 build/Pixhawk1/bin/arducopter.px4

# 检查编译时间戳
stat build/Pixhawk1/bin/arducopter.px4

我的经验:如果你编译的是SITL(软件在环仿真)版本,产物是 arducopter 可执行文件,不是.px4。SITL固件是给仿真环境用的,后面章节我们会专门讲。这里先记住:实物飞控用.px4,仿真用SITL可执行文件。

3.6 常见编译问题与避坑指南

编译过程中可能会遇到一些问题,我把最常见的几个列出来:

错误现象 原因 解决方法
fatal error: AP_Common/AP_Common.h: No such file or directory 子模块未更新 运行 git submodule update --init --recursive
arm-none-eabi-gcc: command not found 工具链未安装或环境变量未加载 运行 . ~/.profile 或重新安装工具链
Python module future is not installed Python依赖缺失 pip install --user future pyserial
configure failed 且日志中有 No such file or directory 系统缺少某些库 重新运行 install-prereqs-ubuntu.py

我曾经在编译时遇到一个特别诡异的问题——编译到一半报 internal compiler error。查了半天,发现是内存不够了。虚拟机只分了1GB内存,编译大型C++项目根本不够用。后来加到4GB,问题解决。所以如果你用虚拟机,记得给够资源。

重要提醒:不要用root用户编译!ArduPilot的编译脚本会检测当前用户,如果检测到root会直接退出。用普通用户,但确保该用户有sudo权限(安装依赖时需要)。

3.7 本章小结

到这里,你应该已经拿到了一个可以用的Copter固件。总结一下我们做了什么:

  • 从GitHub克隆了ArduPilot主仓库
  • 切换到了稳定分支并更新了子模块
  • 配置了编译环境(工具链+Python依赖)
  • 编译了Copter固件(以Pixhawk1为例)
  • 验证了.px4文件的完整性和正确性

这个.px4文件就是后面章节要烧录到飞控里的固件。当然,在仿真联调场景下,我们更多是用SITL模式,但先学会编译实物固件,能帮你理解整个编译流程。后面讲SITL时,你会发现流程几乎一样,只是板型参数从 Pixhawk1 换成 sitl 而已。

好,固件有了,下一件大事就是——怎么把它烧到飞控里?或者怎么用SITL跑起来?别急,我们一步步来。