2. 开发环境搭建与源码工程结构

PX4 的官方开发环境以 Ubuntu LTS 为主,推荐 20.04 或 22.04。整个工具链可以拆成四层:系统基础包、编译工具链、仿真与地面站依赖、以及 PX4 源码本身。理解这四层的依赖关系,比死记安装命令更重要——因为绝大多数“编译失败”都源于某一层缺失或版本不匹配。

Ubuntu 开发环境配置

PX4 官方提供了一键脚本 ubuntu.sh,它会安装 GCC、Python3、Ninja、CMake、ccache、genromfs、kconfig-frontends 等构建依赖,以及 jMAVSim、Gazebo 仿真所需的库。典型流程如下:

git clone https://github.com/PX4/PX4-Autopilot.git --recursive
bash ./PX4-Autopilot/Tools/setup/ubuntu.sh
sudo reboot

脚本执行完成后,建议用 arm-none-eabi-gcc --version 确认交叉编译器可用,用 python3 --version 确认 Python 版本不低于 3.8。若需要 Gazebo 仿真,还要额外确认 gazebo --version 能正常输出。注意:--recursive 参数非常关键,PX4 依赖大量子模块(如 mavlink、uORB 消息定义、NuttX 内核),漏掉会导致编译时找不到头文件。

如果网络受限,可以先配置 Git 代理,或使用 git submodule update --init --recursive 单独拉取子模块。国内用户建议为 GitHub 配置镜像或代理,否则子模块拉取极易中断。

PX4 源码获取与编译

源码获取有两种方式:直接克隆官方仓库,或从 Release 页面下载带子模块的压缩包。推荐前者,便于后续切换分支和提交修改。克隆完成后,进入源码根目录,使用 make 加目标名进行编译。例如编译 Pixhawk 4 的固件:

cd PX4-Autopilot
make px4_fmu-v5_default

编译成功后,固件位于 build/px4_fmu-v5_default/px4_fmu-v5_default.px4。若只想编译 SITL 仿真版本,使用 make px4_sitl_default,产物在 build/px4_sitl_default/bin/px4。编译过程中 ccache 会缓存中间结果,第二次编译通常只需几十秒。判断编译是否成功,除了看终端是否出现 ROMFS 和 px4 目标,还可以检查 build/ 目录下是否生成了对应的 .px4 文件。

目录结构解析

PX4 源码目录数量多,但真正高频接触的只有几个。下面这张结构图把核心目录及其职责关系梳理清楚,便于在阅读代码时快速定位。

PX4-Autopilot 核心目录结构 PX4-Autopilot/ src/ 飞控核心源码 modules / drivers lib / systemcmds boards/ 板级配置 px4_fmu-v5/ default.px4board msg/ uORB 消息定义 .msg 文件 自动生成 C++ 头 Tools/ 构建与仿真脚本 setup / simulator mavlink / uORB 工具 build/ 编译产物 .px4 / .elf 关键子目录速查 src/modules/ commander、navigator、ekf2 mc_pos_control、logger 等 src/drivers/ imu、barometer、gps px4io、pwm_out 等驱动 src/lib/ mathlib、ecl、parameters mixer、version 等公共库 ROMFS/px4fmu_common/ 启动脚本 init.d/rcS 混控器与参数默认值 platforms/ nuttx / posix 平台适配 调度与底层接口 cmake/ 与 CMakeLists.txt 构建规则、目标定义 config 与 toolchain 配置

阅读源码时,一个高效路径是:从 ROMFS/px4fmu_common/init.d/rcS 启动脚本入手,看系统启动了哪些模块;再进入 src/modules/ 找到对应模块的 CMakeLists.txt 和主文件;消息交互则查 msg/ 下的定义。这样能避免在数千个文件中盲目搜索。

Git 版本管理与分支策略

PX4 官方仓库的分支模型比较清晰:main 是开发主线,release/1.14 这类是稳定发布分支,pr-xxxx 是社区拉取请求分支。工程开发中建议遵循以下策略:

  • 以某个 release 分支为基线,创建自己的 feature/xxx 或 fix/xxx 分支,避免直接在 main 上修改。
  • 每次修改前先 git submodule update --init --recursive,确保子模块与当前分支匹配。
  • 提交信息建议包含模块名和变更类型,例如 ekf2: fix baro bias estimation,便于回溯。
  • 需要同步上游时,用 git fetch upstream 后 rebase,而不是直接 merge,保持提交历史线性。

一个常见坑是:切换分支后忘记更新子模块,导致编译报错“找不到 mavlink 头文件”。此时执行 git submodule update --init --recursive 即可恢复。另一个坑是本地修改了 msg/ 下的消息定义但未重新生成头文件,编译时会出现类型不匹配,需要重新执行 make 触发消息生成步骤。

常用构建目标

PX4 的构建目标命名规则是 make <board>_<config>。下表列出工程调试中最常用的几个目标及其用途,可作为日常速查。

构建目标 用途 产物位置
make px4_fmu-v5_default 编译 Pixhawk 4 硬件固件 build/px4_fmu-v5_default/*.px4
make px4_sitl_default 编译 SITL 仿真版本 build/px4_sitl_default/bin/px4
make px4_sitl gazebo 编译并启动 Gazebo 仿真 自动运行,无需手动找产物
make px4_fmu-v5_default upload 编译并烧录到飞控 通过 USB 自动下载
make clean 清理当前目标的编译产物 删除对应 build 子目录
make distclean 清理全部构建缓存 删除整个 build 目录

实际调试中,如果只改了一个模块的源码,直接 make px4_fmu-v5_default 即可,Ninja 会增量编译。若怀疑构建缓存污染,用 make clean 后重编;若连 CMake 配置都异常,再用 make distclean。烧录时若提示“找不到设备”,先确认 ls /dev/ttyACM* 是否存在,并检查当前用户是否在 dialout 组中。

不要用 sudo make 编译,否则 build 目录会变成 root 所有,后续普通用户编译会因权限失败。若已误操作,执行 sudo chown -R $USER:$USER build/ 修复。

把环境配置、源码获取、目录定位、分支管理和构建目标这五件事串起来,就形成了 PX4 工程开发的最小闭环:环境决定能否编译,源码与子模块决定编译什么,目录结构决定改哪里,分支策略决定改动如何管理,构建目标决定产物给谁用。后续所有模块开发、参数调试和固件烧录,都建立在这条链路之上。