PID控制器原理:P、I、D三个环节的作用、公式推导、常见PID变体

说实话,PID控制器是飞控的灵魂。不管你用多好的传感器、多强的处理器,如果PID没调好,飞机照样乱晃。我见过太多人一上来就调参数,结果越调越乱——其实根本原因是不理解P、I、D各自在干什么。

这一章,咱们把PID拆开揉碎了讲。不搞玄学,只讲实战。

2.1 三个环节的作用——用直觉理解

先别急着看公式。咱们用个场景来理解:你用手托着一杯水,想让它保持水平。

  • P(比例):杯子歪了,你立刻往反方向推。歪得越狠,推得越猛。这就是P——根据当前误差大小,给出正比的控制量。
  • I(积分):如果杯子一直往一边偏,说明有持续的外力(比如风)。P只能对抗瞬时偏差,但对抗不了持续偏差。这时候I就起作用了——它把过去的误差累积起来,慢慢增加修正力,直到偏差消失。
  • D(微分):杯子正在快速往一边倒,你提前预判到趋势,提前用力往回拉。这就是D——根据误差的变化率,提前给出阻尼力,抑制震荡。

我在项目中遇到过一架四轴,悬停时总是低频晃动。P调大了晃得更厉害,调小了又回中慢。后来发现是D太小,阻尼不够。加上D之后,飞机像换了个人似的,稳得一批。

一句话总结:

  • P决定响应速度——越大越快,但容易超调
  • I消除稳态误差——越大越能消除静差,但容易积分饱和
  • D抑制震荡——越大越稳,但会放大噪声

2.2 PID公式推导——从离散到连续

标准PID公式长这样:

u(t) = Kp * e(t) + Ki * ∫e(τ)dτ + Kd * de(t)/dt

其中:

  • e(t) = 期望值 - 实际值(误差)
  • Kp、Ki、Kd 分别是比例、积分、微分系数
  • u(t) 是控制输出

但在飞控里,我们用的是离散形式。因为单片机只能处理离散采样,不能处理连续积分。离散化之后:

u(k) = Kp * e(k) + Ki * Σe(i)*Δt + Kd * (e(k) - e(k-1))/Δt

这里:

  • k 是当前采样时刻
  • Δt 是采样周期(飞控里通常是 1ms 或 4ms)
  • Σe(i) 是从开始到现在的误差累加

嗯,这里要注意:积分项里的 Σe(i)*Δt 其实就是矩形法求积分。采样周期越短,积分越精确。但采样周期太短,计算量又上去了。我个人习惯用 1ms 的采样周期,兼顾精度和性能。

实战小技巧: 很多飞控代码里会把 Ki 写成 Ki = Kp / Ti,其中 Ti 是积分时间常数。这样调参时更容易理解——Ti 越大,积分作用越弱。我习惯用 Ti 而不是直接用 Ki,因为物理意义更直观。

2.3 常见PID变体——飞控里真正用的

实际飞控里,没人用纯PID。为什么?因为纯PID有太多坑。下面是我在项目中踩过的几个变体:

2.3.1 位置式PID vs 增量式PID

类型 输出含义 优点 缺点
位置式 直接输出控制量(如油门值) 直观,容易理解 积分饱和严重,容易超调
增量式 输出控制量的增量(Δu) 无积分饱和,抗积分饱和能力强 需要额外累加,有累积误差

我在做固定翼飞控时,高度环用的是位置式PID,因为需要精确控制油门位置。但角速率环我全用增量式,因为响应快、不容易饱和。你想想看,角速率环如果积分饱和了,飞机会直接翻过去——那可不是闹着玩的。

2.3.2 串级PID——飞控标配

串级PID是飞控里最常用的结构。外环(角度环)输出作为内环(角速率环)的期望值。说白了就是:外环告诉内环“你应该转多快”,内环负责执行。

// 伪代码示例:串级PID
// 外环:角度环
angle_error = target_angle - current_angle;
rate_target = Kp_angle * angle_error + Kd_angle * angle_error_dot;

// 内环:角速率环
rate_error = rate_target - current_rate;
output = Kp_rate * rate_error + Ki_rate * rate_error_integral + Kd_rate * rate_error_dot;

我曾经调试一架六轴,外环P给得太大,内环根本追不上,结果飞机像抽风一样抖。后来把外环P减半,内环P加倍,飞机立刻稳了。记住:内环要快,外环要稳。

2.3.3 抗积分饱和(Anti-Windup)

积分饱和是PID最隐蔽的坑。当执行器饱和(比如油门已经100%了),误差还在累积,积分项会变得巨大。等误差反向时,积分项需要很长时间才能退回来——这就是“饱和”。

我曾经在调试一台植保机时,遇到下降时高度过冲。查了半天,发现是积分饱和。解决方案很简单:

  • 积分限幅:给积分项设个上限,比如 ±油门最大值的30%
  • 积分冻结:当执行器饱和时,停止积分累加
  • 反馈积分:用实际输出和期望输出的差值来修正积分

避坑指南: 我曾经在PX4代码里遇到过积分饱和导致的高度震荡。当时查了三天,最后发现是积分限幅设得太大了。把限幅从50%降到20%,问题立刻解决。所以,积分限幅不是越大越好,要根据执行器行程来定。

2.3.4 微分先行(Derivative on Measurement)

标准PID的微分项是对误差求导。但误差突变时(比如目标值突然改变),微分项会瞬间爆炸——这叫“微分冲击”。

解决办法:只对测量值求导,不对误差求导。这样目标值变化时,微分项不会跳变。

// 标准微分:容易冲击
d_term = Kd * (error - last_error);

// 微分先行:只对测量值求导
d_term = Kd * (last_measurement - measurement);

我习惯在角速率环里用微分先行,因为遥控器打杆时目标值变化很快,标准微分会导致电机瞬间猛转,听着都吓人。

2.4 PID知识体系总览

下面这张图把PID的核心逻辑串起来了。我建议你保存下来,调参时对照着看。

PID控制器知识体系 PID控制器知识体系 PID控制器 P 比例环节 I 积分环节 D 微分环节 响应速度 越大越快,但易超调 消除稳态误差 越大越准,但易饱和 抑制震荡 越大越稳,但放大噪声 位置式 / 增量式 串级PID 抗积分饱和 核心原则:内环要快,外环要稳;积分要限幅,微分要先行 调参顺序:先P,再加D,最后加I

2.5 调参顺序——我的实战经验

很多新手拿到飞控,上来就三个参数一起调。结果P大了加I,I大了加D,D大了又减P——陷入死循环。我个人的调参顺序是:

  1. 先调P:从小到大,直到出现轻微震荡。然后回调20%。
  2. 再加D:从小到大,直到震荡消失。D不要太大,否则噪声会放大。
  3. 最后加I:从小到大,直到稳态误差消失。I不要太大,否则积分饱和。

记住:P和D是搭档,I是最后才上的。我见过有人先调I,结果飞机一直晃,还以为是P不够大——其实I已经饱和了。

一个小技巧: 调参时用手轻轻推一下飞机,看它回中的速度和超调量。如果回中慢,加P;如果回中后还在晃,加D;如果回中后停歪了,加I。这个方法比看曲线直观多了。