3. 源码获取与目录结构:从git clone到理解ArduPilot的骨架

好,咱们正式开始动手了。这一章,我带你做两件事:第一,把ArduPilot的源码拉到本地;第二,把它的顶层目录扒开看看,搞清楚每个文件夹是干嘛的。

你想想看,一个几十万行代码的项目,如果连目录结构都不清楚,后面编译、调试、改代码,那真是寸步难行。我刚开始接触ArduPilot时,就犯过这个错——直接一头扎进某个文件夹,结果改了半天发现改错了地方。嗯,咱们别走弯路。

3.1 使用git clone获取源码

获取源码的方式很简单,但有几个细节我建议你注意一下。

首先,打开终端,执行:

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

这一步会下载整个仓库,大概1-2GB。网速慢的话,可能需要十几分钟。我个人习惯在clone之前先看一眼网络状况,别等到一半断了重来。

小技巧: 如果你只需要某个特定版本(比如Copter-4.5),可以加 --branch 参数:
git clone --branch Copter-4.5 https://github.com/ArduPilot/ardupilot.git
这样下载量会小很多,而且省去后面切分支的步骤。

下载完成后,别忘了更新子模块:

git submodule update --init --recursive

这一步很关键。ArduPilot依赖了很多第三方库(比如mavlink、uavcan),这些库是以子模块形式管理的。如果不更新,编译时会报一堆找不到头文件的错误。我曾经在项目里因为忘了这步,排查了半小时才发现是子模块没拉下来……

注意: 如果你在国内,子模块下载可能会很慢。建议配置git代理,或者使用镜像源。具体方法网上有,这里不展开了。

3.2 顶层目录结构总览

好,源码到手了。现在咱们用 ls -la 看看顶层目录:

ardupilot/
├── libraries/        # 核心库,所有飞控共用的代码
├── ArduCopter/       # 多旋翼飞控
├── ArduPlane/        # 固定翼飞控
├── ArduRover/        # 地面车辆/船
├── ArduSub/          # 水下机器人
├── Tools/            # 工具脚本、调试工具
├── mk/               # 编译系统(Makefile相关)
├── modules/          # 第三方模块(子模块)
├── docs/             # 文档
├── cmake/            # CMake构建配置
├── .github/          # CI/CD配置
└── ...

这个结构其实很清晰。说白了,ArduPilot是一个「多平台飞控框架」,每个飞行器类型是一个独立的应用程序,但它们共享同一套底层库。

核心思想: libraries 是「发动机」,ArduCopter/ArduPlane 等是「不同车型」。你改发动机,所有车型都受影响;你改车型,只影响那一类。

3.3 重点目录详解

3.3.1 libraries/ —— 飞控的「心脏」

这个目录是ArduPilot的精髓所在。里面包含了所有与硬件无关的算法、驱动、数学工具等。我随便列几个重要的子目录:

子目录 功能 我的经验
AP_Math/ 数学库:向量、矩阵、四元数、滤波器 做姿态解算时,这里是最常光顾的地方
AP_InertialSensor/ IMU驱动:加速度计、陀螺仪 换传感器时,主要改这里
AP_GPS/ GPS驱动:UBlox、NMEA等协议 GPS丢星问题,排查这里最有效
AP_Motors/ 电机混控:四轴、六轴、八轴等 改机架类型时,必须看这里
AP_NavEKF/ 扩展卡尔曼滤波器(EKF) 定位不准?调EKF参数,但别轻易改代码
GCS_MAVLink/ 地面站通信协议 调试时,这里可以加自定义消息

你可能会问:「这么多库,我该从哪看起?」我的建议是:先看 AP_MathAP_InertialSensor。因为姿态估计是所有飞控的基础,搞懂了这两个,其他库的逻辑就顺了。

3.3.2 ArduCopter/ —— 多旋翼的「大脑」

这个目录是多旋翼飞控的主程序。里面最重要的文件是:

  • ArduCopter.cpp —— 主循环,每秒跑400次(4kHz)
  • system.cpp —— 系统初始化、参数加载
  • mode_*.cpp —— 各种飞行模式(定高、悬停、返航等)
  • commands.cpp —— 任务指令处理

我个人习惯,调试一个新功能时,先看 mode_loiter.cpp(悬停模式)。因为悬停模式逻辑相对简单,而且包含了位置控制、速度控制、姿态控制三层结构,是理解整个飞控的绝佳入口。

避坑指南: 我曾经在改返航模式时,直接改了 mode_rtl.cpp,结果发现返航逻辑还依赖 commands.cpp 里的任务队列。所以,改代码前,先看看这个文件引用了哪些其他文件。

3.3.3 Tools/ —— 调试者的「瑞士军刀」

这个目录容易被忽略,但实际非常有用。里面包含:

  • autotest/ —— 自动化测试脚本(SITL仿真测试)
  • scripts/ —— 各种辅助脚本(日志分析、参数转换等)
  • ardupilotw.py —— Windows下的编译辅助工具
  • LogAnalyzer/ —— 飞行日志分析工具

我特别推荐 autotest 目录。你可以在没有硬件的情况下,用SITL(软件在环仿真)跑整个飞控。我每次改完代码,都会先跑一遍 autotest 里的测试用例,确保没把基础功能搞坏。

3.3.4 其他目录

  • modules/:存放第三方库,比如mavlink协议栈、uavcan驱动。一般不需要动,但如果你要改通信协议,这里就是战场。
  • mk/:Makefile构建系统。说实话,现在新项目都用CMake了,但ArduPilot还保留着传统的Makefile体系。你只需要知道 make 命令怎么用就行,不用深究。
  • docs/:官方文档。内容比较全,但更新速度跟不上代码。我一般把它当参考,具体实现还是看代码本身。

3.4 知识体系结构图

为了让你更直观地理解这些目录之间的关系,我画了一张图:

ArduPilot 源码目录结构关系图 应用程序层(Application Layer) ArduCopter ArduPlane ArduRover ArduSub 核心库层(Libraries Layer) AP_Math AP_InertialSensor AP_GPS AP_Motors AP_NavEKF GCS_MAVLink AP_Compass AP_Baro AP_RangeFinder ...更多 硬件抽象层(HAL Layer) HAL_ChibiOS HAL_Linux HAL_SITL HAL_ESP32 工具层 Tools/ autotest scripts LogAnalyzer mk/ cmake/ modules/ 应用程序 核心库 硬件抽象层 工具/构建

从这张图你可以看到,ArduPilot的架构是分层的。上层(应用程序)调用中层(核心库),中层调用底层(硬件抽象层)。工具层则贯穿始终,为开发和调试提供支持。

3.5 本章小结

嗯,这一章的内容就这些。总结一下:

  • git clone 获取源码,别忘了 submodule update
  • libraries/ 是核心库,所有飞控的基础
  • ArduCopter/ 等是具体应用,每个文件夹对应一种飞行器
  • Tools/ 是调试利器,特别是 autotest
  • 整个架构是分层的,理解这个层次关系,后面改代码才不会迷路

下一章,咱们就要开始配置编译环境了。到时候我会手把手带你装好工具链,跑通第一个编译。别急,先把目录结构记牢,后面会轻松很多。


公众号:蓝海资料掘金营,微信deep3321