Fw: [問題] dspic數位PID控制
有好心人士回答我了
再次感謝
有同樣問題的參考一下吧
-----------------------------------------------------------------------
我簡單說明一下我的看法。
假設你今天只設定Kp而無其他Ki的話。
那你的輸出應該是很不穩定的 if your controller is enable。
因為P controller應該是個隨著誤差而變化的放大器而已。
那他不知道甚麼時候才是你的理想 reference。
他只知道,有差距,我就調整。
但PI controller,會慢慢透過Ki的關係,使得I gain的部分達到了reference。
那剩餘的P gain則是在做高頻切頻所造成的諧波補償罷了。
我是沒用過PID controller,但我猜測Kd的方式只是增強在瞬間的變化而已。
好了,到這邊你有沒有發現一件事情。
你說你只設定Kp,沒有Ki,系統確會穩定?
是不是跟我前面說的前提剛好是顛倒的?
那就表示一件事情,你的Kp所造成的output值(PID出來的那個)趨近於某個數值。
就變成了可能是 0*Duty_range+Duty_ref or 0.2*Duty_range+Duty_ref.
也因此,當你在做output load的變化時候,Kp根本就不會影響到你的output值。
仍然維持在0 or 0.2
所以你的Duty也不會有甚麼太大的變化。(只剩下 Duty_ref)
簡單講,你的Kp太小,根本就不會動作。
但為什麼你調整Kp,加大以後系統會不穩呢?
那就是因為,你的Kp開始影響了你的Duty,但是因為沒有一個reference,所以
你看起來會像是不穩,實際上,這才是真正該有的情形。
簡單講,你應該要設定Ki,至於Kd我覺得可以先不用動,一般都只用PI controller。
好了,到這邊先是給予你觀念的問題。
However,你又說到了,設定Ki還是會不穩。
我個人的猜測,就是你的 output*Duty_range + Duty_ref 這行的問題。
為什麼這麼說,因為你這行就是拿來和三角波比較的值了吧?
但,為什麼我說這行有問題呢?
想想看,我們一般PI controller的構成方式。
Pgain造成的放大,Igain造成的時間累加,這兩個值最後會幹嗎?
是否就是相加以後,來和三角波比較了。
再看看那行式子,有和我說的相似嗎?
好像沒有吧?
我們姑且不論Duty_range,因為他就像是一個倍率罷了。
只是變相的提高或降低Kp or Ki, 這可以先拿掉。
會改寫成 output* + Duty_ref。
看出來了嗎?你多了個Duty_ref這個 offset!
我知道,你會說這是來限制大小的。
但是限制大小應該在這樣限制的嗎?絕對不是。
而是當你與三角波比較的值,大於或小於某個數字,才進行一個限制量
(if a> 1000 , a=1000 , b< 500 , b=500 .. etc)
or一些反向Pgain(這可以問你們的學長),常用在防止Igain過大導致發散。
(Anti_windup : if o>1000, o_err=(o-1000)*p, I_error=I_error-o)
而這也是為什麼你的Kp過小,但是你的Duty仍然可以動作不使得系統完全不穩定。
因為有個Duty_ref,他就好像取代了I gain所出來的值一般一樣。
只是,這個值絕對不是你要的值。
而Kp到達一定量在動作的時候,他發現I gain出來的值是不對的(因為你是Duty_ref)
而一直在變化,導致系統不穩,就好比我要穩在10V,但你的輸出一直說我要12V。
(voltage_ref) (duty_cycle)
因為Duty和輸出電壓有相對關係,你給了一個輸出電壓,卻一直給了不對的Duty。
他這輩子都不會穩定。
而你給了Ki以後,雖然他可以透過Igain使得系統在一定時間過後就穩定。
但因為你後面多給了一個offset。使得Igain再慢慢累加到他穩態了,
卻因為多了個offset,隨著Igain,很可能又跳出了相對關係(如我前述Kp那邊一樣)。
Ki和Kp過小的時候,可能勉強可以work。
(跟你的Kp=0.5, without Ki的情形雷同,只是變成 output*+Duty_ref*,
其中你的Duty_ref*代表著Duty_ref的值不在是你原先的588,可能是600 or 500)
但Kp到達一定量,又開始震盪像前述相同。
因此,你的這個程式可能在某些特定的 PI 和相對的ref,比例等等是可以work。
但是,再其他的值就不能work了。
基於這上述幾點,你可以試著想想看PI controller的組成方式。
再把他轉換成codeing,最後設定個上下限的比較,就和三角波比較,Duty就出來了。
最後我想問一下你是哪個老師的學生?(專題生?)
※ 引述《felghana (adol)》之銘言:
: 想請問一下 dspic的數位PID控制這樣寫是否正確
: 我的目的是要作buck轉換器的定電流控制
: 底下是我的 ADC中斷程式流程
: 其中一些function是參考libirary的document寫的
: Kp Ki Kd已經在程式一開始執行處設定好了
: 目前只有給Kp=0.5 而Ki=Kd=0
: void _ISR _ADCInterrupt(void)
: {
: IFS0bits.ADIF=0;
: voltage=ADCBUF0;//電壓取樣轉換結果(這邊沒用到)
: current=ADCBUF1;//電流取樣轉換結果
: fooPID.measuredOutput=current;//把電流取樣結果輸入到PID控制器
: PID(&fooPID);//執行PID運算
: PDC1 = Fract2Float(fooPID.controlOutput)*PWM_Duty_Range + PWM_Duty_Ref;
: //PDC1暫存器決定duty大小
: //fooPID.controlOutput為PID運算結果 其格式為fractional 所以須轉為float
: //做運算
: //由於PID運算結果為-1~1之間的小數 所以把他乘上duty容許變化範圍再加上一
: //個定值即為PDC1之值 例如 Duty Max=1058 而 Duty Min=118 則
: //PWM_Duty_Ref=(1058+118)/2=588
: //而PWM_Duty_Range=(1058-118)/2=470 如此便可將運算出來的Duty值限制在合
: //理範圍
: }
: 實測結果顯示 只給Kp時 duty沒有隨我負載改變而改變
: (應該說有在調 但是調得很細微 誤差很大)
: 若Kp給大一點 系統又會不穩
: 給Ki系統也是不穩
: 我是掛電子負載作定電壓抽載(模擬電池充電)
: 不知道有沒有會用這類PID function的大大
: 給小的指點一下 謝謝
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.114.253.69
※ 發信站: 批踢踢實業坊(ptt.cc)
※ 轉錄者: felghana (140.116.163.131), 時間: 12/09/2011 14:12:46
※ 編輯: felghana 來自: 140.116.163.131 (12/09 14:14)
討論串 (同標題文章)
完整討論串 (本文為第 2 之 2 篇):