本文將分析《手把手教你看懂並理解Arduino PID控制庫》中第二個問題:設定值改變對微分項的影響。語文很差,原文中叫作Derivative Kick,實在是想不出好的名字,暫且稱爲微分衝擊。ui
既然叫作微分衝擊,那麼這個問題確定和微分項有關,而且是微分項會受到一個突發情況的影響,產生一個較大的衝擊,詳見下圖。spa
從第一張圖看出,當設定值產生一個階躍後,被控量Input隨着時間慢慢向設定值靠近,第二張圖反應的是設定值產生階躍後控制量Output的變化,能夠發現,Output會忽然產生一個較大的階躍,具體緣由能夠參考「萬惡」的PID經典控制方程。第三張圖描述的是Output的梯度(也就是變化率:值變化:時間變化),一樣能夠發現一個脈衝,而且這個脈衝可能會很是的大(dt很是小),遠遠超過Output變化量。同理,圖中頁描述了當設定值忽然減少,Output及其對應的梯度變化狀況。對於通常的系統來講,咱們不但願這樣的突變發生(能夠想象若是採樣週期很長,那麼這個衝擊會持續很長時間,系統估計就飛起來了)。固然若是你的系統須要這個衝擊,那麼這個問題就能夠忽略,下面的解決方案也就不須要瀏覽。.net
首先,感謝咱們偉大的數學家,結合經典PID控制方程,來看一個公式:code
Setpoint這一項就會產生一個巨大的衝擊,並且僅會產生一次,在下一個計算週期就會消失。處理的方法不少,最簡單的就是講Serpoint這一項移除,也就是認爲對於微分項來講不存在設定值的改變。若是這麼處理,系統會不會失控呢?這種玩法已經和咱們根深蒂固的經典PID理論不同了啊!!這怎麼整!blog
上述問題的答案是不會,咱們將上述過程寫成數學表達式:get
用Input變化量取反來表明Error的變化(其實就是忽略Setpoint的變化)。這裏不討論經典的PID控制方程,咱們的目標是使Input根據Setpoint往咱們預計的方向靠攏,上述作法無能否認,與經典PID方程不一致,但核心思想是一致的。因爲Setpoint變化僅對Output產生一次影響(也就是產生了那個尖峯),一旦步入一下個計算週期,Output就不在收到Setpoint變化的影響,迴歸正常,不影響PID調節(具體影響圖示,請參照文末)。數學
/*working variables*/ unsigned long lastTime; double Input, Output, Setpoint; double errSum, lastInput; double kp, ki, kd; int SampleTime = 1000; //1 sec void Compute() { unsigned long now = millis(); int timeChange = (now - lastTime); if(timeChange>=SampleTime) { /*Compute all the working error variables*/ double error = Setpoint - Input; errSum += error; double dInput = (Input - lastInput); /*Compute PID Output*/ Output = kp * error + ki * errSum - kd * dInput; /*Remember some variables for next time*/ lastInput = Input; lastTime = now; } } void SetTunings(double Kp, double Ki, double Kd) { double SampleTimeInSec = ((double)SampleTime)/1000; kp = Kp; ki = Ki * SampleTimeInSec; kd = Kd / SampleTimeInSec; } void SetSampleTime(int NewSampleTime) { if (NewSampleTime > 0) { double ratio = (double)NewSampleTime / (double)SampleTime; ki *= ratio; kd /= ratio; SampleTime = (unsigned long)NewSampleTime; } }
代碼用Input的變化取代了Error的變化。io
NOTE:若有不足之處請告知。^.^ast
下一章將介紹若是在系統運行過程當中,忽然改變PID控制參數對系統的影響class
PS:轉載請註明出處:歐陽天華