ps做网站设计,北京做网站公司的排名,wordpress的文章标签怎么用,免费网站源码大全前面我们发布了一系列PID控制器相关的文章#xff0c;包括经典PID控制器以及参数自适应的PID控制器。这一系列PID控制器虽说实现了主要功能#xff0c;也在实际使用中取得了良好效果#xff0c;但还有很多的细节部分可以改进以提高性能和灵活性。所以在这篇中我们来讨论改进…前面我们发布了一系列PID控制器相关的文章包括经典PID控制器以及参数自适应的PID控制器。这一系列PID控制器虽说实现了主要功能也在实际使用中取得了良好效果但还有很多的细节部分可以改进以提高性能和灵活性。所以在这篇中我们来讨论改进PID控制器以实现降低设定值阶跃带来的扰动。
1、提出问题
我们在使用PID控制器时如果大幅度修改设定值有可能引入一个大的阶跃扰动。特别是对微分作用这一扰动可能引起很大的振荡这种情况我们通常称之为微分冲击。 为了应对因为微分作用对设定值变化造成的激烈响应人们引入了微分先行的PID算法这一算法是将基于偏差的微分修改为基于输入的微分。也就是说设定值的变化对微分不会有突变的影响而只有作用在被控对象后微分才起作用从而消除了设定值的变化带来的微分作用冲击。 然而有些时候设定值的阶跃变化也会通过比例作用反映出来这种冲击也会对系统造成振荡。当然我们也可以将其改为基于输入的比例虽然也可以消除设定值的突变影响但是比例和微分都是面向输入信号的对设定值的响应将会变得滞后这也并非我们想要的。
所以我们希望能找到一种办法既可响应设定值的变化又不会造成大的冲击这就是我们在此要考虑的问题。
2、分析设计
前面实际我们已经讨论了基于输入的比例和微分这实际上改变了PID的调节方式这里我们希望从另一个角度来考虑对设定值的响应问题。我们曾经讨论过步进式PID的控制方式就是一种比较好的处理办法。
所谓步进式PID算法实际就是在设定值发生阶跃变化时不直接对阶跃信号进行响应而是在一定的时间内逐步改变设定值直至使设定值达到目标值。这种逐步改变设定值的办法使得对象运行平稳。适用于高精度伺服系统的位置跟踪。
佷显然这一方法并未改变PID控制器本身而是对设定值做了前期处理。所以其结构框图与控制方程与其他的PID控制算法是一致的。
为了对设定值做必要处理以使其不至快速变化有多种方法。比较常用的是建立线性变化函数的办法。我们可以规定设定值从0-100%的变化时间为T则可以确定设定值变化的斜率绝对值或者说是步长。知道步长后我们就可以根据步长来不断修改设定值直到目标值。可用公式描述为 其中SPt为设定值目标值SPs为设定值的起始值sl为步长k为步长的变化系数 我们希望能够根据我们自己的需要使用步进或者不使用步进所以我们需要在PID对象中添加一个属性来配置其是否使用。
/*定义PID对象类型*/
typedef struct CLASSIC
{float *pPV; //测量值指针float *pSV; //设定值指针float *pMV; //输出值指针float *pKp; //比例系数指针float *pKi; //积分系数指针float *pKd; //微分系数指针uint16_t *pMA; //手自动操作指针float setpoint; //设定值float lasterror; //前一拍偏差float preerror; //前两拍偏差float deadband; //死区float result; //PID控制器计算结果float output; //输出值0-100%float maximum; //输出值上限float minimum; //输出值下限float errorabsmax; //偏差绝对值最大值float errorabsmin; //偏差绝对值最小值float alpha; //不完全微分系数float deltadiff; //微分增量float integralValue; //积分累计量float gama; //微分先行滤波系数float lastPv; //上一拍的过程测量值float lastDeltaPv; //上一拍的过程测量值增量ClassicPIDDRType direct; //正反作用ClassicPIDSMType sm; //设定值平滑}CLASSICPID;
3、软件实现
我们讨论的对设定值的响应方式其实就是直接给定设定值或者采用步进式给定设定值。所谓步进式其实质是将设定值的突变修改为平缓的变化这一处理方式在控制中有大量应用。处理设定值变化过程的流程如下所示 根据我们前面的描述和上面的流程图我们可以实现对PID控制器的修改。我们将对设定值处理的的部分单独置为函数这样除了使用线性方式处理外我们也可以根据需要采取其他方式处理。
/*设定值平滑变化处理函数*/
static void SmoothSetpoint(CLASSICPID *vPID)
{float stepIn(vPID-maximum-vPID-minimum)*0.1;float kFactor0.0;if(fabs(vPID-setpoint-*vPID-pSV)stepIn){vPID-setpoint*vPID-pSV;}else{if(vPID-setpoint-*vPID-pSV0){kFactor-1.0;}else if(vPID-setpoint-*vPID-pSV0){kFactor1.0;}else{kFactor0.0;}vPID-setpointvPID-setpointkFactor*stepIn;}
}/* 通用PID控制器,采用增量型算法具有变积分梯形积分和抗积分饱和功能微分项采用不完全微分一阶滤波alpha值越大滤波作用越强 */
void PIDRegulator(CLASSICPID *vPID)
{float thisError;float result;float factor;float increment;float pError,dError,iError;if(*vPID-pMA1) //手动模式{vPID-output*vPID-pMV;//设置无扰动切换vPID-result(vPID-maximum-vPID-minimum)*vPID-output/100.0-vPID-minimum;*vPID-pSV*vPID-pPV;vPID-setpoint*vPID-pSV;}else //自动模式{if(vPID-smSMOOTH_ENABLE){SmoothSetpoint(vPID);}else{vPID-setpoint*vPID-pSV;}thisErrorvPID-setpoint-(*vPID-pPV); //得到偏差值resultvPID-result;if (fabs(thisError)vPID-deadband){pErrorthisError-vPID-lasterror;iError(thisErrorvPID-lasterror)/2.0;dErrorthisError-2*(vPID-lasterror)vPID-preerror;//变积分系数获取factorVariableIntegralCoefficient(thisError,vPID-errorabsmax,vPID-errorabsmin);//计算微分项增量带不完全微分vPID-deltadiff(*vPID-pKd)*(1-vPID-alpha)*dErrorvPID-alpha*vPID-deltadiff;increment(*vPID-pKp)*pError(*vPID-pKi)*factor*iErrorvPID-deltadiff; //增量计算}else{if((fabs(vPID-setpoint-vPID-minimum)vPID-deadband)(fabs((*vPID-pPV)-vPID-minimum)vPID-deadband)){resultvPID-minimum;}increment0.0;}//正反作用设定if(vPID-directDIRECT){resultresultincrement;}else{resultresult-increment;}/*对输出限值避免超调和积分饱和问题*/if(resultvPID-maximum){resultvPID-maximum;}if(resultvPID-minimum){resultvPID-minimum;} vPID-preerrorvPID-lasterror; //存放偏差用于下次运算vPID-lasterrorthisError;vPID-resultresult;vPID-output(vPID-result-vPID-minimum)/(vPID-maximum-vPID-minimum)*100.0;*vPID-pMVvPID-output;}
}
4、总结
我们引入了让设定值不大范围突变的方式而不需要改变PID控制器的控制方式。经测试效果能够满足我们的要求。在我们这里步长固定采用量程的十分之一事实上我们可以将其作为初始化参数予以修改甚至我们也可以采用一定条件下变步长的方式来满足更高的控制要求。
欢迎关注