2. PID控制器基础:比例、积分、微分的物理意义与飞控应用

各位同学,今天我们聊点真正核心的东西——PID控制器。说实话,我见过不少刚入行的工程师,调参全靠“玄学”,拧一下P,推一下I,炸机了再拧回来。其实,你只要搞懂了P、I、D这三个字母在物理上到底代表什么,调参就不再是碰运气。

PID在飞控里无处不在。姿态控制、高度保持、位置锁定,甚至你手里的遥控器回中手感,背后都是PID在干活。今天我就把这层窗户纸捅破。

一句话总结:P管现在、I管过去、D管未来。飞控就是靠这三个“时间维度”的配合,让无人机听话。

2.1 比例(P)——最直接的“纠偏”

比例控制,说白了就是“偏差越大,出力越大”。你想想看,无人机要悬停在10米高度,现在实际是9米,差了1米。P控制器就会根据这个1米的偏差,给油门一个向上的修正量。

数学上很简单:输出 = Kp × 偏差。Kp就是比例系数。

我在项目中遇到过一个典型问题:新手把P调得特别大,觉得这样响应快。结果飞机像“抽风”一样来回晃,根本稳不住。为什么?因为P只认当前偏差,它不会“刹车”。偏差大了出力大,冲过头了反向偏差又变大,来回震荡。

我的习惯:先给一个保守的P值,让飞机能勉强稳住,然后逐步增加,直到出现轻微震荡,再退回20%。这个点通常就是P的“甜区”。

2.2 积分(I)——专治“顽固偏差”

比例控制有个硬伤——它搞不定“静态误差”。举个例子:你的四轴飞行器重心偏了,或者有风一直吹。P控制器发现偏差后出力,但出力到一定程度就和外力平衡了,偏差就是消不掉。这时候飞机就“偏着飞”。

积分I就是来解决这个问题的。它会把过去的偏差“累加”起来。只要偏差一直存在,积分项就会越来越大,直到把那个顽固的偏差彻底吃掉。

积分输出 = Ki × ∫偏差 dt

我曾经调试一架测绘无人机,高度总是偏个0.3米下不去。P调了无数遍都没用。后来加了点I,高度稳稳锁住。但要注意,I太大会导致“积分饱和”——飞机反应迟钝,甚至一松手就掉高度。

避坑指南:积分项不是越大越好。我建议在姿态控制里I值不要超过P值的1/5。高度控制可以稍微大一点,但一定要配合积分限幅,防止起飞时积分疯狂累积导致超调。

2.3 微分(D)——给系统装上“减震器”

微分D看的是偏差的变化率。它不关心偏差有多大,只关心偏差“变得有多快”。

微分输出 = Kd × d(偏差)/dt

你想想看,飞机快速接近目标高度时,P还在使劲推,但D已经检测到偏差在快速减小,它会输出一个反向力来“刹车”。这就是为什么D能抑制震荡、提高稳定性。

我个人习惯在角速率环(内环)里加D,效果立竿见影。但D对噪声极其敏感——传感器一抖,D输出就炸。所以用D之前,一定要先做好滤波。

小技巧:如果你发现飞机高频抖动,先检查D是不是太大了。如果D已经很小还在抖,那多半是传感器噪声问题,不是D的锅。

2.4 PID在飞控中的典型应用场景

飞控里不是只有一个PID,而是多个PID串级在一起工作。我画了一张图,帮你理清它们的关系:

飞控中的串级PID结构 位置环 (P) 期望位置 → 期望速度 速度环 (PI) 期望速度 → 期望姿态 姿态环 (PID) 期望姿态 → 电机指令 传感器反馈(GPS/IMU/气压计) 串级PID的核心逻辑 外环输出作为内环的期望值,内环响应更快 位置环通常只用P,速度环用PI,姿态环用PID

2.4.1 姿态控制(内环)

这是飞控最核心的环。它直接控制飞机的横滚、俯仰、偏航角。响应速度要求极高,通常要跑到200-400Hz。

  • P:让飞机快速回到目标姿态角。P太小飞机“软绵绵”,P太大飞机“硬邦邦”还震荡。
  • D:抑制角速度震荡,让姿态变化更平滑。我习惯在横滚和俯仰环里加D,偏航环可以少加甚至不加。
  • I:消除稳态误差,比如重心偏移导致的持续倾斜。但I不能太大,否则飞机会“发飘”。

经验值参考(四轴飞行器,3-5kg级别):

参数横滚/俯仰偏航
Kp4.0 - 8.03.0 - 6.0
Ki0.2 - 0.50.1 - 0.3
Kd0.1 - 0.40.0 - 0.1

注意:这只是参考起点,具体数值取决于你的机架、电机、桨叶和重量分布。

2.4.2 高度控制(中环)

高度控制通常用串级结构:外环是高度P,内环是垂直速度PI。

为什么不用D?因为高度测量(气压计/GPS)噪声大、更新慢,微分会放大噪声,得不偿失。我一般只在速度环里加一点D,用来抑制垂直方向的“呼吸感”。

我曾经遇到过一个问题:飞机在悬停时高度上下波动,像在“呼吸”。后来发现是I值太大,加上气压计噪声导致积分项波动。把I减小一半,再给气压计加个低通滤波,问题就解决了。

2.4.3 位置控制(外环)

位置控制是最外层的环,它告诉飞机“你要往哪飞”。通常只用P控制,输出期望速度给速度环。

为什么只用P?因为位置环的响应速度要求不高(5-10Hz就够了),而且积分项在位置环里容易导致“过冲”——飞机飞过头了再飞回来,来回折腾。

我的建议:位置环的P值不要太大。你想想看,位置环的输出是速度,如果P太大,稍微偏一点位置就要求很高的速度,飞机会“窜出去”。我一般从0.5开始调,逐步增加到1.5-2.0就差不多了。

2.5 调参顺序——别搞反了

很多新手一上来就调位置环,这是错的。正确的顺序是:

  1. 先调姿态内环(P → D → I)
  2. 再调速度中环(P → I)
  3. 最后调位置外环(P)

为什么?因为内环是外环的基础。姿态环不稳,速度环和位置环再怎么调都没用。我见过有人花了两周调位置环,结果发现是姿态环的P太小,飞机根本跟不上指令。

重要提醒:每次只调一个参数,调完观察效果。不要同时动P和I,否则你根本不知道是哪个参数起了作用。调参是个“控制变量法”的活,急不得。

2.6 一个简单的PID代码示例

下面是一个我在实际飞控中用过的PID实现,去掉了工程细节,保留了核心逻辑:

// 离散PID控制器(位置式)
typedef struct {
    float Kp, Ki, Kd;       // 三个系数
    float integral;         // 积分累加
    float prev_error;       // 上一次偏差(用于微分)
    float out_limit;        // 输出限幅
    float integral_limit;   // 积分限幅
} PID_Controller;

float PID_Update(PID_Controller *pid, float setpoint, float measurement) {
    float error = setpoint - measurement;
    
    // 比例项
    float p_out = pid->Kp * error;
    
    // 积分项(带限幅)
    pid->integral += error;
    if (pid->integral > pid->integral_limit) pid->integral = pid->integral_limit;
    if (pid->integral < -pid->integral_limit) pid->integral = -pid->integral_limit;
    float i_out = pid->Ki * pid->integral;
    
    // 微分项
    float d_out = pid->Kd * (error - pid->prev_error);
    pid->prev_error = error;
    
    // 合成输出
    float output = p_out + i_out + d_out;
    
    // 输出限幅
    if (output > pid->out_limit) output = pid->out_limit;
    if (output < -pid->out_limit) output = -pid->out_limit;
    
    return output;
}

这段代码里,我特别加了积分限幅。这是血的教训换来的——没有积分限幅,飞机在地面时积分疯狂累积,一解锁就窜天猴。

2.7 本章小结

PID不是魔法,它就是三个“时间维度”的配合:

  • P:看现在,纠偏差
  • I:看过去,消静差
  • D:看未来,抑震荡

在飞控里,它们以串级的形式工作:位置环→速度环→姿态环。调参顺序永远是从内到外。记住这些,你调参就不再是“玄学”,而是有章可循的工程实践。

嗯,这一章就到这里。内容不少,但都是干货。你把这些搞懂了,后面的章节会越学越轻松。