本帖最后由 RunningX 于 2020-2-27 14:34 编辑
PID控制广泛应用于工业过程控制,这里就不多作展开,一般电机控制中用的就是PID控制。PID控制的流程图如下:
P:比例控制 I:积分控制 D:微分控制
PID控制中,设U(t)= Up(t) +Ui(t)+Ud(t); 其中比例控制Up(t) = Kp*Error(t);Kp为比例控制常数
(因为公式输入会有错误,所以只能用图片代替了) 为什么需要用到这三种控制。有一个经典的例子:假设有一个水池,我们往里面注水,目的是达到1米的水深。如果一开始水深为0.5米,那么与目标水深的误差Error为0.5,如果我们往水池里注水,用比例控制法,取Kp值为0.6,则Up(1)=0.6*0.5=0.3,那么第一次注水后水深就为0.8了;此时与目标水深的误差Error为0.2,则在第二次注入水量Up(2)=0.6*0.2=0.12,那么第二次注水后水深为0.92,持续以比例控制的方式注水,最终水量逼近1米。 那积分控制的作用呢?它的作用是为了消除稳态误差。假设每次加水过程中,水池会漏水,每次漏0.12米,那么当水深为0.8米时,下一次注水为0.12米,但是漏掉的水也是0.12米,所以只使用比例控制的话水深一直保持在0.8米深。取Ki值为0.1,第一次Error(1)=0.5,第二次Error(2)=0.3,则Ui(2)=0.1*(0.5+0.3)=0.08;则积分控制加上比例控制的话,第二次的注水量为0.12+0.08=0.2,比漏掉的0.12大,则第二次注水后水深为0.88米;持续以比例控制和积分控制的方式注水,最终水量在1米附近波动。
微分控制的作用?它的作用是减少控制产生的震荡。微分控制实际上是一个负数,当注入的水量过多时,起到减缓的作用,防止水深超过1米太多。 实际编程中,实现方式如下: struct PID //相关参数定义 { float TargetSpeed; 目标转速 float ActualSpeed; 实际转速 float Error; 误差 float LastError; 上一次误差 float Kp,Ki,Kd; PID参数 float Voltage; 电压(这里假设通过调电压可以调节转速) float Integral; 积分 float Differential; 微分
}PID_Speed;
float realize(float speed) //PID函数实现 { PID_Speed. TargetSpeed = speed; PID_Speed.Error = PID_Speed. TargetSpeed- PID_Speed. ActualSpeed; PID_Speed. Integral += PID_Speed.Error; PID_Speed. Differential = PID_Speed.Error- PID_Speed. LastError; PID_Speed. Voltage = Kp* PID_Speed.Error+Ki*PID_Speed. Integral+Kd* PID_Speed. Differential; //PID控制的输出 PID_Speed. LastError = PID_Speed.Error;
}
上面是PID实现的一种方式,根据应用场景的不同,PID使用方法也会有所差异。
|