大家好,欢迎来到IT知识分享网。
PID算法的离散化
论述了PID算法的基本形式,并对其控制过程的实现有了一个简要的说明,通过上一节的总结,基本已经可以明白PID控制的过程。这一节中先继续上一节内容补充说明一下。
1.说明一下反馈控制的原理,通过上一节的框图不难看出,PID控制其实是对偏差的控制过程;
2.如果偏差为0,则比例环节不起作用,只有存在偏差时,比例环节才起作用。
3.积分环节主要是用来消除静差,所谓静差,就是系统稳定后输出值和设定值之间的差值,积分环节实际上就是偏差累计的过程,把累计的误差加到原有系统上以抵消系统造成的静差。
4.而微分信号则反应了偏差信号的变化规律,或者说是变化趋势,根据偏差信号的变化趋势来进行超前调节,从而增加了系统的快速性。
好了,关于PID的基本说明就补充到这里,下面将对PID连续系统离散化,从而方便在处理器上实现。下面把连续状态的公式再贴一下:
假设采样间隔为T,则在第K个 T时刻:
偏差err(K)=rin(K)-rout(K);
积分环节用加和的形式表示,即err(K)+err(K+1)+……;
微分环节用斜率的形式表示,即[err(K)-err(K-1)]/T;
从而形成如下PID离散表示形式:
其中T为采样时间,Kp为比例带,TI为积分时间,TD为微分时间。PID控制的基本原理就是如此。
则u(K)可表示成为:位置型PID
可以这么理解:比例环节将误差线性放大,积分环节将误差值的积分放大,微分环节将两次的误差值放大,所有的值相加得到最终输出值
在不断变化中,err(k)(设定值与实际输出值差值)会降低或者升高,不断降低时比例和微分环节对最终的输出贡献变少而积分环节因为误差值的不断累加贡献最大。
至于说Kp、Ki、Kd三个参数的具体表达式,我想可以轻松的推出了,这里节省时间,不再详细表示了。
其实到这里为止,PID的基本离散表示形式已经出来了。目前的这种表述形式属于位置型PID,另外一种表述方式为增量式PID,由上述表达式可以轻易得到:增量式PID
那么:
这就是离散化PID的增量式表示方式,由公式可以看出,增量式的表达结果和最近三次的偏差有关,这样就大大提高了系统的稳定性。需要注意的是最终的输出结果应该为
u(K)+增量调节值;
PID的离散化过程基本思路就是这样,下面是将离散化的公式转换成为C语言,从而实现微控制器的控制作用。
当然,增量型PID必须记得一点,就是在记住U(k)=U(k-1)+∆U(k)。
PID 控制算法可以分为位置式 PID 和增量式 PID 控制算法。
两者的区别:
(1)位置式PID控制的输出与整个过去的状态有关,用到了误差的累加值;而增量式PID的输出只与当前拍和前两拍的误差有关,因此位置式PID控制的累积误差相对更大;
(2)增量式PID控制输出的是控制量增量,并无积分作用,因此该方法适用于执行机构带积分部件的对象,如步进电机等,而位置式PID适用于执行机构不带积分部件的对象,如电液伺服阀。
(3)由于增量式PID输出的是控制量增量,如果计算机出现故障,误动作影响较小,而执行机构本身有记忆功能,可仍保持原位,不会严重影响系统的工作,而位置式的输出直接对应对象的输出,因此对系统影响较大。
增量型PID的C语言实现
上一节中介绍了最简单的位置型PID的实现手段,这一节主要讲解增量式PID的实现方法,位置型和增量型PID的数学公式请参见我的系列文《PID控制算法的C语言实现二》中的讲解。实现过程仍然是分为定义变量、初始化变量、实现控制算法函数、算法测试四个部分,详细分类请参加《PID控制算法的C语言实现三》中的讲解,这里直接给出代码了。
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 struct _pid{ 5 float SetSpeed; //定义设定值 6 float ActualSpeed; //定义实际值 7 float err; //定义偏差值 8 float err_next; //定义上一个偏差值 9 float err_last; //定义最上前的偏差值 10 float Kp,Ki,Kd; //定义比例、积分、微分系数 11 }pid; 12 13 void PID_init(){ 14 pid.SetSpeed=0.0; 15 pid.ActualSpeed=0.0; 16 pid.err=0.0; 17 pid.err_last=0.0; 18 pid.err_next=0.0; 19 pid.Kp=0.2; 20 pid.Ki=0.015; 21 pid.Kd=0.2; 22 } 23 24 float PID_realize(float speed){ 25 pid.SetSpeed=speed; 26 pid.err=pid.SetSpeed-pid.ActualSpeed; 27 float incrementSpeed=pid.Kp*(pid.err-pid.err_next)+pid.Ki*pid.err+pid.Kd*(pid.err-2*pid.err_next+pid.err_last); 28 pid.ActualSpeed+=incrementSpeed; 29 pid.err_last=pid.err_next; 30 pid.err_next=pid.err; 31 return pid.ActualSpeed; 32 } 33 34 int main(){ 35 PID_init(); 36 int count=0; 37 while(count<1000) 38 { 39 float speed=PID_realize(200.0); 40 printf("%f\n",speed); 41 count++; 42 } 43 return 0; 44 }
运行后的1000个数据为:(结果自行运行观看)
结论:从最终数据的结果显示来看,增量式PID数据的稳定性要好于位置型PID的;
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/30636.html