久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 20303|回復(fù): 4
打印 上一主題 下一主題
收起左側(cè)

你不得不知道的PID控制算法

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:161768 發(fā)表于 2017-3-7 01:21 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
本文以通俗的理解,以小車縱向控制舉例說明PID的一些理解。
(一)首先,為什么要做PID?
由于外界原因,小車的實(shí)際速度有時(shí)不穩(wěn)定,這是其一,
要讓小車以最快的時(shí)間達(dá)達(dá)到既定的目標(biāo)速度,這是其二。
速度控制系統(tǒng)是閉環(huán),才能滿足整個(gè)系統(tǒng)的穩(wěn)定要求,必竟速度是系統(tǒng)參數(shù)之一,這是其三.
    小車調(diào)速肯定不是線性的,外界因素那么多,沒人能證明是線性的。如果是線性的,直接用P就可以了。
比如在PWM=60%時(shí),速度是2M/S,那么你要它3M/S,就把PWM提高到90%。因?yàn)?0/60=3/2,這樣一來太完美了。
完美是不可能的。
    那么不是線性的,要怎么怎么控制PWM使速度達(dá)到即定的速度呢?即要快,又要準(zhǔn),又要狠。(即快準(zhǔn)狠
)系統(tǒng)這個(gè)速度的調(diào)整過程就必須通過某個(gè)算法調(diào)整,一般PID就是這個(gè)所用的算法。
    可能你會(huì)想到,如果通過編碼器測(cè)得現(xiàn)在的速度是2.0m/s,要達(dá)到2.3m/s的速度,那么我把pwm增大一點(diǎn)不
就行了嗎?是的,增大pwm多少呢?必須要通過算法,因?yàn)镻WM和速度是個(gè)什么關(guān)系,對(duì)于整個(gè)系統(tǒng)來說,誰也
不知道。要一點(diǎn)一點(diǎn)的試,加個(gè)1%,不夠,再加1%還是不夠,那么第三次你還會(huì)加1%嗎?很有可能就加2%了。
通過PID三個(gè)參數(shù)得到一個(gè)表達(dá)式:△PWM=a *△V1+b *△V2+c *△V3,a b c是通過PID的那個(gè)長(zhǎng)長(zhǎng)的公式展開
,然后約簡(jiǎn)后的數(shù)字,△V1 ,△V2 ,△V3 此前第一次調(diào)整后的速度差 ,第二次調(diào)整后的速度差,第三次。。
。。。一句話,PID要使當(dāng)前速度達(dá)到目標(biāo)速度最快,需要建立如何調(diào)整pwm和速度之間的關(guān)系。

輸入輸出是什么:
輸入就是前次速度,前前次速度,前前前次速度。
輸出就是你的PWM應(yīng)該增加或減小多少。

(二)為了避免教科書公式化的說明,本文用口語化和通俗的語言描述。雖然不一定恰當(dāng),但意思差不多,就是那個(gè)事。如果要徹頭徹尾地弄PID,建議多調(diào)試,寫幾個(gè)仿真程序。
     PID一般有兩種:位置式PID和增量式PID。在小車?yán)镆话阌迷隽渴剑瑸槭裁茨兀课恢檬絇ID的輸出與過去的所有狀態(tài)有關(guān),計(jì)算時(shí)要對(duì)e(每一次的控制誤差)進(jìn)行累加,這個(gè)計(jì)算量非常大,而明沒有必要。而且小車的PID控制器的輸出并不是絕對(duì)數(shù)值,而是一個(gè)△,代表增多少,減多少。換句話說,通過增量PID算法,每次輸出是PWM要增加多少或者減小多少,而不是PWM的實(shí)際值。
下面均以增量式PID說明。
  這里再說一下P、I、D三個(gè)參數(shù)的作用。P=Proportion,比例的意思,I是Integral,積分,D是Differential微分。
打個(gè)比方,如果現(xiàn)在的輸出是1,目標(biāo)輸出是100,那么P的作用是以最快的速度達(dá)到100,把P理解為一個(gè)系數(shù)即可;而I呢?大家學(xué)過高數(shù)的,0的積分才能是一個(gè)常數(shù),I就是使誤差為0而起調(diào)和作用;D呢?大家都知道微分是求導(dǎo)數(shù),導(dǎo)數(shù)代表切線是吧,切線的方向就是最快到至高點(diǎn)的方向。這樣理解,最快獲得最優(yōu)解,那么微分就是加快調(diào)節(jié)過程的作用了。
公式本來需要推導(dǎo)的,我就不來這一套了。直接貼出來:file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ksohtml/wps_clip_image-24040.png

看看最后的結(jié)果:
△Uk=A*e(k)+B*e(k-1)+C*e(k-2)
這里KP是P的值,TD是D的值,1/Ti是I的值,都是常數(shù),哦,還有一個(gè)T,T是采樣周期,也是已知。而A B C是由P I D換算來的,按這個(gè)公式,就可以簡(jiǎn)化計(jì)算量了,因?yàn)镻 I D是常數(shù),那么A B C可以用一個(gè)宏表示。這樣看來,只需要求e(k) e(k-1) e(k-2)就可以知道△Uk的值了,按照△Uk來調(diào)節(jié)PWM的大小就OK了。PID三個(gè)參數(shù)的確定有很多方法,不在本文討論范圍內(nèi)。采樣周期也是有據(jù)可依的,不能太大,也不能太小。
   ................................................
   寫著寫著成了老太婆的裹腳了,本來說拿個(gè)程序來說明一下,看來只能在下一文中了。
一、轉(zhuǎn)自網(wǎng)友的解釋,呵呵:
制模型:你控制一個(gè)人讓他以PID控制的方式走110步后停下。
(1)P比例控制,就是讓他走110步,他按照一定的步伐走到一百零幾步(如108步)或100多步(如112步)就停了。
說明:
P比例控制是一種最簡(jiǎn)單的控制方式。其控制器的輸出與輸入誤差信號(hào)成比例關(guān)系。當(dāng)僅有比例控制時(shí)系統(tǒng)輸出存在穩(wěn)態(tài)誤差(Steady-state error)。
(2)PI積分控制,就是他按照一定的步伐走到112步然后回頭接著走,走到108步位置時(shí),然后又回頭向110步位置走。在110步位置處來回晃幾次,最后停在110步的位置。
說明:
在積分I控制中,控制器的輸出與輸入誤差信號(hào)的積分成正比關(guān)系。對(duì)一個(gè)自動(dòng)控制系統(tǒng),如果在進(jìn)入穩(wěn)態(tài)后存在穩(wěn)態(tài)誤差,則稱這個(gè)控制系統(tǒng)是有穩(wěn)態(tài)誤差的或簡(jiǎn)稱有差系統(tǒng)(System with Steady-state Error)。為了消除穩(wěn)態(tài)誤差,在控制器中必須引入“積分項(xiàng)”。積分項(xiàng)對(duì)誤差取決于時(shí)間的積分,隨著時(shí)間的增加,積分項(xiàng)會(huì)增大。這樣,即便誤差很小,積分項(xiàng)也會(huì)隨著時(shí)間的增加而加大,它推動(dòng)控制器的輸出增大使穩(wěn)態(tài)誤差進(jìn)一步減小,直到等于零。因此,比例+積分(PI)控制器,可以使系統(tǒng)在進(jìn)入穩(wěn)態(tài)后無穩(wěn)態(tài)誤差。
(3)PD微分控制,就是他按照一定的步伐走到一百零幾步后,再慢慢地向110步的位置靠近,如果最后能精確停在110步的位置,就是無靜差控制;如果停在110步附近(如109步或111步位置),就是有靜差控制。
說明:
在微分控制D中,控制器的輸出與輸入誤差信號(hào)的微分(即誤差的變化率)成正比關(guān)系。
自動(dòng)控制系統(tǒng)在克服誤差的調(diào)節(jié)過程中可能會(huì)出現(xiàn)振蕩甚至失穩(wěn),其原因是由于存在有較大慣性組件(環(huán)節(jié))或有滯后(delay)組件,具有抑制誤差的作用,其變化總是落后于誤差的變化。解決的辦法是使抑制誤差作用的變化“超前”,即在誤差接近零時(shí),抑制誤差的作用就應(yīng)該是零。這就是說,在控制器中僅引入“比例P”項(xiàng)往往是不夠的,比例項(xiàng)的作用僅是放大誤差的幅值,而目前需要增加的是“微分項(xiàng)”,它能預(yù)測(cè)誤差變化的趨勢(shì)。這樣,具有比例+微分的控制器,就能夠提前使抑制誤差的控制作用等于零,甚至為負(fù)值,從而避免了被控量的嚴(yán)重超調(diào)。所以對(duì)有較大慣性或滯后的被控對(duì)象,比例P+微分D(PD)控制器能改善系統(tǒng)在調(diào)節(jié)過程中的動(dòng)態(tài)特性。
解釋二:
  小明接到這樣一個(gè)任務(wù):有一個(gè)水缸有點(diǎn)漏水(而且漏水的速度還不一定固定不變),要求水面高度維持在某個(gè)位置,一旦發(fā)現(xiàn)水面高度低于要求位置,就要往水缸里加水。 小明接到任務(wù)后就一直守在水缸旁邊,時(shí)間長(zhǎng)就覺得無聊,就跑到房里看小說了,每30分鐘來檢查一次水面高度。水漏得太快,每次小明來檢查時(shí),水都快漏完了,離要求的高度相差很遠(yuǎn),小明改為每3分鐘來檢查一次,結(jié)果每次來水都沒怎么漏,不需要加水,來得太頻繁做的是無用功。幾次試驗(yàn)后,確定每10分鐘來檢查一次。這個(gè)檢查時(shí)間就稱為采樣周期。
  開始小明用瓢加水,水龍頭離水缸有十幾米的距離,經(jīng)常要跑好幾趟才加夠水,于是小明又改為用桶加,一加就是一桶,跑的次數(shù)少了,加水的速度也快了,但好幾次將缸給加溢出了,不小心弄濕了幾次鞋,小明又動(dòng)腦筋,我不用瓢也不用桶,老子用盆,幾次下來,發(fā)現(xiàn)剛剛好,不用跑太多次,也不會(huì)讓水溢出。這個(gè)加水工具的大小就稱為比例系數(shù)。
  小明又發(fā)現(xiàn)水雖然不會(huì)加過量溢出了,有時(shí)會(huì)高過要求位置比較多,還是有打濕鞋的危險(xiǎn)。他又想了個(gè)辦法,在水缸上裝一個(gè)漏斗,每次加水不直接倒進(jìn)水缸,而是倒進(jìn)漏斗讓它慢慢加。這樣溢出的問題解決了,但加水的速度又慢了,有時(shí)還趕不上漏水的速度。于是他試著變換不同大小口徑的漏斗來控制加水的速度,最后終于找到了滿意的漏斗。漏斗的時(shí)間就稱為積分時(shí)間。
  小明終于喘了一口,但任務(wù)的要求突然嚴(yán)了,水位控制的及時(shí)性要求大大提高,一旦水位過低,必須立即將水加到要求位置,而且不能高出太多,否則不給工錢。小明又為難了!于是他又開努腦筋,終于讓它想到一個(gè)辦法,常放一盆備用水在旁邊,一發(fā)現(xiàn)水位低了,不經(jīng)過漏斗就是一盆水下去,這樣及時(shí)性是保證了,但水位有時(shí)會(huì)高多了。他又在要求水面位置上面一點(diǎn)將水缸要求的水平面處鑿一孔,再接一根管子到下面的備用桶里這樣多出的水會(huì)從上面的孔里漏出來。這個(gè)水漏出的快慢就稱為微分時(shí)間。 看到幾個(gè)問采樣周期的帖子,臨時(shí)想了這么個(gè)故事。微分的比喻一點(diǎn)牽強(qiáng),不過能幫助理解就行了,呵呵,入門級(jí)的,如能幫助新手理解下PID,于愿足矣。故事中小明的試驗(yàn)是一步步獨(dú)立做,但實(shí)際加水工具、漏斗口徑、溢水孔的大小同時(shí)都會(huì)影響加水的速度,水位超調(diào)量的大小,做了后面的實(shí)驗(yàn)后,往往還要修改改前面
(三)PID實(shí)際編程的過程的,要注意的東西還是有幾點(diǎn)的。PID這東西可以做得很深。
1 PID的診定。湊試法,臨界比例法,經(jīng)驗(yàn)法。
2 T的確定,采樣周期應(yīng)遠(yuǎn)小于過程的擾動(dòng)信號(hào)的周期,在小車程序中一般是ms級(jí)別。
3 目標(biāo)速度何時(shí)賦值問題,如何更新新的目標(biāo)速度?這個(gè)問題一般的人都乎略了。目標(biāo)速度肯定不是個(gè)恒定的,那么何時(shí)改變目標(biāo)速度呢?
4 改變了目標(biāo)速度,那么e(k) e(k-1) e(k-2)怎么改變呢?是賦0還是要怎么變?
5 是不是PID要一直開著?
6 error為多少時(shí)就可以當(dāng)速度已達(dá)到目標(biāo)?
7 PID的優(yōu)先級(jí)怎么處理,如果和圖像采集有沖突怎么辦?
8 PID的輸入是速度,輸出是PWM,按理說PWM產(chǎn)生速度,但二者不是同一個(gè)東西,有沒有問題?
9 PID計(jì)算如何優(yōu)化其速度?指針,匯編,移位?都可以試!
  1. //*****************************************************
  2. //定義PID結(jié)構(gòu)體
  3. //*****************************************************
  4. typedef struct PID
  5. {
  6.     int SetPoint; //設(shè)定目標(biāo)Desired Value
  7.     double Proportion; //比例常數(shù)Proportional Const
  8.     double Integral; //積分常數(shù)Integral Const
  9.     double Derivative; //微分常數(shù)Derivative Const
  10.     int LastError; //Error[-1]
  11.     int PrevError; //Error[-2]
  12. } PID;
  13. //*****************************************************
  14. //定義相關(guān)宏
  15. //*****************************************************
  16. #define P_DATA 100
  17. #define I_DATA 0.6
  18. #define D_DATA 1
  19. #define HAVE_NEW_VELOCITY 0X01
  20. //*****************************************************
  21. //聲明PID實(shí)體
  22. //*****************************************************
  23. static PID sPID;
  24. static PID *sptr = &sPID;
  25. //*****************************************************
  26. //PID參數(shù)初始化
  27. //*****************************************************
  28. void IncPIDInit(void)
  29. {
  30. sptr->LastError = 0; //Error[-1]
  31. sptr->PrevError = 0; //Error[-2]
  32. sptr->Proportion =P_DATA; //比例常數(shù)Proportional Const
  33. sptr->Integral =I_DATA; //積分常數(shù)Integral Const
  34. sptr->Derivative =D_DATA; //微分常數(shù)Derivative Const
  35. sptr->SetPoint =100;  目標(biāo)是100
  36. }
  37. //*****************************************************
  38. //增量式PID控制設(shè)計(jì)
  39. //*****************************************************
  40. int IncPIDCalc(int NextPoint)
  41. {
  42.    int iError, iIncpid; //當(dāng)前誤差
  43.    iError = sptr->SetPoint - NextPoint; //增量計(jì)算
  44.    iIncpid = sptr->Proportion * iError //E[k]項(xiàng)
  45.              - sptr->Integral * sptr->LastError //E[k-1]項(xiàng)
  46.              + sptr->Derivative * sptr->PrevError; //E[k-2]項(xiàng)
  47.     sptr->PrevError = sptr->LastError;   //存儲(chǔ)誤差,用于下次計(jì)算
  48.     sptr->LastError = iError;
  49.     return(iIncpid);                         //返回增量值
  50. }
  51. Int g_CurrentVelocity;
  52. Int g_Flag;

  53. void main(void)
  54. {
  55.    DisableInterrupt
  56. InitMCu();
  57.    IncPIDInit();
  58. g_CurrentVelocity=0;  //全局變量也初始化
  59. g_Flag=0;               //全局變量也初始化
  60. EnableInterrupt;
  61.     While(1)
  62. {
  63.   if (g_Flag& HAVE_NEW_VELOCITY)
  64.      {
  65.          PWMOUT+= IncPIDCalc(CurrentVelocity);
  66.            g_Flag&=~ HAVE_NEW_VELOCITY;
  67. }
  68. }
  69. }
  70. //****************************************
  71. //采樣周期T
  72. //****************************************
  73. Interrrupt TIME void
  74. {
  75.   CurrentVelocity =GetCurrentVelocity;
  76.   g_Flag|= HAVE_NEW_VELOCITY;
  77. }
復(fù)制代碼




評(píng)分

參與人數(shù) 1黑幣 +1 收起 理由
前行者 + 1 很給力!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏4 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:255989 發(fā)表于 2017-12-19 12:53 | 只看該作者
學(xué)習(xí)了。
回復(fù)

使用道具 舉報(bào)

板凳
ID:250601 發(fā)表于 2017-12-28 15:54 | 只看該作者
  CurrentVelocity =GetCurrentVelocity;  這句話什么意思看不太懂
回復(fù)

使用道具 舉報(bào)

地板
ID:250601 發(fā)表于 2017-12-28 15:55 | 只看該作者
   iIncpid = sptr->Proportion * iError //E[k]項(xiàng)
             - sptr->Integral * sptr->LastError //E[k-1]項(xiàng)
             + sptr->Derivative * sptr->PrevError; //E[k-2]項(xiàng)
為什么 是Ek-Ek-1+Ek-2呢
回復(fù)

使用道具 舉報(bào)

5#
ID:267230 發(fā)表于 2018-1-12 21:06 | 只看該作者
形象地了解了PID的概念,不錯(cuò)。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 六月色婷| 中文字幕在线播放第一页 | 午夜视频一区 | 作爱视频免费观看 | 日韩乱码av | 亚洲伊人久久综合 | 日韩在线免费 | 欧美一级淫片免费视频黄 | www.久| 国产高清精品一区 | 嫩草国产 | 亚洲精品久久久久中文字幕欢迎你 | av在线一区二区 | 久久最新 | 免费高潮视频95在线观看网站 | 看毛片的网站 | 日韩精品一区二区三区中文字幕 | 九九热精品免费 | 免费精品视频在线观看 | 中文字幕一区二区三区精彩视频 | 成人国产精品免费观看 | 欧美精品一二区 | 欧美日韩视频一区二区 | 精品视频一区二区在线观看 | 精品久久九九 | 久久99久久99精品免视看婷婷 | 国产一区二区三区免费 | 99久久婷婷国产综合精品电影 | 婷婷激情综合 | 久草资源在线视频 | 亚洲精品综合一区二区 | 手机av在线| 鸳鸯谱在线观看高清 | 一级在线观看 | 国产91精品在线 | 日日骚av| 婷婷精品| 久久精品中文 | 国产夜恋视频在线观看 | 亚洲午夜久久久 | 日韩在线小视频 |