)
从零开始PX4飞控上的Hello Sky开发实战指南引言为什么选择PX4作为无人机开发起点当你第一次打开PX4-AutoPilot的源码仓库面对密密麻麻的文件夹和文件时可能会感到无从下手。作为目前最流行的开源飞控系统之一PX4的强大功能背后是复杂的工程架构。但对于初学者而言最好的入门方式不是直接研究核心算法而是从一个最简单的Hello World级别应用开始——这就像学习编程语言时打印的第一行文字虽然简单却能验证整个开发环境是否正常工作。本文将带你完成一个完整的PX4应用开发闭环从源码目录结构解析、CMakeLists.txt编写、Kconfig配置到编译、烧录最后在QGroundControl地面站中运行并查看日志。我们会特别关注新手在每个环节可能遇到的典型问题比如源码应该放在哪个目录为什么修改了代码却看不到效果如何确认应用已经被正确编译进固件地面站连接飞控后找不到自己写的应用怎么办通过这个看似简单但包含完整流程的Hello Sky项目你将建立起对PX4应用开发的基本认知框架为后续更复杂的功能开发打下坚实基础。1. 开发环境准备与源码结构解析1.1 PX4开发环境搭建在开始编写代码前我们需要确保开发环境配置正确。PX4支持多种开发平台推荐使用Ubuntu 20.04 LTS作为开发环境。以下是必备工具的安装命令# 安装基础编译工具链 sudo apt-get update sudo apt-get install git cmake ninja-build build-essential -y # 安装PX4专用工具链 sudo apt-get install python3-pip pip3 install --user kconfiglib jsonschema future注意如果你使用Windows系统建议通过WSL2安装Ubuntu环境避免原生Windows环境下的兼容性问题。1.2 PX4源码目录结构解析克隆PX4-AutoPilot源码仓库后你会看到如下主要目录结构PX4-AutoPilot/ ├── boards/ # 飞控硬件定义文件 ├── src/ # 核心源码目录 │ ├── drivers/ # 硬件驱动 │ ├── examples/ # 示例程序我们将在这里添加代码 │ ├── modules/ # 主要功能模块 │ └── system/ # 系统级功能 ├── ROMFS/ # 根文件系统 └── Tools/ # 开发工具对于应用开发者来说src/examples/是最常接触的目录这里存放着各种示例程序。我们将在该目录下创建自己的应用。2. 创建第一个PX4应用Hello Sky2.1 应用代码编写在src/examples/目录下创建hello_sky文件夹然后新建hello_sky.c文件/** * file hello_sky.c * 最简单的PX4应用示例 */ #include px4_platform_common/log.h // 必须导出主函数 __EXPORT int hello_sky_main(int argc, char *argv[]); int hello_sky_main(int argc, char *argv[]) { PX4_INFO(Hello Sky! My first PX4 app is running!); return OK; }关键点说明主函数命名必须遵循应用名_main的格式__EXPORT宏确保函数能被外部调用PX4_INFO是PX4专用的日志输出宏相当于标准C的printf2.2 CMake构建配置在同一个目录下创建CMakeLists.txt文件px4_add_module( MODULE examples__hello_sky MAIN hello_sky STACK_MAIN 2000 SRCS hello_sky.c DEPENDS )参数解释参数说明MODULE模块的唯一标识通常使用路径格式MAIN主函数名称不带_main后缀STACK_MAIN主线程栈大小字节SRCS源文件列表DEPENDS依赖的其他模块2.3 Kconfig菜单配置创建Kconfig文件定义编译选项menuconfig EXAMPLES_HELLO_SKY bool Hello Sky Demo Application default n ---help--- Enable the Hello Sky demo application.这个配置将出现在PX4的编译配置菜单中允许用户选择是否编译我们的应用。3. 编译与烧录实战3.1 启用应用编译选项在编译前需要确保我们的应用被包含在构建系统中。找到对应飞控型号的配置文件例如boards/px4/fmu-v5/default.px4board添加CONFIG_EXAMPLES_HELLO_SKYy3.2 编译固件在PX4源码根目录执行编译命令# 针对Pixhawk 4(FMUv5)编译 make px4_fmu-v5_default # 如果使用其他飞控替换对应的目标 # make px4_fmu-v2_default # 针对Pixhawk 1常见编译问题排查找不到编译器确认工具链安装正确运行which arm-none-eabi-gcc检查头文件缺失确保所有#include路径正确PX4标准头文件应使用包含Kconfig不生效检查.px4board文件修改后是否保存3.3 烧录固件编译成功后连接飞控到电脑执行烧录命令make px4_fmu-v5_default upload烧录过程中常见问题飞控未进入烧录模式多数飞控需要在上电时按住BOOT按钮USB权限问题在Linux下可能需要将用户加入dialout组端口被占用关闭QGroundControl等可能占用串口的程序4. 运行与调试技巧4.1 通过QGroundControl运行应用打开QGroundControl并连接飞控进入Analyze → MAVLink Console输入hello_sky命令运行应用正确运行时你将看到输出INFO [hello_sky] Hello Sky! My first PX4 app is running!4.2 常见运行问题解决命令未找到确认应用已正确编译进固件检查编译日志输入help查看所有可用命令确认hello_sky在列表中无输出信息检查代码中是否使用了PX4_INFO而非printf确认日志级别设置足够高默认应能看到INFO级别应用崩溃检查栈大小是否足够STACK_MAIN参数添加更多日志输出定位问题位置4.3 进阶调试技巧增加调试输出PX4_DEBUG(Debug message: %d, some_value); // 仅调试构建时输出使用参数系统// 定义参数 PARAM_DEFINE_FLOAT(HELLO_SCALE, 1.0f); // 获取参数值 param_t scale_p param_find(HELLO_SCALE); float scale 1.0f; param_get(scale_p, scale);添加周期性任务#include px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp class HelloSky : public px4::ScheduledWorkItem { public: HelloSky() : ScheduledWorkItem(MODULE_NAME, px4::wq_configurations::test1) {} void Run() override { PX4_INFO(Periodic hello!); } void start() { ScheduleOnInterval(1000000); // 每1秒执行一次 } }; // 在main函数中启动 HelloSky *hello new HelloSky(); hello-start();5. 从示例到实战扩展应用功能现在我们已经完成了一个最基本的PX4应用接下来可以考虑扩展它的功能添加参数控制让用户可以通过QGC调整应用行为订阅传感器数据读取无人机姿态、位置等信息发布控制指令发送姿态或位置控制命令实现自定义算法如简单的控制逻辑或数据处理例如订阅姿态数据并打印的代码片段#include uORB/topics/vehicle_attitude.h // 在main函数中添加 int att_sub orb_subscribe(ORB_ID(vehicle_attitude)); vehicle_attitude_s att{}; while (!px4_thread_exited()) { orb_copy(ORB_ID(vehicle_attitude), att_sub, att); PX4_INFO(Roll: %.2f, Pitch: %.2f, (double)att.roll, (double)att.pitch); usleep(100000); // 100ms }在实际项目中我经常发现新手最容易忽略的是资源清理。PX4作为嵌入式系统对内存泄漏非常敏感。所有动态分配的资源如订阅、内存分配等都必须在应用退出时正确释放。