第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米时,误差归零了,但积分项里还存着之前累积的一大笔"债"。这笔债会让电机继续加速,飞机直接冲过目标高度——这就是积分饱和。

积分饱和发生的条件:

  1. 系统存在执行器限幅(电机转速上限、舵机角度限位)
  2. 误差持续存在时间较长
  3. 积分增益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 知识体系总览

下面这张图把本章的核心逻辑串起来了,你可以对照着看:

PID控制器核心原理与积分饱和机制 位置式PID 增量式PID 输出 = 绝对控制量 积分累积所有历史误差 饱和风险高 输出 = 控制量增量 无历史误差累积 天然抗饱和 积分饱和问题 执行器限幅 + 持续误差 → 积分项过度累积 → 输出超调/振荡 积分限幅法 简单但需调限幅值 积分分离法 需调阈值参数 反计算法 工业级推荐方案 推荐:反计算法 + 积分限幅配合使用

3.7 实战中的选择建议

说了这么多理论,到底怎么选?我给大家一个实战指南:

  • 飞控内环(角速率环):用增量式PID。响应快、输出平滑,积分饱和风险低。我在PX4的rate controller里就是这么干的。
  • 飞控外环(姿态角环/位置环):用位置式PID + 反计算法抗饱和。需要绝对位置约束,反计算法能保证积分项不失控。
  • 地面站仿真调试:先用位置式PID观察积分项的变化趋势,再决定是否切换到增量式或加抗饱和。

避坑指南:我曾经在一个项目中,为了追求响应速度,把Ki调得很大,结果飞机在风场中频繁出现积分饱和,姿态振荡得像筛糠一样。后来加了反计算法,Ki可以比原来大30%而不饱和。所以,抗饱和不是限制性能,而是释放性能。