最近看到了Brett Beauregard發表的有關PID的系列文章,感受對於理解PID算法頗有幫助,因而將系列文章翻譯過來!在自我提升的過程當中,也但願對同道中人有所幫助。做者Brett Beauregard的原文網址:http://brettbeauregard.com/blog/2011/04/improving-the-beginner%E2%80%99s-pid-tuning-changes/算法
1、問題spa
對於任何可靠的PID算法,擁有在系統運行時更改整定參數的能力都是必須的。翻譯
若是你試圖在系統運行時改變整定參數,在初學PID的人看來會顯得有點瘋狂。讓咱們看看這是爲何?如下是初學者的 PID 在上述參數更改先後的狀態:3d
所以,咱們能夠當即將這種差別歸咎於積分項(或「I項」)。只有當參數發生變化時,它纔會發生劇烈的變化。爲何會這樣?這與初學積分的人對積分的理解有關:code
這種解釋在 Ki 被改變以前都是能夠正常工做的。而後,你忽然把這個新的 Ki 乘以你積累的整個偏差總和。這不是咱們想要的!咱們只想影響事情後續的發展。blog
2、解決方案get
有幾種方法能夠處理這個問題。我在上一個庫中使用的方法是從新縮放誤差累計。Ki 翻了一倍?或者把誤差累計削減一半。這能夠避免積分項撞擊,而且也能工做的很好。不過,這有點笨拙,我想出了更優雅的東西。(我不多是第一個想到這個問題,但我確實是一我的想到的。這算數!)數學
這個方案須要一個小的基本代數 (仍是微積分?)io
咱們不是讓 Ki 處在積分以外,而是把它帶到裏面。看起來咱們視乎什麼都沒作,但咱們會看到,在實踐中,這帶來了很大的變化。ast
如今,咱們把偏差乘以那個時候的Ki。而後咱們存儲它的和。當Ki發生變化時,沒有任何變化,由於全部舊的Ki都已經「存在銀行」了。咱們獲得一個平穩的轉換,沒有額外的數學運算。這可能會讓我成爲一個極客,但我以爲這很性感。
3、代碼
1 /*working variables*/ 2 unsigned long lastTime; 3 double Input,Output,Setpoint; 4 double ITerm,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 ITerm += (ki * error); 16 double dInput = (Input - lastInput); 17 18 /*Compute PID Output*/ 19 Output = kp * error + ITerm - 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 }
所以,咱們用複合積分項變量替換了 [第4行]誤差求和變量。它計算 Ki * 誤差,而不只僅是誤差 [第15行]。此外,因爲 Ki 如今被隱藏在積分項中,所以它將從主 PID 計算 [第19行] 中刪除。
4、結果
那麼,這是如何解決問題的。在修改Ki以前,它從新計算了全部誤差的總和;咱們看到的每個誤差值。有了這段代碼,以前的誤差將保持不變,而新的Ki只會影響事情的進展,這正是咱們想要的。
譯註:對於本篇討論的修改整定參數對積分項的影響問題。採用位置式PID公式確實存在這一問題,做者的解決方式也很贊。由於這就是增量式PID積分項的默認處理方式。因此若是採用增量式PID就不會存在這個問題了。
歡迎關注: