积分作用的引入是为了消除系统的静差,提高控制精度。但是如果一个系统总是存在统一个方向的偏差,就可能无限累加而进而饱和,极大影响系统性能。抗积分饱和就是用以解决这一问题的方法之一。这一节我们就来实现抗积分饱和的PID算法。
1、抗积分饱和的基本思想
所谓积分饱和就是指系统存在一个方向的偏差,PID控制器的输出由于积分作用的不断累加而扩大,从而导致控制器输出不断增大超出正常范围进入饱和区。当系统出现反响的偏差时,需要首先从饱和区退出,而不能对反向的偏差进行快速的响应。
为了解决积分饱和的问题,人们引入了抗积分饱和的PID算法。所谓抗积分饱和算法,其思路是在计算U(k)的时候,先判断上一时刻的控制量U(k-1)是否已经超出了限制范围。若U(k-1)>Umax,则只累加负偏差;若U(k-1)<Umin,则只累加正偏差。从而避免控制量长时间停留在饱和区。
2、算法实现
抗积分饱和的思想很简单,解释在控制器输出的最大最小值附近限制积分的累积情况,以防止在恢复时没有响应。根据前面得分系我们可以得到如下的流程图:
(1)位置型PID算法实现
对于位置型PID的抗积分饱和算法其实就是在基本的PID基础上加上抗积分饱和的操作,增加量个机锋的极限值。首先定义PID对象的结构体:
1 /*定义结构体和公用体*/ 2 3 typedef struct 4 5 { 6 7 float setpoint; //设定值 8 9 float proportiongain; //比例系数 10 11 float integralgain; //积分系数 12 13 float derivativegain; //微分系数 14 15 float lasterror; //前一拍偏差 16 17 float result; //输出值 18 19 float integral;//积分值 20 21 float maximum;//最大值 22 23 float minimum;//最小值 24 25 }PID;
接下来实现PID控制器:
1 void PIDRegulation(PID *vPID, float processValue) 2 3 { 4 5 float thisError; 6 7 thisError=vPID->setpoint-processValue; 8 9 if(vPID->result>vPID->maximum) 10 11 { 12 13 if(thisError<=0) 14 15 { 16 17 vPID->integral+=thisError; 18 19 } 20 21 } 22 23 else if(vPID->result<vPID->minimum) 24 25 { 26 27 if(thisError>=0) 28 29 { 30 31 vPID->integral+=thisError; 32 33 } 34 35 } 36 37 else 38 39 { 40 41 vPID->integral+=thisError; 42 43 } 44 45 46 47 vPID->result=vPID->proportiongain*thisError+vPID->integralgain*vPID->integral+vPID->derivativegain*(thisError-vPID->lasterror); 48 49 vPID->lasterror=thisError; 50 51 }
(2)增量型PID算法实现
增量型PID的抗积分饱和的实现也是一样在最基本的增量型PID算法中引入极大极小的限值,并在算法中通过比较限值实现抗饱和的操作。
首先定义PID对象的结构体:
1 /*定义结构体和公用体*/ 2 3 typedef struct 4 5 { 6 7 float setpoint; //设定值 8 9 float proportiongain; //比例系数 10 11 float integralgain; //积分系数 12 13 float derivativegain; //微分系数 14 15 float lasterror; //前一拍偏差 16 17 float preerror; //前两拍偏差 18 19 float deadband; //死区 20 21 float result; //输出值 22 23 float maximum;//最大值 24 25 float minimum;//最小值 26 27 }PID;
接下来实现PID控制器:
1 void PIDRegulation(PID *vPID, float processValue) 2 3 { 4 5 float thisError; 6 7 float increment; 8 9 float pError,dError,iError; 10 11 12 13 thisError=vPID->setpoint-processValue; //得到偏差值 14 15 pError=thisError-vPID->lasterror; 16 17 iError=0; 18 19 dError=thisError-2*(vPID->lasterror)+vPID->preerror; 20 21 22 23 if(vPID->result>vPID->maximum) 24 25 { 26 27 if(thisError<=0) 28 29 { 30 31 iError=thisError; 32 33 } 34 35 } 36 37 else if(vPID->result<vPID->minimum) 38 39 { 40 41 if(thisError>=0) 42 43 { 44 45 iError=thisError; 46 47 } 48 49 } 50 51 else 52 53 { 54 55 iError=thisError; 56 57 } 58 59 increment=vPID->proportiongain*pError+vPID->integralgain*iError+vPID->derivativegain*dError; //增量计算 60 61 vPID->preerror=vPID->lasterror; //存放偏差用于下次运算 62 63 vPID->lasterror=thisError; 64 65 vPID->result+=increment; 66 67 }
3、总结
所谓抗积分饱和就是防止由于长期存在一个方向的偏差而对相反方向的偏差迟滞响应。本文的方法是在达到极值后将不再对这一方向的偏差做出反应相反只对另一方向的偏差做出反应。事实上由于偏差的存在有可能造成输出值超限的情况,所以还需要对输出值作出限制。
原文地址:https://www.cnblogs.com/foxclever/p/8995308.html