抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

Kelecn

“唯爱与科技不可辜负!”

简介:PID控制算法是结合比例、积分和微分三种环节于一体的控制算法,它是连续系统中技术最为成熟、应用最为广泛的一种控制算法。

一、什么是PID算法


PID,就是“比例(proportional)、积分(integral)、微分(derivative)”,是一种很常见的控制算法。常用于需要将某一个物理量“保持稳定”的场合(比如维持平衡,稳定温度、转速等)。

总的来说,当得到系统的输出后,将输出经过比例,积分,微分3种运算方式,叠加到输入中,从而控制系统的行为。

在工业应用中PID及其衍生算法是应用最广泛的算法之一,是当之无愧的万能算法,如果能够熟练掌握PID算法的设计与实现过程,对于一般的研发人员来讲,应该是足够应对一般研发问题了,而难能可贵的是,在我所接触的控制算法当中,PID控制算法又是最简单,最能体现反馈思想的控制算法,可谓经典中的经典。经典的未必是复杂的,经典的东西常常是简单的,而且是最简单的,想想牛顿的力学三大定律吧,想想爱因斯坦的质能方程吧,何等的简单!简单的不是原始的,简单的也不是落后的,简单到了美的程度。

二、PID算法原理


$$
U(t)=K_P[e(t)+\frac{1}{T_I}\int{e(t)}dt+\frac{T_De(t)}{dt}]
$$

三个重要的参数:
Kp:控制器的比例系数。
Ti:控制器的积分时间,也称积分系数。
Td:控制器的微分时间,也称微分系数。

1、P - 比例部分

比例环节的作用是对偏差瞬间作出反应。偏差一旦产生控制器立即产生控制作用, 使控制量向减少偏差的方向变化。 控制作用的强弱取决于比例系数Kp, 比例系数Kp越大,控制作用越强, 则过渡过程越快, 控制过程的静态偏差也就越小; 但是Kp越大,也越容易产生振荡, 破坏系统的稳定性。 故而,比例系数Kp选择必须恰当, 才能过渡时间少, 静差小而又稳定的效果

2、I - 积分部分

从积分部分的数学表达式可以知道, 只要存在偏差, 则它的控制作用就不断的增加; 只有在偏差e(t)=0时, 它的积分才能是一个常数,控制作用才是一个不会增加的常数。 可见,积分部分可以消除系统的偏差

我们需要设置一个积分量。只要偏差存在,就不断地对偏差进行积分(累加),并反应在调节力度上。
积分环节的调节作用虽然会消除静态误差,但也会降低系统的响应速度,增加系统的超调量。积分常数Ti越大,积分的积累作用越弱,这时系统在过渡时不会产生振荡; 但是增大积分常数Ti会减慢静态误差的消除过程,消除偏差所需的时间也较长, 但可以减少超调量,提高系统的稳定性。

当 Ti 较小时, 则积分的作用较强,这时系统过渡时间中有可能产生振荡,不过消除偏差所需的时间较短。所以必须根据实际控制的具体要求来确定Ti 。

3、D - 微分部分

实际的控制系统除了希望消除静态误差外,还要求加快调节过程。在偏差出现的瞬间,或在偏差变化的瞬间, 不但要对偏差量做出立即响应(比例环节的作用), 而且要根据偏差的变化趋势预先给出适当的纠正。为了实现这一作用,可在 PI 控制器的基础上加入微分环节,形成 PID 控制器。
我们需要一个控制作用,让被控制的物理量的“变化速度”趋于0,即类似于“阻尼”的作用。

微分环节的作用使阻止偏差的变化。它是根据偏差的变化趋势(变化速度)进行控制。偏差变化的越快,微分控制器的输出就越大,并能在偏差值变大之前进行修正。微分作用的引入, 将有助于减小超调量, 克服振荡, 使系统趋于稳定, 特别对髙阶系统非常有利, 它加快了系统的跟踪速度。但微分的作用对输入信号的噪声很敏感,对那些噪声较大的系统一般不用微分, 或在微分起作用之前先对输入信号进行滤波。

三、PID算法应用实例


PID 控制算法可以分为位置式 PID增量式 PID 控制算法。

两者的区别:

(1)位置式PID控制的输出与整个过去的状态有关,用到了误差的累加值;而增量式PID的输出只与当前拍和前两拍的误差有关,因此位置式PID控制的累积误差相对更大;

(2)增量式PID控制输出的是控制量增量,并无积分作用,因此该方法适用于执行机构带积分部件的对象,如步进电机等,而位置式PID适用于执行机构不带积分部件的对象,如电液伺服阀。

(3)由于增量式PID输出的是控制量增量,如果计算机出现故障,误动作影响较小,而执行机构本身有记忆功能,可仍保持原位,不会严重影响系统的工作,而位置式的输出直接对应对象的输出,因此对系统影响较大。

下面给出公式直接体现的C语言源代码(请结合项目修改源代码):

1.位置式PID

$$
u(k)=K_Pe(k)+K_I\sum_{i=0}{e(i)}+K_D[e(k)-e(k-1)]
$$

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
typedef struct
{
float Kp; //比例系数Proportional
float Ki; //积分系数Integral
float Kd; //微分系数Derivative

float Ek; //当前误差
float Ek1; //前一次误差 e(k-1)
float Ek2; //再前一次误差 e(k-2)
float LocSum; //累计积分位置
}PID_LocTypeDef;

/************************************************
函数名称 : PID_Loc
功 能 : PID位置(Location)计算
参 数 : SetValue ------ 设置值(期望值)
ActualValue --- 实际值(反馈值)
PID ----------- PID数据结构
返 回 值 : PIDLoc -------- PID位置
作 者 : strongerHuang
*************************************************/
float PID_Loc(float SetValue, float ActualValue, PID_LocTypeDef *PID)
{
float PIDLoc; //位置

PID->Ek = SetValue - ActualValue;
PID->LocSum += PID->Ek; //累计误差

PIDLoc = PID->Kp * PID->Ek + (PID->Ki * PID->LocSum) + PID->Kd * (PID->Ek1 - PID->Ek);

PID->Ek1 = PID->Ek; return PIDLoc;
}

2.增量式PID

$$
\Delta u(k)=u(k)-u(k-1)=K_P[e(k)-e(k-1)]+K_Ie(k)+K_D[e(k)-2e(k-1)-e(k-2)]
$$

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
typedef struct
{
float Kp; //比例系数Proportional
float Ki; //积分系数Integral
float Kd; //微分系数Derivative

float Ek; //当前误差
float Ek1; //前一次误差 e(k-1)
float Ek2; //再前一次误差 e(k-2)
}PID_IncTypeDef;

/************************************************
函数名称 : PID_Inc
功 能 : PID增量(Increment)计算
参 数 : SetValue ------ 设置值(期望值)
ActualValue --- 实际值(反馈值)
PID ----------- PID数据结构
返 回 值 : PIDInc -------- 本次PID增量(+/-)
作 者 : strongerHuang
*************************************************/
float PID_Inc(float SetValue, float ActualValue, PID_IncTypeDef *PID)
{
float PIDInc; //增量

PID->Ek = SetValue - ActualValue;
PIDInc = (PID->Kp * PID->Ek) - (PID->Ki * PID->Ek1) + (PID->Kd * PID->Ek2);

PID->Ek2 = PID->Ek1;
PID->Ek1 = PID->Ek; return PIDInc;
}

四、参考文章


一文读懂PID控制算法(抛弃公式,从原理上真正理解PID控制)

重温经典PID算法

PID原理和参数调试

结合案例轻松理解PID到底是个啥?

视频来源:【编程三分钟】通俗易懂的PID控制算法讲解

特别鸣谢:微信公众号:strongerHuang的知识整理

评论




博客内容遵循 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议

总访问量为 访客数为

粤ICP备2021157327号

载入天数...载入时分秒...