增量式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增量波動過大造成舵機不穩,進而影響轉速。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM