PID控制器原理详解

简介:

什么是 PID?
它是一种在编程中使用的基本方法,如果正确调整,可以令人难以置信的有效和准确,PID代表比例积分微分,3个单独的部分连接在一起,虽然有时你不需要三个都使用.例如,您可以改为有P控制,PI控制或PD控制。 在本文档中我已经包含了伪代码的例子(非正式语言,不是真正的代码,但是很接近)。

P - Proportional 比例

想象一下一个全速行进的机器人,假设传感器上的值为1000。 现在,由于它的速度和惯性,它可能会超过一点, 当编写程序时,这可能是一个大麻烦,你想尽可能的准确。这个问题如图所示(x轴上的绿色标记代表理想距离):
在理想世界中,您告诉机器人在哪里停止,它就停止在哪里

这里写图片描述

但是,我们不是理想世界,如果我们突然告诉它停止,我们会有超调的问题,结果可能是这样的:
这里写图片描述

现在这个超调不会是一个问题,如果它的距离总是相同的。然而,有很多变量可以改变它超出的距离。 例如:

  • 电池电压。 如果电池电量不足,则电机不能快速运行,会有较少的惯性, 在这种情况下,机器人超调变小
  • 如果机器人碰到一些东西,那么超调会变小
  • 如果某些东西将机器人朝向想要行进的方向推动,则超调将会
    变得更大

所以你可以看到,超调不好。 所以P控制器控制速度, 所以P控制器控制速度平稳地,让它在接近目标时减速,以缩小超调。 这就是为什么它被称为比例控制器 – 输出速度与要更改的值成比例,我们称之为误差(error)。

它是怎么做的?
你有一个很好的变量,叫做误差(error)。这将是根据这个值对应的传感器的读书,它还在变化,就像前文提到的。例如,误差可以是剩下要走的距离,剩下的要提升的高度,需要继续加热的温度,等等。
为了计算误差,我们只需减去传感器给我们的读数,这个读书我们希望传感器在完成后立即告诉我们。

误差 =(目标值) - (传感器读数)

error = (target value) – (sensor reading)

因此,通过给出一些示例值来说明你想要的距离和它实际走过的距离,你会看到当它接近目标时,误差会越来越小。

下面是几个示例值:

目标值当前传感器读数误差
1000200800
1000400600
1000600400
1000800200
100010000

我们可以用这个来控制应用程序的速度,如果你想用一个简单的P控制器,没有I和D项。为此,我们可以写:

error = (target value) – (sensor reading);
speed = error;

另外,误差值可能不太像我们想要的那样。 这个值可能太高了,所以它超标了很多。 如果过调,它会尝试和纠正过调(误差将变成负数),所以你可以在在调试器或窗口观察值和发生的情况,你将看到误差在振荡,超调然后过度校正。

或者,误差值太小,但通常不会遇到这个问题。

对于任一问题,您可以更改误差,以保持其比例因子,但你可以将错误乘以(或除)另一个数字,一个常数。 你可以称之为任何你喜欢的名字,但它通常被称为“Kp” – 比例组件的常数。

Kp = 0.5;
while (condition)
{
error = (target value) – (sensor reading);
speed = Kp * error;
}

I - Integral 积分

所以代码的比例部分已经得到了,所以剩下的误差是相当小的。比例太小,不能产生很大的差异。这就是积分。积分是之前的误差的总和。所以当你的误差非常小,积分起到作用,但它实际上如何工作的呢?

积分想要得到它,使其行进足够快以缩小误差,但不要太快,因为那样可能会有超调的风险.它通过慢慢加速的方式去决定走多快,积分可以想这样计算

积分=积分+误差* 时间增量
integral = integral + error*dT

以上的设置是这样的,所以“积分”的新值等于(等号左侧)
先前的“积分”值,加上(误差*时间增量)。忽略时间增量部分,我稍后再来讨论这个问题。
积分增加的方式可以如下表中所示(使用误差为2 做例子):

Cycle #Previous value for integralErrorNew value for integral
0022
1224
2426
3628
48210

粗体的数字(New value for integral积分的新值)在不断增加.

那么我们如何将它添加到现有代码中呢? 我们把它加起来。所以现在的速度是:

speed = (Kp * error) + integral

那么现在加了积分伪代码就变成这样:

Kp = 0.5;
while (condition)
{
error = (target value) – (sensor reading);
integral = integral + error;
speed = Kp*error + integral;
}

就像比例部分的代码一样,我们需要对积分加上一个常数项。我将使用0.2作为Ki的一个例子值,尽管和K一样,它只是一个数字我随便举例的。

Kp = 0.5;
Ki = 0.2;
while (condition)
{
error = (target value) – (sensor reading);
integral = integral + error;
speed = Kp*error + Ki*integral;
}                                                                                                    

前文告诉过你忽略时间增量,但我现在就解释一下

Integral = integral + error*dT

增量时间是必须的,因为循环不会总是花费同样的时间完成每个周期,但是当每个周期花费同样的时间时, dT可以合并到Ki中,如果每个周期不花费同样的时间,只需要将代码用于每个周期,这样你可以使用这个周期的时间作为你的增量时间

在这个教程里,我们将假设周期之间的时间总是相同的,因此dT将被并入Ki。

这里是关于积分的几个问题:

问题1:

当你的误差几近于0时,你的积分可能任然是一个可以保持速度足够高保持错误的变化的值,方程只会自己达到0,如果它超过一个等于0 的误差,那么负误差就会减去现有的积分.所以,如果速度任然很高来保持误差,我们将面临一个问题,是吧?

对于这个题,有一个非常简单的解决方案,那就是在误差达到0时重新设置积分,如下所示

Kp = 0.5;
Ki = 0.2;
while (condition)
{
error = (target value) – (sensor reading);
integral = integral + error;
if (error is 0)
{
integral = 0;
}
speed = Kp*error + Ki*integral;
}

问题2:

它被称为integral wind-up.它可以从一个大误差开始,一旦循环开始运行,积分将开始构建。所以,在这个积分需要的时候

使用时,它的值已经远远超过可用的值。有一些简单的解决办法, 我列举三个解决方案:

解决方案#1 –限制积分所能达到的值。如果太高,为什么不给它加个限度?一个限制可以写成如下:

if (integral is greater than or equal to the maximum value)
{
integral = maximum value;
}

但是,如果积分太大,但它是负的形式(即,使速度相反)快速地,你需要重写和上面一样的,但是为负的版本的积分。

解决方案#2 - 限制积分允许建立的范围。因此,如果错误对于积分来说太大了,我们可以禁用该范围的积分。

if ( error is greater than useful for the integral )
{
disable the integral (set the integral to 0);
}

但同样,就像在解决方案1中一样,你需要重写相同的但要是积分的负值。或者,如果您的编程语言支持使用一个绝对值的工具,您可以使用它使代码更短,也许更简单。
如何在代码中实现绝对值的工具:

if ( abs(error) is greater than useful for the integral)
{
disable the integral (set the integral to 0);
}

解决方案#3–限制积分允许积累的时间。这样做有点复杂,但仍然可行。

对于本教程,我们将使用解决方案#2,因为它是最简短的.
适合计算积分的范围将为+/- 40,但只是一个随机数。 下面代码的完整版(如果剩下的话会被称为“PI控制“[比例积分控制])将是这样的:

Kp = 0.5;
Ki = 0.2;
while (condition)
{
error = (target value) – (sensor reading);
integral = integral + error;
if (error = 0)
{
integral = 0;
}
if ( abs(error) > 40)
{
integral = 0;
}
speed = Kp*error + Ki*integral;
}

D - Derivative 导数

PID代码的最后一点——导数!导数的工作就是预测未来的误差价值,然后进行相应的速度行为。例如,如果它认为它会过调,会使它慢下来。
为了能够预测下一个误差,我们需要知道先前的误差,然后找到这两者的区别。
derivative = ( (current error) – (previous error) ) / dT

这个公式将发现当前误差和之前的误差之间的变化,然后我们可以通过将其添加到当前误差中来预测下一个误差。就像积分一样,导数是由dT影响的,但是一个循环的周期话费的时间总是相同的,dT可以合并到Kd。

这里有一个表,展示了未来可能发生的误差的例子,通过导数计算的:

Current errorPrevious errorNext error (error + derivative)
505545
203010
231
515-5

在我们的代码中,导数是用上面的方程计算出来的,然后加到速度上(在这里也乘以Kd来达到缩放的目的)。

我们需要创建一个新的整数,来命名先前的误差(或者任何一个你喜欢的方式,只要它表示之前的误差值),我们让它更新自己在我们我们计算完导数后。我们可以用简单的方式让它更新,设置它的值为误差值。

一下是完整的控制PID的伪代码:

Kp = 0.5;
Ki = 0.2;
Kd = 0.1;
while (condition)
{
error = (target value) – (sensor reading);
integral = integral + error;
if (error = 0)
{
integral = 0;
}
if ( abs(error) > 40)
{
integral = 0;
}
derivative = error – previous_error;
previous_error = error;
speed = Kp*error + Ki*integral + Kd*derivative;
}

调整常数项

这是费时又费力的工作。 有很多不同的方法来调整Kp,Ki和Kd,我会尽我所能地解释一下他们。 调整PID常数可以通过计算机程序完成,通过数学计算或通过手动调整, 我强烈建议您随时查看误差,速度等等,所以你可以看到距离到达目标还剩下多少需要改变。 使用调试器或类似的监视工具来检查结果。

首先,了解调节PID控制器的规则很重要。 当每个常数增加时有什么改变如下表所示。 常数
术语在左侧的列中,并且它们具有的效果在顶行列出。
效果如下:

Rise time - 从起点到目标点所需的时间
Overshoot - 改变的量太大了; 值比错误更大
Settling time - 遇到变化时需要解决的时间
Steady-state error - 均衡时的误差
Stability - 速度的“平滑度”

当每个常数增加时会发生什么?

Constant:Rise time:Overshoot:SettlingSteady-state Stability:Stability:
KpdecreaseincreaseSmall changedecreasedegrade
Kidecreaseincreaseincreasedecreasedegrade
Kdminor changedecreasedecreaseNo effectImprove (if small enough)

手工调优:
手动调优是完全由你自己完成的——没有涉及到数学,但有时也会有些低效。我个人使用手动调优方法,因为我可以温和地增加每一个常量,并且知道什么时候会变得太高,而像ziegler - nichols方法这样的数学方法,你永远不会知道事情会怎样发展,直到你尝试之后。毕竟,在理论上,实践和理论是一样的,但在实践中,它们不是
我调整常量的方式如下:

  1. 将Kp、Ki和Kd设置为0。这将使他们暂时瘫痪。
  2. 增加Kp直到误差相当小,但是它仍然从开始到结束足够快。
  3. 增加Kd,直到任何超过你可能拥有的覆盖。但是小心Kd——太多会使它过度
  4. 增加Ki,直到任何仍然存在的错误被消除。从一个非常小的数字开始,不要惊讶,如果它小到0.0001甚至更小。
  5. 使用调整常量的规则(在上一页的表格中),您可以稍微更改一些常量,以使其工作到最佳性能。

数学方式
@todo 试过再补充
工具方式
@todo试过再补充

补充

while循环:
您可能已经注意到,在我的所有伪代码示例中,我将主代码放在while循环中。 这是因为误差变化时需要重新计算误差,积分,微分和速度。 例如,如果您将速度计算一次,但不再次计算,则无法重新刷新并相应地更改速度 - 它将以原始速度继续运行!

循环对PID控制器至关重要 - 不要忘记添加一个!

那么,你如何让它最终退出循环,每次当它完成了它的工作?
其中的一个常见的方法是,如果你知道它需要多长时间才能完成,你
可以将循环设置为指定的时间量(但显然比它需要的稍微多一点),以确保它确实完成了循环。

另一种方法是检测一旦误差达到零,并且已经完成。如果你选择这种方式,一定要注意确保它已经完全停止。举个例子,如果你告诉它运行循环直到误差达到0,如果有任何过度,没什么能做的,因为它将会停止(过度,错误必须通过一个点(0)。所以,你可以得到循环多长时间内误差保持在0。如果它只是在一个非常短的时间内处于0,那么很有可能它已经被过度并且需要重新调整自己。或者,如果它在一段较长时间内保持在0的值,那么说它已完全停止是安全的。

重新设置积分和之前的错误:
我前面已经讲过了,有时你需要把积分重置为0,但是最后一次需要0的值。当您开始循环时,代码会自动假设这个积分是0,之前的误差是它应该的值。但是,如果循环已经运行,那么这个积分的值和之前的错误仍然是原来的值。

这可以通过在循环开始之前设置积分值和前一个错误的值来确定。

总结:

Proportional-你的误差,在真实值和预期值之间。
​ error = (target value) – (sensor reading)

Integral – 先前误差的运行和,用于在误差很小的时候进行精细的调整。
​ integral = integral + error*dT

Derivative – 误差的变化,用来预测下一个误差可能是什么。
​ derivative = ( (current error) – (previous error) ) / dT

The loop – 所有的计算都需要在循环中运行-不要忘记包含它!

将三个组件放在一起,再加上一些对Kp、Ki和Kd的精确值,您将拥有一个非常一致和精确的控制器。

调试口诀

参数整定找最佳,从小到大顺序查,先是比例后积分,最后再把微分加,
曲线振荡很频繁,比例度盘要放大,曲线漂浮绕大湾,比例度盘往小扳,
曲线偏离回复慢,积分时间往下降,曲线波动周期长,积分时间再加长,
曲线振荡频率快,先把微分降下来,动差大来波动慢,微分时间应加长,
理想曲线两个波,前高后低4比1

具体方法

(1)确定比例系数Kp
确定比例系数Kp时,首先去掉PID的积分项和微分项,可以令Ti=0、Td=0,使之成为纯比例调节。输入设定为系统允许输出最大值的60%~70%,比例系数Kp由0开始逐渐增大,直至系统出现振荡;再反过来,从此时的比例系数Kp逐渐减小,直至系统振荡消失。记录此时的比例系数Kp,设定PID的比例系数Kp为当前值的60%~70%。
(2)确定积分时间常数Ti
比例系数Kp确定之后,设定一个较大的积分时间常数Ti,然后逐渐减小Ti,直至系统出现振荡,然后再反过来,逐渐增大Ti,直至系统振荡消失。记录此时的Ti,设定PID的积分时间常数Ti为当前值的150%~180%。
(3) 确定微分时间常数Td
微分时间常数Td一般不用设定,为0即可,此时PID调节转换为PI调节。如果需要设定,则与确定Kp的方法相同,取不振荡时其值的30%。
(4) 系统空载、带载联调
对PID参数进行微调,直到满足性能要求。

reference:
An introduction and tutorial for PID controllers, by George Gillard

  • 38
    点赞
  • 206
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
PID控制是一种经典的反馈控制算法,它能够自动调节控制对象的输出,使其达到期望值。PID控制由三个部分组成:比例(P)、积分(I)和微分(D)。下面详细介绍PID控制原理及其实例说明。 1. PID控制原理 PID控制的目标是调节控制对象的输出,使其达到期望值。控制通过不断地测量被控制对象的输出与期望值的差异,根据PID控制算法输出控制信号,从而调节被控制对象的输出。PID算法的具体实现是:将目标值与实际值的差值称为偏差(error),PID控制根据偏差来计算控制信号。 PID控制的三个参数分别控制着控制的比例、积分和微分部分。比例部分输出与偏差成正比,如果偏差越大,则输出信号越强,反之输出信号越弱。积分部分输出与偏差的积分成正比,可以消除静态误差。微分部分输出与偏差的微分成正比,可以抑制瞬间变化和震荡。 2. PID控制实例说明 一个常见的PID控制实例是温度控制系统。假设我们需要将一个房间的温度控制在22℃左右。我们可以使用一个PID控制来自动调节空调的温度设置,使得房间的温度保持在设定值附近。 比例控制部分:根据当前温度与设定温度的差异计算出偏差,乘以比例系数Kp,得到比例控制输出。 积分控制部分:将偏差的累积之和与积分系数Ki相乘,得到积分控制输出。 微分控制部分:将偏差的变化率与微分系数Kd相乘,得到微分控制输出。 将三个控制输出加权相加,得到最终的PID控制输出,控制空调的温度设定值。 总的来说,PID控制是一种简单而有效的控制算法,可以应用于许多领域,如自动控制、机器人、工业控制等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值