目录
一、参数设定
二、PID计算公式
三、位置式PID代码实现
四、增量式PID代码实现
五、两种控制算法的优缺点
六、PID算法的改进
一、参数设定
-
比例系数(kp):P项的作用是根据当前误差的大小来产生一个控制量。它直接与误差成正比,误差越大,控制量的变化越大。P项可以提高系统的响应速度,但可能会导致系统的超调和稳态误差。
-
积分时间(Ti):I项的作用是累积误差并产生一个控制量。它可以消除系统的稳态误差,因为它会积累误差并持续地调整控制量,直到误差为零。然而,I项可能会导致系统的超调和振荡。
-
微分常数(Td):D项的作用是根据误差变化的速度来产生一个控制量。它可以提高系统的稳定性,因为它可以减小误差的快速变化。D项可以抑制超调和减小振荡,但可能会增加系统的灵敏度。
PD算法:适用于惯性较大的设备,比如舵机。
PI算法:适用于不允许有静差的设备。
二、PID计算公式
1)位置式PID
2)增量式PID
三、位置式PID代码实现
#define IntegralMAX 2000
//pid结构体
typedef struct
{
float target_val; //目标值
float temp_val; //当前值
float actual_val; //输出控制值
float err; //定义偏差值
float err_last; //定义上一个偏差值
float Kp,Ki,Kd; //定义比例、积分、微分系数
float sum; //定义历史偏差
}pid_t;
//pid算法实现
void PID_realize(pid_t *pid)
{
/*目标值只在这里参与计算,计算目标值与实际值的误差*/
pid->err=pid->target_val - pid->temp_val;
/*误差累积*/
pid->sum+=pid.err;
//此处可以进行误差限幅
//*if(pid->integral > IntegralMAX) pid->integral = IntegralMAX;
// else if(pid->integral < -IntegralMAX) pid->integral = -IntegralMAX;
//*
/*PID算法实现*/
pid->actual_val = pid->Kp*pid->err + pid->Ki*pid->sum
+ pid->Kd*(pid->err - pid->err_last);
/*误差传递*/
pid->err_last=pid->err;
}
位置式 PID 适用于执行机构不带积分部件的对象,如舵机和平衡小车的直立和温控系统的控制。
四、增量式PID代码实现
/*pid*/
typedef struct
{
float target_val; //目标值
float actual_val; //实际输出值
float temp_val; //当前值
float err; //定义当前偏差值
float err_next; //定义下一个偏差值
float err_last; //定义最后一个偏差值
float Kp, Ki, Kd; //定义比例、积分、微分系数
}_pid;
//增量式PID算法实现
void PID_realize(pid_t *pid)
{
/*目标值只在这里参与计算,计算目标值与实际值的误差*/
pid->err = pid->target_val - pid->temp_val;
/*PID算法实现*/
float increment_val = pid->Kp*(pid->err - pid->err_next) + pid->Ki*pid->err + pid->Kd*(pid->err - 2 * pid->err_next + pid->err_last);
/*累加*/
pid->actual_val += increment_val;
/*传递误差*/
pid->err_last = pid->err_next;
pid->err_next = pid->err;
}
可见,增量式PID不需要进行累加,能对其产生影响的只有最近的三次的采样,容易通过加权处理获得比较好的控制效果,并且在系统发生问题时,增量式不会严重影响系统的工作。
增量式PID控制输出的是控制量增量,并无积分作用,因此该方法适用于执行机构带积分部件的对象,如步进电机等。
五、两种控制算法的优缺点
1)位置式PID的优缺点
优点:
①位置式PID是一种非递推式算法,可直接控制执行机构(如平衡小车),u(k)的值和执行机构的实际位置(如小车当前角度)是一一对应的,因此在执行机构不带积分部件的对象中可以很好应用
缺点:
①每次输出均与过去的状态有关,计算时要对e(k)进行累加,运算工作量大。
2)增量式PID优缺点:
优点:
①误动作时影响小,必要时可用逻辑判断的方法去掉出错数据。
②手动/自动切换时冲击小,便于实现无扰动切换。当计算机故障时,仍能保持原值。
③算式中不需要累加。控制增量Δu(k)的确定仅与最近3次的采样值有关。
缺点:
①积分截断效应大,有稳态误差;
②溢出的影响大。有的被控对象用增量式则不太好;
六、PID算法的改进
1)积分饱和
位置式PID在积分项达到饱和时,误差仍然会在积分作用下继续累积,一旦误差开始反向变化,系统需要一定时间从饱和区退出。
解决方法:
1、积分限幅:在积分积累达到最大值时,停止积分的积累。
//积分限幅
if(pid->integral > IntegralMAX) pid->integral = IntegralMAX;
else if(pid->integral < -IntegralMAX) pid->integral = -IntegralMAX;
2、变速积分:
在系统误差较大时对积分进行积累会导致积分过饱和,此后需要很长的一段时间进行消除。所以我们希望在系统偏差大时积分作用应减弱甚至全无,而在偏差小时则应加强。变速积分可以根据系统偏差大小改变积分的速度。
使用变速积分后
I
项的表达式:其中系数f 为:
当积分误差小于B时,对误差进行全积累;当误差大于A+B时,不积累;当误差处于两者之间时,积累量和误差值是线性关系。
若A=0,f取值为0或1,此时为积分分离。
3、抗积分饱和
是在计算输出的时候,先判断上一时刻的控制量U(k-1)是否已经超出了限制范围。若U(k-1)>Umax,则只累加负偏差;若U(k-1)<Umin,则只累加正偏差。从而避免控制量长时间停留在饱和区。
2)梯形积分
在积分项中,默认是按矩形方式来计算积分,将矩形积分改为梯形积分可以提高运算精度。即在每次计算积分时,积累的误差总是修改为当前误差与上一次误差的平均值。
3)不完全微分
从PID控制的基本原理我们知道,微分信号的引入可改善系统的动态特性,但也存在一个问题,那就是容易引进高频干扰,在偏差扰动突变时尤其显出微分项的不足。为了解决这个问题人们引入低通滤波方式来解决这一问题。
位置式PID的微分部分计算公式:
增量式PID的微分部分计算公式:
其中为不完全微分系数。
4)死区PID控制
在实际控制中可能总是存在微小的静差难以消除,导致系统频繁地不稳定,这时就可以引入带死区的PID算法,即在偏差达到一定程度时才进行调节,否则认为已经到达目标值。
5)步进式PID
所谓步进式PID算法,实际就是在设定值发生阶跃变化时,不直接对阶跃信号进行响应,而是在一定的时间内逐步改变设定值,直至使设定值达到目标值。这种逐步改变设定值的办法使得对象运行平稳。适用于高精度伺服系统的位置跟踪。
其基本思想是设定一个适当的步长,每次控制移动一个步长的值,直到达到目标值。
float StepInProcessing(pid_t *vPID)
{
float stepIn=(vPID->maximum-vPID->minimum))*0.1;
float kFactor=0.0;
if(fabs(vPID->actual_val - vPID->target_val)<=stepIn)
{
vPID->actual_val = vPID->target_val;
}
else
{
if(vPID->actual_val - vPID->target_val > 0)
{
kFactor=-1.0;
}
else if(vPID->actual_val - vPID->target_val < 0)
{
kFactor=1.0;
}
else
{
kFactor=0.0;
}
vPID->actual_val = vPID->actual_val + kFactor*stepIn;
}
return vPID->actual_val;
}