學習PID


最近在想自己的文章有些是不是寫的太難以理解了呢.........竟然好多人看了還是會直接問我很多問題.......

其實PID哈靠自己想像就能自己寫出來自己的代碼,也許是網上的講的太過的高深什么積分微分,搞的暈頭轉向,本來這么實用的想法為什么偏偏說的那么的琢磨不透......感覺那些人根本就沒有真正的自己動腦思考,PID最初肯定是人們在做控制的時候不斷的思考,不斷的嘗試然后總結出來的...現在咱們也來思考一下啊

咱舉一個例子就是控制電機----控制電機的轉速

咱們先規定好

對了其實事先會規定一個PWM的周期,,假設是10KHZ,,,,周期的大小會對電機的轉速有影響,這是必然的,講到后面就知道如何選擇周期了.....

設置PWM占空比的函數 PWMSet(0-10000(PWM變量));0的時候占空比為0%,,也就是那個引腳一直輸出低電平,5000的時候占空比為50%,,也就是那個引腳半周期低電平半周期高電平,10000的時候占空比為100%,也就是那個引腳一直輸出高電平

采集到的電機的轉速 V采集

設置的電機的速度  V設置

現在想怎么樣才能根據采集的和設置的控制電機的速度呢?????

電機轉的快的時候要減速控制PWM變量變小,電機轉的慢的時候要加速控制PWM變量增大,

可以讓設置的速度和采集的速度做差

讓  V偏差 = V設置 - V采集;

電機轉的快的時候 V采集 > V設置  V偏差一直是負值

電機轉的慢的時候 V采集 < V設置  V偏差一直是正值

但是呢如果直接  PWMSet(V偏差);這是瞎胡鬧......

但是呢   如果   

 

V偏差 = V設置 - V采集;

V控制PWM = V偏差累加和  + V偏差;

PWMSet(V控制PWM);

 

上面的這3句話假設是每間隔10ms執行一次哈!!!又會有疑問,,為什么10ms執行一次哈??這是假設的,,,但是這個也會影響到控制電機的速度,,講到后面就知道了

 

現在分析一下,,假設設置的速度是90

剛啟動的時候采集的速度是0,,然后呢速度再沒有達到90之前,,,V控制PWM一直在增加,,,,PWMSet(V控制PWM),,所以電機一直在加速

然后采集的速度到達90之后V偏差是0,設置電機的PWM不變,假設超過了設置的速度呢V偏差是小於0,,,V控制PWM = V控制PWM  + V偏差;所以V控制PWM又會減小PWMSet(V控制PWM),最終呢電機又會減速,,,所以就會這樣的反反復復了

 

現在呢再想一下,,,,難道這樣就行了嗎???

假設PWMSet(V控制PWM),這里面控制速度的變量在7000的時候才能達到咱設置的速度90......

這樣的話其實V控制PWM = V控制PWM  + V偏差;第一次V控制PWM是90,然后后面的肯定比90小,,,因為電機開始轉了,,,有沒有什么感覺不好的地方????V控制PWM變化的太慢.......這樣就會出現問題...達到自己設定的速度需要的時間太長......要是中途我出現了事故需要趕緊控制電機的速度為230吧,,,,那家伙還是慢吞吞的....實在是受不了.....

      受不了這么慢(圖1)

 

所以呢!需要控制它變化的快一些對吧,,也就是讓V控制PWM = V控制PWM  + V偏差;這個程序吧讓它每次累加的大一點

直接加上一個常數肯定不行....但是可以乘以一個常數

V控制PWM = V控制PWM  + V偏差*P;

現在就開始考慮這個常數了.....

咱就想一想如果常數太小的話,,起不到作用....

常數慢慢增大....假設設置的是3,

其實就會發現即使偏差是1那么調整的會是3,,就是控制占空比變化3,,,,如果再大就會出現電機抖動的厲害...理所當然因為越大PWM變化的越厲害.....導致電機一停一轉的人眼都看出來了.............

        受不了你的不穩定(圖2)

 

現在就在想怎么樣確定這個比例值呢.......

咱做的程序肯定能打印電機的速度哈....

咱們可以看着速度慢慢的增加比例P,,,親們感覺速度的變化成什么樣子就行了呢??????

在增加P的時候肯定有一個值是電機出現抖動...當然咱是看電機的速度數據,那個速度呢一增一減的而且最大速度和最小速度距離設置的速度很大.....咱們要的是速度立馬加上去,,但是呢也能夠在很短時間內平穩下來...絕對不能出現來回的抖動

 

                                           這樣還算可以

 

但是呢!電機有慣性或者比例還是有點大,導致會出現一個波峰..............然后呢又慢慢的平穩下來.....

現在要做的是想辦法消除這個波峰,,,或者呢能不能把這個波峰往下降一降...

 怎么樣才能對付這個波峰呢!!!怎樣才能在速度快要達到的時候,或者已經達到了,,別在過度的增加PWM了,,,肯定是在偏差上下功夫,,在變化的時候想辦法再給他一個變化的變量,,能夠抑制住

 就整體趨勢來講,,偏差是越來越小,,然后變為負值越來越小,,然后到頂.....我們想的是能不能把前面的變為負值開始到到頂,,抑制一下

圖畫的不一定是對的....只是講一下整體的趨勢

 

有些人發現這時候的變化趨勢之后就在想,,怎樣把這種趨勢應用到解決以上的問題中.....

然后有些人發現....斜率.....

 

怎樣計算每個點的斜率呢!!!!!!!!微分......

我的數學都忘干凈了......有時候會發現,,沒上大學的時候會的挺多的,,一上大學感覺什么東西都忘了.....

隨着時間的推移,我可以通過那個斜率得到一個慢慢變化的值(開始挺小的(稍微有些抑制),慢慢變大(抑制作用越來越強) 或者開始挺大的(開始還能促進),慢慢變小(促進作用越來越小) ).......

所以這才引入了微分的概念........

但是呢有人又會想,我也同意微分確實可以描述,,,但是呢單片機程序怎么寫呢??????????

您看哈,,,既然知道程序中一些變量的作用了,,,,咱們可以去百度一下別人寫的程序哈,,,然后帶着自己的想法思考一下別人的程序看一看是不是滿足要求,而且PID都這么多年了,,肯定有人寫,自學的能力在於勤於思考,擅於學習.....

注:拷貝您的程序無冒犯之意,只是為了學習一下,如果有什么問題您可以留言,我馬上刪掉....

看剛百度的第一個

 

 因為我們現在在意的是微分部分,,所以只看

突然發現有點問題....說好的增量計算呢,,,,,,不管它了

V控制PWM = V控制PWM  + V偏差*P + (一個比例數)*上次偏差;

來感受感受....這好像......(一個比例數)*上次偏差     和   V偏差*P   有多大的區別呢........

算了看下一個...

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);//最后相加
   
}

現在我們關注的是

dError=pp->LastError-pp->PrevError ;//微分環節---上次偏差減去上上次偏差

咱們先假設偏差數據是這樣的

90, 70, 55, 46,30,25,18,10,5,1,-1,-5,-13,-15(到頂)

 上次偏差減去上上次偏差----好像大部分都是負值  而且這個負值越來越小

V控制PWM = V控制PWM + V偏差*P + (一個比例數)*(上次偏差-上上次偏差);

如果那個比例數是正的.....就相當於

V控制PWM = V控制PWM  + V偏差*P  - (一個越來越小的數).......(整體來說,,一開始抑制作用很強,,慢慢變弱)

然后到了后面的負值部分....就相當於

V控制PWM = V控制PWM  + V偏差*P  +(一個數).......(抑制了調節)

這是幾乎永遠的都在抑制調節呢.....還可以畢竟可以抑制....

 

如果那個比例值是負值

V控制PWM = V控制PWM  + V偏差*P  + (一個越來越小的數).......(整體來說,,一開始促進作用很強,然后慢慢變弱)

然后到了后面的負值部分....就相當於

V控制PWM = V控制PWM  + V偏差*P  - (一個數).......(促進了調節)

 

永遠的在促進,但是促進作用在減弱

當然如果不想讓那個比例值為負值..可以讓 上上次偏差減去上次偏差嘛

就變成了

V控制PWM = V控制PWM  + V偏差*P + (一個比例數)*(上上次偏差-上次偏差);

但是呢!!!感覺現在應該要減小一點比例P了....因為后面也是促進.....如果不減小肯定達不到效果.....

 

既然還可以就再接着說----思想有了怎樣實現就要自己動腦了......

 

有了上面的PD調節了...現在呢再說一下可能還有問題.....就是說到了穩定的狀態以后呢,,還是有誤差

怎么辦呢,,,只要有誤差就需要調節.....誤差的累加,,只要有誤差就一直累加

如果是這樣

 

偏差的和 = 偏差的和  + V偏差

V控制PWM = V控制PWM  + V偏差*P + (一個比例數)*(偏差的和);

只要存在偏差,那么通過 偏差的和 一直在促進着去調節....

 

如果組合起來

V控制PWM = V控制PWM + V偏差*P + (一個比例數)*(上次偏差-上上次偏差) + (一個比例數)*(偏差的和);

應該還可以....

對了最后一個就是所謂的積分調節

其實呢我也只是明白要這樣做

最后別人總結的口訣

 

 一篇文章

http://baike.sogou.com/v108236.htm?fromTitle=PID

 

 

如果問我控制兩個電機的速度一樣怎么辦???

寫兩個一樣的PID,然后設置的速度寫成一樣哈

 

上面的呢叫增量式PID

還有一個叫做位置式PID---列如控制舵機

舵機是給占空比固定的PWM 舵機就一直轉自身固定的角度

所以呢就沒有了上面的累加的那部分

V控制PWM =  V偏差*P ;

假設是控制一個小車前進和急轉彎,,,,我們希望的是在直道的時候呢,,舵機的比例不要那么的大,,彎道的時候可以大一些

其實可以

 

 V控制PWM =  V偏差*V偏差*P ;(用二次函數解決)

 其實呢關鍵是思想

 


免責聲明!

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



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