一、PID的数学模型 在工业应用中PID及其衍生算法是应用最广泛的算法之一,是当之无愧的万能算法,如果能够熟练掌握PID算法的设计与实现过程,对于一般的研发人员来讲,应该是足够应对一般研发问题了,而难能可贵的是,在很多控制算法当中,PID控制算法又是最简单,最能体现反馈思想的控制算法,可谓经典中的经典。经典的未必是复杂的,经典的东西常常是简单的,而且是最简单的。PID算法的一般形式: ![]() PID算法通过误差信号控制被控量,而控制器本身就是比例、积分、微分三个环节的加和。这里我们规定(在t时刻): 1. 输入量为 2.输出量为 3.偏差量为 ![]() ![]() 二、PID算法的数字离散化 假设采样间隔为T,则在第K个T时刻: 偏差= ![]() 积分环节用加和的形式表示,即 ![]() 微分环节用斜率的形式表示,即 ![]() PID算法离散化后的式子: ![]() 则可表示成为: ![]() 其中式中: 比例参数 积分参数 微分参数 PID的基本离散表示形式如上。目前的这种表述形式属于位置型PID,另外一种表述方式为增量式PID,由上述表达式可以轻易得到: ![]() 那么: ![]() 上式就是离散化PID的增量式表示方式,由公式可以看出,增量式的表达结果和最近三次的偏差有关,这样就大大提高了系统的稳定性。需要注意的是最终的输出结果应该为: 输出量 = 三、PID的C语言实现 1.位置式PID的C语言实现 上边已经抽象出了位置性PID和增量型PID的数学表达式,这里重点讲解C语言代码的实现过程。 第一步:定义PID变量结构体,代码如下: struct t_pid{ float SetSpeed; //定义设定值 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; 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_last); pid.err_last=pid.err; pid.ActualSpeed=pid.voltage*1.0; return pid.ActualSpeed; } 注意:这里用了最基本的算法实现形式,没有考虑死区问题,没有设定上下限,只是对公式的一种直接的实现,后面的介绍当中还会逐渐的对此改进。 到此为止,PID的基本实现部分就初步完成了。下面是测试代码: int main(){ PID_init(); int count=0; while(countumax,则只累加负偏差; 如果u(k-1)pid.umax) //灰色底色表示抗积分饱和的实现 { if(abs(pid.err)>200) //蓝色标注为积分分离过程 { index=0; }else{ index=1; if(pid.err0) { pid.integral+=pid.err; } } }else{ if(abs(pid.err)>200) //积分分离过程 { 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); pid.err_last=pid.err; pid.ActualSpeed=pid.voltage*1.0; return pid.ActualSpeed; } 5.梯形积分的PID控制算法 先看一下梯形算法的积分环节公式 ![]() 作为PID控制律的积分项,其作用是消除余差,为了尽量减小余差,应提高积分项运算精度,为此可以将矩形积分改为梯形积分,具体实现的语句为: pid.voltage=pid.Kp*pid.err+index*pid.Ki*pid.integral/2+pid.Kd*(pid.err-pid.err_last); //梯形积分 6.变积分的PID控制算法 变积分PID可以看成是积分分离的PID算法的更一般的形式。在普通的PID控制算法中,由于积分系数是常数,所以在整个控制过程中,积分增量是不变的。但是,系统对于积分项的要求是,系统偏差大时,积分作用应该减弱甚至是全无,而在偏差小时,则应该加强。积分系数取大了会产生超调,甚至积分饱和,取小了又不能短时间内消除静差。因此,根据系统的偏差大小改变积分速度是有必要的。 变积分PID的基本思想是设法改变积分项的累加速度,使其与偏差大小相对应:偏差越大,积分越慢; 偏差越小,积分越快。 这里给积分系数前加上一个比例值index: 当abs(err)0时,说明误差在朝向误差绝对值增大的方向变化,此时,如果abs(e)>Mmid,说明误差也较大,可考虑由控制器实施较强的控制作用,以达到扭转误差绝对值向减小的方向变化,并迅速减小误差的绝对值。此时如果abs(e) |
|免责声明|本站介绍|工控课堂
( 沪ICP备14007696号-3 )|网站地图
GMT+8, 2019-3-21 23:26 , Processed in 0.030207 second(s), 29 queries .
Powered by Discuz! X3.4
© 2001-2017 Comsenz Inc.