久久久国产精品视频袁燕,99re久久精品国产,亚洲欧美日韩国产综合v,天天躁夜夜躁狠狠久久,激情五月婷婷激情五月婷婷

從零理解PID控制:小球仿真到代碼實(shí)現(xiàn),手把手教你掌握工業(yè)級(jí)控制算法

前言

很多人應(yīng)該都聽(tīng)說(shuō)過(guò)PID,它的運(yùn)算過(guò)程簡(jiǎn)單,并能在大多情況下實(shí)現(xiàn)較好的控制效果,因此它是工程實(shí)踐中使用最廣泛的控制方法之一。

拋開(kāi)公式,我將帶你從案例出發(fā),詳細(xì)了解PID的工作原理和使用方法。

注:閱讀本文不需要有過(guò)多的基礎(chǔ)知識(shí),只需中學(xué)物理和數(shù)學(xué)知識(shí)就能看懂(當(dāng)然如果有高等數(shù)學(xué)知識(shí)和單片機(jī)知識(shí)的話理解起來(lái)會(huì)更容易)

仿真調(diào)參環(huán)境

我專門為本文搭了一個(gè)在線仿真環(huán)境,下面使用的案例都來(lái)自這個(gè)環(huán)境,讀者可以搭配使用

https://pid-simulator-web.skythinker.top/

案例引入——小球位置控制

任務(wù)介紹

我們假設(shè)有一個(gè)一維的坐標(biāo)軸(向右為正方向),在上面上有一個(gè)小球(可以看作質(zhì)點(diǎn)),小球不受任何阻力,可以自由左右滑動(dòng);另外,我們還為小球規(guī)定了一個(gè)目標(biāo)位置(圖中的綠色標(biāo)線):

現(xiàn)在我們有下述任務(wù):

  • 目標(biāo):在小球上施加一個(gè)水平方向的力(稱為控制力),使小球在偏離目標(biāo)位置時(shí)回到目標(biāo)位置
  • 已知條件:小球的實(shí)時(shí)坐標(biāo)、目標(biāo)位置坐標(biāo)

看到這里的你可以停下來(lái)想一想,應(yīng)該用什么樣的策略來(lái)計(jì)算這個(gè)力呢?

這里大多數(shù)人應(yīng)該都能想出這樣的方法:

“當(dāng)小球在目標(biāo)左邊的時(shí)候向右施力,當(dāng)小球在目標(biāo)右邊的時(shí)候向左施力,就可以保證小球一直在目標(biāo)位置上了”

思路是非常正確的,但這個(gè)策略仍不夠完善。由于小球存在慣性,我們施加的力將小球拉回目標(biāo)位置后小球還會(huì)具有一定的速度繼續(xù)運(yùn)動(dòng),并不會(huì)直接停在目標(biāo)位置。

用PID完成任務(wù)

接下來(lái)我們來(lái)看看如果使用PID,我們應(yīng)該如何計(jì)算出這個(gè)控制力呢?

誤差計(jì)算

計(jì)算PID的第一步就是計(jì)算誤差(Error):誤差=目標(biāo)值-反饋值。在這個(gè)例子中,目標(biāo)值是目標(biāo)位置坐標(biāo),反饋值是小球?qū)崟r(shí)位置坐標(biāo),那么誤差就是小球當(dāng)前位置與目標(biāo)間的距離。

接下來(lái)的運(yùn)算我們都會(huì)圍繞誤差進(jìn)行,分為三個(gè)步驟使用誤差分別算出一個(gè)分力,并將三個(gè)分力一起施加在小球上。

比例環(huán)節(jié)

第一個(gè)環(huán)節(jié)是比例環(huán)節(jié)P(Proportion),這個(gè)環(huán)節(jié)產(chǎn)生的分力是

即:分力大小與誤差成正比,且當(dāng)小球在目標(biāo)左邊的時(shí)候分力向右,當(dāng)小球在目標(biāo)右邊的時(shí)候分力向左,其中kp是比例系數(shù)。

比例環(huán)節(jié)的計(jì)算方法其實(shí)與上面大家通過(guò)直覺(jué)得出的方法差不多,如果只有這個(gè)分力作用的話,會(huì)產(chǎn)生什么效果呢?

大家可能會(huì)發(fā)現(xiàn),這就與中學(xué)物理里的彈簧滑塊模型是一樣的,力與距離成正比,顯然小球會(huì)以目標(biāo)位置為中心進(jìn)行左右擺動(dòng)(簡(jiǎn)諧振動(dòng))(注:圖中藍(lán)色短線表示控制力):

只有比例環(huán)節(jié)時(shí)的小球運(yùn)動(dòng)

微分環(huán)節(jié)

那么如何讓小球能夠靜止在目標(biāo)點(diǎn)呢?這就要請(qǐng)出PID的另一個(gè)環(huán)節(jié):微分環(huán)節(jié)D(Differential)。

微分環(huán)節(jié)也會(huì)計(jì)算出一個(gè)分力,計(jì)算方法是:

也就是說(shuō),這個(gè)分力與誤差的變化速度有關(guān)。假設(shè)目標(biāo)位置不變,小球向右運(yùn)動(dòng)時(shí)誤差減小,即誤差變化速度為負(fù),分力向左;反之當(dāng)小球向左運(yùn)動(dòng)時(shí)分力向右;綜合看來(lái),微分環(huán)節(jié)產(chǎn)生的分力始終阻礙小球的運(yùn)動(dòng)。

因此如果在剛剛的基礎(chǔ)上加入微分產(chǎn)生的分力,就會(huì)產(chǎn)生一個(gè)阻尼效果,小球會(huì)仿佛始終受到一個(gè)阻力,因此左右擺動(dòng)的幅度會(huì)逐漸減小,最終收斂到目標(biāo)位置上:

有比例和微分環(huán)節(jié)時(shí)的小球運(yùn)動(dòng)

由公式還可以看出,微分系數(shù)Kd可以影響這個(gè)“阻力”的大小,因此如果我們把系數(shù)調(diào)大一些,就可以讓小球的運(yùn)動(dòng)收斂得更快一些:

調(diào)大kd后的小球運(yùn)動(dòng)

到這里,其實(shí)我們已經(jīng)完成我們的目標(biāo)任務(wù)了,小球可以在驅(qū)動(dòng)力的作用下運(yùn)動(dòng)到目標(biāo)位置。

積分環(huán)節(jié)

但現(xiàn)在,我們更希望在小球有一些外部干擾時(shí)也能實(shí)現(xiàn)上面的效果,比如我們?cè)谛∏蛏霞由弦粋€(gè)水平向右的恒力,此時(shí)會(huì)發(fā)生什么呢?

恒力干擾下小球靜止?fàn)顟B(tài)

小球在運(yùn)動(dòng)過(guò)程中仍然會(huì)像之前一樣接近目標(biāo)點(diǎn),但在最終停下來(lái)時(shí)我們會(huì)發(fā)現(xiàn),小球無(wú)法精確停在目標(biāo)點(diǎn)上,而是像上圖一樣停在離目標(biāo)點(diǎn)有一定距離的地方。此時(shí)控制力與干擾恒力平衡,小球靜止。

稍加分析我們就能發(fā)現(xiàn),此時(shí)小球靜止,微分環(huán)節(jié)產(chǎn)生的分力為零,控制力完全由比例環(huán)節(jié)產(chǎn)生,且若距離更小則比例環(huán)節(jié)的輸出更小,更無(wú)法平衡干擾力,因此小球無(wú)法繼續(xù)向目標(biāo)點(diǎn)接近。

此時(shí)就需要我們的第三個(gè)環(huán)節(jié)出場(chǎng)了:積分環(huán)節(jié)I(Integral),它的計(jì)算方法是:

也就是說(shuō)積分環(huán)節(jié)產(chǎn)生的分力正比于誤差的積分,當(dāng)誤差持續(xù)存在時(shí),這個(gè)分力會(huì)逐漸變大,試圖消除誤差。

加入積分作用,我們的PID就能完美實(shí)現(xiàn)在有恒力干擾的情況下對(duì)小球的控制了:

PID作用下小球控制效果

拋開(kāi)案例——更專業(yè)地理解PID

常用術(shù)語(yǔ)

  • 被控對(duì)象:需要控制的對(duì)象,案例中指小球
  • 目標(biāo)值:期望被控對(duì)象達(dá)到的狀態(tài)量,案例中指目標(biāo)位置的坐標(biāo)
  • 反饋值:被控對(duì)象當(dāng)前時(shí)刻的狀態(tài)量,案例中指小球的實(shí)時(shí)位置坐標(biāo)
  • 輸出量:PID的計(jì)算結(jié)果,案例中指控制力
  • 誤差:目標(biāo)值-反饋值
  • 穩(wěn)態(tài)誤差:系統(tǒng)穩(wěn)定狀態(tài)下仍存在的誤差,如案例中加入干擾恒力后小球靜止時(shí)仍存在的誤差

不同參數(shù)下系統(tǒng)的階躍響應(yīng)(源:百度百科)

  • 階躍輸入:在穩(wěn)定狀態(tài)下目標(biāo)值發(fā)生突然變化(上圖目標(biāo)值在0時(shí)刻由0躍升到虛線位置)
  • 階躍響應(yīng):階躍輸入后被控對(duì)象的跟隨狀態(tài),能夠代表系統(tǒng)的控制性能(上圖彩色線條)
  • 響應(yīng)速度:階躍輸入后被控對(duì)象再次到達(dá)目標(biāo)值的速度
  • 超調(diào)量:階躍輸入后,被控對(duì)象到達(dá)目標(biāo)值后超出目標(biāo)值的距離(上圖各彩色線條第一個(gè)峰值與目標(biāo)值的距離)

PID計(jì)算過(guò)程

PID信號(hào)框圖

上圖就是PID的信號(hào)框圖,表示了PID的運(yùn)行過(guò)程:

  1. 為系統(tǒng)指定一個(gè)目標(biāo)值;

  2. PID將目標(biāo)值與被控對(duì)象當(dāng)前的反饋量作差得到誤差;

  3. PID將誤差值分別經(jīng)過(guò)三個(gè)環(huán)節(jié)計(jì)算得到輸出分量,三個(gè)分量加起來(lái)得到PID的輸出;

  4. 將PID的輸出施加到被控對(duì)象上,使反饋量向目標(biāo)值靠攏。

PID三個(gè)環(huán)節(jié)的作用

由控制小球案例我們可以總結(jié)出PID三個(gè)環(huán)節(jié)各自的主要作用和效應(yīng):

  • 比例環(huán)節(jié):起主要控制作用,使反饋量向目標(biāo)值靠攏,但可能導(dǎo)致振蕩
  • 積分環(huán)節(jié):消除穩(wěn)態(tài)誤差,但會(huì)增加超調(diào)量
  • 微分環(huán)節(jié):產(chǎn)生阻尼效果,抑制振蕩和超調(diào),但會(huì)降低響應(yīng)速度

PID中物理量的設(shè)計(jì)

我們?cè)谠O(shè)計(jì)PID時(shí)主要關(guān)注三個(gè)量:目標(biāo)值、反饋值、輸出值,PID會(huì)根據(jù)目標(biāo)值和反饋值計(jì)算輸出值。

需要強(qiáng)調(diào)的是,PID并不知道被控對(duì)象是什么,它僅負(fù)責(zé)進(jìn)行數(shù)值計(jì)算,而我們——作為控制系統(tǒng)的設(shè)計(jì)者,就需要為PID指定這三個(gè)量所對(duì)應(yīng)的實(shí)際物理量,這在不同的控制系統(tǒng)中是不一樣的。

那么如何確定實(shí)際物理量呢,我為大家總結(jié)了一個(gè)常用準(zhǔn)則。

  • 目標(biāo)值和反饋值通常為同種物理量,就是你需要控制的物理量
  • 輸出值通常是直接驅(qū)動(dòng)被控對(duì)象的控制量
  • 輸出量作用在被控對(duì)象上需要經(jīng)過(guò)時(shí)間積累才會(huì)產(chǎn)生反饋量的變化,換言之輸出值通常為反饋值對(duì)于時(shí)間的低階物理量。比如:目標(biāo)值和反饋值為位置,則輸出值可以為速度或加速度
  • 對(duì)于線性關(guān)系的兩個(gè)物理量(只差一個(gè)系數(shù)),可以直接替換。比如:目標(biāo)和反饋值為小球位置,根據(jù)上一條準(zhǔn)則,輸出值可以為加速度。但我們無(wú)法直接控制加速度,只能控制驅(qū)動(dòng)力大小,由于驅(qū)動(dòng)力與加速度只差一個(gè)系數(shù)(F=ma),因此可以將輸出值直接定為驅(qū)動(dòng)力

接下來(lái)給出幾個(gè)例子:

任務(wù)一:對(duì)小球進(jìn)行速度控制

可用條件:已知小球的實(shí)時(shí)速度,并且可施加一個(gè)力來(lái)改變小球的速度

PID目標(biāo)值:需要小球達(dá)到的速度

PID反饋值:小球的實(shí)時(shí)速度

PID輸出值:施加在小球上的力

分析:小球加速度是小球速度的低階物理量,而施加的力正比于小球加速度

任務(wù)二:對(duì)電機(jī)轉(zhuǎn)速進(jìn)行控制

可用條件:已知電機(jī)的實(shí)時(shí)轉(zhuǎn)速,并且可控制電機(jī)中流過(guò)的電流大小

PID目標(biāo)值:需要電機(jī)達(dá)到的轉(zhuǎn)速

PID反饋值:電機(jī)的實(shí)時(shí)轉(zhuǎn)速

PID輸出值:電機(jī)中流過(guò)的電流大小

分析:電機(jī)中流過(guò)的電流大小近似正比于電機(jī)的扭矩,也就近似正比于電機(jī)角加速度的大小,是轉(zhuǎn)速的低階物理量,因此可以用電流大小作為輸出值

任務(wù)三:液位高度控制

描述:容器有進(jìn)水口和出水口,需要通過(guò)進(jìn)水口的閥門控制容器內(nèi)液位的高度

可用條件:容器內(nèi)液位實(shí)時(shí)高度,可控制進(jìn)水口閥門液體流速

PID目標(biāo)值:需要達(dá)到的液位高度

PID反饋值:液位實(shí)時(shí)高度

PID輸出值:閥門液體流速

分析:閥門液體流速正比于液位高度的變化速度,是液位高度的低階物理量

由虛到實(shí)——代碼編寫(xiě)

程序流程

根據(jù)上面的步驟,我們其實(shí)很容易就能得出程序的執(zhí)行流程了,就是在計(jì)算誤差后逐個(gè)進(jìn)行PID各環(huán)節(jié)的計(jì)算。要注意的是整個(gè)采樣-計(jì)算-輸出的流程需要定時(shí)執(zhí)行,可以在每次流程運(yùn)行完后延時(shí)一段固定的時(shí)間(一般而言計(jì)算頻率不高于傳感器反饋頻率,但也不能太低,否則會(huì)使控制精度下降)。

代碼流程圖

實(shí)現(xiàn)細(xì)節(jié)

有一個(gè)問(wèn)題沒(méi)有解決,積分和微分應(yīng)該怎么算呢?畢竟微積分都是連續(xù)的,而我們采樣得到的是離散的數(shù)據(jù)點(diǎn)。其實(shí)也很簡(jiǎn)單,離散狀態(tài)下的積分計(jì)算其實(shí)就是把過(guò)去采樣得到的所有誤差加在一起,而微分計(jì)算就是把這一輪計(jì)算得到的誤差與上一輪的誤差相減。

最后,我們一般還會(huì)對(duì)PID的積分和輸出進(jìn)行限幅(規(guī)定上下限),積分限幅可以減小積分引起的超調(diào),輸出限幅可以保護(hù)執(zhí)行機(jī)構(gòu)或被控對(duì)象。

C語(yǔ)言代碼

//首先定義PID結(jié)構(gòu)體用于存放一個(gè)PID的數(shù)據(jù)
typedef struct
{
   	float kp, ki, kd; //三個(gè)系數(shù)
    float error, lastError; //誤差、上次誤差
    float integral, maxIntegral; //積分、積分限幅
    float output, maxOutput; //輸出、輸出限幅
}PID;
 
//用于初始化pid參數(shù)的函數(shù)
void PID_Init(PID *pid, float p, float i, float d, float maxI, float maxOut)
{
    pid->kp = p;
    pid->ki = i;
    pid->kd = d;
    pid->maxIntegral = maxI;
    pid->maxOutput = maxOut;
}
 
//進(jìn)行一次pid計(jì)算
//參數(shù)為(pid結(jié)構(gòu)體,目標(biāo)值,反饋值),計(jì)算結(jié)果放在pid結(jié)構(gòu)體的output成員中
void PID_Calc(PID *pid, float reference, float feedback)
{
 	//更新數(shù)據(jù)
    pid->lastError = pid->error; //將舊error存起來(lái)
    pid->error = reference - feedback; //計(jì)算新error
    //計(jì)算微分
    float dout = (pid->error - pid->lastError) * pid->kd;
    //計(jì)算比例
    float pout = pid->error * pid->kp;
    //計(jì)算積分
    pid->integral += pid->error * pid->ki;
    //積分限幅
    if(pid->integral > pid->maxIntegral) pid->integral = pid->maxIntegral;
    else if(pid->integral < -pid->maxIntegral) pid->integral = -pid->maxIntegral;
    //計(jì)算輸出
    pid->output = pout+dout + pid->integral;
    //輸出限幅
    if(pid->output > pid->maxOutput) pid->output =   pid->maxOutput;
    else if(pid->output < -pid->maxOutput) pid->output = -pid->maxOutput;
}
 
PID mypid = {0}; //創(chuàng)建一個(gè)PID結(jié)構(gòu)體變量
 
int main()
{
    //...這里有些其他初始化代碼
    PID_Init(&mypid, 10, 1, 5, 800, 1000); //初始化PID參數(shù)
    while(1)//進(jìn)入循環(huán)運(yùn)行
    {
        float feedbackValue = ...; //這里獲取到被控對(duì)象的反饋值
        float targetValue = ...; //這里獲取到目標(biāo)值
        PID_Calc(&mypid, targetValue, feedbackValue); //進(jìn)行PID計(jì)算,結(jié)果在output成員變量中
        設(shè)定執(zhí)行器輸出大小(mypid.output);
        delay(10); //等待一定時(shí)間再開(kāi)始下一次循環(huán)
    }
}

最后一步——PID參數(shù)調(diào)整

在完成控制器代碼編寫(xiě)后,就要連接好系統(tǒng)進(jìn)行調(diào)參了,我們需要確定最合適的KpKiKd使控制效果最優(yōu)。

通常還是使用經(jīng)驗(yàn)法調(diào)參,通俗而言就是“試參數(shù)”,測(cè)試多個(gè)參數(shù)選取最好的控制效果,一般的步驟如下:

  1. 先將所有參數(shù)置零

  2. 將輸出限幅設(shè)為執(zhí)行機(jī)構(gòu)能接受的最大值

  3. 增大p參數(shù),使響應(yīng)速度達(dá)到比較好的水平

  4. 若存在穩(wěn)態(tài)誤差,逐漸增加i參數(shù)和積分限幅,使穩(wěn)態(tài)誤差消失

  5. 若希望減少超調(diào)或振蕩,逐漸增加d參數(shù),在保證響應(yīng)速度的前提下盡可能降低超調(diào)

此時(shí)大家可以使用上述的小球仿真環(huán)境體驗(yàn)一下各參數(shù)對(duì)系統(tǒng)的影響。到這里,我們就已經(jīng)能夠使用PID來(lái)控制各種對(duì)象了。

總結(jié)——使用PID的步驟

  1. 確定需要控制的對(duì)象,確定需要控制的物理量,確定反饋量的獲取方式,確定被控對(duì)象的控制方式;

  2. 檢查目標(biāo)值、反饋值、輸出值對(duì)應(yīng)物理量的關(guān)系是否符合上面說(shuō)的準(zhǔn)則;

  3. 編寫(xiě)代碼,將上述三個(gè)值的數(shù)值變量傳入PID進(jìn)行運(yùn)算,并將PID運(yùn)算結(jié)果輸出到執(zhí)行機(jī)構(gòu);

  4. 進(jìn)行參數(shù)調(diào)整。

聲明:本內(nèi)容為作者獨(dú)立觀點(diǎn),不代表電子星球立場(chǎng)。未經(jīng)允許不得轉(zhuǎn)載。授權(quán)事宜與稿件投訴,請(qǐng)聯(lián)系:editor@netbroad.com
覺(jué)得內(nèi)容不錯(cuò)的朋友,別忘了一鍵三連哦!
贊 6
收藏 7
關(guān)注 13
成為作者 賺取收益
全部留言
0/200
  • 電子渣男 08-12 11:38
    講的很棒
    回復(fù) 1條回復(fù)