改進初學者的PID-微分沖擊


  最近看到了Brett Beauregard發表的有關PID的系列文章,感覺對於理解PID算法很有幫助,於是將系列文章翻譯過來!在自我提高的過程中,也希望對同道中人有所幫助。作者Brett Beauregard的原文網址:http://brettbeauregard.com/blog/2011/04/improving-the-beginner%E2%80%99s-pid-derivative-kick/

 

1、問題

  這個修改將稍微調整微分項。其目標是消除一種被稱為“微分沖擊”的現象。

 

  上圖說明了問題。由於error = Setpoint-Input,設定值的任何變化都會導致偏差的瞬時變化。這種變化的導數是無窮大(實際上,由於dt不是0,它只是一個非常大的數字。)這個數字被輸入PID方程,這導致輸出中出現不希望的峰值。幸運的是,有一種簡單的方法可以擺脫這種情況。

2、解決方案

 

  事實證明,當設定值發生變化時,偏差的導數等於輸入的負導數。這最終成為一個完美的解決方案。我們減去(Kd *輸入的導數)而不是添加(Kd *偏差的導數)。這被稱為使用“基於測量的微分”。

3、代碼

 1 /*working variables*/
 2 unsigned long lastTime;
 3 double Input,Output,Setpoint;
 4 double errSum,lastInput;
 5 double kp,ki,kd;
 6 int SampleTime = 1000; //1 sec
 7 void Compute()
 8 {
 9    unsigned long now = millis();
10    int timeChange = (now - lastTime);
11    if(timeChange>=SampleTime)
12    {
13       /*Compute all the working error variables*/
14       double error = Setpoint - Input;
15       errSum += error;
16       double dInput = (Input - lastInput);
17  
18       /*Compute PID Output*/
19       Output = kp * error + ki * errSum - kd * dInput;
20  
21       /*Remember some variables for next time*/
22       lastInput = Input;
23       lastTime = now;
24    }
25 }
26  
27 void SetTunings(double Kp,double Ki,double Kd)
28 {
29   double SampleTimeInSec = ((double)SampleTime)/1000;
30    kp = Kp;
31    ki = Ki * SampleTimeInSec;
32    kd = Kd / SampleTimeInSec;
33 }
34  
35 void SetSampleTime(int NewSampleTime)
36 {
37    if (NewSampleTime > 0)
38    {
39       double ratio  = (double)NewSampleTime
40                       / (double)SampleTime;
41       ki *= ratio;
42       kd /= ratio;
43       SampleTime = (unsigned long)NewSampleTime;
44    }
45 }

  這里的修改非常簡單。我們用-dInput替換+ dError。我們現在需要記住lastInput,而不是記住lastError

4、結果

 

  以下是這些修改對我們的影響。請注意,輸入看起來仍然相同。所以我們得到相同的性能,但是每次設定點改變時我們都不會發出巨大的輸出尖峰。

  這也許沒什么大不了的。這完全取決於應用程序對輸出峰值有多敏感。但在我看來,沒有沖擊就不需要做更多的工作,所以為什么不把事情做好呢?

歡迎關注:


免責聲明!

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



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