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

PID电机控制目录 第1 章 数字PID 控制 1.1 PID 控制原理 1.2 连续系统的模拟PID 仿真 1.3 数字PID 控制 1.3.1 位置式PID 控制算法 1.3.2 连续系统的数字PID 控制仿真 1.3.3 离散系统的数字PID 控制仿真 1.3.4 增量式PID 控制算法及仿真 1.3.5 积分分离PID 控制算法及仿真 1.3.6 抗积分饱和PID 控制算法及仿真 1.3.7 梯形积分PID 控制算法 1.3.8 变速积分PID 算法及仿真 1.3.9 带滤波的PID 控制仿真 1.3.10 不完全微分PID 控制算法及仿真 1.3.11 微分先行PID 控制算法及仿真 1.3.12 带死区的PID 控制算法及仿真 1.3.13 基于前馈补偿的PID 控制算法及仿真 1.3.14 步进式PID 控制算法及仿真 第2 章 常用的PID 控制系统 2.1 单回路PID 控制系统 2.2 串级PID 控制 2.2.1 串级PID 控制原理 2.2.2 仿真程序及分析 2.3 纯滞后系统的大林控制算法 2.3.1 大林控制算法原理 2.3.2 仿真程序及分析 2.4 纯滞后系统的Smith 控制算法 2.4.1 连续Smith 预估控制 2.4.2 仿真程序及分析 2.4.3 数字Smith 预估控制 2.4.4 仿真程序及分析 第3 章 专家PID 控制和模糊PID 控制 3.1 专家PID 控制 3.1.1 专家PID 控制原理 3.1.2 仿真程序及分析 3.2 模糊自适应整定PID 控制 3.2.1 模糊自适应整定PID 控制原理 3.2.2 仿真程序及分析 3.3 模糊免疫PID 控制算法 3.3.1 模糊免疫PID 控制算法原理 3.3.2 仿真程序及分析 第4 章 神经PID 控制 4.1 基于单神经元网络的PID 智能控制 4.1.1 几种典型的学习规则 4.1.2 单神经元自适应PID 控制 4.1.3 改进的单神经元自适应PID 控制 4.1.4 仿真程序及分析 4.1.5 基于二次型性能指标学习算法的单神经元自适应PID 控制 4.1.6 仿真程序及分析 4.2 基于BP 神经网络整定的PID 控制 4.2.1 基于BP 神经网络的PID 整定原理 4.2.2 仿真程序及分析 4.3 基于RBF 神经网络整定的PID 控制 4.3.1 RBF 神经网络模型 4.3.2 RBF 网络PID 整定原理 4.3.3 仿真程序及分析 4.4 基于RBF 神经网络辨识的单神经元PID 模型参考自适应控制 4.4.1 神经网络模型参考自适应控制原理 4.4.2 仿真程序及分析 4.5 基于CMAC(神经网络)与PID 的并行控制 4.5.1 CMAC 概述 4.5.2 CMAC 与PID 复合控制算法 4.5.3 仿真程序及分析 4.6 CMAC 与PID 并行控制的Simulink 仿真 4.6.1 Simulink 仿真方法 4.6.2 仿真程序及分析 第5 章 基于遗传算法整定的PID 控制 5.1 遗传算法的基本原理 5.2 遗传算法的优化设计 5.2.1 遗传算法的构成要素 5.2.2 遗传算法的应用步骤 5.3 遗传算法求函数极大值 5.3.1 遗传算法求函数极大值实例 5.3.2 仿真程序 5.4 基于遗传算法的PID 整定 5.4.1 基于遗传算法的PID 整定原理 5.4.2 基于实数编码遗传算法的PID 整定 5.4.3 仿真程序 5.4.4 基于二进制编码遗传算法的PID 整定 5.4.5 仿真程序 5.5 基于遗传算法摩擦模型参数辨识的PID 控制 5.5.1 仿真实例 5.5.2 仿真程序 第6 章 先进PID 多变量解耦控制 6.1 PID 多变量解耦控制 6.1.1 PID 解耦控制原理 6.1.2 仿真程序及分析 6.2 单神经元PID 解耦控制 6.2.1 单神经元PID 解耦控制原理 6.2.2 仿真程序及分析 6.3 基于DRNN 神经网络整定的PID 解耦控制 6.3.1 基于DRNN 神经网络参数自学习PID 解耦控制原理 6.3.2 DRNN 神经网络的Jacobian 信息辨识 6.3.3 仿真程序及分析 第7 章 几种先进PID 控制方法 7.1 基于干扰观测的PID 控制 7.1.1 干扰观测设计原理 7.1.2 连续系统的控制仿真 7.1.3 离散系统的控制仿真 7.2 非线性系统的PID 鲁棒控制 7.2.1 基于NCD 优化的非线性优化PID 控制 7.2.2 基于NCD 与优化函数结合的非线性优化PID 控制 7.3 一类非线性PID 控制设计 7.3.1 非线性控制设计原理 7.3.2 仿真程序及分析 7.4 基于重复控制补偿的高精度PID 控制 7.4.1 重复控制原理 7.4.2 基于重复控制补偿的PID 控制 7.4.3 仿真程序及分析 7.5 基于零相差前馈补偿的PID 控制 7.5.1 零相差控制原理 7.5.2 基于零相差前馈补偿的PID 控制 7.5.3 仿真程序及分析 7.6 基于卡尔曼滤波的PID 控制 7.6.1 卡尔曼滤波原理 7.6.2 仿真程序及分析 7.6.3 基于卡尔曼滤波的PID 控制 7.6.4 仿真程序及分析 7.7 单级倒立摆的PID 控制 7.7.1 单级倒立摆建模 7.7.2 单级倒立摆控制 7.7.3 仿真程序及分析 7.8 吊车-双摆系统的控制 7.8.1 吊车-双摆系统的建模 7.8.2 吊车-双摆系统的仿真 第8 章 灰色PID 控制 8.1 灰色控制原理 8.1.1 生成数列 8.1.2 GM 灰色模型 8.2 灰色PID 控制 8.2.1 灰色PID 控制的理论基础 8.2.2 连续系统灰色PID 控制 8.2.3 仿真程序及分析 8.2.4 离散系统灰色PID 控制 8.2.5 仿真程序及分析 8.3 灰色PID 的位置跟踪 8.3.1 连续系统灰色PID 位置跟踪 8.3.2 仿真程序及分析 8.3.3 离散系统灰色PID 位置跟踪 8.3.4 仿真程序及分析 第9 章 伺服系统PID 控制 9.1 伺服系统低速摩擦条件下PID 控制 9.1.1 Stribeck 摩擦模型描述 9.1.2 一个典型伺服系统描述 9.1.3 仿真程序及分析 9.2 伺服系统三环的PID 控制 9.2.1 伺服系统三环的PID 控制原理 9.2.2 仿真程序及分析 9.3 二质量伺服系统的PID 控制 9.3.1 二质量伺服系统的PID 控制原理 9.3.2 仿真程序及分析 第10 章 PID 实时控制的C++语言设计及应用 10.1 M 语言的C++转化 10.2 基于C++的三轴飞行模拟转台伺服系统PID 实时控制 10.2.1 控制系统构成 10.2.2 系统各部分功能的软件设计 10.2.3 仿真程序及分析 参考文献
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值