有上图我们知道,与普通的PID算法的区别,只是判断偏差的大小,偏差大时,为PD算法,偏差小时为PID算法。于是我们需要一个偏差检测与积分项分离系数β的函数。
static uint16_t BetaGeneration(float error,float epsilon)
{
uint16_t beta=0;
if(abs(error)<= epsilon)
{
beta=1;
}
return beta;
}
(1)位置型PID算法实现
根据前面的分析我们可以很轻松的编写程序,只需要在编写程序时判断偏差以确定是否引入积分项就可以了。同样先定义PID对象的结构体:
/*定义结构体和公用体*/
typedef struct
{
floatsetpoint; //设定值
floatproportiongain; //比例系数
floatintegralgain; //积分系数
floatderivativegain; //微分系数
floatlasterror; //前一拍偏差
floatresult; //输出值
floatintegral;//积分值
float epsilon; //偏差检测阈值
}PID;
接下来实现PID控制器:
void PIDRegulation(PID *vPID, float processValue)
{
floatthisError;
thisError=vPID->setpoint-processValue;
vPID->integral+=thisError;
uint16_tbeta= BetaGeneration(error,vPID->epsilon);
if(beta>0)
{
vPID->result=vPID->proportiongain*thisError+vPID->derivativegain*(thisError-vPID->lasterror);
}
else
{
vPID->result=vPID->proportiongain*thisError+vPID->integralgain*vPID->integral+vPID->derivativegain*(thisError-vPID->lasterror);
}
vPID->lasterror=thisError;
}
与普通的PID算法的区别就是上述代码中增加了偏差判断,来决定积分项的分离与否。
(2)增量型PID算法实现
对于增量型PID控制,我们也可以采取相同的处理。首先定义PID对象的结构体:
/*定义结构体和公用体*/
typedef struct
{
floatsetpoint; //设定值
floatproportiongain; //比例系数
floatintegralgain; //积分系数
floatderivativegain; //微分系数
floatlasterror; //前一拍偏差
floatpreerror; //前两拍偏差
floatdeadband; //死区
floatresult; //输出值
float epsilon; //偏差检测阈值
}PID;
接下来实现PID控制器:
void PIDRegulation(PID *vPID, float processValue)
{
floatthisError;
floatincrement;
floatpError,dError,iError;
thisError=vPID->setpoint-processValue; //得到偏差值
pError=thisError-vPID->lasterror;
iError=thisError;
dError=thisError-2*(vPID->lasterror)+vPID->preerror;
uint16_tbeta= BetaGeneration(error,vPID->epsilon);
if(beta>0)
{
increment=vPID->proportiongain*pError+vPID->derivativegain*dError; //增量计算
}
else
{
increment=vPID->proportiongain*pError+vPID->integralgain*iError+vPID->derivativegain*dError; //增量计算
}
vPID->preerror=vPID->lasterror; //存放偏差用于下次运算
vPID->lasterror=thisError;
vPID->result+=increment;
}
这就实现了增量型PID控制器积分分离算法,也没有考虑任何的干扰条件,仅仅只是对数学公式的计算机语言化。
3、总结
积分分离算法的思想非常简单。当然,对于β的取值,很多人提出了改进措施,例如分多段取值,设定多个阈值ε1、ε2、ε3、ε4等,不过这些阈值也需要根据实际的系统来设定。除了分段取值外,甚至也有采用函数关系来获取β值。当然,这样处理后就不再是简单的积分分离了,特别是在增量型算法中,实际上已经演变为一种变积分算法了。已经偏离了积分分离算法的设计思想,在后面我们会进一步说明。
欢迎关注:
`
2