第3章 PID控制器核心原理:位置式PID与增量式PID,积分饱和与抗积分饱和机制
各位好,我是你们的老朋友。今天咱们来聊聊PID控制器里两个绕不开的话题:位置式PID和增量式PID,以及那个让无数飞控工程师头疼的积分饱和问题。
说实话,我刚入行那会儿,觉得PID不就是P、I、D三个参数调来调去嘛,能有多复杂?直到有一次在四旋翼上做定点悬停测试,飞机突然像抽风一样猛地抬头,差点把桨叶打到自己脸上。后来一查,就是积分饱和惹的祸。从那以后,我对这部分内容再也不敢马虎了。
3.1 位置式PID:最直观的控制器
位置式PID,说白了就是直接计算当前时刻的控制量。它的数学形式长这样:
u(t) = Kp * e(t) + Ki * ∫e(τ)dτ + Kd * de(t)/dt
在离散系统中,我们把它写成:
u(k) = Kp * e(k) + Ki * Σe(i) * T + Kd * (e(k) - e(k-1)) / T
其中T是采样周期,e(k)是当前误差,Σe(i)是从开始到现在的误差累积和。
位置式PID的特点:
- 输出直接对应执行机构的绝对位置(比如舵机角度、电机PWM占空比)
- 积分项会累积所有历史误差,这意味着任何过去的偏差都会影响当前输出
- 一旦积分项饱和,需要很长时间才能退饱和
核心要点:位置式PID的输出是全量输出,它知道"现在该给多少",而不是"现在该比上次多给多少"。
3.2 增量式PID:只关心变化量
增量式PID的思路完全不同。它不计算当前时刻的绝对控制量,而是计算当前时刻相对于上一时刻的控制量增量。
公式推导其实很简单,从位置式出发:
Δu(k) = u(k) - u(k-1)
= Kp * [e(k) - e(k-1)]
+ Ki * e(k) * T
+ Kd * [e(k) - 2*e(k-1) + e(k-2)] / T
你看,增量式PID的输出只跟最近三次的误差有关,跟历史累积误差完全没关系。
增量式PID的优势:
- 没有积分累积,天然抗积分饱和
- 输出变化平缓,不会出现大幅跳变
- 容易实现手动/自动切换的无扰切换
- 计算量小,适合资源受限的嵌入式系统
我的经验:在飞控中,内环(角速率环)我习惯用增量式PID,因为响应快、输出平滑。外环(姿态角环)则用位置式PID,因为需要明确的绝对位置约束。
3.3 两种PID的对比
| 对比维度 | 位置式PID | 增量式PID |
|---|---|---|
| 输出含义 | 绝对控制量 | 控制量增量 |
| 积分累积 | 累积所有历史误差 | 无累积 |
| 积分饱和风险 | 高 | 低(无积分项累积) |
| 输出突变风险 | 高(积分饱和时) | 低 |
| 手动/自动切换 | 需要额外处理 | 天然无扰 |
| 计算复杂度 | 中等 | 低 |
| 适用场景 | 外环控制、位置控制 | 内环控制、速度控制 |
3.4 积分饱和:飞控的隐形杀手
积分饱和是什么?我举个例子你就明白了。
假设你的四旋翼要爬升到10米高度,但当前只有1米。误差是9米,很大。积分项开始疯狂累积。当飞机到达10米时,误差归零了,但积分项里还存着之前累积的一大笔"债"。这笔债会让电机继续加速,飞机直接冲过目标高度——这就是积分饱和。
积分饱和发生的条件:
- 系统存在执行器限幅(电机转速上限、舵机角度限位)
- 误差持续存在时间较长
- 积分增益Ki设置偏大
警告:积分饱和不是"参数没调好"那么简单。它是PID控制器的固有问题,只要你的执行器有物理限幅,积分饱和就一定会出现。区别只在于严重程度。
3.5 抗积分饱和机制:实战中的解决方案
我在项目中用过好几种抗积分饱和方法,这里给大家介绍最实用的三种。
3.5.1 积分限幅法
最简单粗暴的方法:给积分项设置上下限。
// 伪代码示例
integral += error * dt;
if (integral > integral_max) integral = integral_max;
if (integral < integral_min) integral = integral_min;
这个方法实现简单,但有个问题:限幅值设多少合适?设小了影响控制精度,设大了防不住饱和。
3.5.2 积分分离法
当误差较大时,停止积分;误差较小时,恢复积分。
if (abs(error) < threshold) {
integral += error * dt;
} else {
// 误差太大,不积分
integral = integral; // 保持当前值
}
这个方法效果不错,但阈值需要仔细调。阈值太大,积分作用不明显;阈值太小,饱和防不住。
3.5.3 反计算法(Back-Calculation)
这是我最推荐的方法,也是工业界用得最多的。核心思想:当输出饱和时,把超出部分反馈回积分项,让它"吐"出来。
// 反计算法伪代码
u_saturated = saturate(u, u_min, u_max);
integral += error * dt + Kc * (u_saturated - u) * dt;
// Kc是反计算增益,通常取1/Ki
你看,当输出饱和时,u_saturated - u是负的,积分项会减小。当输出退出饱和时,积分项已经调整到合适的大小了。
我的习惯:在PX4和ArduPilot的飞控代码里,我通常用反计算法配合积分限幅。反计算法负责动态调整,积分限幅负责兜底。两者配合,基本能解决99%的积分饱和问题。
3.6 知识体系总览
下面这张图把本章的核心逻辑串起来了,你可以对照着看:
3.7 实战中的选择建议
说了这么多理论,到底怎么选?我给大家一个实战指南:
- 飞控内环(角速率环):用增量式PID。响应快、输出平滑,积分饱和风险低。我在PX4的rate controller里就是这么干的。
- 飞控外环(姿态角环/位置环):用位置式PID + 反计算法抗饱和。需要绝对位置约束,反计算法能保证积分项不失控。
- 地面站仿真调试:先用位置式PID观察积分项的变化趋势,再决定是否切换到增量式或加抗饱和。
避坑指南:我曾经在一个项目中,为了追求响应速度,把Ki调得很大,结果飞机在风场中频繁出现积分饱和,姿态振荡得像筛糠一样。后来加了反计算法,Ki可以比原来大30%而不饱和。所以,抗饱和不是限制性能,而是释放性能。