岳元龍 賈創 羅雄麟 徐寶昌 許亞嵐
摘要:實踐教學環節是自動化專業本科生課程體系的重要組成部分,也是強化學生掌握專業理論、培養實踐創新能力的有效方法。目前,校內現有的縮比實踐教學裝置和可操作范圍有限、甚至沒有實操環節的工廠實習,使學生無法通過實踐教學環節了解實際生產裝置對控制系統和操作人員的要求。本文給出全尺度仿真實踐教學平臺的建設方法,包括基于UniSim的全尺度仿真對象搭建和基于OPC服務器的數據接口開發,使學生可以通過OPC客戶端直接控制全仿真對象。
關鍵詞:自動化;實踐教學平臺;全仿真;OPC
中圖分類號:G642.0 文獻標志碼:A 文章編號:1674-9324(2018)24-0149-04
一、引言
獨立解決被控對象的狀態參數測量、控制方案設計和控制系統投用是自動化專業本科生重要的培養目標。所以,自動化專業課程體系中設置了與培養目標相對應的(配套的)理論教學和實踐教學。目前,教師課堂講授是理論教學的主要方式。通過系統的理論教學,學生一般可以較好理解和掌握自動化專業的基礎理論。在實踐教學方面,由于不同學校依托的行業背景不同,所以實踐教學環節比較多樣化[1]。中國石油大學(北京)自動化專業的定位是“突出石油石化行業特點,強化專業技能訓練”,本科實踐教學主要依托校內的煉油化工領域典型生產單元的縮比仿真模型和校外的煉化企業。但是,縮比仿真模型不能完全復現實際的生產過程特性,特別是在時間尺度方面,不能進行全時間尺度的仿真與操作。受限于生產過程的高溫、高壓、有毒等危險因素的影響,學生在校外煉化企業開展實踐教學過程中無法進行實際操作,校外實踐效果甚微[2]。所以,目前的實踐教學條件導致畢業生整體呈現解決實際問題能力與理論基礎不匹配的現象,進而出現用人單位招聘不到可用技術人員和學生找不到合適工作的雙重問題[3]。為了提高自動化專業本科生的實踐教學水平,探討自動化專業全仿真實踐教學平臺建設方案。提供一個基于UniSim工業軟件開發煉油化工領域全尺度仿真對象及其與控制算法進行實時通訊的方法。通過該方法,學生可以編寫控制算法并通過通信接口控制全尺度仿真對象,以驗證算法的可行性。搭建仿真教學平臺的基本步驟包括:第一步,在UniSim工業軟件環境下建立全尺度動態仿真對象;第二步,采用VB軟件讀取仿真對象的物性參數,特別是讀取被控變量和操作變量;第三步,開發集成了仿真對象物性參數的OPC服務器,實現與具有OPC客戶端功能的控制算法進行通訊。
二、全尺度動態仿真對象的開發
本文以原油常壓蒸餾工藝為例,在UniSim軟件平臺上通過設置流程的物性參數和時間尺度參數,搭建全仿真實踐教學平臺的動態仿真對象[4],主要步驟包括選擇物性包、選擇基本組分、對原油劃分虛擬組分、安裝物流和操作單元、檢查最終結果等。工藝流程中的操作單元主要包括預閃蒸、加熱爐、混合器和常壓蒸餾塔等,產品包括汽油、柴油等。具體操作請參考UniSim軟件使用指南,本文不再贅述。
三、全仿真對象物性參數的讀取
本文以VB讀取預閃蒸操作單元的數據為例,給出全仿真對象物性參數讀取方法,為OPC服務器開發提供數據源。讀取數據的步驟為:
第一步:建立VB開發環境與常壓蒸餾工藝模型之間的連接
啟動UniSim程序,打開常壓蒸餾工藝主流程圖。然后,在VB的菜單“工具”下“引用”中,選中“UniSim Type Library”,引入UniSim的類庫,然后聲明自動化對象,語法格式為:
Public unisimApp As UniSimDesign.Application
Public unisimCases As SimulationCases
Public unisimCase As SimulationCase
其中,Application對象代表了UniSim程序本身。SimulationCases代表了一個正在運行的UniSim程序中的所有模型案例,SimulationCase代表了其中的一個,后者是前者中的一個子案例。聲明自動化對象后,使用如下方法連接UniSim模型:
Set unisimApp = GetObject(,"UniSimdesign.Application")或
Set unisimApp = CreateObject("UniSimdesign.Application","192.168.1.1")
Set unisimCases = unisimApp.SimulationCases
Set unisimCase = unisimCases.Item(0)
其中,GetObject和CreateObject語句均可成功連接到UniSim模型。UniSimdesign.Application在這里指向的就是當前環境中正在運行的常壓蒸餾工藝主流程圖。若VB程序連接的流程圖在另外一臺計算機上,可以使用CreateObject語句,括號內逗號后的IP地址代表了局域網內運行了UniSim的計算機的地址。為了方便,將unisimCases聲明為程序中所有的案例集合,若只有一個運行的模擬案例,則該案例為集合中的第一個也是唯一一個,可用“.Item(0)”來指代和引用,若還有其他的案例則可依次類推進行聲明。
第二步:聲明預閃蒸操作單元
下面定義和聲明模型中的對象,包括模型的流程、物流集合、操作單元以及物流,語法格式為:
Public MainFlow As Flowsheet
Public SubFlow As Flowsheet
Public MainStream As Streams
Public SubStream As Streams
Set MainFlow = unisimCase.Flowsheet
Set SubFlow = MainFlow.Flowsheets(0)
Set MainStream = MainFlow.MaterialStreams
Set SubStream = SubFlow.MaterialStreams
本例中有兩個流程,MainFlow和SubFlow。MainFlow是主流程,定義為案例(SimulationCase)的Flowsheet,即流程;SubFlow為子流程,本例中為常壓塔的流程圖,可認為是主流程中的第一個子流程,用“.Flowsheets(0)”來聲明。主流程中的物流(MainStream)定義在主流程對象(MainFlow)中,子流程的物流(SubStream)定義在子流程對象(SubFlow)中,均用“.MaterialStreams”來聲明。在定義和聲明模型中對象的基礎上,下面定義預閃蒸操作單元。
Dim PreFlash As Object
Set PreFlash = MainFlow.Operations.Item(0)
預閃蒸(PreFlash)為主流程的Operations的第一個單元,用“.Item(0)”來聲明,類似的可以依次對第二個、第三個等單元進行對象聲明。
第三步:讀取預閃蒸操作單元的數據
基于第一步和第二步就可以讀取對象的數據了。由于每個對象所包含的屬性各不相同,有的包含有壓力、溫度數據,有的則是流量、壓降數據,所以在數據讀取的過程中需要進行區分,不同對象的不同參數值需要對應定義不同的變量,但是每個數據的讀取方法卻都是相同的。讀取預閃蒸操作單元的數據方法如下:
Text1.Text = PreFlash.VesselTemperature
Text2.Text = PreFlash.VesselPressure
Text3.Text = PreFlash.LiquidPercentLevelValue
讀取數據時在對象后用“.”加上所需要的屬性名即可,如上述的溫度(VesselTemperature)、壓力(VesselPressure)等。其他的操作單元和物流均與此相同,只是對應的屬性不一樣而已。
四、OPC服務器的開發
OPC服務器開發包括兩部分內容,分別是開發與預閃蒸操作單元數據連接的接口和開發OPC服務器標準接口。本文利用開發工具WtOPCServer.dll開發OPC服務器[5]。WtOPCServer.dll中封裝了COM和OPC規范等細節信息,只需要開發人員熟練地調用接口函數便可以完成OPC接口的開發。下面給出開發OPC服務器的步驟。
第一步:聲明函數
聲明開發工具中用于開發OPC服務器的函數,只有聲明成功后才可以在VB中使用這些函數。
(1)服務器初始化函數聲明
Declare Function InitWTOPCsvr Lib "WtOPCSvr" Alias "_InitWTOPCsvr@8" (ByRef CLSID_Svr As Byte,ByVal ServerRate As Long) As Long
實現DCOM的初始化并在計算機中創建OPC服務器對象。其中參數CLSID_Svr為OPC服務器的類標識(CLSID),用于計算機和OPC客戶端識別和連接服務器;參數ServerRate定義服務器的數據刷新速率,單位為毫秒。若該函數調用成功返回值為TRUE,否則為FALSE。
(2)服務器注冊函數聲明
Declare Function UpdateRegistry Lib "WtOPCSvr" Alias "_UpdateRegistry@16" (ByRef CLSID_Svr As Byte,ByRef Name As Byte,ByRef Descr As Byte,ByRef ExePath As Byte) As Long
(3)服務器注銷函數聲明
Declare Function UnregisterServer Lib "WtOPCSvr" Alias "_UnregisterServer@8" (ByRef CLSID_Svr As Byte,ByRef Name As Byte) As Long。
(4)標簽創建函數聲明
Declare Function CreateTag Lib "WtOPCSvr" Alias "_CreateTag@28" (ByRef Name As Byte,ByVal Value As Variant,ByVal InitialQuality As Integer,ByVal IsWritable As Long) As Long
作用是建立OPC服務器的過程標簽,Name為字符串,表明了所建標簽的名字,為服務器可接受的文本字符串;參數Value定義了標簽的初始值,為Variant類型;參數InitialQuality定義標簽的OPC品質屬性;參數IsWritable定義標簽是否可寫,可寫為TRUE,否則為FALSE。標簽創建成功會返回一個長整型值,為創建標簽的句柄值,是標簽的唯一識別值,在對標簽進行各種操作時起識別作用。
(4)標簽刪除函數聲明
Declare Function RemoveTag Lib "WtOPCSvr" Alias "_RemoveTag@4" (ByVal TagHandle As Long) As Long:。作用就是在服務器結束進程時將所創建的過程標簽刪除,TagHandle為創建標簽時所生成的句柄。
(5)標簽刷新函數聲明
Declare Function UpdateTag Lib "WtOPCSvr" Alias "_UpdateTag@24" (ByVal TagHandle As Long,ByVal Value As Variant,ByVal Quality As Integer) As Long
其作用是刷新過程標簽的數據值。參數TagHandle是句柄,由標簽創建函數在創建標簽時得到;參數Value為標簽要更新的值;參數Quality為標簽屬性條件。若函數調用成功返回值在為TRUE,否則返回FALSE。
(6)調用寫函數的函數聲明
Declare Function EnableWriteNotification Lib "WtOPCSvr" Alias "_EnableWriteNotification@8" (ByVal Callback As Long,ByVal ConvertToNative As Long) As Long
當用戶對服務器中標簽的數據進行寫操作時會觸發該函數,從而調用相應的寫函數完成該操作。
第二步:注冊服務器
利用第一步聲明的UpdateRegistry在計算機中注冊OPC服務器,以便OPC客戶端與其進行連接。
UpdateRegistry GUID(0),SerName(0),Desc(0),ExePath(0)
注意,UpdateRegistry函數的輸入值的類型為Byte,故在使用前要把各數據轉換為Byte類型。
GUID為全局唯一標示符,在Windows系統中稱為Class ID,即CLSID,是系統對不同應用程序分配的唯一的表示該程序的ID代碼,通常為一個128位的隨機數,在創建OPC服務器時需要人為定義一個CLSID,可以是任意的。在注冊成功后系統會將相關信息注冊至注冊表中。SerNam為創建的服務器的名字,Desc為服務器描述,ExePath為服務器的路徑。
第三步:初始化服務器
創建了服務器后還需要進行初始化才可以進行數據通信,初始化的主要作用是完成有關COM/DCOM的初始化,并且創建OPC服務器接口對象,使OPC客戶可順利連接到服務器。
InitWTOPCsvr GUID(0),1000
初始化通過GUID來識別服務器,這里設置其數據刷新速率為1000毫秒,也可根據具體的需要進行設置。
第四步:創建標簽
創建標簽用到上文聲明的標簽創建函數,語法格式為:
TagHandle(0) = CreateTag(TagName(0),Value,192,True)
TagHandle為當前創建的標簽的句柄,具有唯一性。TagName為標簽的名字,由用戶自行定義,需要注意的是這里TagName的數據類型為Byte。若標簽名定義為“##.%%”則函數會自動創建一個組,組名為“##”,組內包含了一個標簽,標簽名為“%%”,若再創建一個標簽為“##.$$”,則該標簽就會和前一個分在同一組下,標簽名為“$$”,這一性質為創建具有相關性的一組標簽提供了可行性,在UniSim模型中有許多標簽的數據來自同一個對象,利用該方法可以很好地將不同對象的標簽區別開,分組定義。Value為標簽的數據值,192表示當前標簽屬性為GOOD,True表示標簽可寫。
通過該語句就可以在服務器中創建標簽,對于一個UniSim模型,有大量的數據需要定義,本文在標簽的創建中用了以下方法,仍然以主流程的預閃蒸為例,創建其第一個屬性標簽。
Dim x As String
Dim y As Variant
Dim UniObj As Object
Set UniObj = MainFlow.Operations.Item(0)
x = "Main Flow." & UniObj & "." & "Vessel Temperature"
y = UniObj.VesselTemperature
TagHandle(0) = CreateTag(TagName(0),y,192,True)
程序定義了一個臨時對象UniObj,用來引用UniSim中的不同設備單元。x為字符串變量,通過上面的定義方法可以省去對每個對象一一定義的麻煩。
第五步:刷新標簽
標簽創建完成后需要對各個標簽進行刷新,保持數據值的實時更新,通常在定時器中調用標簽刷新函數來完成。
UpdateTag TagHandle(0),Value,192
TagHandle為標簽句柄,作用是為了識別標簽;Value為標簽數據值的刷新值;192依然是表明當前標簽的屬性為GOOD。與創建標簽時相同,刷新UniSim中的標簽數量巨大,本文使用了如下的方式,通過定義一個臨時對象變量來完成賦值。
Set UniObj = MainFlow.Operations.Item(0)
y = UniObj.VesselTemperature
UpdateTag TagHandle(0),y,192
第六步:注銷服務器
利用服務器進行通信完成后,需要關閉和注銷服務器。首先要刪除服務器創建的所有標簽,使用RemoveTag函數,其中的TagHandle為標簽句柄,對于有多個標簽的服務器來說可以使用循環語句刪除標簽。注銷使用UnregisterServer函數,GUID和SerName分別為服務器標示和名字。語法格式為:
RemoveTag TagHandle(0)
UnregisterServer GUID(0),SerName(0)
第七步:OPC服務器界面設計
服務器包括六個按鈕,在每個按鈕中通過調用函數實現相應的功能,包括注冊服務器、初始化服務器、連接UniSim、創建標簽、刷新標簽、注銷服務器。
五、實驗結果
本文設計的OPC服務器將UniSim模型的仿真數據制作為符合OPC通信標準的標簽,可由客戶端讀取。為了測試服務器運行情況,使用Matrikon OPC Explorer讀取服務器創建的數據標簽,讀取OPC服務器數據的結果。
六、結論
針對自動化專業本科生實踐教學環節中現場實習缺少實操訓練和實驗室實驗對象與工程設備不匹配的問題,探討了全尺度仿真實踐教學平臺的建設方法。基于該方法,學生可以根據實踐環節的具體需求,依托UniSim軟件搭建與工業實際生產裝置具有相同參數的仿真模型,用于產生全時間尺度的工藝數據。利用開發工具WtOPCServer.dll編寫OPC服務器程序,將仿真模型生成的工藝數據封裝為符合OPC通信標準的標簽數據。學生設計的帶有OPC客戶端的監控系統通過與OPC服務器通信,實現對生產裝置仿真模型的控制。本文給出實踐教學平臺建設方法極大地豐富了實踐教學內容,提高了學生操作實際生產裝置的能力。
參考文獻:
[1]李清泉.強化高校科技優勢轉化 提升高素質人才培養質量[J].中國高教研究,2011,(12):16-18.
[2]聶建英,羅雄麟,左信.自動化專業實踐教學基地建設研究[J].中國電力教育,2012,(15):80-82.
[3]張宏偉,張英琦,王新環.自動化專業校內外實踐基地建設與實踐教學改革[J].實驗室研究與探索,2013,32(11):448-451.
[4]朱玉杰.UniSim單元模型二次開發及外部通信研究[N].北京:中國石油大學(北京),2008.
[5]WinTECH Software Design.WTOPCSvr[Z].DLL User's Guide.