PID控制學習彙總

調節器講解:

https://wenku.baidu.com/view/3ff4d807ba1aa8114431d928.html

PID控制解釋

[ 原地址 ] http://blog.gkong.com/liaochangchu_117560.ashx
PID是比例、積分、微分的簡稱,PID控制的難點不是編程,而是控制器的參數整定。參數整定的關鍵是正確地理解各參數的物理意義,PID控制的原理可以用人對爐溫的手動控制來理解。閱讀本文不需要高深的數學知識。
1.比例控制
有經驗的操作人員手動控制電加熱爐的爐溫,可以獲得非常好的控制品質,PID控制與人工控制的控制策略有很多相似的地方。
下面介紹操作人員怎樣用比例控制的思想來手動控制電加熱爐的爐溫。假設用熱電偶檢測爐溫,用數字儀表顯示溫度值。在控制過程中,操作人員用眼睛讀取爐溫,並與爐溫給定值比較,得到溫度的誤差值。然後用手操作電位器,調節加熱的電流,使爐溫保持在給定值附近。
操作人員知道爐溫穩定在給定值時電位器的大致位置(我們將它稱爲位置L),並根據當時的溫度誤差值調整控制加熱電流的電位器的轉角。爐溫小於給定值時,誤差爲正,在位置L的基礎上順時針增大電位器的轉角,以增大加熱的電流。爐溫大於給定值時,誤差爲負,在位置L的基礎上反時針減小電位器的轉角,並令轉角與位置L的差值與誤差成正比。上述控制策略就是比例控制,即PID控制器輸出中的比例部分與誤差成正比。
閉環中存在着各種各樣的延遲作用。例如調節電位器轉角後,到溫度上升到新的轉角對應的穩態值時有較大的時間延遲。由於延遲因素的存在,調節電位器轉角後不能馬上看到調節的效果,因此閉環控制系統調節困難的主要原因是系統中的延遲作用。
比例控制的比例係數如果太小,即調節後的電位器轉角與位置L的差值太小,調節的力度不夠,使系統輸出量變化緩慢,調節所需的總時間過長。比例係數如果過大,即調節後電位器轉角與位置L的差值過大,調節力度太強,將造成調節過頭,甚至使溫度忽高忽低,來回震盪。
增大比例係數使系統反應靈敏,調節速度加快,並且可以減小穩態誤差。但是比例係數過大會使超調量增大,振盪次數增加,調節時間加長,動態性能變壞,比例係數太大甚至會使閉環系統不穩定。
單純的比例控制很難保證調節得恰到好處,完全消除誤差。
2.積分控制
PID控制器中的積分對應於圖1中誤差曲線 與座標軸包圍的面積(圖中的灰色部分)。PID控制程序是週期性執行的,執行的週期稱爲採樣週期。計算機的程序用圖1中各矩形面積之和來近似精確的積分,圖中的TS就是採樣週期。
這裏寫圖片描述
圖1 積分運算示意圖
每次PID運算時,在原來的積分值的基礎上,增加一個與當前的誤差值ev(n)成正比的微小部分。誤差爲負值時,積分的增量爲負。
手動調節溫度時,積分控制相當於根據當時的誤差值,週期性地微調電位器的角度,每次調節的角度增量值與當時的誤差值成正比。溫度低於設定值時誤差爲正,積分項增大,使加熱電流逐漸增大,反之積分項減小。因此只要誤差不爲零,控制器的輸出就會因爲積分作用而不斷變化。積分調節的“大方向”是正確的,積分項有減小誤差的作用。一直要到系統處於穩定狀態,這時誤差恆爲零,比例部分和微分部分均爲零,積分部分纔不再變化,並且剛好等於穩態時需要的控制器的輸出值,對應於上述溫度控制系統中電位器轉角的位置L。因此積分部分的作用是消除穩態誤差,提高控制精度,積分作用一般是必須的。
PID控制器輸出中的積分部分與誤差的積分成正比。因爲積分時間TI在積分項的分母中,TI越小,積分項變化的速度越快,積分作用越強。
3.PI控制
控制器輸出中的積分項與當前的誤差值和過去歷次誤差值的累加值成正比,因此積分作用本身具有嚴重的滯後特性,對系統的穩定性不利。如果積分項的係數設置得不好,其負面作用很難通過積分作用本身迅速地修正。而比例項沒有延遲,只要誤差一出現,比例部分就會立即起作用。因此積分作用很少單獨使用,它一般與比例和微分聯合使用,組成PI或PID控制器。
PI和PID控制器既克服了單純的比例調節有穩態誤差的缺點,又避免了單純的積分調節響應慢、動態性能不好的缺點,因此被廣泛使用。
如果控制器有積分作用(例如採用PI或PID控制),積分能消除階躍輸入的穩態誤差,這時可以將比例係數調得小一些。
如果積分作用太強(即積分時間太小),相當於每次微調電位器的角度值過大,其累積的作用會使系統輸出的動態性能變差,超調量增大,甚至使系統不穩定。積分作用太弱(即積分時間太大),則消除穩態誤差的速度太慢,積分時間的值應取得適中。
4.微分作用
誤差的微分就是誤差的變化速率,誤差變化越快,其微分絕對值越大。誤差增大時,其微分爲正;誤差減小時,其微分爲負。控制器輸出量的微分部分與誤差的微分成正比,反映了被控量變化的趨勢。
有經驗的操作人員在溫度上升過快,但是尚未達到設定值時,根據溫度變化的趨勢,預感到溫度將會超過設定值,出現超調。於是調節電位器的轉角,提前減小加熱的電流。這相當於士兵射擊遠方的移動目標時,考慮到子彈運動的時間,需要一定的提前量一樣。
這裏寫圖片描述
圖2 階躍響應曲線
圖2中的c (∞)爲被控量c (t)的穩態值或被控量的期望值,誤差e(t) = c (∞) - c (t)。在圖2中啓動過程的上升階段,當 時,被控量尚未超過其穩態值。但是因爲誤差e(t)不斷減小,誤差的微分和控制器輸出的微分部分爲負值,減小了控制器的輸出量,相當於提前給出了制動作用,以阻礙被控量的上升,所以可以減少超調量。因此微分控制具有超前和預測的特性,在超調尚未出現之前,就能提前給出控制作用。
閉環控制系統的振盪甚至不穩定的根本原因在於有較大的滯後因素。因爲微分項能預測誤差變化的趨勢,這種“超前”的作用可以抵消滯後因素的影響。適當的微分控制作用可以使超調量減小,增加系統的穩定性。
對於有較大的滯後特性的被控對象,如果PI控制的效果不理想,可以考慮增加微分控制,以改善系統在調節過程中的動態特性。如果將微分時間設置爲0,微分部分將不起作用。
微分時間與微分作用的強弱成正比,微分時間越大,微分作用越強。如果微分時間太大,在誤差快速變化時,響應曲線上可能會出現“毛刺”。
微分控制的缺點是對干擾噪聲敏感,使系統抑制干擾的能力降低。爲此可在微分部分增加慣性濾波環節。
5.採樣週期
PID控制程序是週期性執行的,執行的週期稱爲採樣週期。採樣週期越小,採樣值越能反映模擬量的變化情況。但是太小會增加CPU的運算工作量,相鄰兩次採樣的差值幾乎沒有什麼變化,將使PID控制器輸出的微分部分接近爲零,所以也不宜將採樣週期取得過小。
應保證在被控量迅速變化時(例如啓動過程中的上升階段),能有足夠多的採樣點數,不致因爲採樣點數過少而丟失被採集的模擬量中的重要信息。
6.PID參數的調整方法
在整定PID控制器參數時,可以根據控制器的參數與系統動態性能和穩態性能之間的定性關係,用實驗的方法來調節控制器的參數。有經驗的調試人員一般可以較快地得到較爲滿意的調試結果。在調試中最重要的問題是在系統性能不能令人滿意時,知道應該調節哪一個參數,該參數應該增大還是減小。
爲了減少需要整定的參數,首先可以採用PI控制器。爲了保證系統的安全,在調試開始時應設置比較保守的參數,例如比例係數不要太大,積分時間不要太小,以避免出現系統不穩定或超調量過大的異常情況。給出一個階躍給定信號,根據被控量的輸出波形可以獲得系統性能的信息,例如超調量和調節時間。應根據PID參數與系統性能的關係,反覆調節PID的參數。
如果階躍響應的超調量太大,經過多次振盪才能穩定或者根本不穩定,應減小比例係數、增大積分時間。如果階躍響應沒有超調量,但是被控量上升過於緩慢,過渡過程時間太長,應按相反的方向調整參數。
如果消除誤差的速度較慢,可以適當減小積分時間,增強積分作用。
反覆調節比例係數和積分時間,如果超調量仍然較大,可以加入微分控制,微分時間從0逐漸增大,反覆調節控制器的比例、積分和微分部分的參數。
總之,PID參數的調試是一個綜合的、各參數互相影響的過程,實際調試過程中的多次嘗試是非常重要的,也是必須的。

代碼實現:

/****************************所謂PID即爲P(比例)+I(積分)+D(微分**************************/
**(1)P控制(比例控制):    e(t) = SP - y(t);        SP--設定值   e(t)--誤差值(設定的值和當前的誤差) y(t)--反饋值(當前值)
**適用於滯後性不大的系統   u(t) = e(t) * P;        u(t)--輸出值(需要輸出的) P--比例係數
**
**(2)PI控制(比例+積分):  u(t) = Kp*e(t) + Ki∑e(t) + u0
**可使系統進入穩態無穩態誤差u(t)--輸出 Kp--比例放大係數 ki--積分放大係數 e(t)--誤差 u0--控制量基準值(基礎偏差)
**
**(3)PD控制(微分控制):     
**微分項解決響應速度問題   積分項解決穩定性
**(4)PID控制(比例積分微分控制):
**微分項解決響應速度問題   u(t) = Kp*e(t) + Ki∑e(t)+ Kd[e(t) – e(t-1)] + u0            
**採樣週期(即反饋值的採樣週期)
**控制週期(就是每隔多長時間進行一次PID運算,並將結果輸出)
****************************小結:P(比例)--即時性 I(積分)--響應速度 D(微分)--穩定性************************************
*/
#include<stdio.h>
#include<string.h>
#include"StandardPID.h"
//#include<stdib.h>

//對變量的聲明
typedef struct PID{
    double SetPoint;            //設定值
    double Kp;                  //比例係數
    double Ki;                  //積分系數
    double Kd;                  //微分系數
    double LastError;           //最後一次誤差數Er[-1]
    double PrevError;           //最後第二次誤差數er[-2]
    double SumError;            //誤差積分  
}PID;

/*
**PID計算部分
*/
double PIDCalc(PID *pp, double NextPoint)   
{
    double dError,                              //當前微分
           Error;                               //偏差
    Error = pp->SetPoint - NextPoint;           //偏差值=設定值-輸入值(當前值)
    pp->SumError += Error;                      //積分=積分+偏差  --偏差的累加
    dError = pp->LastError - pp->PrevError;     //當前微分 = 最後誤差 - 之前誤差
    pp->PrevError = pp->LastError;              //更新“之前誤差”
    pp->LastError = Error;                      //更新“最後誤差”
    return (pp->Kp * Error                      //比例項 = 比例常數 * 偏差
        +   pp->Ki *  pp->SumError              //積分項 = 積分常數 * 誤差積分
        +   pp->Kd * dError                     //微分項 = 微分常數 * 當前微分
        );
}
//爲PID變量申請內存,範圍指向pp的指針
void PIDInit (PID *pp)   
{
                                //memset是計算機中C / C++語言函數。將s所指向的某一塊內存中的前n個
    memset(pp, 0, sizeof(PID)); //字節的內容全部設置爲ch指定的ASCII值,塊的大小由第三個參數指定,
}                               //這個函數通常爲新申請的內存做初始化工作, 其返回值爲指向s的指針。

double sensor(void)                 //輸入
{   
    double shuru;
    scanf("%lf", &shuru);
    return shuru;
}

void actuator(double rDelta)       //輸出
{
    printf("%lf\n", rDelta);
}

int main()
{
    PID sPID;                       //PID結構體
    double rOut;                    //輸出變量
    double rIn;                     //輸入變量
    PIDInit(&sPID);                 //初始化結構體
    sPID.Kp = 0.5;
    sPID.Ki = 0.5;                  
    sPID.Kd = 0.5;
    sPID.SetPoint = 100.0;

    for (;;){
        rIn = sensor();             //取輸入值
        rOut = PIDCalc(&sPID, rIn); //PID運算
        actuator(rOut);             //輸出
    }
}

#define __StandardPID_H

double PIDCalc(PID *pp, double NextPoint);
void PIDInit (PID *pp);
double sensor(void);
void actuator(double rDelta);

#endif 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章