• 增量式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增量波动过大造成舵机不稳,进而影响转速。

  • 相关阅读:
    由老赵反对青鸟想到的——关于自学编程的讨论
    蛙蛙推荐:《代码大全》第45章读书笔记
    大家来找错自己写个正则引擎(二)构建抽象模式树
    大家来找错自己写个正则引擎(五)检查表及总结
    大家来找错自己写个正则引擎(一)概要介绍
    大家来找错自己写个正则引擎(三)构建正则解析树及分词
    蛙蛙推荐:《代码大全》1至3章读书笔记
    sql for xml path用法(转) dodo
    sql语句总结一 dodo
    System.Management.ManagementException: 访问遭到拒绝的解决方案 dodo
  • 原文地址:https://www.cnblogs.com/xyelectric/p/12199802.html
Copyright © 2020-2023  润新知