1. 程式人生 > >PID控制器開發筆記之十二:模糊PID控制器的實現

PID控制器開發筆記之十二:模糊PID控制器的實現

poi 技術 last 全部 arr linear 數值 .com 數據

  在現實控制中,被控系統並非是線性時不變的,往往需要動態調整PID的參數,而模糊控制正好能夠滿足這一需求,所以在接下來的這一節我們將討論模糊PID控制器的相關問題。模糊PID控制器是將模糊算法與PID控制參數的自整定相結合的一種控制算法。可以說是模糊算法在PID參數整定上的應用。

1、模糊算法的原理

  模糊算法是一種基於智能推理的算法,雖然稱之為模糊算法其實並不模糊,實際上是一種逐步求精的思想。一個模糊控制器主要是由模糊化,模糊推理機和精確化三個功能模塊和知識庫(包括數據庫和規則庫)構成的。在此我們近討論模糊控制的幾個主要問題。

1.1、輸入量的量化

  輸入數據都是精確的,要實現模糊算法需要現對其實現量化。所謂量化就是通過量化函數將輸入量投射到一定的數字級別,一般都是相對於0對稱的數字區間。具體投射到怎樣的區間根據實際情況而定,因為這會直接影響到計算的精度。

1.2、模糊化

  模糊化是模糊算法非常重要的一步,首先確定對應各語言變量的模糊子集,然後根據量化的結果,我們就可以判斷該輸入所屬的集合並計算出對應的隸屬度。計算隸屬度的方法有很多,最常用的是使用三角形隸屬度函數或梯形隸屬度函數等來計算獲得。

1.3、規則庫

  規則庫是基於控制量的模糊化而的味道的,是實現模糊推理的基礎,很大程度上依賴於經驗來完成。規則庫的表現形式可以有多種,具體實現的形式根據我們實現的方便。

1.4、推理機

  推理決策才是模糊控制的核心,它利用知識庫中的信息和模糊運算方式,模擬人的推理決策的思想方法,在一定的輸入條件下激活相應的控制規則給出適當的模糊控制輸出。

1.5、精確化

  我們通過模糊推理,得到一系列的模糊表達,需要進行解模糊操作才能得到緊缺的數據。常用的解模糊方法有:

  • 最大隸屬度法——計算簡單,適用於控制要求不高場合。
  • 重心法——輸出更平滑,但計算難度大
  • 加權平均法——一般在工業上應用最廣泛

1.6、工程量化

  系統控制輸出是一個精確的數,但不是可以直接用於對象控制的物理量,所以在最後還要按照我們的需要進行轉換。比如對應PID的參數則可進行必要的轉換和修正在輸出給PID控制器。

2、模糊PID算法的設計

  前面簡單的描述了模糊算法的基本原理,接下來我們將討論如何將其應用於PID控制當中。所謂模糊PID控制是以偏差e及偏差的變化ec為輸入,利用模糊控制規則在線對PID參數進行調整,以滿足不同的偏差e和偏差的增量ec對PID參數的不同要求。其結構圖如下:

技術分享圖片

2.1輸入值的模糊化

  輸入值的模糊化就是將用於計算的輸入對應到標準化的數值區間,並根據量化結果和模糊化子集得到該輸入對子集的隸屬度。我們在使用偏差e和偏差增量ec作為輸入實現控制參數調整則需要對e和ec進行模糊化。

  首先,我們確定e和ec的模糊子集,對於PID控制我們選則:負大[NB]、負中[NM]、負小[NS]、零[ZO]、正小[PS]、正中[PM]、正大[PB]等7個語言變量就能夠有足夠精度表達其模糊子集。所以我們定義e和ec的模糊子集均為{NB,NM,NS,ZO,PS,PM,PB}。

  確定了模糊子集,我們怎麽將e和ec的具體值和模糊集對應上呢?我們需要引入量化函數。要確定量化函數,我們先引入e和ec模糊集對應的論域,定義為{-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6}。對於任何一個物理量測量信號都有一個量程範圍,我們記為Vmax和Vmin,和自然在PID調節時設定值的範圍預期相同,所以偏差e的範圍就是Vmin-Vmax到Vmax-Vmin的範圍內,而偏差的增量範圍則是其兩倍。這裏我們采用線性方式量化,則其函數關系為:

技術分享圖片

  利用上述的量化函數就可以將e和ec量化,我們可以采用如4舍5入的方式獲取確定的模糊子集。但考慮到e和ec的變化是連續變化的,4舍5入對控制精度可能存在影響,所以我們引入隸屬度來實現這一過程。

  最後我們確定e和ec在模糊子集上的隸屬度。隸屬度是一個介於0和1之間的值,用以描述對應一個輸入屬於某一個模糊自己的程度。一般我們描述成隸屬度函數,可采用的隸屬度函數很多,我們在次采用線性的隸屬度函數,或者稱為三角隸屬度函數,其函數關系如下:

技術分享圖片

  如果我們量化後的結果是1,那麽屬於ZO的隸屬度為0.5,同樣屬於PS的隸屬度也是0.5。至此,模糊化全部完成。

2.2、建立模糊規則表

  前面我們簡述了輸入的模糊化,但模糊推理才是模糊控制的根本。為了實現模糊推理首先我們要建立模糊推理的規則庫或者稱知識庫,然後建立推理機進行推理。

首先,我們來建立模糊規則庫,在這裏我們要對Kp、Ki和Kd三個參數進行調整,所以要建立這3個變量的模糊規則庫。

1)、Kp模糊規則設計

  在PID控制器中,Kp值的選取決定於系統的響應速度。增大Kp能提高響應速度,減小穩態偏差;但是,Kp值過大會產生較大的超調,甚至使系統不穩定減小Kp可以減小超調,提高穩定性,但Kp過小會減慢響應速度,延長調節時間。因此,調節初期應適當取較大的Kp值以提高響應速度,而在調節中期,Kp則取較小值,以使系統具有較小的超調並保證一定的響應速度;而在調節過程後期再將Kp值調到較大值來減小靜差,提高控制精度。基於上述描述我們定義Kp的模糊規則如下:

技術分享圖片

2)、Ki模糊規則設計

  在系統控制中,積分控制主要是用來消除系統的穩態偏差。由於某些原因(如飽和非線性等),積分過程有可能在調節過程的初期產生積分飽和,從而引起調節過程的較大超調。因此,在調節過程的初期,為防止積分飽和,其積分作用應當弱一些,甚至可以取零;而在調節中期,為了避免影響穩定性,其積分作用應該比較適中;最後在過程的後期,則應增強積分作用,以減小調節靜差。依據以上分析,我們制定的Ki模糊規則如下:

技術分享圖片

3)、Kd模糊規則設計

  微分環節的調整主要是針對大慣性過程引入的,微分環節系數的作用在於改變系統的動態特性。系統的微分環節系數能反映信號變化的趨勢,並能在偏差信號變化太大之前,在系統中引入一個有效的早期修正信號,從而加快響應速度,減少調整時間,消除振蕩.最終改變系統的動態性能。因此,Kd值的選取對調節動態特性影響很大。Kd值過大,調節過程制動就會超前,致使調節時間過長;Kd值過小,調節過程制動就會落後,從而導致超調增加。根據實際過程經驗,在調節初期,應加大微分作用,這樣可得到較小甚至避免超調;而在中期,由於調節特性對Kd值的變化比較敏感,因此,Kd值應適當小一些並應保持固定不變;然後在調節後期,Kd值應減小,以減小被控過程的制動作用,進而補償在調節過程初期由於Kd值較大所造成的調節過程的時間延長。依據以上分析,我們制定Kd的模糊規則如下:

技術分享圖片

  接下來,根據偏差E和偏差增量EC模糊化的結果以及規則庫推理出?Kp、?Ki、?Kd對應的模糊子集。由於前面我們設計的是采用隸屬度函數來定義輸入輸出量在模糊子集的隸屬度,所以推理出來的?Kp、?Ki、?Kd的模糊子集通常是一個由模糊變量組成的矩陣。而輸入量E和EC則是一個由模糊變量組成的向量。

  最後,我們需要明確不同的模糊變量所對應的量化數據。這個量化數據與物理量的對應則根據具體的不同對象是完全不一樣的。

2.3、解模糊處理

  對於求得的目標對象,我們還需要將其你模糊處理以使其與具體的物理量相對應。在模糊PID調解中,我們需要的是Kp,Ki和Kd,所以我們需要根據模糊推理的結果得到我們想要的Kp,Ki和Kd值。

  我們前面設計了三角隸屬度函數,並采用相同的量化目標即論域{-6,6},所以在某一時刻,輸入輸出所處的模糊變量的隸屬度是相同的,基於這一基礎,我們采用重心法計算各輸出量的量化值。其公式如下:

技術分享圖片

  其實因為我們采用的隸屬度函數的特性,在任何方向的計算隸屬度的和均為1,所以分母可以省略。於是每一個對象的計算實際上就是矩陣操作,公式如下:

技術分享圖片

  如果使用的是量化值,則還需要轉為實際值,關於這一點直接使用物理量值也是沒問題的,怎麽處理根據實際需要確定。得到增量後,我們也可以引入系數來放大和縮小Kp,Ki和Kd變化量,具體實現公式如下:技術分享圖片,其中?K為我們所計算得到的值,而α為系數,設定增量對最終只的影響。

3、模糊PID算法實現

  前面我們描述了算法的全過程,接下來我們編碼實現之。首先我們依然需要定義一個模糊PID控制器的結構對象。

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

typedef struct

{

float setpoint; /*設定值*/

float kp; /*比例系數*/

float ki; /*積分系數*/

float kd; /*微分系數*/

float lasterror; /*前一拍偏差*/

float preerror; /*前兩拍偏差*/

float deadband; /*死區*/

float output; /*輸出值*/

float result; /*物理量輸出值*/

float maximum; /*輸出值的上限*/

float minimum; /*輸出值的下限*/

float maxdKp; /*Kp增量的最大限值*/

float mindKp; /*Kp增量的最小限值*/

float qKp; /*Kp增量的影響系數*/

float maxdKi; /*Ki增量的最大限值*/

float mindKi; /*Ki增量的最小限值*/

float qKi; /*Ki增量的影響系數*/

float maxdKd; /*Kd增量的最大限值*/

float mindKd; /*Kd增量的最小限值*/

float qKd; /*Kd增量的影響系數*/

}FUZZYPID;

  接下來,實現輸入值的模糊化。我們前面已經設計了采用線性量化函數以及三角隸屬度函數,所以實現就簡單了。

/*線性量化操作函數,論域{-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6}*/

static void LinearQuantization(FUZZYPID *vPID,float pv,float *qValue)

{

float thisError;

float deltaError;

thisError=vPID->setpoint-pv; //計算偏差值

deltaError=thisError-vPID->lasterror; //計算偏差增量

qValue[0]=6.0*thisError/(vPID->maximum-vPID->minimum);

qValue[1]=3.0*deltaError/(vPID->maximum-vPID->minimum);

}

  對於量化函數實際上可根據需要采用不同的函數,如速降曲線函數,正太分布函數以及其它一元函數等都是可以的,但對於我們在這裏的實現目標使用線性函數就足夠了。還有隸屬度函數也是一樣有多種選擇,我們這裏采用計算量較小的三角隸屬度函數:

/*隸屬度計算函數*/

static void CalcMembership(float *ms,float qv,int * index)

{

if((qv>=-NB)&&(qv<-NM))

{

index[0]=0;

index[1]=1;

ms[0]=-0.5*qv-2.0; //y=-0.5x-2.0

ms[1]=0.5*qv+3.0; //y=0.5x+3.0

}

else if((qv>=-NM)&&(qv<-NS))

{

index[0]=1;

index[1]=2;

ms[0]=-0.5*qv-1.0; //y=-0.5x-1.0

ms[1]=0.5*qv+2.0; //y=0.5x+2.0

}

else if((qv>=-NS)&&(qv<ZO))

{

index[0]=2;

index[1]=3;

ms[0]=-0.5*qv; //y=-0.5x

ms[1]=0.5*qv+1.0; //y=0.5x+1.0

}

else if((qv>=ZO)&&(qv<PS))

{

index[0]=3;

index[1]=4;

ms[0]=-0.5*qv+1.0; //y=-0.5x+1.0

ms[1]=0.5*qv; //y=0.5x

}

else if((qv>=PS)&&(qv<PM))

{

index[0]=4;

index[1]=5;

ms[0]=-0.5*qv+2.0; //y=-0.5x+2.0

ms[1]=0.5*qv-1.0; //y=0.5x-1.0

}

else if((qv>=PM)&&(qv<=PB))

{

index[0]=5;

index[1]=6;

ms[0]=-0.5*qv+3.0; //y=-0.5x+3.0

ms[1]=0.5*qv-2.0; //y=0.5x-2.0

}

}

  接下來,我們實現模糊推理的函數,有了前面的基礎和模糊規則庫,模糊計算的函數其實已經簡單了。

/*解模糊化操作,根據具體的量化函數和隸屬度函數調整*/

static void FuzzyComputation (FUZZYPID *vPID,float pv,float *deltaK)

{

float qValue[2]={0,0}; //偏差及其增量的量化值

int indexE[2]={0,0}; //偏差隸屬度索引

float msE[2]={0,0}; //偏差隸屬度

int indexEC[2]={0,0}; //偏差增量隸屬度索引

float msEC[2]={0,0}; //偏差增量隸屬度

float qValueK[3];

LinearQuantization(vPID,pv,qValue);

CalcMembership(msE,qValue[0],indexE);

CalcMembership(msEC,qValue[1],indexEC);

qValueK[0]=msE[0]*(msEC[0]*ruleKp[indexE[0]][indexEC[0]]+msEC[1]*ruleKp[indexE[0]][indexEC[1]])

+msE[1]*(msEC[0]*ruleKp[indexE[1]][indexEC[0]]+msEC[1]*ruleKp[indexE[1]][indexEC[1]]);

qValueK[1]=msE[0]*(msEC[0]*ruleKi[indexE[0]][indexEC[0]]+msEC[1]*ruleKi[indexE[0]][indexEC[1]])

+msE[1]*(msEC[0]*ruleKi[indexE[1]][indexEC[0]]+msEC[1]*ruleKi[indexE[1]][indexEC[1]]);

qValueK[2]=msE[0]*(msEC[0]*ruleKd[indexE[0]][indexEC[0]]+msEC[1]*ruleKd[indexE[0]][indexEC[1]])

+msE[1]*(msEC[0]*ruleKd[indexE[1]][indexEC[0]]+msEC[1]*ruleKd[indexE[1]][indexEC[1]]);

deltaK[0]=LinearRealization(vPID->maxdKp,vPID->mindKp,qValueK[0]);

deltaK[1]=LinearRealization(vPID->maxdKi,vPID->mindKi,qValueK[1]);

deltaK[2]=LinearRealization(vPID->maxdKd,vPID->mindKd,qValueK[2]);

}

  至此,Kp、Ki和Kd的增量已經得到,剩下的就是修正三個參數,並用於實現PID調節,與普通的增量型PID無異,不再贅述。

4、總結

  模糊PID算法是模糊算法在PID參數整定上的應用,與純粹的模糊控制算法是有區別的。普通的模糊控制器適用於直接推理控制器的輸出,而模糊PID算法使用模糊算法修改PID參數,最終的控制器輸出依然是由PID控制器來實現的。

  模糊控制本身是非常復雜且具體應用方式很多。大多是針對特定對象的專業控制器,已經脫離了PID這種通用性控制器的範疇。此外比較熱門的還有模糊多變量控制器是屬於先進控制系統(APC)的範疇,有機會再討論。

歡迎關註:

技術分享圖片

PID控制器開發筆記之十二:模糊PID控制器的實現