PID的优化与改进
-
输出限幅
对于被控对象,通常会进行输出限幅 使我们输出的值,处于被控对象的接收输出区间,不至于损毁
而通常 会采用归一化映射到 0~100 或 0~1
简单推导一下
cx(100)= 期望值/分辨率(1024)*100;将其映射的0~100的区间上 if(大于上限){输出上限} if(小于-上限){输出-上限} -
积分限幅
由最基本的PID公式面我们可以知道, 积分项是用来消除稳态误差,而逐渐累加的,那么如果当被控对象,突然间断电或故障,无法改变自身状态,但是于我们的期望值 又存在误差时,这个误差就会不断的累计,导致积分项所产生的力在不断的累加,当故障恢复时,系统就需要先抵消掉积分项累加的力,从而才能稳定,如下图

系统会变得不稳定 为了防止积分的力不至于无限增加(积分过饱和)所以需要积分限幅
cif(error_cont > 上限){error_cont=上限} if(error_cont<下限){error_cont=下限}而积分限幅的参数也不能随意给 过大超过输出限幅 也并不会输出
可以通过计算使其为积分项输出最大时的误差值
在比例项 微分项都为0 时 力是最大 最大误差值=输出上限/Ki -
积分分离
在定位置控制时 ,由于保持位置不变不需要力, 而积分项在之前积累的力,就会产生超调
积分分离是将积分项的误差积累 移动至调控的后半段 使前半段误差大时 由比例项主导 而不进行误差累计

所以 如果误差比较大使用PD控制 误差比较小使用PID控制
cif(|error|<积分分离阈值){error_cont +=errort;} else{ error_cont=0; } -
变速积分
分离积分对于积分阈值的取值要求就比较高了
在未进入阈值是纯比例项可以进行调控(不在稳态误差的区间) 但是阈值过大则又会产生积分的积累
为了消除这个问题 --变速积分

给出伪码
cerror=errort; errort = E - act; error_cont+=errort // 积分限幅 if(error_cont > 上限){error_cont=上限} if(error_cont<下限){error_cont=下限} // 定义一个C作为Ki项系数 C = 1/(1+k*error_cont); // 限制积分项 out = Kp * errort + Ki * C *error_cont_ + Kd *errort-error; if(out >上限){out = 上限;} if(out< - 上限){out= - 上限;} -
微分先行
在目标值进行大幅度改变时,目标值与实际值的误差也就会大幅度改变,微分项会瞬时增加一个很大的力
而微分项应该是阻尼项 但是此时所输出的力是正向的力
所以使用实际值的差来进行微分 而实际值趋势的反向刚好就是阻尼 amize
C-Kd*(acl(t)-acl(t-1));
-
不完全微分
在电路或控制过程中,如果产生了噪声那么对于 实际值的变化趋势的影响是很大的,而微分项又是基于趋势的所以为了避免这个影响,需要对微分项进行滤波
cD= Kd* (errort - errort_1) //普通的微分项 //引入滤波之后 D= (1-a)*Kd*(errort-errort_1) + a* D(k-1);这里采用一阶惯性滤波 使用当前的值与上一次值 通过权重a 得出当前的滤波后的值
-
输出偏移
输出偏移是由于电机存在内阻,当输出信号不足以驱动电机抵消内阻时电机就不会转动
cif(out<转动信号){out=0;} -
输入死区
输入死区是在目标值与实际值直接存在一个极小或可以接受的误差时频繁调控最终不能稳定,那么在这时引入输入死区
cif(error< 死区阈值){error =0}