BLDC低速目标时超调

如果BLDC没有编码器,速度反馈要靠hall(反电动势同理)时,如果想电机反应迅速,更快的达到预设速度时,经常就会遇到这样一种情况,在预设目标为高速时能够迅速到达且没有超调,但是在低速时基本都会超调之后才稳定下来

如下图所示,我从目标速度为 100 PRM 和目标为500时的实测波形,黄线为预设速度,红线为实际速度,可以看到在同样一套PID参数,在低速时超调了,在高速时没有超调

原因分析

为什么会这样呢 ,原因出在速度更新时间上,比如在100RPM速度时,即使是使用3 hall 测速,对于我的四电极(2极对)电机来说,每次更新速度的时间也要 60/100/12 = 0.05=50ms 也就是20HZ,,而我的pid 频率为625HZ,每次速度更新期间都经过了31.25次pid 算法,PID算法里面,如下面公式会以后31.25次积分,而如果速度是1000,则速度更新期间平均只有3.125次积分。也就是速度更新越慢,积分次数越多

$$ u_k = K_p\,e_k + K_i \sum_{j=0}^{k} e_j + K_d\,(e_k - e_{k-1}) $$


2、另外还有个问题就是,因为我的电机的转子及hall 有机械偏差,且还不小,需要使用整圈测速法,虽然使用滑动窗口平均法可用做到每次hall有变化就有更新,但是本质上速度其实有滞后性,因为它也是一个平均一圈的速度。在高速时,一圈很快过去,pid的积分没积分几次,但是在低速这个时间拉的比较长,造成速度更新期间有多次积分,导致超调。

解决办法

其实无论是从公式出发,还是从上面的曲线图出发,都知道是因为速度更新慢导致积分分量值太大最后导致超调,那么按常规思路是应该将积分参数变小,但是积分参数变小,它也会导致响应变慢,高速时本来就没有超调,这样做导致高速时本可以有更快的响应速度而没有做到。所以最好的办法是根据速度来分阶段来给新增积分分量不同的增益,的也就是自适应积分增益算法

具体做法如下,在低速时,新增的积分按比例增加。

int32_t pid_ctrl(PID_TypeDef *PID,float Feedback_value)
{
    PID->error = (float)(PID->target_value - Feedback_value); //获得偏差

    if(Feedback_value <= 400){      //当速度在低速时
        adaptive_ki = (Feedback_value/400);  //将积分参数按比例降低
        if(adaptive_ki < 0.3f){
            adaptive_ki = 0.3f;
        }
    } else {
        adaptive_ki = 1.0f; //高速
    }
    PID->sum_error += (PID->error*adaptive_ki);


    g_pid_inter.p_value = PID->proportion * PID->error;
    g_pid_inter.i_value = PID->integral * PID->sum_error;
    g_pid_inter.d_value = PID->derivative * (PID->error - PID->last_error);
    g_pid_inter.sum_value = g_pid_inter.p_value + g_pid_inter.i_value + g_pid_inter.d_value;
    
    ..........省略..................................
    }

如图可用看到低速和高速都不会超调,只是低速时,到达目标速度会更慢,但是可以接受。