《PID控制算法介绍与实现(共16页).docx》由会员分享,可在线阅读,更多相关《PID控制算法介绍与实现(共16页).docx(16页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、精选优质文档-倾情为你奉上PID控制算法介绍与实现一、PID的数学模型在工业应用中PID及其衍生算法是应用最广泛的算法之一,是当之无愧的万能算法,如果能够熟练掌握PID算法的设计与实现过程,对于一般的研发人员来讲,应该是足够应对一般研发问题了,而难能可贵的是,在很多控制算法当中,PID控制算法又是最简单,最能体现反馈思想的控制算法,可谓经典中的经典。经典的未必是复杂的,经典的东西常常是简单的,而且是最简单的。PID算法的一般形式:PID算法通过误差信号控制被控量,而控制器本身就是比例、积分、微分三个环节的加和。这里我们规定(在t时刻):1.输入量为i(t)2.输出量为o(t)3.偏差量为err
2、t= i(t)- o(t)u(t)=kp(errt+1Ti.errtdt+TDderr(t)dt)二、PID算法的数字离散化假设采样间隔为T,则在第K个T时刻:偏差err(k)=i(k) - o(k)积分环节用加和的形式表示,即errk + err(k+1) + 微分环节用斜率的形式表示,即err(k)- err(k-1)/T;PID算法离散化后的式子:u(k)=kp(errk+TTi.errj+TDT(errk-err(k-1)则u(k)可表示成为:u(k)=kp(errk+kierrj+kd(errk-err(k-1)其中式中:比例参数kp:控制器的输出与输入偏差值成比例关系。系统一旦出现
3、偏差,比例调节立即产生调节作用以减少偏差。特点:过程简单快速、比例作用大,可以加快调节,减小误差;但是使系统稳定性下降,造成不稳定,有余差。积分参数ki:积分环节主要是用来消除静差,所谓静差,就是系统稳定后输出值和设定值之间的差值,积分环节实际上就是偏差累计的过程,把累计的误差加到原有系统上以抵消系统造成的静差。微分参数kd:微分信号则反应了偏差信号的变化规律,或者说是变化趋势,根据偏差信号的变化趋势来进行超前调节,从而增加了系统的快速性。PID的基本离散表示形式如上。目前的这种表述形式属于位置型PID,另外一种表述方式为增量式PID,由上述表达式可以轻易得到:u(k-1)=kp(errk-1
4、+kierrj+kd(errk-1-err(k-2)那么:u(k)=kp(errk-errk-1)+kierr(k)+kd(errk-2err(k-1)+err(k-2)上式就是离散化PID的增量式表示方式,由公式可以看出,增量式的表达结果和最近三次的偏差有关,这样就大大提高了系统的稳定性。需要注意的是最终的输出结果应该为:输出量 = u(k) + 增量调节值三、PID的C语言实现1.位置式PID的C语言实现上边已经抽象出了位置性PID和增量型PID的数学表达式,这里重点讲解C语言代码的实现过程。 第一步:定义PID变量结构体,代码如下:struct t_pid float SetSpeed;
5、 /定义设定值 float ActualSpeed; /定义实际值 float err; /定义偏差值 float err_last; /定义上一个偏差值 float Kp,Ki,Kd; /定义比例、积分、微分系数 float voltage; /定义电压值(控制执行器的变量) float integral; /定义积分值pid;第二部:初始化变量,代码如下:void PID_init() pid.SetSpeed=0.0; pid.ActualSpeed=0.0; pid.err=0.0; pid.err_last=0.0; pid.voltage=0.0; pid.integral=0.0
6、; pid.Kp=0.2; pid.Ki=0.015; pid.Kd=0.2; 统一初始化变量,尤其是Kp,Ki,Kd三个参数,调试过程当中,对于要求的控制效果,可以通过调节这三个量直接进行调节。第三步:编写控制算法,代码如下:float PID_realize(float speed) pid.SetSpeed=speed; pid.err=pid.SetSpeed-pid.ActualSpeed; pid.integral+=pid.err; pid.voltage=pid.Kp*pid.err+pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_las
7、t); pid.err_last=pid.err; pid.ActualSpeed=pid.voltage*1.0; return pid.ActualSpeed;注意:这里用了最基本的算法实现形式,没有考虑死区问题,没有设定上下限,只是对公式的一种直接的实现,后面的介绍当中还会逐渐的对此改进。 到此为止,PID的基本实现部分就初步完成了。下面是测试代码:int main() PID_init(); int count=0; while(count1000) float speed=PID_realize(200.0); printf(%fn,speed); count+; return 0;
8、2.增量型PID的C语言实现 上一节中介绍了最简单的位置型PID的实现手段,这一节讲解增量式PID的实现方法。#include#includestruct t_pid float SetSpeed; /定义设定值 float ActualSpeed; /定义实际值 float err; /定义偏差值 float err_next; /定义上一个偏差值 float err_last; /定义最上前的偏差值 float Kp,Ki,Kd; /定义比例、积分、微分系数pid;void PID_init() pid.SetSpeed=0.0; pid.ActualSpeed=0.0; pid.err=
9、0.0; pid.err_last=0.0; pid.err_next=0.0; pid.Kp=0.2; pid.Ki=0.015; pid.Kd=0.2;float PID_realize(float speed) pid.SetSpeed=speed; pid.err=pid.SetSpeed-pid.ActualSpeed; float incrementSpeed=pid.Kp*(pid.err-pid.err_next)+pid.Ki*pid.err+pid.Kd*(pid.err-2*pid.err_next+pid.err_last); pid.ActualSpeed+=incr
10、ementSpeed; pid.err_last=pid.err_next; pid.err_next=pid.err; return pid.ActualSpeed;int main() PID_init(); int count=0; while(count200) index=0; else index=1; pid.integral+=pid.err; pid.voltage=pid.Kp*pid.err+index*pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last); /算法具体实现过程4.抗积分饱和的PID控制算法C语言实现 所谓的积
11、分饱和现象是指如果系统存在一个方向的偏差,PID控制器的输出由于积分作用的不断累加而加大,从而导致执行机构达到极限位置,若控制器输出U(k)继续增大,执行器开度不可能再增大,此时计算机输出控制量超出了正常运行范围而进入饱和区。一旦系统出现反向偏差,u(k)逐渐从饱和区退出。进入饱和区越深则退出饱和区时间越长。在这段时间里,执行机构仍然停留在极限位置而不随偏差反向而立即做出相应的改变,这时系统就像失控一样,造成控制性能恶化,这种现象称为积分饱和现象或积分失控现象。 防止积分饱和的方法之一就是抗积分饱和法,该方法的思路是在计算u(k)时,首先判断上一时刻的控制量u(k-1)是否已经超出了极限范围:
12、 如果u(k-1)umax,则只累加负偏差; 如果u(k-1)pid.umax) /灰色底色表示抗积分饱和的实现 if(abs(pid.err)200) /蓝色标注为积分分离过程 index=0; else index=1; if(pid.err0) pid.integral+=pid.err; else if(pid.ActualSpeed200) /积分分离过程 index=0; else index=1; if(pid.err0) pid.integral+=pid.err; else if(abs(pid.err)200) /积分分离过程 index=0; else index=1;
13、pid.integral+=pid.err; pid.voltage=pid.Kp*pid.err+index*pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last); pid.err_last=pid.err; pid.ActualSpeed=pid.voltage*1.0; return pid.ActualSpeed;5.梯形积分的PID控制算法先看一下梯形算法的积分环节公式0Te(t)dt=i=0ke(i)+e(i-1)2.T 作为PID控制律的积分项,其作用是消除余差,为了尽量减小余差,应提高积分项运算精度,为此可以将矩形积分改为梯形积分,
14、具体实现的语句为:pid.voltage=pid.Kp*pid.err+index*pid.Ki*pid.integral/2+pid.Kd*(pid.err-pid.err_last); /梯形积分6.变积分的PID控制算法 变积分PID可以看成是积分分离的PID算法的更一般的形式。在普通的PID控制算法中,由于积分系数ki是常数,所以在整个控制过程中,积分增量是不变的。但是,系统对于积分项的要求是,系统偏差大时,积分作用应该减弱甚至是全无,而在偏差小时,则应该加强。积分系数取大了会产生超调,甚至积分饱和,取小了又不能短时间内消除静差。因此,根据系统的偏差大小改变积分速度是有必要的。 变积分
15、PID的基本思想是设法改变积分项的累加速度,使其与偏差大小相对应:偏差越大,积分越慢; 偏差越小,积分越快。 这里给积分系数前加上一个比例值index: 当abs(err)180时,index=1; 当180abs(err)200时,index=0; 最终的比例环节的比例系数值为ki*index; 具体PID实现代码如下: pid.Kp=0.4; pid.Ki=0.2; /增加了积分系数 pid.Kd=0.2; float PID_realize(float speed) float index; pid.SetSpeed=speed; pid.err=pid.SetSpeed-pid.Act
16、ualSpeed; if(abs(pid.err)200) /变积分过程 index=0.0; else if(abs(pid.err)Mmax时,说明误差的绝对值已经很大了,不论误差变化趋势如何,都应该考虑控制器的输入应按最大(或最小)输出,以达到迅速调整误差的效果,使误差绝对值以最大的速度减小。此时,相当于实施开环控制。 当e*ec0时,说明误差在朝向误差绝对值增大的方向变化,此时,如果abs(e)Mmid,说明误差也较大,可考虑由控制器实施较强的控制作用,以达到扭转误差绝对值向减小的方向变化,并迅速减小误差的绝对值。此时如果abs(e)Mmid,说明尽管误差是向绝对值增大的方向变化,但是
17、误差绝对值本身并不是很大,可以考虑控制器实施一般的控制作用,只需要扭转误差的变化趋势,使其向误差绝对值减小的方向变化即可。 当e*err0或者e=0时,说明误差的绝对值向减小的方向变化,或者已经达到平衡状态,此时保持控制器输出不变即可。 当e*err0且e*err(k-1)0时,说明误差处于极限状态。如果此时误差的绝对值较大,大于Mmin,可以考虑实施较强控制作用。如果此时误差绝对值较小,可以考虑实施较弱控制作用。 当abs(e)Mmin时,说明误差绝对值很小,此时加入积分,减小静态误差。上面的逻辑判断过程,实际上就是对于控制系统的一个专家判断过程。 实际上模糊算法属于智能算法,智能算法也可以
18、叫非模型算法,智能算法包含了专家系统、模糊算法、遗传算法、神经网络算法等。其实这其中的任何一种算法都可以跟PID去做结合,而选择的关键在于,处理的实时性能不能得到满足。当我们处理器的速度足够快速时,我们可以选择更为复杂的、精度更加高的算法。但是,控制器的处理速度限制了我们算法的选择。当然,成本是限制处理器速度最根本的原因。模糊PID适应一般的控制系统是没有问题。 模糊算法其实并不模糊。模糊算法其实也是逐次求精的过程。这里举个例子说明。我们设计一个倒立摆系统,假如摆针偏差5,我们说它的偏差比较“小”;摆针偏差在5和10之间,我们说它的偏差处于“中”的状态;当摆针偏差10的时候,我们说它的偏差有点
19、儿“大”了。对于“小”、“中”、“大”这样的词汇来讲,他们是精确的表述,可问题是如果摆针偏差是3呢,那么这是一种什么样的状态呢。我们可以用“很小”来表述它。如果是7呢,可以说它是“中”偏“小”。那么如果到了80呢,它的偏差可以说“非常大”。而我们调节的过程实际上就是让系统的偏差由非常“大”逐渐向非常“小”过度的过程。当然,我们系统这个调节过程是快速稳定的。通过上面的说明,可以认识到,其实对于每一种状态都可以划分到大、中、小三个状态当中去,只不过他们隶属的程度不太一样,比如6隶属于小的程度可能是0.3,隶属于中的程度是0.7,隶属于大的程度是0。这里实际上是有一个问题的,就是这个隶属的程度怎么确
20、定?这就要求我们去设计一个隶属函数。详细内容可以查阅相关的资料,这里没有办法那么详细的说明了。那么,知道了隶属度的问题,就可以根据目前隶属的程度来控制电机以多大的速度和方向转动了,当然,最终的控制量肯定要落实在控制电压上。这点可以很容易的想想,我们控制的目的就是让倒立摆从隶属“大”的程度为1的状态,调节到隶属“小”的程度为1的状态。当隶属大多一些的时候,我们就加快调节的速度,当隶属小多一些的时候,我们就减慢调节的速度,进行微调。可问题是,大、中、小的状态是汉字,怎么用数字表示,进而用程序代码表示呢?其实我们可以给大、中、小三个状态设定三个数字来表示,比如大表示用3表示,中用2表示,小用1表示。
21、那么我们完全可以用1*0.3+2*0.7+3*0.0=1.7来表示它,当然这个公式也不一定是这样的,这个公式的设计是系统模糊化和精确化的一个过程,读者也可参见相关文献理解。但就1.7这个数字而言,可以说明,目前6的角度偏差处于小和中之间,但是更偏向于中。我们就可以根据这个数字来调节电机的转动速度和时间了。当然,这个数字与电机转速的对应关系,也需要根据实际情况进行设计和调节。 前面一个例子已经基本上说明了模糊算法的基本原理了。可是实际上,一个系统的限制因素常常不是一个。上面的例子中,只有偏差角度成为了系统调节的参考因素。而实际系统中,比如PID系统,我们需要调节的是比例、积分、微分三个环节,那么
22、这三个环节的作用就需要我们认清,也就是说,我们需要根据超调量、调节时间、震荡情况等信息来考虑对这三个环节调节的比重,输入量和输出量都不是单一的,可是其中必然有某种内在的逻辑联系。所以这种逻辑联系就成为我们设计工作的重点了。四、PID算法参数整定方法1.临界比例度法(1)将调节器的积分时间Ti置于最大(Ti=),微分时间置零(Td=0),比例度适当,平衡操作一段时间,把系统投入自动运行。 (2)将比例度逐渐减小,得到等幅振荡过程,记下临界比例度k和临界振荡周期Tk值。 (3)根据k和Tk值,采用经验公式,计算出调节器各个参数,即、Ti、Td的值。 (4)按“先P后I最后D”的操作程序将调节器整定
23、参数调到计算值上。若还不够满意,可再作进一步调整。参数(%)Ti(min)Td(min)P2kP/I2.2kTk/1.2P/I/D1.6k0.5k0.25Ti临界振荡整定计算公式2.衰减曲线法 在纯比例作用下,由大到小调整比例度以得到具有衰减比(4:1)的过渡过程,记下此时的比例度s及振荡周期Ts,根据经验公式,求出相应的积分时间Ti和微分时间Td。 参数(%)Ti(min)Td(min)PsP/I1.2s0.5TsP/I/D0.8s0.3Ts0.1Ts衰减曲线法控制器参数计算表Note:(1).反应较快的控制系统,要认定4:1衰减曲线和读出Ts比较困难,此时,可用记录来回摆动两次就达到稳定作
24、为4:1衰减过程。 (2).在生产过程中,负荷变化会影响过程特性。当负荷变化较大时,必须重新整定调节器参数值。 (3).若认为4:1衰减太慢,宜应用10:1衰减过程。对于10:1衰减曲线法整定调节器参数的步骤与上述完全相同,仅仅采用计算公式有些不同。3.经验法 根据经验先将控制器参数放在某些数值上,直接在闭合的控制系统中通过改变给定值以施加干扰,看输出曲线的形状,以、Ti、Td,对控制过程的规律为指导,调整相应的参数进行凑试,直到合适为止。系统参数(%)TI ( min)TD( min)温度流量压力液位206040100307020803 100.110.430.53长期的生产实践中总结出来的
25、参数表4.经验口诀参数整定找最佳,从小到大顺序查。先是比例后积分,最后再把微分加。曲线振荡很频繁,比例度盘要放大。曲线漂浮绕大湾,比例度盘往小扳。曲线偏离回复慢,积分时间往下降。曲线波动周期长,积分时间再加长。曲线振荡频率快,先把微分降下来。动差大来波动慢。微分时间应加长。理想曲线两个波,前高后低4比1。一看二调多分析,调节质量不会低。为了方便理解这个式子以电机为例,具体控制流程梳理一下:1.输入量i(t)为电机转速预定值;2.输出量o(t)为电机转速实际值;3.执行器为直流电机;4.传感器为光电码盘,假设码盘为10线;5.直流电机采用PWM调速,转速用单位 转/min 表示;不难看出以下结论:1.输入量i(t)为电机转速预定值;2. 输出量o(t)为电机转速实际值;3.偏差量errt=i(t)-o(t)为预定值和实际值之差;那么以下几个问题需要弄清楚:1.通过PID环节之后的U(t)是什么值呢?2.直流电机转动转速应该为电压值(也就是PWM占空比)。3.那么U(t)与PWM之间存在怎样的联系呢?专心-专注-专业
限制150内