3. 源码获取与结构:PX4源码仓库、git clone与子模块更新、源码目录结构解析

好,咱们开始动手了。这一章我带你干两件事:第一,把PX4源码从GitHub上拉下来;第二,把它的目录结构摸清楚。说白了,就是先拿到武器,再知道武器库里都放了些什么。

很多新手上来就急着改代码,结果连源码目录都找不对,编译报错也不知道去哪看。我刚开始搞PX4的时候,就犯过这个错——git clone完直接make,然后看着满屏的error发呆。后来才发现,子模块没更新,工具链也没配好。嗯,咱们今天就把这些坑提前填上。

3.1 PX4源码仓库与分支选择

PX4的官方源码托管在GitHub上,仓库地址是:https://github.com/PX4/PX4-Autopilot。这个仓库包含了飞控固件的全部代码、板级支持包、编译脚本和文档。

仓库的分支策略其实挺清晰的。我个人习惯用稳定版分支做产品开发,用main分支跟踪最新特性。下面这张表帮你快速理解:

分支类型 命名示例 适用场景 稳定性
稳定版 v1.13.x, v1.14.x 产品开发、量产 高
预发布 release/v1.15 功能验证、测试 中
开发版 main 学习、贡献代码 低(可能随时变)
我的建议:如果你是第一次接触PX4,直接拉取最新的稳定版分支。比如当前稳定版是v1.14.x,就用这个。别追新,稳定压倒一切。

3.2 git clone与子模块更新

拿到源码的第一步,当然是git clone。但这里有个关键点——PX4依赖大量子模块(submodules),比如uORB消息定义、硬件抽象层、第三方库等。如果只拉主仓库,这些子模块是空的,编译必挂。

正确的操作流程是这样的:

  1. 克隆主仓库(带子模块初始化)
  2. 更新子模块(确保所有依赖到位)
  3. 检查子模块状态(确认没有遗漏)

具体命令如下:

# 方式一:一步到位(推荐)
git clone --recursive https://github.com/PX4/PX4-Autopilot.git

# 方式二:如果已经clone了主仓库
git clone https://github.com/PX4/PX4-Autopilot.git
cd PX4-Autopilot
git submodule update --init --recursive

# 检查子模块是否完整
git submodule status
注意:子模块更新这一步,在国内网络环境下经常超时。我曾经在客户现场演示时,git submodule update卡了半小时,场面一度很尴尬。建议你提前配好代理,或者用国内镜像源。

为什么会超时?因为PX4的子模块托管在多个不同的GitHub仓库里,每个都要单独拉取。网络不好的时候,一个子模块失败,整个更新就停了。解决办法有两个:

  • 设置git代理:git config --global http.proxy http://127.0.0.1:7890
  • 使用国内镜像:比如Gitee上有人同步了PX4的完整仓库(含子模块)

3.3 源码目录结构解析

好,源码拉下来了。现在咱们看看这个仓库里到底有什么。你打开PX4-Autopilot目录,第一眼可能会觉得乱——文件夹很多,命名也五花八门。别慌,我带你拆开看。

核心目录就这几个:src、boards、ROMFS、platforms、Tools。下面这张SVG图帮你理清它们的关系:

PX4-Autopilot 核心目录结构 PX4-Autopilot src/ boards/ ROMFS/ platforms/ modules/ drivers/ lib/ systemcmds/ px4/ (Pixhawk系列) intel/ (Aero) holybro/ (定制板) px4fmu_common/ init.d/ (启动脚本) mixers/ (混控器) 核心逻辑 src/ 放代码逻辑,boards/ 放硬件适配,ROMFS/ 放运行时文件 三者配合,才能完成从编译到飞行的完整链路

3.4 核心目录详解

3.4.1 src/ —— 代码主战场

这是你以后最常待的目录。所有飞控功能模块、驱动、库和命令行工具都在这里。我按功能给你拆一下:

  • modules/:飞控的核心功能模块。比如commander(飞行状态机)、navigator(导航)、mc_pos_control(多旋翼位置控制)。你自定义参数调优,主要就是改这些模块里的参数。
  • drivers/:各种传感器和设备的驱动。GPS、IMU、气压计、磁力计、RC接收机……都在这里。如果你要适配一个新传感器,就得来这个目录加代码。
  • lib/:通用算法库。比如数学库、滤波算法、EKF(扩展卡尔曼滤波)的核心实现。这些代码不依赖具体硬件,可以跨平台复用。
  • systemcmds/:系统级命令行工具。比如param(参数读写)、top(任务监控)、reboot(重启飞控)。调试时经常用到。

我的经验:刚开始学PX4,别一头扎进modules里看所有代码。先盯住一个模块,比如mc_pos_control,把它的参数和逻辑搞明白。一个模块吃透了,其他模块的套路都差不多。

3.4.2 boards/ —— 硬件适配层

这个目录存放了所有支持的飞控板的配置文件。每个板子一个子目录,里面定义了引脚映射、传感器配置、时钟频率、Flash和RAM大小等。

举个例子,Pixhawk 4的配置在boards/px4/fmu-v5/下。你打开这个目录,会看到:

  • board.c:板级初始化代码
  • board_config.h:硬件宏定义(比如GPIO、SPI总线)
  • CMakeLists.txt:编译配置
  • nuttx-config/:NuttX RTOS的配置文件

如果你要移植PX4到一块新板子上,主要工作就是在这里加一个新目录,然后按照模板把配置填好。我曾经帮一个客户移植到STM32F7的定制板,花了三天时间调board_config.h里的引脚定义——一个管脚错了,整个传感器就读不到数据。

3.4.3 ROMFS/ —— 运行时文件系统

ROMFS是只读文件系统,编译时被打包进固件里。飞控启动时,这些文件会被挂载到/etc目录下。它主要包含三类东西:

子目录 内容 作用
init.d/ 启动脚本(rcS, rc.xxx) 飞控上电后自动执行,启动各个模块
mixers/ 混控器配置文件(.mix) 定义电机/舵机输出与控制信号的映射关系
extras/ 额外配置文件 比如摄像头参数、自定义启动脚本

你想想看,飞控上电后,系统先跑NuttX内核,然后执行init.d/rcS脚本。这个脚本会依次启动uORB、传感器驱动、姿态估计、位置控制等模块。如果你想让某个模块在启动时加载自定义参数,就得改这里的脚本。

注意:ROMFS里的文件是只读的,运行时不能修改。如果你要改启动脚本或混控器,必须重新编译固件。我曾经在调试时直接SSH上去改/etc/init.d/rcS,结果重启后所有修改都丢了——因为ROMFS在每次启动时都会从固件里重新解压。

3.5 其他重要目录

除了上面三个核心目录,还有几个你迟早会用到的:

  • platforms/:操作系统抽象层。PX4支持NuttX和Linux(POSIX)两个平台。这个目录里放了不同平台的系统接口实现,比如任务创建、时间管理、文件操作。
  • Tools/:编译工具链、仿真脚本、代码检查工具。比如make px4_sitl调用的仿真脚本就在这里。
  • msg/:uORB消息定义文件(.msg)。所有模块之间的通信协议都在这里定义。你自定义参数时,如果需要新增一个话题,就得在这里加一个.msg文件。
  • mavlink/:MAVLink协议的子模块。地面站和飞控之间的通信就靠它。

3.6 本章小结

这一章我们干了三件事:从GitHub拉取了PX4源码,更新了子模块,然后拆解了目录结构。你现在应该知道:

  • 代码逻辑在src/里找
  • 硬件配置在boards/里改
  • 运行时文件在ROMFS/里调
  • 编译和仿真工具在Tools/里用