3. ArduPilot源码结构与编译系统

ArduPilot 是一个跨平台、跨机型的飞控固件工程,它同时支持多旋翼(Copter)、固定翼(Plane)、无人车(Rover)、潜艇(Sub)、天线跟踪器(AntennaTracker)等多种载具。理解它的源码目录布局与 waf 编译系统,是后续修改代码、添加自定义功能、编译固件并运行 SITL 仿真的前提。本节从仓库结构入手,逐步过渡到板级配置、固件编译与 SITL 启动的完整链路。

一、代码仓库目录布局

克隆 ArduPilot 主仓库后,顶层目录大致分为三类:载具应用目录、共享库目录和构建/工具目录。载具应用目录以 ArduCopter/、ArduPlane/、APMrover2/(Rover)、ArduSub/、AntennaTracker/ 命名,每个目录下都有各自的 main 入口、飞行模式实现、参数定义(Parameters.cpp)和 wscript 构建脚本。共享库集中在 libraries/ 下,例如 AP_InertialSensor(IMU 驱动)、AP_GPS、AP_Baro、AP_Motors、AC_AttitudeControl、AP_Scheduler 等,它们被所有载具复用,是 ArduPilot 模块化设计的核心。

构建与工具目录包括:Tools/(含 autotest/、scripts/、AP_Periph/ 等)、modules/(通过 git submodule 引入的 ChibiOS、mavlink、DroneCAN 等第三方组件)、libraries/AP_HAL_ChibiOS/(ChibiOS 硬件抽象层)、libraries/AP_HAL_Linux/(Linux/SITL 硬件抽象层)。waf 与 wscript 位于顶层,是整个构建系统的入口。

ArduPilot 仓库结构与构建链路 顶层目录 载具应用 ArduCopter/ ArduPlane/ APMrover2/ 共享库 libraries/ AP_* / AC_* HAL 硬件抽象 AP_HAL_ChibiOS/ AP_HAL_Linux/ 第三方模块 modules/ ChibiOS mavlink 构建工具 waf / wscript Tools/ 板级配置文件(libraries/AP_HAL_ChibiOS/hwdef/) Pixhawk6X/hwdef.dat MCU/引脚/外设定义 CubeOrange/hwdef.dat IMU/GPS/串口映射 SITL/hwdef.dat 仿真环境虚拟外设 defaults.parm 默认参数集 waf 编译系统 ./waf configure --board Pixhawk6X → ./waf copter → build/Pixhawk6X/bin/arducopter.apj SITL 仿真启动 Tools/autotest/sim_vehicle.py -v ArduCopter -f quad --console --map

二、waf 编译系统

ArduPilot 早期使用 make,现在统一使用 waf。waf 是一个基于 Python 的构建工具,通过读取各目录下的 wscript 文件来收集源文件、依赖关系和编译选项。顶层 wscript 负责解析 --board 参数、加载对应板级配置、决定目标载具类型,并调用各子目录的 wscript 完成编译。

典型编译流程分两步:先 configure,再 build。configure 阶段会检查工具链、生成 build/<board>/ 目录、写入 config.h 等头文件。build 阶段则根据目标载具(copter/plane/rover)编译对应的 ArduCopter/ 等目录,并链接共享库。常用命令如下:

# 配置 Pixhawk6X 板级目标
./waf configure --board Pixhawk6X

# 编译 Copter 固件
./waf copter

# 编译 Plane 固件
./waf plane

# 编译 Rover 固件
./waf rover

# 编译 SITL 仿真固件(默认使用 Linux HAL)
./waf configure --board sitl
./waf copter

编译产物位于 build/<board>/bin/ 下,例如 arducopter.apj、arduplane.apj、ardurover.apj。其中 .apj 是 ArduPilot 的固件封装格式,包含校验信息,可直接通过 Mission Planner 或 uploader.py 烧录到飞控。

三、板级配置文件

板级配置位于 libraries/AP_HAL_ChibiOS/hwdef/<board>/ 下,核心文件是 hwdef.dat。它用声明式语法描述 MCU 型号、时钟、引脚复用、外设总线(SPI/I2C/UART/CAN)、IMU/GPS/气压计等传感器连接关系。例如 Pixhawk6X 的 hwdef.dat 中会定义 MCU STM32H743、APJ_BOARD_ID、FLASH_SIZE_KB,以及 IMU Invensense SPI:icm42688 等条目。编译时 waf 会解析这些定义,生成对应的 HAL 初始化代码。

除 hwdef.dat 外,同目录下还可能有 defaults.parm(该板默认参数)、hwdef-bl.dat(Bootloader 配置)、scripts/(板级脚本)。修改板级配置后必须重新执行 ./waf configure --board <board>,否则不会生效。

四、编译 Copter、Plane、Rover 固件

编译不同载具只需切换 waf 目标。以 Pixhawk6X 为例:

./waf configure --board Pixhawk6X
./waf copter    # 生成 build/Pixhawk6X/bin/arducopter.apj
./waf plane     # 生成 build/Pixhawk6X/bin/arduplane.apj
./waf rover     # 生成 build/Pixhawk6X/bin/ardurover.apj

若需同时编译多个载具,可依次执行,waf 会复用已编译的共享库对象,第二次编译通常更快。编译完成后可用 ls build/Pixhawk6X/bin/ 确认产物。若出现链接错误,优先检查 modules/ 子模块是否完整(git submodule update --init --recursive),以及工具链版本是否匹配。

五、使用 sim_vehicle.py 启动 SITL 仿真

SITL(Software In The Loop)让固件在 PC 上以普通进程运行,配合 sim_vehicle.py 脚本可快速启动仿真。该脚本位于 Tools/autotest/,它会自动完成:编译 SITL 固件、启动仿真进程、连接 MAVProxy 地面站、加载默认参数。常用命令:

# 启动 Copter 四旋翼 SITL,带控制台和地图
cd Tools/autotest
./sim_vehicle.py -v ArduCopter -f quad --console --map

# 启动 Plane 固定翼 SITL
./sim_vehicle.py -v ArduPlane -f plane --console --map

# 启动 Rover 无人车 SITL
./sim_vehicle.py -v Rover -f rover --console --map

参数说明:-v 指定载具类型,-f 指定机型帧(quad、plane、rover 等),--console 打开 MAVProxy 控制台,--map 打开地图窗口。启动成功后,控制台会显示 APM: ArduCopter V4.x.x 等版本信息,并进入 STABILIZE 模式。此时可输入 mode guided、arm throttle、takeoff 10 等命令测试飞行逻辑。若需自定义参数,可在启动时加 --add-param-file=my.parm,或直接在控制台用 param set 修改。

SITL 默认使用 build/sitl/bin/arducopter 等可执行文件。若修改了源码,需先 ./waf copter 重新编译,再运行 sim_vehicle.py,否则仿真仍使用旧固件。