增量式PID控制代码的实现
Posted xyelectric
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了增量式PID控制代码的实现相关的知识,希望对你有一定的参考价值。
/************************************************************* 函数: int16_t Idle_PID_Ctrl(uint16_t setpoint,uint16_t point) 功能: 增量式PID算法,得到增量值 参数: setpoint: 设定值 point: 当前值 返回: uk: PID算法的控制增量 描述: 返回增量值,即在上一次的控制量的基础上需要增加(负值意味减少)控制量 **************************************************************/ int16_t Idle_PID_Calc(uint16_t setpoint,uint16_t point) { float Kp = 0.0; //Proportion float Ki = 0.0; //Integral float Kd = 0.0; //Differential static int32_t ek_2 = 0; //上上次误差 static int32_t ek_1 = 0; //上一次误差 static int32_t ek = 0; //当前误差 int16_t uk; //控制量增量 Kp = inpram.RPMOXLimit/100.0; Ki = inpram.TPSOXLimit/1000.0; //这里上位机将edit里的数据*10,所以Ki的实际结果为edit/100 Kd = inpram.MAPOXLimit/1000.0; //这里上位机将edit里的数据*10,所以Kd的实际结果为edit/100 ek = setpoint - point; //得到当前误差 uk = (int16_t)(Kp*(ek - ek_1)+ Ki*ek + Kd*(ek - 2*ek_1 + ek_2));
ek_2 = ek_1; ek_1 = ek;
return (uk); }
上面是增量式PID算法的当前增量值代码段,完整并且实用的程序,还要与历史增量值相加,并要对总历史总量值进行限幅,为何要限幅呢?因为控制的总量要送到执行机构,而执行机构往往是有机械限位的,
比如此例子中,实际是控制节气门的开关角度,而节气门是由舵机控制的,舵机不能变化的太大,否则转速不稳定,造成发动机熄火,还会损坏舵机,减少其寿命。
看下一段代码:
if(cnt_xS++ >= INTERVAL_50MS) //PID控制周期,在1ms定时中断内 { cnt_xS = 0; rpm_setpoint = (inpram.RevLimRpm2 - inpram.Idle_rpm)*outpc.tps; //飞控油门对应的转速增值 rpm_setpoint = rpm_setpoint/1000 + inpram.Idle_rpm; //当前油门对应的目标转速 Idle.PID_increment = Idle_PID_Calc(rpm_setpoint,outpc.rpm); //得到PID控制增量 Idle.PID_value = Idle.PID_value + Idle.PID_increment; //得到PID控制总量,实际赋值给outpc.tps //PID控制总量(即总历史值)加入限幅算法,控制在10%,防止单个控制周期内节气门波动过大,造成转速不稳 if(Idle.PID_value > 100) { Idle.PID_value = 100; }
else if(Idle.PID_value < -100) { Idle.PID_value = -100; } tps_temp = outpc.tps + Idle.PID_value;
//对舵机进行机械限幅 if(tps_temp > 1000) { Syspara.tps = 1000; } else if(tps_temp < 0) { Syspara.tps = 0; } else { Syspara.tps = tps_temp; }
}
根据自己的需要加入合适的限幅算法,也可以只保留机械限幅,这里在每次总增量控制处加入10%的限幅,是防止PID增量波动过大造成舵机不稳,进而影响转速。
以上是关于增量式PID控制代码的实现的主要内容,如果未能解决你的问题,请参考以下文章