PX4姿态控制概览:整体架构、控制流、姿态控制与角速率控制的关系
大家好,欢迎来到这门课程的第一章。我是你们的老朋友,一个在飞控领域摸爬滚打了十来年的工程师。今天咱们不聊虚的,直接切入PX4姿态控制的核心。你想想看,一架四旋翼或者固定翼,为什么能稳稳地悬停、灵活地转弯?背后就是这套控制逻辑在起作用。
我个人习惯,在深入代码之前,先画一张大图。把整个控制链路看清楚,知道每个模块是干什么的,它们之间怎么配合。这样你读源码的时候,才不会迷路。
一、PX4姿态控制的整体架构
PX4的飞控系统,说白了就是一个多级嵌套的环路。从最外层的导航控制,到最内层的电机混控,中间夹着姿态控制和角速率控制。我把它画成了下面这张图,你一看就明白。
核心观点:姿态控制是外环,角速率控制是内环。外环输出期望角速率,内环去跟踪这个角速率。两者缺一不可。
嗯,这里要注意。外环和内环的运行频率是不一样的。姿态控制通常跑在100到250赫兹,而角速率控制要快得多,400到1000赫兹。为什么?因为角速率变化更快,需要更快的响应。我在项目中遇到过,有人把内环频率降得太低,结果飞机一打舵就晃得厉害,根本稳不住。
二、控制流:数据是怎么走的?
咱们顺着数据流走一遍。从传感器数据采集,到最终电机输出,中间经历了什么?
- 传感器数据采集:IMU(惯性测量单元)读取加速度计和陀螺仪的原始数据。注意,陀螺仪数据直接就是角速率,而加速度计数据需要融合才能得到姿态。
- 姿态估计:通过EKF(扩展卡尔曼滤波)或者互补滤波,把加速度计和陀螺仪数据融合,得到当前的真实姿态(四元数或欧拉角)。
- 姿态控制:把期望姿态和当前姿态做差,经过PID控制器,输出期望角速率。这里用的是旋转矩阵或者四元数误差,不是简单的角度相减。
- 角速率控制:把期望角速率和当前角速率做差,经过PID控制器,输出期望力矩(或者说期望加速度)。
- 混控输出:根据机架类型(四旋翼、六旋翼、固定翼等),把期望力矩映射到每个电机的PWM值。
我的小技巧:调试的时候,我习惯先看内环(角速率控制)能不能跟踪好。内环稳了,外环才有意义。否则你姿态控制调得再好,内环抖得像筛子,飞机照样乱晃。
三、姿态控制与角速率控制的关系
这两个环的关系,说白了就是「老板和员工」。姿态控制是老板,它说「我要往左倾斜30度」;角速率控制是员工,它负责「以多快的速度往左转」。老板只关心目标,员工关心执行过程。
为什么会这样设计?因为物理世界有惯性。你不可能让飞机瞬间从0度变成30度,必须有一个旋转的过程。角速率控制就是管理这个过程的。
| 控制环 | 输入 | 输出 | 典型频率 | 控制器类型 |
|---|---|---|---|---|
| 姿态控制(外环) | 期望姿态 + 当前姿态 | 期望角速率 | 100 - 250 Hz | P + 前馈 |
| 角速率控制(内环) | 期望角速率 + 当前角速率 | 期望力矩 | 400 - 1000 Hz | PID |
你看这个表格,姿态控制只用到了P(比例)和前馈,没有I(积分)。为什么?因为姿态误差可以通过角速率积分来消除,不需要在姿态环再加积分。加了反而容易超调。我曾经在早期版本里试过给姿态环加I,结果飞机像喝醉了酒一样来回晃,后来果断去掉了。
避坑指南:千万不要把姿态控制和角速率控制的参数混在一起调。先调内环,再调外环。我曾经见过有人一上来就调姿态环的P值,结果内环根本没调好,飞机直接翻了个跟头。嗯,那次炸机让我记忆犹新。
四、代码层面的对应关系
在PX4源码里,姿态控制主要在 mc_att_control 模块中。核心文件是 AttitudeControl.cpp 和 RateControl.cpp。我简单列一下关键函数:
// 姿态控制主函数
void AttitudeControl::control_attitude(const vehicle_attitude_setpoint_s &att_sp,
const vehicle_attitude_s &att,
const vehicle_rates_setpoint_s &rates_sp,
const float dt)
{
// 1. 计算姿态误差(四元数误差)
// 2. 通过旋转矩阵把误差映射到机体坐标系
// 3. 乘以P增益,得到期望角速率
// 4. 加上前馈项(来自遥控器或位置控制)
}
// 角速率控制主函数
void RateControl::control_rates(const vehicle_rates_setpoint_s &rates_sp,
const vehicle_angular_velocity_s &rates,
const float dt)
{
// 1. 计算角速率误差
// 2. PID计算(P、I、D三项)
// 3. 输出期望力矩(归一化到[-1, 1])
}
注意看,姿态控制里没有积分项,而角速率控制有完整的PID。这就是两者的本质区别。你调参的时候,姿态环只需要调P和前馈,角速率环需要调P、I、D三个参数。
五、调参实战思路
说了这么多理论,咱们聊聊实际怎么调。我个人习惯的步骤是这样的:
- 第一步:锁定外环。先把姿态控制的P值设得很小(比如0.1),这样外环基本不起作用。然后只调内环。
- 第二步:调内环P。慢慢增大角速率控制的P值,直到飞机能快速响应打舵,但不要出现高频抖动。如果抖了,说明P太大了。
- 第三步:调内环D。D值用来抑制超调。慢慢加,直到打舵后飞机能稳稳停住,不来回晃。
- 第四步:调内环I。I值用来消除稳态误差。比如飞机悬停时有点偏,加一点I就能拉回来。
- 第五步:放开外环。内环调好后,慢慢增大姿态控制的P值,直到飞机能快速响应姿态指令。
记住:内环的响应速度一定要比外环快。如果内环跟不上外环的指令,飞机就会振荡。我一般让内环的带宽是外环的3到5倍。
好了,这一章的内容就到这里。咱们把PX4姿态控制的整体架构、数据流、内外环关系都捋了一遍。下一章我会带着大家逐行解析 AttitudeControl.cpp 的源码,看看那些数学公式在代码里是怎么实现的。到时候见。
公众号:蓝海资料掘金营,微信deep3321