PID控制器開發筆記之一:PID算法原理及基本實現

        在自動控制中, PID 及其衍生出來的算法是應用最廣的算法之一。各個做自動控制的廠家基本都有會實現這一經典算法。我們在做項目的過程中,也時常會遇到類似的需求,所以就想實現這一算法以適用於更多的應用場景。

1PID算法基本原理

PID算法是控制行業最經典、最簡單、而又最能體現反饋控制思想的算法。對於一般的研發人員來說,設計和實現PID算法是完成自動控制系統的基本要求。這一算法雖然簡單,但真正要實現好,卻也需要下一定功夫。首先我們從PID算法最基本的原理開始分析和設計這一經典命題。

PID算法的執行流程是非常簡單的,即利用反饋來檢測偏差信號,並通過偏差信號來控制被控量。而控制器本身就是比例、積分、微分三個環節的加和。其功能框圖如下:

 

根據上圖我們考慮在某個特定的時刻t,此時輸入量爲rin(t),輸出量爲rout(t),於是偏差就可計算爲err(t)=rin(t)-rout(t)。於是PID的基本控制規律就可以表示爲如下公式:

 

其中Kp爲比例帶,TI爲積分時間,TD爲微分時間。PID控制的基本原理就是如此。

2PID算法的離散化

上一節簡單介紹了PID算法的基本原理,但要在計算機上實現就必須將其離散化,接下來我們就說一說PID算法的離散化問題。在實現離散化之前,我們需要對比例、積分、微分的特性做一個簡單的說明。

比例就是用來對系統的偏差進行反應,所以只要存在偏差,比例就會起作用。積分主要是用來消除靜差,所謂靜差就是指系統穩定後輸入輸出之間依然存在的差值,而積分就是通過偏差的累計來抵消系統的靜差。而微分則是對偏差的變化趨勢做出反應,根據偏差的變化趨勢實現超前調節,提高反應速度。

在實現離散前,我們假設系統採樣週期爲T。假設我們檢查第K個採樣週期,很顯然系統進行第K次採樣。此時的偏差可以表示爲err(K)=rin(K)-rout(K),那麼積分就可以表示爲:err(K)+ err(K+1)+┈┈,而微分就可以表示爲:(err(K)- err(K-1))/T。於是我們可以將第K次採樣時,PID算法的離線形式表示爲:

 

也可以記爲:

 

這就是所謂的位置型PID算法的離散描述公式。我們知道還有一個增量型PID算法,那麼接下來我們推到一下增量型PID算法的公式。上面的公式描述了第k個採樣週期的結果,那麼前一時刻也就是k-1個採樣週期就不難表示爲:

 

那麼我們再來說第K個採樣週期的增量,很顯然就是U(k)-U(k-1)。於是我們用第k個採樣週期公式減去第k-1個採樣週期的公式,就得到了增量型PID算法的表示公式:

 

當然,增量型PID必須記得一點,就是在記住U(k)=U(k-1)+∆U(k)

3PID控制器的基本實現

完成了離散化後,我們就可以來實現它了。已經用離散化的數據公式表示出來後,再進型計算機編程已經不是問題了。接下來我們就使用C語言分別針對位置型公式和增量型公式來具體實現。

1)位置型PID的簡單實現

位置型PID的實現就是以前面的位置型公式爲基礎。這一節我們只是完成最簡單的實現,也就是將前面的離散位置型PID公式的計算機語言化。

首先定義PID對象的結構體:

/*定義結構體和公用體*/

typedef struct

{

  float setpoint;       //設定值

  float proportiongain;     //比例係數

  float integralgain;      //積分系數

  float derivativegain;    //微分系數

  float lasterror;     //前一拍偏差

  float result; //輸出值

  float integral;//積分值

}PID;

接下來實現PID控制器:

void PIDRegulation(PID *vPID, float processValue)

{

  float thisError;

  thisError=vPID->setpoint-processValue;

  vPID->integral+=thisError;

  vPID->result=vPID->proportiongain*thisError+vPID->integralgain*vPID->integral+vPID->derivativegain*(thisError-vPID->lasterror);

  vPID->lasterror=thisError;

}

這就實現了一個最簡單的位置型PID控制器,當然沒有考慮任何干擾條件,僅僅只是對數學公式的計算機語言化。

2)增量型PID的簡單實現

增量型PID的實現就是以前面的增量型公式爲基礎。這一節我們只是完成最簡單的實現,也就是將前面的離散增量型PID公式的計算機語言化。

首先定義PID對象的結構體:

/*定義結構體和公用體*/

typedef struct

{

  float setpoint;       //設定值

  float proportiongain;     //比例係數

  float integralgain;      //積分系數

  float derivativegain;    //微分系數

  float lasterror;     //前一拍偏差

  float preerror;     //前兩拍偏差

  float deadband;     //死區

  float result; //輸出值

}PID;

接下來實現PID控制器:

void PIDRegulation(PID *vPID, float processValue)

{

  float thisError;

  float increment;

  float pError,dError,iError;

 

  thisError=vPID->setpoint-processValue; //得到偏差值

  pError=thisError-vPID->lasterror;

  iError=thisError;

  dError=thisError-2*(vPID->lasterror)+vPID->preerror;

  increment=vPID->proportiongain*pError+vPID->integralgain*iError+vPID->derivativegain*dError;   //增量計算

 

  vPID->preerror=vPID->lasterror;  //存放偏差用於下次運算

  vPID->lasterror=thisError;

  vPID->result+=increment;

}

這就實現了一個最簡單的增量型PID控制器,也沒有考慮任何的干擾條件,僅僅只是對數學公式的計算機語言化。

4、基本特點

前面講述並且實現了PID控制器,包括位置型PID控制器和增量型PID控制器。界限來我們對這兩種類型的控制器的特點作一個簡單的描述。

位置型PID控制器的基本特點:

  • 位置型PID控制的輸出與整個過去的狀態有關,用到了偏差的累加值,容易產生累積偏差。

  • 位置型PID適用於執行機構不帶積分部件的對象。

  • 位置型的輸出直接對應對象的輸出,對系統的影響比較大。

增量型PID控制器的基本特點:

  • 增量型PID算法不需要做累加,控制量增量的確定僅與最近幾次偏差值有關,計算偏差的影響較小。

  • 增量型PID算法得出的是控制量的增量,對系統的影響相對較小。

  • 採用增量型PID算法易於實現手動到自動的無擾動切換。

歡迎關注: