1. PX4新机型开发入门指南
作为一名在无人机飞控领域摸爬滚打多年的工程师,我深知PX4开源飞控平台的强大之处。它不仅是一个成熟的无人机控制系统,更是一个高度模块化的机器人控制框架。今天我想分享的是如何从零开始基于PX4进行新机型开发的全套流程。
为什么选择PX4?首先,它支持从微型四轴到大型VTOL(垂直起降飞行器)的各种机型;其次,其内置的EKF2(扩展卡尔曼滤波)、位置控制等算法经过多年实战检验;最重要的是,PX4的模块化设计让开发者可以快速实现定制化需求,而无需从头造轮子。
本教程适合以下几类开发者:
- 需要为特殊应用场景(如农业喷洒、物流运输)开发定制无人机的工程师
- 希望深入理解无人机控制原理的学生和研究者
- 想要基于PX4开发其他类型机器人(如无人船、无人车)的技术爱好者
在开始前,你需要准备:
- 一台运行Ubuntu 18.04/20.04的电脑(推荐配置:4核CPU/8GB内存/50GB硬盘)
- STM32系列开发板(如Holybro Pixhawk 4)
- 基础的C++编程知识
- 对无人机基本原理的了解
提示:虽然PX4支持Windows和Mac开发,但在Ubuntu上可以获得最佳开发体验,且官方文档主要基于Linux环境。
2. 开发环境搭建与QGC配置
2.1 安装编译工具链
PX4开发环境的搭建是后续所有工作的基础。以下是经过多次实践验证的安装步骤:
bash复制# 1. 添加PPA源并更新
sudo add-apt-repository ppa:git-core/ppa -y
sudo apt update
# 2. 安装基础依赖
sudo apt install -y git zip qtcreator cmake \
build-essential genromfs ninja-build \
python3-pip python3-dev python3-setuptools
# 3. 安装特定版本的Python包
pip3 install --user kconfiglib future jinja2
# 4. 安装ARM工具链
sudo apt install gcc-arm-none-eabi -y
安装完成后,验证工具链是否正常工作:
bash复制arm-none-eabi-gcc --version
# 应显示类似:gcc version 9.3.1 20200408 (release)
2.2 获取PX4源码
PX4代码托管在GitHub上,使用以下命令克隆仓库:
bash复制git clone https://github.com/PX4/PX4-Autopilot.git --recursive
cd PX4-Autopilot
注意:必须添加
--recursive参数,因为PX4依赖多个子模块。如果克隆时网络不稳定导致子模块下载失败,可以后续执行git submodule update --init --recursive补全。
2.3 配置QGroundControl地面站
QGroundControl(QGC)是与PX4配合使用的地面站软件,提供参数配置、飞行监控等功能。
安装最新稳定版QGC:
bash复制sudo usermod -a -G dialout $USER
sudo apt-get remove modemmanager -y
wget https://s3-us-west-2.amazonaws.com/qgroundcontrol/latest/QGroundControl.AppImage
chmod +x QGroundControl.AppImage
./QGroundControl.AppImage
首次连接飞控板时需要注意:
- 使用优质Micro USB线(劣质线可能导致连接不稳定)
- 如果设备未被识别,尝试在终端执行
ls /dev/ttyACM*查看设备节点 - 在QGC的"Vehicle Setup"中完成传感器校准和遥控器配对
3. PX4软件架构解析
3.1 核心模块功能解析
PX4采用模块化设计,主要功能模块如下表所示:
| 模块名称 | 功能描述 | 关键文件位置 |
|---|---|---|
| Commander | 处理飞行模式切换、安全机制(如失控保护) | src/modules/commander |
| Navigator | 管理任务执行(如航点飞行、返航) | src/modules/navigator |
| Sensors | 处理所有传感器数据(IMU、磁力计、气压计等) | src/modules/sensors |
| EKF2 | 多传感器融合算法(姿态、位置估计) | src/lib/ecl |
| MC Attitude Ctrl | 多旋翼姿态控制算法 | src/modules/mc_att_control |
| Logger | 记录飞行数据(可用于事后分析) | src/modules/logger |
3.2 关键配置文件说明
开发新机型时需要重点关注以下配置文件:
-
机架定义文件:
ROMFS/px4fmu_common/init.d/airframes/- 定义电机布局、混控参数等
- 命名规则:
4xxx_<机架名称>
-
参数定义文件:
src/modules/px4_parameters.yaml- 声明所有可调参数及其元数据
- 参数在代码中通过
PARAM_DEFINE_*宏定义
-
启动脚本:
ROMFS/px4fmu_common/init.d/- 控制模块启动顺序
- 使用特殊的shell-like语法
4. 第一个PX4应用:Hello World
4.1 创建新模块
PX4模块通常包含以下文件:
<module_name>/<module_name>.cpp:主实现文件<module_name>/CMakeLists.txt:构建配置<module_name>/module.yaml:模块元数据
以创建"hello_world"模块为例:
- 在
src/modules/下新建目录:
bash复制mkdir -p src/modules/hello_world
- 创建
module.yaml:
yaml复制name: hello_world
description: A simple hello world module
dependencies:
commands:
start_config:
- 创建
CMakeLists.txt:
cmake复制px4_add_module(
MODULE modules__hello_world
MAIN hello_world
SRCS
hello_world.cpp
DEPENDS
)
4.2 实现模块功能
编辑hello_world.cpp:
cpp复制#include <px4_platform_common/module.h>
class HelloWorld : public ModuleBase<HelloWorld> {
public:
static int task_spawn(int argc, char *argv[]);
static int custom_command(int argc, char *argv[]);
static int print_usage(const char *reason = nullptr);
void run() override;
};
int HelloWorld::task_spawn(int argc, char *argv[]) {
HelloWorld *instance = new HelloWorld();
if (instance) {
instance->run();
return 0;
}
return -1;
}
void HelloWorld::run() {
PX4_INFO("Hello World from PX4 module!");
while (!should_exit()) {
sleep(1);
}
}
// 注册模块
extern "C" __EXPORT int hello_world_main(int argc, char *argv[]);
int hello_world_main(int argc, char *argv[]) {
return HelloWorld::main(argc, argv);
}
4.3 编译与测试
- 编译固件:
bash复制make px4_fmu-v5_default
- 刷写飞控板:
bash复制make px4_fmu-v5_default upload
- 在QGC的MAVLink控制台中执行:
bash复制hello_world start
调试技巧:使用
dmesg命令查看内核日志,或通过uorb top观察主题发布情况。
5. 遥控器数据获取与电机控制
5.1 接收遥控器输入
PX4通过uORB(微对象请求代理)消息系统传递遥控器数据。关键步骤如下:
- 订阅
manual_control_setpoint主题:
cpp复制#include <uORB/topics/manual_control_setpoint.h>
// 在类定义中添加
int _manual_control_sub;
// 在初始化时订阅
_manual_control_sub = orb_subscribe(ORB_ID(manual_control_setpoint));
// 在运行循环中读取
manual_control_setpoint_s manual;
if (orb_copy(ORB_ID(manual_control_setpoint), _manual_control_sub, &manual) == OK) {
float roll = manual.roll; // [-1,1]
float pitch = manual.pitch; // [-1,1]
float yaw = manual.yaw; // [-1,1]
float throttle = manual.throttle; // [0,1]
}
5.2 控制电机输出
PX4使用混控器(Mixer)将控制指令转换为电机PWM信号。典型控制流程:
- 发布
actuator_controls主题:
cpp复制#include <uORB/topics/actuator_controls.h>
actuator_controls_s controls = {};
controls.control[0] = roll_cmd; // 横滚
controls.control[1] = pitch_cmd; // 俯仰
controls.control[2] = yaw_cmd; // 偏航
controls.control[3] = thrust_cmd; // 推力
orb_advert_t _actuator_pub = orb_advertise(ORB_ID(actuator_controls_0), &controls);
- 混控器配置文件示例(
etc/mixers/quad_x.main.mix):
code复制R: 4x 10000 10000 10000 0
M: 1
S: 0 0 -10000 10000
M: 1
S: 0 1 10000 10000
M: 1
S: 0 2 10000 10000
M: 1
S: 0 3 -10000 10000
安全提示:首次测试电机时,务必卸下螺旋桨,并使用
motor_test命令逐个测试电机转向是否正确。
6. 传感器数据获取与处理
6.1 访问IMU数据
PX4传感器数据也通过uORB发布。以获取IMU数据为例:
cpp复制#include <uORB/topics/sensor_combined.h>
int _sensor_sub = orb_subscribe(ORB_ID(sensor_combined));
sensor_combined_s sensors;
if (orb_copy(ORB_ID(sensor_combined), _sensor_sub, &sensors) == OK) {
float gyro_x = sensors.gyro_rad[0]; // X轴角速度(rad/s)
float accel_z = sensors.accelerometer_m_s2[2]; // Z轴加速度(m/s²)
}
6.2 自定义传感器驱动
如果需要添加新传感器,通常需要实现以下接口:
- 继承
I2CSPIDriver基类 - 实现
start()、stop()等方法 - 定期发布传感器数据主题
以I2C设备为例的框架代码:
cpp复制class MySensor : public I2CSPIDriver<MySensor> {
public:
MySensor(I2CSPIBusOption bus_option, int bus);
~MySensor() override;
static I2CSPIDriverBase *instantiate(const BusCLIArguments &cli, const BusInstanceIterator &iterator);
void print_status() override;
int init() override;
void RunImpl();
private:
uORB::Publication<sensor_accel_s> _accel_pub{ORB_ID(sensor_accel)};
perf_counter_t _sample_perf;
};
7. 参数调试与PID整定
7.1 QGC参数界面使用技巧
PX4有数千个可调参数,QGC提供了便捷的调节界面:
- 按组筛选:如"MC_"开头的参数属于多旋翼控制器
- 参数搜索:支持模糊匹配(如搜索"roll"找到所有相关参数)
- 参数导出/导入:便于备份和分享配置
实用技巧:修改参数后,可以通过"Tools > Reboot Vehicle"立即生效,而不必重启整个系统。
7.2 PID控制器调试实战
以多旋翼姿态控制PID为例,关键参数有:
- MC_ROLLRATE_P:横滚角速率比例项
- MC_ROLLRATE_I:横滚角速率积分项
- MC_ROLLRATE_D:横滚角速率微分项
调试步骤:
- 将所有I和D值设为0,P设为较小值(如0.05)
- 缓慢增加P直到出现高频振荡,然后降至80%的值
- 增加D值抑制振荡(通常为P值的1/10到1/5)
- 最后增加I值消除稳态误差(通常为P值的1/100到1/50)
遥控器调参技巧:
- 在QGC中启用"MC_AT_RATE_MENU"参数
- 飞行时通过遥控器开关切换调参模式
- 使用旋钮实时调整PID值
8. 新机架开发全流程
8.1 定义机架配置
创建新机架需要以下步骤:
- 在
ROMFS/px4fmu_common/init.d/airframes/中添加定义文件,例如4010_my_quad:
bash复制#!/bin/sh
[ ${PX4_SIM_MODEL}__ == "none" ] && PX4_SIM_MODEL="my_quad"
set MODEL my_quad
set MIXER quad_x
set FRAME_CLASS 1
- 在
ROMFS/px4fmu_common/init.d/airframes/CMakeLists.txt中注册新机架:
cmake复制px4_add_romfs_files(
...
airframes/4010_my_quad
...
)
- 在
Tools/sitl_gazebo/models/中添加对应的仿真模型(如需)
8.2 关键机架参数解析
| 参数名 | 描述 | 典型值示例 |
|---|---|---|
| CA_AIRFRAME | 机架类型标识符 | 4010 |
| MPC_THR_CURVE | 油门曲线类型(0=线性,1=平滑) | 1 |
| MPC_Z_P | 高度控制P增益 | 0.8 |
| MPC_XY_VEL_P | 水平速度控制P增益 | 0.4 |
| MC_ROLLRATE_MAX | 最大横滚角速率(deg/s) | 220 |
| MNT_RC_IN_MODE | 云台控制输入模式 | 1(遥控器输入) |
8.3 混控器高级配置
对于特殊机型(如VTOL、六轴等),需要自定义混控器。以六轴(Hexacopter)为例:
code复制R: 6x 10000 10000 10000 0
M: 1
S: 0 0 -10000 10000
M: 1
S: 0 1 10000 10000
M: 1
S: 0 2 10000 10000
M: 1
S: 0 3 -10000 10000
M: 1
S: 0 4 10000 10000
M: 1
S: 0 5 -10000 10000
经验分享:在开发新机架时,务必先在仿真环境中充分测试。推荐使用Gazebo的
iris模型作为起点,逐步修改参数验证效果。
9. 实战问题排查指南
9.1 常见编译问题
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 子模块下载失败 | 网络问题/Git配置问题 | 执行git submodule update --init --recursive |
| 缺少python依赖 | pip包未正确安装 | pip3 install -r requirements.txt |
| 内存不足导致编译中断 | 系统资源不足 | 增加swap空间或关闭其他内存占用程序 |
9.2 运行时典型故障
-
传感器校准失败:
- 检查设备是否连接稳定
- 确保校准时机体保持绝对水平
- 在
/fs/microsd/log中查看详细错误日志
-
电机不响应:
- 验证PWM输出配置是否正确
- 检查安全开关状态(
CBRK_IO_SAFETY参数) - 使用
motor_test命令单独测试每个电机
-
位置估计漂移:
- 检查EKF2参数(如
EKF2_GPS_P_NOISE) - 确保磁力计校准准确
- 在室外开阔区域进行GPS测试
- 检查EKF2参数(如
9.3 调试工具推荐
-
uORB命令行工具:
uorb top:查看主题发布频率listener <topic_name>:实时查看主题内容
-
系统状态监控:
top:查看CPU和内存使用情况work_queue status:监控任务队列状态
-
日志分析:
- 使用Flight Review在线工具(https://logs.px4.io)
- 本地分析工具:pyulog
在实际项目中,我遇到最棘手的问题是电机启动不同步导致的机体抖动。最终发现是PWM信号线受到电源干扰,通过以下措施解决:
- 使用带屏蔽的电缆
- 在电机电源端增加电容滤波
- 调整
PWM_MAIN_MIN和PWM_MAIN_MAX参数匹配电调校准范围
开发PX4新机型是一个系统工程,需要耐心和系统性的调试方法。建议每次只修改一个变量,并通过日志记录每次更改的效果。当遇到难以解决的问题时,PX4社区(https://discuss.px4.io)是非常有价值的资源。
