在這里暫且將其歸為模擬技術吧!
前一段時間由於開關電源的控制,做了一下PID的控制算法,和之前自己的方法對比了一下,感覺效果確實要好不好,關鍵是參數調好了之后就會很穩定,電壓波動比較小,因此有一定的使用價值和實用價值!由於沒有學過自動控制原理,所以很多的東西還是從網上看到的,理解起來還是比較生硬,昨天晚上遇到一個問題,現在想拿出來和大家一起思考一下,望大家批評指正!
首先還是拿出公式:
(1)式為PID控制的離散公式,其中e(k)為目標值和輸出反饋值的誤差。
由(1)式可以得到(2)式,然后將兩者想減,得到(3)式。
其次,對公式進行簡單的介紹。PID控制在實際應用廣泛主要分為兩種控制方式:位置式和增量式。
(1)式是簡單的求和公式的使用方式,這個也是位置式的控制依據,(3)式為對(1)式的變形,是增量式的控制依據。由於依據的公式的形式不一樣,所以具體的實現形勢不一樣。
由公式(1)的實現形式可以看到,其中有求和項,也就是積分項,而公式(3)則沒有求和項。但是注意 一點,后者的得出的是相鄰的兩者的差值,所以這個不是實際的控制量,實際的控制量是對(u(k)-u(k-1))進行求和得到的。由公式可知,(1)式是能夠直接給出控制量的,而(3)式需要多次控制量的累加得到的,這樣就導致了我們實現的時間相對長一些,響應速度也就慢一些。
兩者實現各有優點,位置式相當於是一個指南針吧,始終向着設定的目標值,而增量式就是一點點想着目標值靠近。前者實現的過程中要求反饋量比較精確,或是說你的采樣量比較干凈,反饋比例誤差小,否則指南針就會指偏了方向。而增量式則是相當於一個死纏難打求婚的男士,一點點向你靠近,不是直接達到,先是靠近你朋友,然后未來的丈母娘,搞滲透,最后才慢慢達到目標。這個原因很簡單,因為現在他現在沒有信息的反饋渠道,也就是反饋量不准確,他必須要先去獲得反饋量,想一蹴而就,要是反饋量不准確,那肯定就會超調,就會吃閉門羹的。所以說增量式還是適合反饋量不准確,反饋噪聲大,或是要求輸出盡可能比較穩定的情況下面。
現在拿出程序,看看吧!
先看位置式。 *==================================================================================================== PID計算部分 =====================================================================================================*/ unsigned int PIDCalc( struct PID *pp, unsigned int NextPoint ) { unsigned int dError,Error; Error = pp->SetPoint - NextPoint; // 偏差 pp->SumError += Error; // 積分 dError = pp->LastError - pp->PrevError; // 當前微分 pp->PrevError = pp->LastError; pp->LastError = Error; return (pp->Proportion * Error//比例 + pp->Integral * pp->SumError //積分項 + pp->Derivative * dError); // 微分項 } /*********************************************************** 位置式在實現的過程中,一目了然,清楚明白,看一下公式就能知道實現過程。因此沒有什么好說的。還是先看看增量式。(以下是我的一個搞智能汽車的同學幫我修改的增量式的程序,但是我一直覺得有點問題,雖然也能實現控制,但是和公式對着看了一下還是不對應,而在進行累加的時候,我發現那樣根本就不行,因為累加得到的結果一直是負值,這個是不能直接給我的pwm控制寄存器的。然后我人為修改為進行累減,然后就可以進行控制了)。我不知道問題是不是出在這里,所以還是拿出來和大家討論討論。
先看程序:
float PIDCalc( struct PID *pp, unsigned int NextPoint ) { float dError,Error,temp; temp=(NextPoint*3.3/4096.0)*7.5;//將采樣電壓值轉換位輸出電壓值
pp->SumError = pp->SetPoint-temp ; //積分 Error = pp->SumError-pp->LastError; // 偏差 dError = Error - pp->PrevError; // 當前微分 pp->PrevError = Error; pp->LastError = pp->SumError; temp=(pp->Proportion * Error//比例 + pp->Integral * pp->SumError //積分項 + pp->Derivative * dError); // 微分項 return temp; }
現在我們對應這個公式和微分項看看,由於增量式中微分項為e(k)-e(k-1)-(e(k-1)-e(k-2)=e(k)-2e(k-1)+e(k-2);
那么在我的這個程序實現的過程中,這是直接將e(k)-e(k-1)作為微分項,顯然這個公式的差距很大,即便是工程應用上有很大的簡約或是其他處理,但是這個已經嚴重超出等效的范圍。
另外昨天晚上轉載了一文章,在空間里面,也就將PID的增量控制的,但是實現方式和這個卻不大相同,大家也參考一下,這個在理解的時候可能要簡單一些,但是初期的跳出合理的參數會更難一點,因為簡化后和簡化前的關系並不是線性關系。因為有更加線性條件下,適當使用二分法還是能迅速找到最佳參數的位置。
希望大家批評指正哈!