3、ArduPilot源码编译:从GitHub克隆到固件验证
好,咱们进入正题。上一章我们把仿真环境搭好了,但光有环境没有灵魂——ArduPilot源码才是核心。这一章我就带你走一遍完整的编译流程:从GitHub拉代码、配环境、编译Copter固件,最后验证结果。
说实话,我第一次编译ArduPilot时踩了不少坑。那时候文档没现在全,光依赖问题就折腾了两天。你跟着我走,这些弯路我帮你绕过去。
3.1 从GitHub克隆ArduPilot
先找个干净的工作目录。我个人习惯在 ~/workspace 下放所有项目,你随意,但路径里别带中文和空格。
cd ~/workspace
git clone https://github.com/ArduPilot/ardupilot.git
cd ardupilot
这里有个细节——克隆的是完整仓库,包含所有飞控类型(Copter、Plane、Rover等)和全部历史记录。如果你只想看最新代码,可以加 --depth=1 参数做浅克隆,省时间也省硬盘。
git pull 更新。浅克隆虽然快,但切分支、查历史时容易受限。
克隆完后,记得初始化子模块。ArduPilot依赖很多第三方库(比如MAVLink、DroneKit),这些是以子模块形式管理的。
git submodule update --init --recursive
这一步别跳过。我曾经遇到过编译到一半报错,查了半天发现是子模块没拉全。嗯,血的教训。
3.2 配置编译环境
ArduPilot支持多种编译工具链。咱们用最主流的——waf 构建系统 + arm-none-eabi-gcc 交叉编译器。为什么选这个?因为Pixhawk系列飞控的STM32芯片全靠它。
3.2.1 安装依赖包
Ubuntu 22.04下,一行命令搞定大部分依赖:
sudo apt update
sudo apt install -y git build-essential g++ python3-pip \
python3-dev python3-numpy python3-matplotlib \
libtool autoconf automake pkg-config \
libusb-1.0-0-dev libxml2-dev libxslt1-dev \
libssl-dev libffi-dev
然后装Python工具链:
pip3 install --user future pyserial empy pexpect
sudo pip3 装,容易搞乱系统Python。加 --user 装到用户目录下,干净又安全。
3.2.2 安装交叉编译器
ArduPilot官方推荐用 gcc-arm-none-eabi-10.3-2021.10 版本。你可以从ARM官网下载,但我建议直接用脚本:
cd ~/workspace/ardupilot
Tools/environment_install/install-prereqs-ubuntu.sh -y
这个脚本会自动检测系统、装依赖、下编译器。跑完后重启终端或 source ~/.profile 让环境变量生效。
验证一下编译器是否装好:
arm-none-eabi-gcc --version
如果输出类似 arm-none-eabi-gcc (GNU Arm Embedded Toolchain 10.3-2021.10) 10.3.1 20210824,说明成了。
3.3 编译Copter固件
环境配好,咱们开始编译。ArduPilot用waf作为构建系统,和CMake不太一样,但逻辑更直白。
3.3.1 配置编译目标
先看看有哪些板子支持:
./waf list_boards
输出会很长,咱们关注几个常用的:
| 板子名称 | 对应硬件 | 适用场景 |
|---|---|---|
Pixhawk1 |
Pixhawk 1 / 2.4.8 | 入门调试、教学 |
CubeBlack |
CubePilot Cube Black | 工业级飞控 |
sitl |
软件在环仿真 | 无硬件调试 |
navio2 |
Raspberry Pi + Navio2 | 树莓派飞控 |
咱们先编译SITL版本——这样不用硬件也能跑,方便验证。
./waf configure --board sitl
配置成功后,会看到类似 Configuring for board sitl 的提示。
3.3.2 执行编译
配置完,直接开编:
./waf copter
第一次编译会比较慢,因为要编译整个Copter固件和所有库。我的机器大概要5-8分钟。你可以去泡杯咖啡。
编译过程中,终端会滚动输出编译信息。看到 Waf: Leaving directory 和 Build commands: 0 就表示成功了。
-j 参数指定并行任务数。比如4核CPU可以跑 ./waf copter -j4,速度能快一倍。但别超过CPU物理核心数,否则反而变慢。
3.4 验证编译结果
编译完,固件在 build/sitl/bin/ 目录下。咱们看看都有啥:
ls -lh build/sitl/bin/
你会看到 arducopter 这个可执行文件。这就是咱们编译出来的SITL固件。
验证它能不能跑:
./build/sitl/bin/arducopter --help
如果输出一堆启动参数说明,说明编译没问题。你也可以直接启动试试:
./build/sitl/bin/arducopter --model quad --speedup 1
看到类似 Starting SITL 和 Waiting for connection 的日志,恭喜你——固件跑起来了!
pkill arducopter 杀掉再试。
3.5 本章知识体系
下面这张图把整个编译流程串起来了,你对照着看会更清楚:
3.6 常见问题与避坑
编译过程中你可能会遇到一些问题。我把最常见的几个列出来:
- 子模块拉取失败:网络问题导致
git submodule update中断。重跑一次,或者用--depth=1只拉最新版本。 - 编译器版本不对:ArduPilot对GCC版本有要求。太新的版本可能不兼容,太老的版本不支持新特性。10.3版本最稳。
- Python包冲突:如果你同时用系统Python和Anaconda,容易搞混。建议在虚拟环境里操作。
- 磁盘空间不足:完整编译一次大概占2-3GB。注意你的
/home分区够不够。
arm-none-eabi-gcc: internal compiler error。查了半天发现是内存不够——虚拟机只给了2GB。加到4GB后一次通过。所以编译时尽量别开太多应用。