|
|
| <!--插入廣告JS代碼--> |
作者:Byron Miller 獨立固件工程師
模糊邏輯并不需要特別的硬件或新的編程語言,只是要求有一種不同的設(shè)置隸屬關(guān)系(membership)的方法。從電梯到電飯煲,大量的物理系統(tǒng)都可受益于模糊邏輯編程。本文探討了對一個商用DSP芯片編程來創(chuàng)建一個基本的模糊邏輯控制器。
你可以采用現(xiàn)成的標準微處理器來構(gòu)建模糊邏輯系統(tǒng)。傳統(tǒng)的微處理器對于大多數(shù)應(yīng)用來說是足夠的,即使是模糊邏輯,但對于需要可預(yù)測且非?焖夙憫(yīng)時間的高安全性系統(tǒng)來說則未必。當傳統(tǒng)處理器不夠快時,數(shù)字信號處理器(DSP)可能正是你的系統(tǒng)所需要的。

圖1:“高”的布爾變量。
DSP是具有指令集和面向算術(shù)運算特性的專用微處理器,其最初只是用在信號處理應(yīng)用。現(xiàn)在,隨著DSP軟件開發(fā)工具種類的增加和質(zhì)量的提升,這種處理器變得越來越流行。DSP如今在成本上與通用微處理器也能競爭。今天,任何可以受益于高速乘法/累加 (MAC)運算的應(yīng)用都可以考慮采用DSP。
本文將闡述模糊邏輯系統(tǒng)的組成部分,并給出如何采用DSP來實現(xiàn)的實例。
模糊邏輯基礎(chǔ)
Lotfi Zadeh被認為是模糊邏輯的創(chuàng)立者,他在1965年的一篇文章中提出了布爾數(shù)學體系集合論的擴展,將二元擴展到多值。他的模糊邏輯集合論是一種廣義的經(jīng)典集合論,是對非精確性的極好表述。模糊邏輯的優(yōu)勢在于它可以在不采用數(shù)學方法的情況下使你能準確地描述一個過程或行為。

圖2:“高”的模糊變量。
布爾數(shù)學體系集合既可以是真,也可以是假,而模糊集合可以具有部分的這種隸屬關(guān)系。例如,圖1給出了一個布爾變量。在布爾表中,對于6英尺來說“高”是真,而低于6英尺則為假,但在圖2中,模糊變量的高既不是真也不是假,它具有可變的真假隸屬關(guān)系。布爾變量通常被稱為明確的集合(crisp set),模糊變量成為模糊集合。模糊集合行為類似于其對應(yīng)的明確集合。舉例來說,模糊邏輯采用“與”、“或”、“非”以及補數(shù)運算!芭c”處理是取輸入量中的小者,“或”處理是取輸入量的較大者,補數(shù)運算是用1減去輸入值。
控制器的組件
任何基于模糊邏輯的控制器具有三個組件:模糊化器(fuzzifier)、規(guī)則庫和去模糊化器。在將一個明確(數(shù)字)輸入轉(zhuǎn)變成模糊值并對該值進行處理,然后再將模糊值轉(zhuǎn)變成明確值輸出的過程中,每個組件扮演著重要的角色。盡管模糊控制器的實現(xiàn)不盡相同,他們都具有這三個基本部分。
模糊化器獲取一個明確輸入值,并根據(jù)是否需要將其進行縮放來轉(zhuǎn)換成模糊值,并轉(zhuǎn)變?yōu)槎嘀祵嶓w(entity)。縮放處理將輸入域映射到所有變量都采用的一些內(nèi)部格式。該多值實體是將輸入值與其對應(yīng)的輸入集合進行比較的結(jié)果,并對該值進行映射處理以反應(yīng)出其隸屬關(guān)系特性。
列表1:去模糊化器:主函數(shù)的C代碼。
規(guī)則庫從前一級取得輸入值,并將其與每個相關(guān)語句的區(qū)間相加。規(guī)則庫由一系列一個或多個IF-THEN語句組成。每個語句依次組成了兩個部分:條件(antecedent),在關(guān)鍵字then的左邊;結(jié)果(consequent),在then的右邊。一個語句可能具有一個或更多的antecedent和consequent。典型的規(guī)則語句看起來就像這樣:
IF antecedent1 . . . antecedentN THEN
consequence1 . . . consequenceN
條件和結(jié)果都采用條件形式變量,這里的變量是條件的輸入變量或結(jié)果的輸出變量。結(jié)果的條件部分是一個模糊隸屬函數(shù),如“冷”、“暖和”、“熱”。規(guī)則庫對來自模糊化器的數(shù)據(jù)與規(guī)則進行比較。當它遇到一個條件是真,就觸發(fā)語句的結(jié)果動作。

列表2:去模糊化器:GetData()函數(shù)的C代碼。
以電梯為例,規(guī)則庫可能就像:
IF門打開AND速度為零 AND距離可以忽略 THEN電機轉(zhuǎn)速為0
IF 門關(guān)閉AND速度慢 AND 距離大THEN電機轉(zhuǎn)速最大
IF 門關(guān)閉AND速度中等 AND距離一般 THEN電機轉(zhuǎn)速一般
IF 門關(guān)閉AND 速度快AND 距離一般THEN電機轉(zhuǎn)速一般
這個例子有四個規(guī)則,每個規(guī)則有四個變量:門、電機、速度、距離(到選定層)。每個規(guī)則有三個條件和一個結(jié)果,總共有十種情況組成了四個變量的隸屬關(guān)系集合。例如,速度具有變量0、慢、中等和快速?勺兙嚯x具有以下四個值:忽略、很小、一般、大。門要么開要么就是關(guān)閉。對于各種隸屬集合,電機轉(zhuǎn)速具有0、最小、平均和最大四個變量。
舉例來說,我們假設(shè)升降機門是關(guān)閉的,速度為10英尺每秒,這個速度定義在慢和中兩種隸屬關(guān)系區(qū)間的中間(所有的隸屬關(guān)系區(qū)間互相重疊)。距離是42英尺,這個值同時被定義在大和中兩個區(qū)間。這樣一來規(guī)則庫中的兩個規(guī)則都被激發(fā)(第二個和第三個規(guī)則),結(jié)果就被平均了。

列表3:模糊化器部分的實現(xiàn)。
規(guī)則激發(fā)是控制器組件中的關(guān)鍵問題。當規(guī)則激發(fā)時將導(dǎo)致語句的條件部分變成有效。一旦有效,語句的結(jié)果部分就與所有被激發(fā)規(guī)則的結(jié)果累加起來。這樣一來,該級的輸出將產(chǎn)生一個所有激發(fā)結(jié)果的復(fù)合值。這看起來就像被激發(fā)結(jié)果的所有隸屬集合的和。
模糊邏輯的第三個組件是去模糊化器。去模糊化器將來自前一級的輸出轉(zhuǎn)變?yōu)槊鞔_的輸出值。當今有四種方法在執(zhí)行去模糊化中比較流行,分別是重心法(Centroid)、最大化、單點(singleton)和權(quán)重平均。每種方法都有其優(yōu)勢和不足,重心法最流行。這里只討論一下重心法。
重心法去模糊化是計算來自前一級的復(fù)合模糊集合的“重心”。這是一種數(shù)字密集型方法,需要計算集合的積分,還要求輸出集合重疊以避免產(chǎn)生無效輸出的情況,以及每個變量的隸屬集合由一個奇數(shù)或區(qū)間組成。
代碼轉(zhuǎn)換
為在DSP上實現(xiàn)實時模糊邏輯控制器,你需要將模糊邏輯引擎設(shè)計轉(zhuǎn)換到實際的代碼。為了將每個組件轉(zhuǎn)換為軟件,你必須了解控制器、控制器的每部分以及它將控制的系統(tǒng)。

列表4:規(guī)則代碼。
將主要的程序轉(zhuǎn)換成代碼是很簡單的。本質(zhì)上,它無外乎就是這樣的無限循環(huán):獲得數(shù)據(jù)值并將他們轉(zhuǎn)換成對等的模糊量,處理模糊數(shù)據(jù),再將輸出去模糊化形成明確值,最后將這個值輸出到正確的輸出端口。這些操作的每一個都對應(yīng)著一個C函數(shù),它們共同組成了模糊引擎。
在列表1中的GetData()函數(shù)從一個I/O器件重新獲得數(shù)據(jù)點。這個函數(shù)只是一部分,僅用來測試,但是如果完全實現(xiàn)它,將訪問物理I/O器件。在本例中,函數(shù)從一個陣列中提取存儲數(shù)據(jù)點,每個循環(huán)提取一個數(shù)據(jù)點集合,并將提取的數(shù)據(jù)饋入到下一個函數(shù),即模糊化器。
Fuzzifier()函數(shù)將數(shù)據(jù)轉(zhuǎn)換為一個模糊表達,轉(zhuǎn)換方法是通過一個結(jié)構(gòu)將明確的數(shù)據(jù)值變換成規(guī)則庫能使用的值。然后,F(xiàn)uzzifier()必須為每次循環(huán)反復(fù)清除數(shù)據(jù)點。在每次反復(fù)后,另外一個內(nèi)置函數(shù)來清除這個結(jié)構(gòu)。一旦轉(zhuǎn)換完成,規(guī)則庫就可以使用這些數(shù)據(jù)點。
RuleBase得到模糊化器的結(jié)果(數(shù)據(jù)點),然后將這些點與內(nèi)部規(guī)則庫表進行比較。當產(chǎn)生一個匹配,RuleBase就獲取對應(yīng)的結(jié)果值,并將這個值用于每個被觸發(fā)的規(guī)則。之后,RuleBase將所有的觸發(fā)規(guī)則相加產(chǎn)生一個最后的模糊結(jié)果,最后將這個結(jié)果應(yīng)用到Defuzzifier()函數(shù)。
Defuzzifier()函數(shù)將模糊數(shù)據(jù)轉(zhuǎn)換回一個明確的量,這個量可以為數(shù)模轉(zhuǎn)換器或其它的物理器件所用。通常,一個輸出片段將這個輸出轉(zhuǎn)變成一個外部世界可以處理的值。然而,由于我們通過采用陣列使系統(tǒng)受到限制,去模糊化器組件僅簡單地將結(jié)果存儲到輸出陣列。列表1和2顯示了主函數(shù)和GetData()函數(shù)的C代碼。

列表5:去模糊化器。
為了將模糊程序編寫成代碼,讓我們回到模糊化器的介紹以確保我們了解模糊化器是如何工作的。模糊化器是將明確的輸入數(shù)據(jù)轉(zhuǎn)換成可以操作的模糊數(shù)據(jù),這意味著這個數(shù)據(jù)被轉(zhuǎn)換成了一個多值量。而且這個量還是該特定輸入數(shù)據(jù)的隸屬集合的一個函數(shù)。一個C結(jié)構(gòu)是用來存儲模糊化數(shù)據(jù)單元的理想結(jié)構(gòu),因為它可以具有多個值。這種結(jié)構(gòu)的每一個單元對應(yīng)著一個隸屬區(qū)間。例如模糊輸入變量Deflection具有“小”、“中”、“大”三個區(qū)間。假設(shè)區(qū)間定義如下:
0 <“小” < 25
10<“中”< 55
20 <“大”< 90
如果這個變量的明確輸入具有13這個值,其對等的模糊化量就由一個多值變量組成,這個變量具有三個布爾值:“小”、“中”和“大”。這三個單元是根據(jù)明確輸入數(shù)據(jù)來設(shè)置的。每個域都是一個布爾量,初始值設(shè)置為“假”。13這個值落入到兩個類別,因此小和中兩個單元都設(shè)置為真。同樣,23這個輸入值將所有三個組件集合設(shè)置為真。在代碼中實現(xiàn)模糊化器這個概念需要由下面的步驟組成:創(chuàng)建一個C結(jié)構(gòu)、將其范圍與輸入數(shù)據(jù)比較,根據(jù)比較來指定一個適當?shù)挠颉A斜?給出了模糊化器部分的實現(xiàn)。如果有需要的話,模糊化器通常執(zhí)行縮放處理。

圖3: FuzzyLevel系統(tǒng)。
控制器的規(guī)則庫部分執(zhí)行輸入數(shù)據(jù)的處理。由于這部分處理大部分的工作,因此規(guī)則庫是最復(fù)雜的。前面講過,規(guī)則庫將表中所有觸發(fā)規(guī)則值進行求和,然后將和除以這些規(guī)則的數(shù)量。表中包含了每個輸入變量的隸屬區(qū)間值。例如“Position”變量有三個區(qū)間,變量“Error”有5個區(qū)間。表總共有15(5*3)個單元。表的列和行的交叉點對應(yīng)IF-THEN語句中的條件部分中的兩個條件的AND。矩陣中的值從左向右增加,從上向下增加。例如,如果“Position”的區(qū)間為“近”、“鄰近”、“遠”。近對應(yīng)著矩陣中的0列,鄰近對應(yīng)著第一列,依次類推。類似地,如果變量“Error”具有“很小”、“小”、“一般、”“大”、“很大”五個量,“很小”對應(yīng)第一行,“小”為第二行,依次類推。因此,矩陣中的交叉點就對應(yīng)條件語句中的AND處理。例如第0列和第0行對應(yīng)為真:
IF Position 為近 AND Error很小 THEN . . .
列表4給出了規(guī)則庫的代碼。注意到單元都為序數(shù),在模型定義和調(diào)整后,這些單元都被填滿。另外,這個表的大小是規(guī)則數(shù)的函數(shù),因此表的大小隨應(yīng)用而變。如果表改變,與陣列相關(guān)的變量必須也改變以反映它的大小改變。
去模糊化器模塊將模糊化的輸出轉(zhuǎn)換成明確的輸出。通常,去模糊化器將模糊輸出轉(zhuǎn)變?yōu)槊鞔_輸出,然后再將其縮放到變量的外部域。該引擎在兩方面與傳統(tǒng)的去模糊化器相背離:第一,實際的明確數(shù)值存儲在規(guī)則表中,故不必對它們進行轉(zhuǎn)換。在大部分真實場景中,模擬輸入和輸出通常由在0-5伏之間隨時變化的電壓構(gòu)成。一個例子就是常用于控制馬達和伺服電機的PWM。列表5給出了去模糊化器的代碼。注意,通過使它經(jīng)過一個陣列來訪問,這部分還簡化了外部接口。這使我們可以專注于邏輯調(diào)試。一旦邏輯調(diào)試完,真正的I/O被加進來。使用一個陣列用于測試的另一個好處就是可使過程更容易移植。
應(yīng)用實例
FuzzyLevel是基于DSP控制器的一個實例,用來控制一個工業(yè)控制應(yīng)用的液體槽中流體的高度和壓強。這種控制器通常用在煉油廠。

表1:FuzzyLevel模型表。
FuzzyLevel保持槽中液體在一個確定的高度,同時保證其中的氣壓不會達到危險的程度。槽中的液體高度和壓強是相關(guān)聯(lián)的,液體越多壓強越大。同樣,液體以某個恒定的速度流入槽中。圖3給出了FuzzyLevel系統(tǒng)的簡化框圖。采用傳感器來監(jiān)測氣壓和液體高度,一個電機用來控制輸出閥門打開的程度。
了解了系統(tǒng)如何動作之后,現(xiàn)在需要將這個動作轉(zhuǎn)換為能通過仿真來得到其最佳工作點的設(shè)計。為實現(xiàn)這種轉(zhuǎn)換,首先需要確定系統(tǒng)的輸入、輸出以及將進行的處理。從前面的描述中我們知道系統(tǒng)的輸入來自傳感器,因此,壓強和高度是輸入變量。此外,電機是系統(tǒng)中的唯一輸出。因此,“閥門”是系統(tǒng)唯一的輸出變量。緊接著需要定義變量的范圍。對于本例,我們假設(shè)每個變量有三個區(qū)間。例如,壓強的區(qū)間為“小”、“中”、“大”;“高度”的區(qū)間為“低”、“一般”、“高”;唯一的輸出變量閥門的區(qū)間為“全關(guān)”、“部分開”、“全開”。
定義了變量和它們的區(qū)間之后就可以描述系統(tǒng)處理了。正如前面提到的,輸入和輸出之間存在一定關(guān)系,描述這種關(guān)系也就定義了系統(tǒng)的行為。而且這種行為使用系統(tǒng)本身的規(guī)則來描述的,規(guī)則的數(shù)量與輸入變量的區(qū)間相關(guān)。由于每個規(guī)則有三個區(qū)間,因此該系統(tǒng)有9個規(guī)則。現(xiàn)在就完成了大致的模型。

圖4: FuzzyLevel應(yīng)用拷屏圖。
接著需要仿真這個模型來產(chǎn)生進入模糊引擎矩陣的去模糊化的點。本例將采用來自Impatiens Publications 的TeachFuzz模糊邏輯仿真器。在將設(shè)計轉(zhuǎn)換為仿真器能理解的格式之前,必須設(shè)置輸入和輸出變量的實際值。仿真器并不關(guān)心所有單位的類別,它唯一的要求就是一些正數(shù)。單位對仿真器并不重要(設(shè)計師為了方便而采用這些單位)。變量的范圍如下:0<高< 80,0 <壓強 <1,600和0<閥門 < 240。這些變量的單位分別為英尺、磅/平方英寸和轉(zhuǎn)矩的英尺*磅。
運行仿真器將產(chǎn)生關(guān)于模型的可視數(shù)據(jù),你通常必須對模型進行修改,因為模型的動作并不像所期望的那樣。對模型參數(shù)的修改也稱為調(diào)整過程。調(diào)整使我們能找到控制器最佳的工作點。通常,調(diào)整包括區(qū)間數(shù)的修改以及改變這些區(qū)間的形狀。這里的模型也不例外。在完成調(diào)整后,就可以將規(guī)則矩陣載入。我們可以通過找到只觸發(fā)一個規(guī)則的數(shù)據(jù)集合來確定去模糊化值。這個值被放入到矩陣中相應(yīng)輸入變量區(qū)間的交叉點。例如,下面的規(guī)則是某個給定輸入數(shù)據(jù)集合觸發(fā)的唯一規(guī)則:IF高度為“低”且壓強為“中”THEN閥門為“部分開”。
30這個值被放入到矩陣中,對應(yīng)“高度”為“低”和“壓強”為“中”的交叉點。這對應(yīng)的是那個結(jié)果的重心點。對所有的規(guī)則反復(fù)進行這個過程不斷,直到矩陣完全填滿為止。表1顯示了FuzzyLevel模型表完全填滿的結(jié)果。當表矩陣滿時,控制器就可以進行測試了。圖4和圖5顯示了一個在十次代碼反復(fù)之后的編譯/調(diào)試片段,這里采用TI的Code Composer仿真C5402 DSP芯片。插入的printfs在這里用來簡化I/O驗證。仿真統(tǒng)計表顯示了第一次反復(fù)占用了722個周期,十次反復(fù)占用7,100個周期,平均每次反復(fù)為710個周期。在一個100MHz的C5402芯片上,F(xiàn)uzzyLevel從輸入到輸出的每一個反復(fù)需要0.71毫秒。對于大多數(shù)應(yīng)用來說,這個速度可能太大材小用了,但對于安全很關(guān)鍵的應(yīng)用來說,這又是很合理的,例如前面的流體槽。
快速模糊
當采用一般的微處理器不能滿足快速系統(tǒng)響應(yīng)要求時,采用模糊邏輯的DSP加速將非常有效,當前很多應(yīng)用采用這種方法,例如一些醫(yī)學麻醉系統(tǒng)或伺服電機控制器。Fuzzy Level的例子也是一種類似于一些當前在煉油廠中所用的簡化控制系統(tǒng)。你可以修改引擎來提供更多的輸入和輸出。特別是,通過修改陣列將引擎修改成N輸入×M輸出的控制器?梢酝ㄟ^改變陣列為輸入的函數(shù)來增加額外的輸入,例如三個輸入--三維規(guī)則矩陣。多個輸出可以通過幾種方法來處理,例如矩陣的交叉單元可以包含多個值。反過來,交叉點單元可以包含一個指向保持所有去模糊化數(shù)值的數(shù)據(jù)結(jié)構(gòu)的指針。另一個改進就是使不同的條件只觸發(fā)特定的結(jié)果。然而,這涉及到多控制器的重構(gòu)以及指針的廣泛間接應(yīng)用。如果你決定這樣做,請確保最后的響應(yīng)時間能夠足夠快來響應(yīng)系統(tǒng)的輸入。

圖5:Code Composer Studio仿真FuzzyLevel應(yīng)用的結(jié)果。
作者簡介:Byron Miller是一位獨立的固件工程師,專注于微處理器、DSP的設(shè)計和硬件調(diào)試、移植,以及針對控制數(shù)據(jù)獲取、模糊邏輯、互聯(lián)網(wǎng)設(shè)備的固件開發(fā)。他具有計算機科學學士學位和軟件工程碩士學位。