对传统PID控制算的优化改善

关注
对传统PID控制算的优化改善www.shan-machinery.com

针对传统PID控制算法的优化       

 

 

一,原理图

根据原理图,MCU通过输出0~100%占空比的PWM来控制温度;通过ADC0808来采集温度

二,PID控制代码

void PIDCalu(PID_para *pid )

{

    pid->Yn = 0.3906*GetADC(); 

    pid->En = pid->Rn - pid->Yn;

    pid->SumOfEn += Pid.En;

 

    pid->Un =     pid->Kp*pid->En + 

                  pid->Ki*Pid.SumOfEn +

                  pid->Kd*(pid->En - pid->En_1); 

 

   

    pid->En_1 = pid->En;

 

}

 

三,分析

PID控制代码并不是难点。难点是Kp,Ki,Kd三个参数的最优配置。这三个参数可能随便配一个差不多的数,温度也能最终稳定下来;但需要的时间、超调量、精准度这些指标,却并不一定是所有情况中最好的。

 

当Kp,Ki,Kd为5,0.005,20时,期望温度50℃,控制效果为

 

 

通过此图可以得知:

a,系统的输出控制,前期主要由比例项决定;后期主要由微分项和积分项决定;

b,比例项的大小决定了前期升温的速度;微分项和积分项决定了后期稳定的精度。

 

 

 

 

根据这两个结论,我们设计一个公式,让Kp,Ki,Kd参数在控制过程中实时改变。当距离期望温度很大时,便采用较大的Kp,较小的积分项和Kd;而距离期望温度较小时,用较小的Kp,较大的积分项和Kd。

 

注意,改积分项并不是改改Ki就行了。积分是一种累加运算,你即便在后期改了Ki,那前期的累计值依然在积分项中,影响着后期的控制。所以实际上改积分项应该改不同阶段的积分权值,即:

 

 积分项 =  

 

注意Ki和k(t)并不是一回事。Ki是一个常量,影响了积分项在PID中的整体权重。而k(t)是一个函数,它实时性的为每一个样本e(t0),e(t1),e(t2)...分配了不同的权重。

 

我们下面采用单一变量法进行实验。

 

1,验证变参数Kp的效果。

 

A组:Ki,Kd,Kp为5,0.005,20不变 

B组:Ki,Kd不变;令Kp = En/5 + 5;当En从50到0时,Kp相应的从15变化到5。

 

根据以上实验得知,在其他性能相似的情况下,B组达到稳定状态的速度要比A组好。

 

2,验证变参数Kd的效果

A组:Kp,Ki,kd为5,0.003,50,期望温度为50度

B组:Kp,Ki不变,Kd = 10/En,当En从10到0.2时,Kd也从1到50;

 

显然,B优于A。

 

3,验证变参数Ki的效果

A组:Kp,Ki,kd为5,0.05,50,期望温度为50度

B组:在Kp,Ki,Kd不变的情况下;引入一个“积分强弱”控制因子Kit = 1-En/Rn;原来的积分项公式修改为:

 

 

 

显然,即便在系统肯定会产生超调的情况下,B组的超调也比A组小。

 

四,改进之后的PID控制代码,加了一个KpKiKdCalu函数,用于实时调整Kp,Ki,Kd.

void KpKiKdCalu(PID_para *pid)

{

 

    //变参数Kp

    pid->Kp =  Abs(pid->En)/5 + 5;

    //变参数Kd

    if(Abs(pid->En) < 0.2)

    {

       pid->Kd = 50;

    }

    else

    {

       pid->Kd = 10/ Abs(pid->En)  ;

    }

    //变参数Kit

    if(pid->Rn!=0)

    {

       pid->Kit =  1 -  Abs(pid->En /  pid->Rn)  ;

    }

 

     

}

 

void PIDCalu(PID_para *pid )

{

    pid->Yn = 0.3906*GetADC(); 

    pid->En = pid->Rn - pid->Yn;

    pid->SumOfEn +=  pid->Kit*pid->En;

   

    pid->Un =     pid->Kp*pid->En + 

                  pid->Ki*Pid.SumOfEn +

                  pid->Kd*(pid->En - pid->En_1); 

   

     

    pid->En_1 = pid->En;

 

}

 

 

Kp,Ki,Kd初始值:5,0.01,50

期望温度50℃,控制效果:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

https://www.shan-machinery.com