0


PID算法

目录

前言

本篇文章仅为个人笔记,不是教程
本文所参考的文章
【基础知识】PID(比例微分积分)控制
改进的PID算法
PID控制器算法系列

PID算法简单分类(改进PID之间可以结合使用)

  1. 基础PID
  • 位置式PID算法
  • 增量式PID算法
  • 带死区的PID算法
  1. 积分改进PID
  • 积分分离PID算法
  • 抗积分饱和PID算法
  • 梯形积分PID算法
  • 变速积分PID算法
  1. 微分改进PID
  • 不完全微分PID算法
  • 微分先行PID算法

连续型PID算法

输入量为rin(t),输出量为rout(t),偏差为err(t)=rin(t)-rout(t)。

      U 
     
    
      ( 
     
    
      t 
     
    
      ) 
     
    
      = 
     
     
     
       k 
      
     
       p 
      
     
    
      ( 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      t 
     
    
      ) 
     
    
      + 
     
     
     
       1 
      
      
      
        T 
       
      
        I 
       
      
     
    
      ∫ 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      t 
     
    
      ) 
     
    
      d 
     
    
      t 
     
    
      + 
     
     
     
       T 
      
     
       D 
      
     
     
      
      
        d 
       
      
        e 
       
      
        r 
       
      
        r 
       
      
        ( 
       
      
        t 
       
      
        ) 
       
      
      
      
        d 
       
      
        t 
       
      
     
    
      ) 
     
    
   
     U(t)=k_p\bigl( err(t)+\frac 1{T_I}\int err(t)dt+ T_D\frac {derr(t)}{dt} \bigr) 
    
   
 U(t)=kp​(err(t)+TI​1​∫err(t)dt+TD​dtderr(t)​)

其中Kp为比例带,TI为积分时间,TD为微分时间。

离散型PID算法

输入量为rin(k),输出量为rout(k),偏差为err(k)=rin(k)-rout(k)。

位置式PID算法

基本公式

      U 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      = 
     
     
     
       K 
      
     
       p 
      
     
    
      ( 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      + 
     
     
     
       T 
      
      
      
        T 
       
      
        I 
       
      
     
     
     
       ∑ 
      
      
      
        j 
       
      
        = 
       
      
        0 
       
      
     
       k 
      
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      j 
     
    
      ) 
     
    
      + 
     
     
      
      
        T 
       
      
        D 
       
      
     
       T 
      
     
    
      ( 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      − 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      − 
     
    
      1 
     
    
      ) 
     
    
      ) 
     
    
      ) 
     
    
   
     U(k)=K_p \Bigl (err(k)+\frac T{T_I}\sum_{j=0}^{k} err(j)+\frac {T_ D}T\bigl (err(k)-err(k-1)\bigr ) \Bigr) 
    
   
 U(k)=Kp​(err(k)+TI​T​j=0∑k​err(j)+TTD​​(err(k)−err(k−1)))

其中T为系统采样周期时间,K表示第K个采样周期。
也可以简写为:

      U 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      = 
     
     
     
       K 
      
     
       p 
      
     
    
      ∗ 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      + 
     
     
     
       K 
      
     
       i 
      
     
     
     
       ∑ 
      
      
      
        j 
       
      
        = 
       
      
        0 
       
      
     
       k 
      
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      j 
     
    
      ) 
     
    
      + 
     
     
     
       K 
      
     
       d 
      
     
    
      ∗ 
     
    
      ( 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      − 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      − 
     
    
      1 
     
    
      ) 
     
    
      ) 
     
    
   
     U(k)=K_p*err(k)+K_i\sum_{j=0}^{k} err(j)+K_d*\big (err(k)-err(k-1)\big ) 
    
   
 U(k)=Kp​∗err(k)+Ki​j=0∑k​err(j)+Kd​∗(err(k)−err(k−1))

简单实现

typedefstruct{float setpoint;//设定值float proportiongain;//比例系数float integralgain;//积分系数float derivativegain;//微分系数float lasterror;//前一拍偏差float result;//输出值float integral;//积分值}PID;voidPIDRegulation(PID *vPID,float processValue){float thisError;
    thisError=vPID->setpoint-processValue;
    vPID->integral+=thisError;
    vPID->result=vPID->proportiongain*thisError+
                 vPID->integralgain*vPID->integral+
                 vPID->derivativegain*(thisError-vPID->lasterror);
    vPID->lasterror=thisError;}

特点

  • 位置型PID控制的输出与整个过去的状态有关,用到了偏差的累加值,容易产生累积偏差。
  • 位置型PID适用于执行机构不带积分部件的对象。
  • 位置型的输出直接对应对象的输出,对系统的影响比较大。

增量式PID算法

基本公式

          Δ 
         
        
          U 
         
        
          ( 
         
        
          k 
         
        
          ) 
         
        
       
      
      
       
        
         
        
          = 
         
        
          U 
         
        
          ( 
         
        
          k 
         
        
          ) 
         
        
          − 
         
        
          U 
         
        
          ( 
         
        
          k 
         
        
          − 
         
        
          1 
         
        
          ) 
         
        
       
      
     
     
      
       
        
       
      
      
       
        
         
        
          = 
         
         
         
           K 
          
         
           p 
          
         
        
          ( 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          ) 
         
        
          − 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          − 
         
        
          1 
         
        
          ) 
         
        
          ) 
         
        
       
      
     
     
      
       
        
       
      
      
       
        
         
        
          + 
         
         
         
           K 
          
         
           i 
          
         
        
          ∗ 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          ) 
         
        
       
      
     
     
      
       
        
       
      
      
       
        
         
        
          + 
         
         
         
           K 
          
         
           d 
          
         
        
          ( 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          ) 
         
        
          − 
         
        
          2 
         
        
          ∗ 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          − 
         
        
          1 
         
        
          ) 
         
        
          + 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          − 
         
        
          2 
         
        
          ) 
         
        
          ) 
         
        
       
      
     
    
   
     \begin{aligned} \Delta U(k) &= U(k)-U(k-1)\\ &=K_p\big (err(k)-err(k-1)\big )\\&+K_i*err(k)\\&+K_d\big (err(k)-2*err(k-1)+err(k-2)\big) \end{aligned} 
    
   
 ΔU(k)​=U(k)−U(k−1)=Kp​(err(k)−err(k−1))+Ki​∗err(k)+Kd​(err(k)−2∗err(k−1)+err(k−2))​

简单实现

typedefstruct{float setpoint;//设定值float proportiongain;//比例系数float integralgain;//积分系数float derivativegain;//微分系数float lasterror;//前一拍偏差float preerror;//前两拍偏差float result;//输出值}PID;voidPIDRegulation(PID *vPID,float processValue){float thisError;float increment;float pError,dError,iError;
    thisError=vPID->setpoint-processValue;
    pError=thisError-vPID->lasterror;
    iError=thisError;
    dError=thisError-2*(vPID->lasterror)+vPID->preerror;
    increment=vPID->proportiongain*pError+
              vPID->integralgain*iError+
              vPID->derivativegain*dError;
    vPID->preerror=vPID->lasterror;
    vPID->lasterror=thisError;
    vPID->result+=increment;}

特点

  • 增量型PID算法不需要做累加,控制量增量的确定仅与最近几次偏差值有关,计算偏差的影响较小。
  • 增量型PID算法得出的是控制量的增量,对系统的影响相对较小。
  • 采用增量型PID算法易于实现手动到自动的无扰动切换。

积分分离PID算法

位置式PID算法

基本公式

      U 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      = 
     
     
     
       K 
      
     
       p 
      
     
    
      ∗ 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      + 
     
    
      β 
     
     
     
       K 
      
     
       i 
      
     
     
     
       ∑ 
      
      
      
        j 
       
      
        = 
       
      
        0 
       
      
     
       k 
      
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      j 
     
    
      ) 
     
    
      + 
     
     
     
       K 
      
     
       d 
      
     
    
      ∗ 
     
    
      ( 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      − 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      − 
     
    
      1 
     
    
      ) 
     
    
      ) 
     
    
   
     U(k)=K_p*err(k)+\beta K_i\sum_{j=0}^{k} err(j)+K_d*\big (err(k)-err(k-1)\big ) 
    
   
 U(k)=Kp​∗err(k)+βKi​j=0∑k​err(j)+Kd​∗(err(k)−err(k−1))

其中β称为积分开关系数,其取值范围为:

      β 
     
    
      = 
     
     
     
       { 
      
      
       
        
         
         
           0 
          
         
        
        
         
          
          
            ∣ 
           
          
            e 
           
          
            r 
           
          
            r 
           
          
            ( 
           
          
            k 
           
          
            ) 
           
          
            ∣ 
           
          
            > 
           
          
            ξ 
           
          
         
        
       
       
        
         
         
           1 
          
         
        
        
         
          
          
            ∣ 
           
          
            e 
           
          
            r 
           
          
            r 
           
          
            ( 
           
          
            k 
           
          
            ) 
           
          
            ∣ 
           
          
            ≤ 
           
          
            ξ 
           
          
         
        
       
      
     
    
   
     \beta= \begin{cases} 0& \vert err(k) \vert\gt\xi\\1& \vert err(k) \vert\leq\xi\end{cases} 
    
   
 β={01​∣err(k)∣>ξ∣err(k)∣≤ξ​

根据实际情况,设定一个阈值

     ξ 
    
   
  
    \xi 
   
  
ξ;当偏差大于阈值时,消除积分仅用PD控制;当偏差小于等于阈值时,引入积分采用PID控制。

简单实现

staticuint16_tBetaGeneration(float error,float epsilon){uint16_t beta=0;if(abs(error)<= epsilon){
        beta=1;}return beta;}typedefstruct{float setpoint;//设定值float proportiongain;//比例系数float integralgain;//积分系数float derivativegain;//微分系数float lasterror;//前一拍偏差float result;//输出值float integral;//积分值float epsilon;//偏差检测阈值}PID;voidPIDRegulation(PID *vPID,float processValue){float thisError;
    thisError=vPID->setpoint-processValue;
    vPID->integral+=thisError;uint16_t beta=BetaGeneration(error,vPID->epsilon);if(beta>0){
        vPID->result=vPID->proportiongain*thisError+
                     vPID->derivativegain*(thisError-vPID->lasterror);}else{
        vPID->result=vPID->proportiongain*thisError+
                     vPID->integralgain*vPID->integral+
                     vPID->derivativegain*(thisError-vPID->lasterror);}
    vPID->lasterror=thisError;}

增量式PID算法

基本公式

          Δ 
         
        
          U 
         
        
          ( 
         
        
          k 
         
        
          ) 
         
        
       
      
      
       
        
         
        
          = 
         
         
         
           K 
          
         
           p 
          
         
        
          ( 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          ) 
         
        
          − 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          − 
         
        
          1 
         
        
          ) 
         
        
          ) 
         
        
       
      
     
     
      
       
        
       
      
      
       
        
         
        
          + 
         
        
          β 
         
         
         
           K 
          
         
           i 
          
         
        
          ∗ 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          ) 
         
        
       
      
     
     
      
       
        
       
      
      
       
        
         
        
          + 
         
         
         
           K 
          
         
           d 
          
         
        
          ( 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          ) 
         
        
          − 
         
        
          2 
         
        
          ∗ 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          − 
         
        
          1 
         
        
          ) 
         
        
          + 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          − 
         
        
          2 
         
        
          ) 
         
        
          ) 
         
        
       
      
     
    
   
     \begin{aligned} \Delta U(k) &=K_p\big (err(k)-err(k-1)\big )\\&+\beta K_i*err(k)\\&+K_d\big (err(k)-2*err(k-1)+err(k-2)\big) \end{aligned} 
    
   
 ΔU(k)​=Kp​(err(k)−err(k−1))+βKi​∗err(k)+Kd​(err(k)−2∗err(k−1)+err(k−2))​

其中β称为积分开关系数,其取值范围为:

      β 
     
    
      = 
     
     
     
       { 
      
      
       
        
         
         
           0 
          
         
        
        
         
          
          
            ∣ 
           
          
            e 
           
          
            r 
           
          
            r 
           
          
            ( 
           
          
            k 
           
          
            ) 
           
          
            ∣ 
           
          
            > 
           
          
            ξ 
           
          
         
        
       
       
        
         
         
           1 
          
         
        
        
         
          
          
            ∣ 
           
          
            e 
           
          
            r 
           
          
            r 
           
          
            ( 
           
          
            k 
           
          
            ) 
           
          
            ∣ 
           
          
            ≤ 
           
          
            ξ 
           
          
         
        
       
      
     
    
   
     \beta= \begin{cases} 0& \vert err(k) \vert\gt\xi\\1& \vert err(k) \vert\leq\xi\end{cases} 
    
   
 β={01​∣err(k)∣>ξ∣err(k)∣≤ξ​

简单实现

staticuint16_tBetaGeneration(float error,float epsilon){uint16_t beta=0;if(abs(error)<= epsilon){
        beta=1;}return beta;}typedefstruct{float setpoint;//设定值float proportiongain;//比例系数float integralgain;//积分系数float derivativegain;//微分系数float lasterror;//前一拍偏差float preerror;//前两拍偏差float result;//输出值float epsilon;//偏差检测阈值}PID;voidPIDRegulation(PID *vPID,float processValue){float thisError;float increment;float pError,dError,iError;
    thisError=vPID->setpoint-processValue;
    pError=thisError-vPID->lasterror;
    iError=thisError;
    dError=thisError-2*(vPID->lasterror)+vPID->preerror;uint16_t beta=BetaGeneration(error,vPID->epsilon);if(beta>0){
        increment=vPID->proportiongain*pError+
                  vPID->derivativegain*dError;}else{
        increment=vPID->proportiongain*pError+
                  vPID->integralgain*iError+
                  vPID->derivativegain*dError;}
    vPID->preerror=vPID->lasterror;
    vPID->lasterror=thisError;
    vPID->result+=increment;}

特点

  • 偏差值较大时,取消积分作用,以免于超调量增大。
  • 偏差值较小时,引入积分作用,以便消除静差,提高控制精度。

抗积分饱和PID算法

原理

积分饱和就是指系统存在一个方向的偏差,PID控制器的输出由于积分作用的不断累加而扩大,从而导致控制器输出不断增大超出正常范围进入饱和区。当系统出现反响的偏差时,需要首先从饱和区退出,而不能对反向的偏差进行快速的响应。
抗积分饱和算法,其思路是在计算U(k)的时候,先判断上一时刻的控制量U(k-1)是否已经超出了限制范围。若U(k-1)>Umax,则只累加负偏差;若U(k-1)<Umin,则只累加正偏差。从而避免控制量长时间停留在饱和区。

位置式PID算法

简单实现

typedefstruct{float setpoint;//设定值float proportiongain;//比例系数float integralgain;//积分系数float derivativegain;//微分系数float lasterror;//前一拍偏差float result;//输出值float integral;//积分值float maximum;//最大值float minimum;//最小值}PID;voidPIDRegulation(PID *vPID,float processValue){float thisError;
    thisError=vPID->setpoint-processValue;if(vPID->result>vPID->maximum){if(thisError<=0){
            vPID->integral+=thisError;}}elseif(vPID->result<vPID->minimum){if(thisError>=0){
            vPID->integral+=thisError;}}else{
        vPID->integral+=thisError;}
    vPID->result=vPID->proportiongain*thisError+
                 vPID->integralgain*vPID->integral+
                 vPID->derivativegain*(thisError-vPID->lasterror);
    vPID->lasterror=thisError;}

增量式PID算法

简单实现

typedefstruct{float setpoint;//设定值float proportiongain;//比例系数float integralgain;//积分系数float derivativegain;//微分系数float lasterror;//前一拍偏差float preerror;//前两拍偏差float result;//输出值float maximum;//最大值float minimum;//最小值}PID;voidPIDRegulation(PID *vPID,float processValue){float thisError;float increment;float pError,dError,iError;
    thisError=vPID->setpoint-processValue;
    pError=thisError-vPID->lasterror;
    iError=0;
    dError=thisError-2*(vPID->lasterror)+vPID->preerror;if(vPID->result>vPID->maximum){if(thisError<=0){
            iError=thisError;}}elseif(vPID->result<vPID->minimum){if(thisError>=0){
            iError=thisError;}}else{
        iError=thisError;}
    increment=vPID->proportiongain*pError+
              vPID->integralgain*iError+
              vPID->derivativegain*dError;
    vPID->preerror=vPID->lasterror;
    vPID->lasterror=thisError;
    vPID->result+=increment;}

特点

  • 解决积分饱和的问题

梯形积分PID算法

原理

在PID控制其中,积分项的作用是消除余差,为了尽量减小余差,应提高积分项的运算精度。在积分项中,默认是按矩形方式来计算积分,将矩形积分改为梯形积分可以提高运算精度。

位置式PID算法

基本公式

      U 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      = 
     
     
     
       K 
      
     
       p 
      
     
    
      ∗ 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      + 
     
     
     
       K 
      
     
       i 
      
     
     
     
       ∑ 
      
      
      
        j 
       
      
        = 
       
      
        0 
       
      
     
       k 
      
     
     
      
      
        e 
       
      
        r 
       
      
        r 
       
      
        ( 
       
      
        j 
       
      
        ) 
       
      
        + 
       
      
        e 
       
      
        r 
       
      
        r 
       
      
        ( 
       
      
        j 
       
      
        − 
       
      
        1 
       
      
        ) 
       
      
     
       2 
      
     
    
      + 
     
     
     
       K 
      
     
       d 
      
     
    
      ∗ 
     
    
      ( 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      − 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      − 
     
    
      1 
     
    
      ) 
     
    
      ) 
     
    
   
     U(k)=K_p*err(k)+K_i\sum_{j=0}^{k} \frac {err(j)+err(j-1)}2 +K_d*\big (err(k)-err(k-1)\big ) 
    
   
 U(k)=Kp​∗err(k)+Ki​j=0∑k​2err(j)+err(j−1)​+Kd​∗(err(k)−err(k−1))

简单实现

typedefstruct{float setpoint;//设定值float proportiongain;//比例系数float integralgain;//积分系数float derivativegain;//微分系数float lasterror;//前一拍偏差float result;//输出值float integral;//积分值}PID;voidPIDRegulation(PID *vPID,float processValue){float thisError;
    thisError=vPID->setpoint-processValue;
    vPID->integral+=(thisError+vPID->lasterror)/2;
    vPID->result=vPID->proportiongain*thisError+
                 vPID->integralgain*vPID->integral+
                 vPID->derivativegain*(thisError-vPID->lasterror);
    vPID->lasterror=thisError;}

增量式PID算法

基本公式

          Δ 
         
        
          U 
         
        
          ( 
         
        
          k 
         
        
          ) 
         
        
       
      
      
       
        
         
        
          = 
         
        
          U 
         
        
          ( 
         
        
          k 
         
        
          ) 
         
        
          − 
         
        
          U 
         
        
          ( 
         
        
          k 
         
        
          − 
         
        
          1 
         
        
          ) 
         
        
       
      
     
     
      
       
        
       
      
      
       
        
         
        
          = 
         
         
         
           K 
          
         
           p 
          
         
        
          ( 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          ) 
         
        
          − 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          − 
         
        
          1 
         
        
          ) 
         
        
          ) 
         
        
       
      
     
     
      
       
        
       
      
      
       
        
         
        
          + 
         
         
         
           K 
          
         
           i 
          
         
        
          ∗ 
         
         
          
          
            e 
           
          
            r 
           
          
            r 
           
          
            ( 
           
          
            k 
           
          
            ) 
           
          
            + 
           
          
            e 
           
          
            r 
           
          
            r 
           
          
            ( 
           
          
            k 
           
          
            − 
           
          
            1 
           
          
            ) 
           
          
         
           2 
          
         
        
       
      
     
     
      
       
        
       
      
      
       
        
         
        
          + 
         
         
         
           K 
          
         
           d 
          
         
        
          ( 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          ) 
         
        
          − 
         
        
          2 
         
        
          ∗ 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          − 
         
        
          1 
         
        
          ) 
         
        
          + 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          − 
         
        
          2 
         
        
          ) 
         
        
          ) 
         
        
       
      
     
    
   
     \begin{aligned} \Delta U(k) &= U(k)-U(k-1)\\ &=K_p\big (err(k)-err(k-1)\big )\\&+K_i*\frac {err(k)+err(k-1)}2\\&+K_d\big (err(k)-2*err(k-1)+err(k-2)\big) \end{aligned} 
    
   
 ΔU(k)​=U(k)−U(k−1)=Kp​(err(k)−err(k−1))+Ki​∗2err(k)+err(k−1)​+Kd​(err(k)−2∗err(k−1)+err(k−2))​

简单实现

typedefstruct{float setpoint;//设定值float proportiongain;//比例系数float integralgain;//积分系数float derivativegain;//微分系数float lasterror;//前一拍偏差float preerror;//前两拍偏差float result;//输出值}PID;voidPIDRegulation(PID *vPID,float processValue){float thisError;float increment;float pError,dError,iError;
    thisError=vPID->setpoint-processValue;
    pError=thisError-vPID->lasterror;
    iError=(thisError+vPID->lasterror)/2;
    dError=thisError-2*(vPID->lasterror)+vPID->preerror;
    increment=vPID->proportiongain*pError+
              vPID->integralgain*iError+
              vPID->derivativegain*dError;
    vPID->preerror=vPID->lasterror;
    vPID->lasterror=thisError;
    vPID->result+=increment;}

特点

  • 梯形积分相较于矩形积分其精度有比较大的提高,所以对消除余差也就越有效

变速积分PID算法

原理

在普通的PID控制算法中,由于积分系数Ki是常数,所以在整个控制过程中,积分增量是不变的。然而,系统对于积分项的要求是,系统偏差大时,积分作用应该减弱甚至是全无,而在偏差小时,则应该加强。积分系数取大了会产生超调,甚至积分饱和,取小了又不能短时间内消除静差。
变积分PID的基本思想是设法改变积分项的累加速度,使其与偏差大小相对应:偏差越大,积分越慢; 偏差越小,积分越快。
设定系数为f(err(k)),它是err(k)的函数。当|err(k)|增大时,f减小,反之增大。变积分的PID积分项表达式为:

       U 
      
     
       i 
      
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      = 
     
     
     
       K 
      
     
       i 
      
     
    
      { 
     
    
      f 
     
    
      ( 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      ) 
     
    
      ∗ 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      + 
     
     
     
       ∑ 
      
      
      
        j 
       
      
        = 
       
      
        0 
       
      
      
      
        k 
       
      
        − 
       
      
        1 
       
      
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      j 
     
    
      ) 
     
    
      } 
     
    
   
     U_i(k)=K_i\Big\{ f\big (err(k)\big )*err(k)+\sum_{j=0}^{k-1}err(j)\Big\} 
    
   
 Ui​(k)=Ki​{f(err(k))∗err(k)+j=0∑k−1​err(j)}

其中f(err(k))与|err(k)|的函数关系可根据具体情况设定,可以是线性的也可以是非线性的,通常比较简单的设置如下:

      f 
     
    
      ( 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      ) 
     
    
      = 
     
     
     
       { 
      
      
       
        
         
         
           1 
          
         
        
        
         
          
          
            ∣ 
           
          
            e 
           
          
            r 
           
          
            r 
           
          
            ( 
           
          
            k 
           
          
            ) 
           
          
            ∣ 
           
          
            > 
           
          
            ξ 
           
          
         
        
       
       
        
         
         
           0 
          
         
        
        
         
          
          
            ∣ 
           
          
            e 
           
          
            r 
           
          
            r 
           
          
            ( 
           
          
            k 
           
          
            ) 
           
          
            ∣ 
           
          
            ≤ 
           
          
            ξ 
           
          
         
        
       
      
     
    
   
     f\big(err(k)\big)=\begin{cases} 1& \vert err(k) \vert\gt\xi\\0& \vert err(k) \vert\leq\xi\end{cases} 
    
   
 f(err(k))={10​∣err(k)∣>ξ∣err(k)∣≤ξ​

  
   
    
    
      f 
     
    
      ( 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      ) 
     
    
      = 
     
     
     
       { 
      
      
       
        
         
         
           1 
          
         
        
        
         
          
          
            ∣ 
           
          
            e 
           
          
            r 
           
          
            r 
           
          
            ( 
           
          
            k 
           
          
            ) 
           
          
            ∣ 
           
          
            ≤ 
           
          
            B 
           
          
         
        
       
       
        
         
          
           
           
             A 
            
           
             + 
            
           
             B 
            
           
             − 
            
           
             ∣ 
            
           
             e 
            
           
             r 
            
           
             r 
            
           
             t 
            
           
             ( 
            
           
             k 
            
           
             ) 
            
           
             ∣ 
            
           
          
            A 
           
          
         
        
        
         
          
          
            B 
           
          
            < 
           
          
            ∣ 
           
          
            e 
           
          
            r 
           
          
            r 
           
          
            ( 
           
          
            k 
           
          
            ) 
           
          
            ∣ 
           
          
            ≤ 
           
          
            A 
           
          
            + 
           
          
            B 
           
          
         
        
       
       
        
         
         
           0 
          
         
        
        
         
          
          
            ∣ 
           
          
            e 
           
          
            r 
           
          
            r 
           
          
            ( 
           
          
            k 
           
          
            ) 
           
          
            ∣ 
           
          
            > 
           
          
            A 
           
          
            + 
           
          
            B 
           
          
         
        
       
      
     
    
   
     f\big(err(k)\big)=\begin{cases}1 & \vert err(k)\vert\leq B \\\frac{A+B-\vert errt(k)\vert}{A} & B\lt\vert err(k)\vert\leq A+B\\0 & \vert err(k)\vert\gt A+B\end{cases} 
    
   
 f(err(k))=⎩⎨⎧​1AA+B−∣errt(k)∣​0​∣err(k)∣≤BB<∣err(k)∣≤A+B∣err(k)∣>A+B​

位置式PID算法

基本公式

      U 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      = 
     
     
     
       K 
      
     
       p 
      
     
    
      ∗ 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      + 
     
     
     
       K 
      
     
       i 
      
     
    
      { 
     
    
      f 
     
    
      ( 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      ) 
     
    
      ∗ 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      + 
     
     
     
       ∑ 
      
      
      
        j 
       
      
        = 
       
      
        0 
       
      
      
      
        k 
       
      
        − 
       
      
        1 
       
      
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      j 
     
    
      ) 
     
    
      } 
     
    
      + 
     
     
     
       K 
      
     
       d 
      
     
    
      ∗ 
     
    
      ( 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      − 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      − 
     
    
      1 
     
    
      ) 
     
    
      ) 
     
    
   
     U(k)=K_p*err(k)+K_i\Big\{ f\big (err(k)\big )*err(k)+\sum_{j=0}^{k-1}err(j)\Big\} +K_d*\big (err(k)-err(k-1)\big ) 
    
   
 U(k)=Kp​∗err(k)+Ki​{f(err(k))∗err(k)+j=0∑k−1​err(j)}+Kd​∗(err(k)−err(k−1))

简单实现

staticfloatVariableIntegralCoefficient(floaterror,float absmax,float absmin){float factor=0.0;if(abs(error)<=absmin){
        factor=1.0;}elseif(abs(error)>absmax){
        factor=0.0;}else{
        factor=(absmax-abs(error))/(absmax-absmin);}
    returnfactor;}typedefstruct{float setpoint;//设定值float proportiongain;//比例系数float integralgain;//积分系数float derivativegain;//微分系数float lasterror;//前一拍偏差float result;//输出值float integral;//积分值float errorabsmax;//偏差绝对值最大值float errorabsmin;//偏差绝对值最小值}PID;voidPIDRegulation(PID *vPID,float processValue){float thisError;float factor;
    thisError=vPID->setpoint-processValue;
    factor=VariableIntegralCoefficient(thisError, vPID->errorabsmax,vPID->errorabsmin);
    vPID->integral+= factor*thisError;
    vPID->result=vPID->proportiongain*thisError+
                 vPID->integralgain*vPID->integral+
                 vPID->derivativegain*(thisError-vPID->lasterror);
    vPID->lasterror=thisError;}

增量式PID算法

基本公式

          Δ 
         
        
          U 
         
        
          ( 
         
        
          k 
         
        
          ) 
         
        
       
      
      
       
        
         
        
          = 
         
         
         
           K 
          
         
           p 
          
         
        
          ( 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          ) 
         
        
          − 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          − 
         
        
          1 
         
        
          ) 
         
        
          ) 
         
        
       
      
     
     
      
       
        
       
      
      
       
        
         
        
          + 
         
         
         
           K 
          
         
           i 
          
         
        
          ∗ 
         
        
          f 
         
        
          ( 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          ) 
         
        
          ) 
         
        
          ∗ 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          ) 
         
        
       
      
     
     
      
       
        
       
      
      
       
        
         
        
          + 
         
         
         
           K 
          
         
           d 
          
         
        
          ( 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          ) 
         
        
          − 
         
        
          2 
         
        
          ∗ 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          − 
         
        
          1 
         
        
          ) 
         
        
          + 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          − 
         
        
          2 
         
        
          ) 
         
        
          ) 
         
        
       
      
     
    
   
     \begin{aligned} \Delta U(k) &=K_p\big (err(k)-err(k-1)\big )\\&+K_i*f\big (err(k)\big)*err(k)\\&+K_d\big (err(k)-2*err(k-1)+err(k-2)\big) \end{aligned} 
    
   
 ΔU(k)​=Kp​(err(k)−err(k−1))+Ki​∗f(err(k))∗err(k)+Kd​(err(k)−2∗err(k−1)+err(k−2))​

简单实现

staticfloatVariableIntegralCoefficient(floaterror,float absmax,float absmin){float factor=0.0;if(abs(error)<=absmin){
        factor=1.0;}elseif(abs(error)>absmax){
        factor=0.0;}else{
        factor=(absmax-abs(error))/(absmax-absmin);}
    returnfactor;}typedefstruct{float setpoint;//设定值float proportiongain;//比例系数float integralgain;//积分系数float derivativegain;//微分系数float lasterror;//前一拍偏差float preerror;//前两拍偏差float result;//输出值float errorabsmax;//偏差绝对值最大值float errorabsmin;//偏差绝对值最小值}PID;voidPIDRegulation(PID *vPID,float processValue){float thisError;float increment;float pError,dError,iError;float factor;
    thisError=vPID->setpoint-processValue;
    factor=VariableIntegralCoefficient(thisError, vPID->errorabsmax,vPID->errorabsmin);
    pError=thisError-vPID->lasterror;
    iError=factor*thisError;
    dError=thisError-2*(vPID->lasterror)+vPID->preerror;
    increment=vPID->proportiongain*pError+
              vPID->integralgain*iError+
              vPID->derivativegain*dError;
    vPID->preerror=vPID->lasterror;
    vPID->lasterror=thisError;
    vPID->result+=increment;}

不完全微分PID算法

原理

微分项有引入高频干扰的风险,但若在控制算法中加入低通滤波器,则可使系统性能得到改善。方法之一就是在PID算法中加入一个一阶低通滤波器。这就是所谓的不完全微分。

位置式PID算法

基本公式

      U 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      = 
     
     
     
       K 
      
     
       p 
      
     
    
      ∗ 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      + 
     
     
     
       K 
      
     
       i 
      
     
     
     
       ∑ 
      
      
      
        j 
       
      
        = 
       
      
        0 
       
      
     
       k 
      
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      j 
     
    
      ) 
     
    
      + 
     
     
     
       U 
      
     
       d 
      
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
   
     U(k)=K_p*err(k)+K_i\sum_{j=0}^{k} err(j)+U_d(k) 
    
   
 U(k)=Kp​∗err(k)+Ki​j=0∑k​err(j)+Ud​(k)

  
   
    
     
     
       U 
      
     
       d 
      
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      = 
     
     
     
       K 
      
     
       d 
      
     
    
      ( 
     
    
      1 
     
    
      − 
     
    
      α 
     
    
      ) 
     
    
      ( 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      − 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      − 
     
    
      1 
     
    
      ) 
     
    
      ) 
     
    
      + 
     
    
      α 
     
     
     
       U 
      
     
       d 
      
     
    
      ( 
     
    
      k 
     
    
      − 
     
    
      1 
     
    
      ) 
     
    
   
     U_d(k)=K_d(1-\alpha)\big(err(k)-err(k-1)\big)+\alpha U_d(k-1) 
    
   
 Ud​(k)=Kd​(1−α)(err(k)−err(k−1))+αUd​(k−1)

简单实现

typedefstruct{float setpoint;//设定值float proportiongain;//比例系数float integralgain;//积分系数float derivativegain;//微分系数float lasterror;//前一拍偏差float lastdev;//前一拍时的微分项值float alpha;//不完全微分系数float result;//输出值float integral;//积分值}PID;voidPIDRegulation(PID *vPID,float processValue){float thisError;float thisDev;
    thisError=vPID->setpoint-processValue;
    vPID->integral+=thisError;
    thisDev=vPID->derivativegain*(1-vPID->alpha)*(thisError-vPID->lasterror)+
            vPID->alpha*vPID->lastdev;
    vPID->result=vPID->proportiongain*thisError+
                 vPID->integralgain*vPID->integral+
                 thisDev;
    vPID->lasterror=thisError;
    vPID->lastdev=thisDev;}

增量式PID算法

基本公式

      Δ 
     
    
      U 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      = 
     
     
     
       K 
      
     
       p 
      
     
    
      ( 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      − 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      − 
     
    
      1 
     
    
      ) 
     
    
      ) 
     
    
      + 
     
     
     
       K 
      
     
       i 
      
     
    
      ∗ 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      + 
     
    
      Δ 
     
     
     
       U 
      
     
       d 
      
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
   
     \Delta U(k) =K_p\big (err(k)-err(k-1)\big )+K_i*err(k)+\Delta U_d(k) 
    
   
 ΔU(k)=Kp​(err(k)−err(k−1))+Ki​∗err(k)+ΔUd​(k)

  
   
    
    
      Δ 
     
     
     
       U 
      
     
       d 
      
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      = 
     
     
     
       K 
      
     
       d 
      
     
    
      ( 
     
    
      1 
     
    
      − 
     
    
      α 
     
    
      ) 
     
    
      ( 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      − 
     
    
      2 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      − 
     
    
      1 
     
    
      ) 
     
    
      + 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      − 
     
    
      2 
     
    
      ) 
     
    
      ) 
     
    
      + 
     
    
      α 
     
    
      Δ 
     
     
     
       U 
      
     
       d 
      
     
    
      ( 
     
    
      k 
     
    
      − 
     
    
      1 
     
    
      ) 
     
    
   
     \Delta U_d(k)=K_d(1-\alpha)\big(err(k)-2err(k-1)+err(k-2)\big)+\alpha\Delta U_d(k-1) 
    
   
 ΔUd​(k)=Kd​(1−α)(err(k)−2err(k−1)+err(k−2))+αΔUd​(k−1)

简单实现

typedefstruct{float setpoint;//设定值float proportiongain;//比例系数float integralgain;//积分系数float derivativegain;//微分系数float lasterror;//前一拍偏差float preerror;//前两拍偏差float lastdeltadev;//前一拍时的微分项增量float alpha;//不完全微分系数float result;//输出值}PID;voidPIDRegulation(PID *vPID,float processValue){float thisError;float increment;float deltaDev;float pError,dError,iError;
    thisError=vPID->setpoint-processValue;
    pError=thisError-vPID->lasterror;
    iError=thisError;
    dError=thisError-2*(vPID->lasterror)+vPID->preerror;
    deltaDev=vPID->derivativegain*(1-vPID->alpha)*dError+
             vPID->alpha*vPID->lastdeltadev;
    increment=vPID->proportiongain*pError+
              vPID->integralgain*iError+
              deltaDev;
    vPID->preerror=vPID->lasterror;
    vPID->lasterror=thisError;
    vPID->lastdeltadev=deltaDev;
    vPID->result+=increment;}

特点

  • 不完全微分方式在微分环节采用了低通滤波有效地提高了微分项的特性。其中α的取值是一个0~1之间的数。两个极限值,在0时其实就是没有滤波的普通微分环节;而取1时,则没有微分作用。

微分先行PID算法

位置式PID算法

基本公式

      U 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      = 
     
     
     
       K 
      
     
       p 
      
     
    
      ∗ 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      + 
     
     
     
       K 
      
     
       i 
      
     
     
     
       ∑ 
      
      
      
        j 
       
      
        = 
       
      
        0 
       
      
     
       k 
      
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      j 
     
    
      ) 
     
    
      + 
     
     
     
       U 
      
     
       d 
      
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
   
     U(k)=K_p*err(k)+K_i\sum_{j=0}^{k} err(j)+U_d(k) 
    
   
 U(k)=Kp​∗err(k)+Ki​j=0∑k​err(j)+Ud​(k)

  
   
    
     
     
       U 
      
     
       d 
      
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      = 
     
    
      ( 
     
     
      
      
        γ 
       
       
       
         K 
        
       
         d 
        
       
      
      
      
        γ 
       
       
       
         K 
        
       
         d 
        
       
      
        + 
       
       
       
         K 
        
       
         p 
        
       
      
     
    
      ) 
     
     
     
       U 
      
     
       d 
      
     
    
      ( 
     
    
      k 
     
    
      − 
     
    
      1 
     
    
      ) 
     
    
      + 
     
    
      ( 
     
     
      
       
       
         K 
        
       
         d 
        
       
      
        + 
       
       
       
         K 
        
       
         p 
        
       
      
      
      
        γ 
       
       
       
         K 
        
       
         d 
        
       
      
        + 
       
       
       
         K 
        
       
         p 
        
       
      
     
    
      ) 
     
    
      y 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      + 
     
    
      ( 
     
     
      
      
        K 
       
      
        d 
       
      
      
      
        γ 
       
       
       
         K 
        
       
         d 
        
       
      
        + 
       
       
       
         K 
        
       
         p 
        
       
      
     
    
      ) 
     
    
      y 
     
    
      ( 
     
    
      k 
     
    
      − 
     
    
      1 
     
    
      ) 
     
    
   
     U_d(k)=\Big(\frac{\gamma K_d}{\gamma K_d+K_p}\Big)U_d(k-1)+\Big(\frac{K_d+K_p}{\gamma K_d+K_p}\Big)y(k)+\Big(\frac{K_d}{\gamma K_d+K_p}\Big)y(k-1) 
    
   
 Ud​(k)=(γKd​+Kp​γKd​​)Ud​(k−1)+(γKd​+Kp​Kd​+Kp​​)y(k)+(γKd​+Kp​Kd​​)y(k−1)

简单实现

typedefstruct{float setpoint;//设定值float proportiongain;//比例系数float integralgain;//积分系数float derivativegain;//微分系数float lasterror;//前一拍偏差float result;//输出值float integral;//积分值float derivative;//微分项float lastPv;//前一拍的测量值float gama;//微分先行滤波系数}PID;voidPIDRegulation(PID *vPID,float processValue){float thisError;float c1,c2,c3,temp;
    
    thisError=vPID->setpoint-processValue;
    vPID->integral+=thisError;
    temp=vPID->gama*vPID->derivativegain+vPID->proportiongain;
    c3=vPID->derivativegain/temp;
    c2=(vPID->derivativegain+vPID->proportiongain)/temp;
    c1=vPID->gama*c3;
    vPID->derivative=c1*vPID->derivative+c2*processValue+c3*vPID->lastPv;
    
    vPID->result=vPID->proportiongain*thisError+
                 vPID->integralgain*vPID->integral+
                 vPID->derivative;
    vPID->lasterror=thisError;
    vPID->lastPv=processValue;}

增量式PID算法

基本公式

      Δ 
     
    
      U 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      = 
     
     
     
       K 
      
     
       p 
      
     
    
      ( 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      − 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      − 
     
    
      1 
     
    
      ) 
     
    
      ) 
     
    
      + 
     
     
     
       K 
      
     
       i 
      
     
    
      ∗ 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      + 
     
    
      Δ 
     
     
     
       U 
      
     
       d 
      
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
   
     \Delta U(k) =K_p\big (err(k)-err(k-1)\big )+K_i*err(k)+\Delta U_d(k) 
    
   
 ΔU(k)=Kp​(err(k)−err(k−1))+Ki​∗err(k)+ΔUd​(k)

  
   
    
    
      Δ 
     
     
     
       U 
      
     
       d 
      
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      = 
     
    
      ( 
     
     
      
      
        γ 
       
       
       
         K 
        
       
         d 
        
       
      
      
      
        γ 
       
       
       
         K 
        
       
         d 
        
       
      
        + 
       
       
       
         K 
        
       
         p 
        
       
      
     
    
      ) 
     
    
      Δ 
     
     
     
       U 
      
     
       d 
      
     
    
      ( 
     
    
      k 
     
    
      − 
     
    
      1 
     
    
      ) 
     
    
      + 
     
    
      ( 
     
     
      
       
       
         K 
        
       
         d 
        
       
      
        + 
       
       
       
         K 
        
       
         p 
        
       
      
      
      
        γ 
       
       
       
         K 
        
       
         d 
        
       
      
        + 
       
       
       
         K 
        
       
         p 
        
       
      
     
    
      ) 
     
    
      Δ 
     
    
      y 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      + 
     
    
      ( 
     
     
      
      
        K 
       
      
        d 
       
      
      
      
        γ 
       
       
       
         K 
        
       
         d 
        
       
      
        + 
       
       
       
         K 
        
       
         p 
        
       
      
     
    
      ) 
     
    
      Δ 
     
    
      y 
     
    
      ( 
     
    
      k 
     
    
      − 
     
    
      1 
     
    
      ) 
     
    
   
     \Delta U_d(k)=\Big(\frac{\gamma K_d}{\gamma K_d+K_p}\Big)\Delta U_d(k-1)+\Big(\frac{K_d+K_p}{\gamma K_d+K_p}\Big)\Delta y(k)+\Big(\frac{K_d}{\gamma K_d+K_p}\Big)\Delta y(k-1) 
    
   
 ΔUd​(k)=(γKd​+Kp​γKd​​)ΔUd​(k−1)+(γKd​+Kp​Kd​+Kp​​)Δy(k)+(γKd​+Kp​Kd​​)Δy(k−1)

简单实现

typedefstruct{float setpoint;//设定值float proportiongain;//比例系数float integralgain;//积分系数float derivativegain;//微分系数float lasterror;//前一拍偏差float preerror;//前两拍偏差float lastdeltadev;//前一拍时的微分项增量float alpha;//不完全微分系数float result;//输出值float deltadiff;//微分增量float integralValue;//积分累计量float gama;//微分先行滤波系数float lastPv;//上一拍的过程测量值float lastDeltaPv;//上一拍的过程测量值增量}PID;voidPIDRegulation(PID *vPID,float processValue){float thisError;float increment;float pError,iError;float c1,c2,c3,temp;float deltaPv;
    
    temp=vPID->gama*vPID->derivativegain+vPID->proportiongain;
    c3=vPID->derivativegain/temp;
    c2=(vPID->derivativegain+vPID->proportiongain)/temp;
    c1=vPID->gama*c3;
    deltaPv=processValue-vPID->lastDeltaPv
    vPID->deltadiff=c1*vPID->deltadiff+c2*deltaPv+c3*vPID->lastDeltaPv;
    thisError=vPID->setpoint-processValue;
    pError=thisError-vPID->lasterror;
    iError=thisError;
    
    increment=vPID->proportiongain*pError+
              vPID->integralgain*iError+
              vPID->deltadiff;
    vPID->preerror=vPID->lasterror;
    vPID->lastDeltaPv=deltaPv;
    vPID->lastPv=processValue;
    vPID->lasterror=thisError;
    vPID->result+=increment;}

特点

  • 微分先行由于微分部分只对测量值起作用所以可以消除设定值突变的影响,还可以引入低通滤波,甚至在必要时将比例作用也可进行相应的改进。

带死区的PID算法

位置式PID算法

基本公式

      U 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      = 
     
     
     
       K 
      
     
       p 
      
     
    
      ∗ 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      + 
     
     
     
       K 
      
     
       i 
      
     
     
     
       ∑ 
      
      
      
        j 
       
      
        = 
       
      
        0 
       
      
     
       k 
      
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      j 
     
    
      ) 
     
    
      + 
     
     
     
       K 
      
     
       d 
      
     
    
      ∗ 
     
    
      ( 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      − 
     
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      − 
     
    
      1 
     
    
      ) 
     
    
      ) 
     
    
   
     U(k)=K_p*err(k)+K_i\sum_{j=0}^{k} err(j)+K_d*\big (err(k)-err(k-1)\big ) 
    
   
 U(k)=Kp​∗err(k)+Ki​j=0∑k​err(j)+Kd​∗(err(k)−err(k−1))

  
   
    
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      = 
     
     
     
       { 
      
      
       
        
         
         
           0 
          
         
        
        
         
          
          
            ∣ 
           
          
            e 
           
          
            r 
           
          
            r 
           
          
            ( 
           
          
            k 
           
          
            ) 
           
          
            ∣ 
           
          
            ≤ 
           
          
            ∣ 
           
          
            e 
           
          
            r 
           
           
           
             r 
            
           
             0 
            
           
          
            ∣ 
           
          
         
        
       
       
        
         
          
          
            e 
           
          
            r 
           
          
            r 
           
          
            ( 
           
          
            k 
           
          
            ) 
           
          
         
        
        
         
          
          
            ∣ 
           
          
            e 
           
          
            r 
           
          
            r 
           
          
            ( 
           
          
            k 
           
          
            ) 
           
          
            ∣ 
           
          
            > 
           
          
            ∣ 
           
          
            e 
           
          
            r 
           
           
           
             r 
            
           
             0 
            
           
          
            ∣ 
           
          
         
        
       
      
     
    
   
     err(k)=\begin{cases}0 & \vert err(k)\vert\leq \vert err_0\vert \\err(k) & \vert err(k)\vert\gt \vert err_0\vert\end{cases} 
    
   
 err(k)={0err(k)​∣err(k)∣≤∣err0​∣∣err(k)∣>∣err0​∣​

简单实现

typedefstruct{float setpoint;//设定值float proportiongain;//比例系数float integralgain;//积分系数float derivativegain;//微分系数float lasterror;//前一拍偏差float result;//输出值float integral;//积分值float deadband;//死区}PID;voidPIDRegulation(PID *vPID,float processValue){float thisError;
    thisError=vPID->setpoint-processValue;if(fabs(thisError)>vPID->deadband){
        vPID->integral+=thisError;}else{
        thisError=0;}
    vPID->result=vPID->proportiongain*thisError+
                 vPID->integralgain*vPID->integral+
                 vPID->derivativegain*(thisError-vPID->lasterror);
    vPID->lasterror=thisError;}

增量式PID算法

基本公式

          Δ 
         
        
          U 
         
        
          ( 
         
        
          k 
         
        
          ) 
         
        
       
      
      
       
        
         
        
          = 
         
        
          U 
         
        
          ( 
         
        
          k 
         
        
          ) 
         
        
          − 
         
        
          U 
         
        
          ( 
         
        
          k 
         
        
          − 
         
        
          1 
         
        
          ) 
         
        
       
      
     
     
      
       
        
       
      
      
       
        
         
        
          = 
         
         
         
           K 
          
         
           p 
          
         
        
          ( 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          ) 
         
        
          − 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          − 
         
        
          1 
         
        
          ) 
         
        
          ) 
         
        
       
      
     
     
      
       
        
       
      
      
       
        
         
        
          + 
         
         
         
           K 
          
         
           i 
          
         
        
          ∗ 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          ) 
         
        
       
      
     
     
      
       
        
       
      
      
       
        
         
        
          + 
         
         
         
           K 
          
         
           d 
          
         
        
          ( 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          ) 
         
        
          − 
         
        
          2 
         
        
          ∗ 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          − 
         
        
          1 
         
        
          ) 
         
        
          + 
         
        
          e 
         
        
          r 
         
        
          r 
         
        
          ( 
         
        
          k 
         
        
          − 
         
        
          2 
         
        
          ) 
         
        
          ) 
         
        
       
      
     
    
   
     \begin{aligned} \Delta U(k) &= U(k)-U(k-1)\\ &=K_p\big (err(k)-err(k-1)\big )\\&+K_i*err(k)\\&+K_d\big (err(k)-2*err(k-1)+err(k-2)\big) \end{aligned} 
    
   
 ΔU(k)​=U(k)−U(k−1)=Kp​(err(k)−err(k−1))+Ki​∗err(k)+Kd​(err(k)−2∗err(k−1)+err(k−2))​

  
   
    
    
      e 
     
    
      r 
     
    
      r 
     
    
      ( 
     
    
      k 
     
    
      ) 
     
    
      = 
     
     
     
       { 
      
      
       
        
         
         
           0 
          
         
        
        
         
          
          
            ∣ 
           
          
            e 
           
          
            r 
           
          
            r 
           
          
            ( 
           
          
            k 
           
          
            ) 
           
          
            ∣ 
           
          
            ≤ 
           
          
            ∣ 
           
          
            e 
           
          
            r 
           
           
           
             r 
            
           
             0 
            
           
          
            ∣ 
           
          
         
        
       
       
        
         
          
          
            e 
           
          
            r 
           
          
            r 
           
          
            ( 
           
          
            k 
           
          
            ) 
           
          
         
        
        
         
          
          
            ∣ 
           
          
            e 
           
          
            r 
           
          
            r 
           
          
            ( 
           
          
            k 
           
          
            ) 
           
          
            ∣ 
           
          
            > 
           
          
            ∣ 
           
          
            e 
           
          
            r 
           
           
           
             r 
            
           
             0 
            
           
          
            ∣ 
           
          
         
        
       
      
     
    
   
     err(k)=\begin{cases}0 & \vert err(k)\vert\leq \vert err_0\vert \\err(k) & \vert err(k)\vert\gt \vert err_0\vert\end{cases} 
    
   
 err(k)={0err(k)​∣err(k)∣≤∣err0​∣∣err(k)∣>∣err0​∣​

简单实现

typedefstruct{float setpoint;//设定值float proportiongain;//比例系数float integralgain;//积分系数float derivativegain;//微分系数float lasterror;//前一拍偏差float preerror;//前两拍偏差float result;//输出值float deadband;//死区}PID;voidPIDRegulation(PID *vPID,float processValue){float thisError;float increment;float pError,dError,iError;
    thisError=vPID->setpoint-processValue;if(fabs(thisError)>vPID->deadband){
        vPID->integral+=thisError;}else{
        thisError=0;}
    pError=thisError-vPID->lasterror;
    iError=thisError;
    dError=thisError-2*(vPID->lasterror)+vPID->preerror;
    increment=vPID->proportiongain*pError+
              vPID->integralgain*iError+
              vPID->derivativegain*dError;
    vPID->preerror=vPID->lasterror;
    vPID->lasterror=thisError;
    vPID->result+=increment;}

特点

  • 消除稳定点附近的波动

基于前馈补偿的PID算法

不太懂,直接给链接
基于前馈补偿的PID算法


本文转载自: https://blog.csdn.net/weixin_61692649/article/details/127560255
版权归原作者 图灵tuling 所有, 如有侵权,请联系我们删除。

“PID算法”的评论:

还没有评论