,
(昆明船舶設(shè)備研究試驗中心,昆明 650051)
數(shù)據(jù)采集系統(tǒng)包括硬件采集設(shè)備及配套軟件,硬件采集設(shè)備用于模擬信號到數(shù)字信號的轉(zhuǎn)換,配套軟件一般稱為“數(shù)據(jù)采集與處理軟件”,負責(zé)硬件設(shè)備的配置、控制及對轉(zhuǎn)換后數(shù)字信號的處理及終端顯示等。硬件采集設(shè)備的實現(xiàn)一般使用FPGA(field programmable gate array,現(xiàn)場可編程邏輯門陣列)+ADC(analog digital convert,模-數(shù)轉(zhuǎn)換器)的硬件平臺自主開發(fā),或直接選用市場通用產(chǎn)品。在市場產(chǎn)品中,美國NI(National Instruments)公司開發(fā)的DAQ系列硬件采集設(shè)備采用模塊化設(shè)計,用戶可針對不同項目自由選擇組合功能、性能各異的硬件模塊實現(xiàn)一套功能完整的硬件采集設(shè)備,使得在開發(fā)數(shù)據(jù)采集系統(tǒng)時,節(jié)約硬件開發(fā)時間,用戶只需著重考慮軟件部分的設(shè)計工作。
LabVIEW(Laboratory Virtual Instrument Engineering Work bench)是NI公司針對于該公司硬件采集產(chǎn)品配套開發(fā)的一種程序設(shè)計語言[2],LabVIEW編程語言可與NI公司的硬件采集設(shè)備無縫連接,實現(xiàn)采集硬件的實時配置、實時控制[3],同時LabVIEW具備高度封裝底層邏輯、圖形化編程方式、以數(shù)據(jù)流為導(dǎo)向、可實時插入過程監(jiān)視探針等特點,使得LabVIEW在測量與控制系統(tǒng)的開發(fā)中有著得天獨厚的優(yōu)勢[4]。
本文以實際項目為例,項目中硬件采集設(shè)備均使用市場上成熟的NI公司DAQ系列產(chǎn)品,項目開發(fā)的主要工作是軟件部分的開發(fā),本文具體闡述一種以LabVIEW編程語言設(shè)計實現(xiàn)的數(shù)據(jù)采集處理軟件的設(shè)計方法,該軟件的新穎之處在于既能滿足多個項目通用的數(shù)據(jù)采集功能,又能針對不同項目提供定制化的數(shù)據(jù)處理手段及針對性的終端顯示界面。
對于不同的數(shù)據(jù)采集項目,有著形態(tài)各異的前端傳感器,一般情況下,針對不同項目的需求,需要定制化設(shè)計數(shù)據(jù)采集系統(tǒng)[5]。如下圖所示,圖1中標示3個獨立的項目的開發(fā)內(nèi)容,在軟件開發(fā)部分,存在大量的重復(fù)工作,對于任意的一個數(shù)據(jù)采集軟件,均需要開發(fā)用戶界面、采集硬件控制、數(shù)據(jù)存儲、數(shù)據(jù)處理等功能,其中數(shù)據(jù)處理功能需要針對項目定制開發(fā)[6],例如溫度采集、聲信號采集、磁信號采集,軟件界面均需要顯示實時采集波形、頻譜等基礎(chǔ)數(shù)據(jù),而數(shù)據(jù)處理功能模塊就不能共用,溫、聲、磁有各自截然不同的數(shù)據(jù)處理方法。
圖1 不同項目的數(shù)據(jù)采集系統(tǒng)
為了提高軟件開發(fā)效率,整合各數(shù)據(jù)采集軟件可共用的通用功能(如圖1中的用戶界面、硬件控制、數(shù)據(jù)存儲),設(shè)計一個適用于大部分前端傳感器的“通用采集平臺”,負責(zé)通用的數(shù)據(jù)采集功能。對于不能通用的定制化代碼(例如圖1中針對“項目C”定制開發(fā)的“數(shù)據(jù)處理C”模塊),采用一種靈活的“插件”編程風(fēng)格,將定制化代碼設(shè)計成一種必須依托于“通用采集平臺”才能運行的“插件”,“插件”可以按需求動態(tài)加載到通用采集平臺中,這樣即實現(xiàn)了通用的數(shù)據(jù)采集功能,又滿足了針對特定項目的定制化開發(fā),這種設(shè)計方法如圖2所示。
圖2 通用數(shù)據(jù)采集平臺+插件的設(shè)計方式
圖2中,傳感器為任意的模擬量傳感器,NI-DAQ-X為NI公司的各型DAQ硬件采集設(shè)備。數(shù)據(jù)采集與處理軟件分為“通用采集平臺”及“定制化插件”兩部分,其中“通用采集平臺”一次開發(fā)成型后,對于不同的項目,只需進行極少的改動、甚至無需改動就可以使用,負責(zé)通用的數(shù)據(jù)采集功能;“定制化插件”需要根據(jù)項目定制化開發(fā),滿足特定項目的軟件功能需求。例如“定制化插件”內(nèi)的“插件C”就是針對“項目C”定制化開發(fā)的。簡單來說“通用采集平臺”實現(xiàn)了“數(shù)據(jù)采集與處理軟件”的“采集”功能,而“定制化插件”則負責(zé)實現(xiàn)“處理”功能。
“通用采集平臺”實現(xiàn)了適用于大部分模擬信號采集項目的基本數(shù)據(jù)采集功能,包括采集硬件配置、用戶操作響應(yīng)、信號采集、數(shù)據(jù)存儲、數(shù)據(jù)回放、圖形顯示界面等功能,具體實現(xiàn)上,本項目采用基于消息隊列的生產(chǎn)者消費者編程框架[7],該框架的多線程編程方式使得數(shù)據(jù)采集、數(shù)據(jù)存儲、圖形顯示等模塊化功能處于不同的線程并行運行,保證數(shù)據(jù)采集的實時性要求,限于篇幅,“通用采集平臺”的實現(xiàn)方法不作為本文重點,不再贅述。
“通用采集平臺”實現(xiàn)了各項目的通用采集需求,對于不同項目的特殊需求,開發(fā)針對性的定制化“插件”,同時在“通用采集平臺”上搭建一個通用接口,可調(diào)用所有的定制化“插件”,而且這種調(diào)用必須要能“動態(tài)”實現(xiàn),“動態(tài)”的意義在于針對不同項目調(diào)用加載不同“插件”,其他無關(guān)“插件”并不加載入內(nèi)存[8],更不會調(diào)用,避免隨著“插件”數(shù)量的增加軟件性能降低及內(nèi)存溢出。如圖3所示為接口設(shè)計的原理框圖,包括項目信息檢索、UI菜單初始化、用戶操作響應(yīng)、“插件”動態(tài)調(diào)用、消息隊列初始化等幾部分邏輯代碼功能塊。
圖3 接口實現(xiàn)原理框圖
總體上,“通用采集平臺”負責(zé)數(shù)據(jù)的采集,采集后的數(shù)據(jù)通過隊列的方式,傳輸?shù)脚c項目對應(yīng)的“插件”中,具體數(shù)據(jù)傳輸?shù)侥膫€項目、哪個“插件”,由用戶操作菜單選項指定,“插件”的工作方式由具體代碼決定,既可以是只在后臺運行的某種數(shù)據(jù)處理方法,也可以是在前臺運行可與用戶交互的窗口。
軟件啟動時,首先檢索項目信息,包括項目名與對應(yīng)“插件”資源位置等。具體實現(xiàn)方法上,將各項目的定制化代碼存放在特定文件夾(本項目使用“Dynamic vi”文件夾),文件夾下以項目名(例如“ProjectA”、“ProjectB”……)創(chuàng)建子文件夾存儲項目相關(guān)定制化代碼vi文件(LabVIEW的源代碼文件的后綴名為.vi,指代源代碼文件),項目名文件夾下的所有vi文件的集合既是對應(yīng)該項目的“插件”?!安寮钡娜肟趘i文件以“項目名-Main.vi”命名,文檔結(jié)構(gòu)如圖4所示。
圖4 項目文件結(jié)構(gòu)圖
程序初始化時,遍歷整個“Dynamic vi”文件夾,得到所有項目名及“插件”資源位置,遍歷算法的具體實現(xiàn)如圖5所示。值得一提的是,圖5中為了查找“Dynamic vi”的路徑,基路徑使用的是函數(shù)——“本vi路徑”提供的相對路徑,而沒有使用絕對路徑,這樣的好處在于代碼移植到其他計算機或文件夾下無需更改[9]。另外,在得到遍歷的項目名之后,對應(yīng)每一個項目名均創(chuàng)建了一個“通知器”,“通知器”可以簡單的理解為容量只有1的隊列,且數(shù)據(jù)為損耗式入隊(Lossy Enqueue),隊列滿時,不管隊列已有數(shù)據(jù)是否被讀取,強制將已有數(shù)據(jù)清除并將新數(shù)據(jù)入隊,這種數(shù)據(jù)入隊的方式好處是不會發(fā)生數(shù)據(jù)阻塞,保證線程之間的獨立性,本文中“通知器”與“隊列”意義相同,該“通知器”的使用在下文詳述。
圖5 遍歷算法及隊列初始化
軟件啟動時,默認運行在通用采集狀態(tài)下,需要針對項目定制化分析時,需要用戶指定用于哪個項目,也就是告知程序調(diào)用哪個“插件”。本項目通過UI(User Interface,用戶界面)菜單選項的方式提供給用戶操作接口[10],菜單的初始化是在程序啟動時動態(tài)完成的,菜單選項對應(yīng)項目名,項目名的來源由上文所述的遍歷檢索Dynamic vi文件夾得到。如圖6所示為軟件運行時用戶點擊菜單選擇項目的效果截圖,當(dāng)用戶點擊“定制化分析”菜單選項下面的“ProjectA”時,后臺程序就會調(diào)用項目對應(yīng)的“插件A”,準確來說是調(diào)用入口vi文件“ProjectA-Main.vi”,之后彈出該vi的前面板,也就實現(xiàn)了“ProjectA”的定制化分析及顯示功能。
圖6 點擊UI界面菜單選項效果截圖
軟件主UI使用菜單選項提供給了用戶操作接口,真正的設(shè)計重點在于后臺接收到用戶點擊菜單選項后如何實現(xiàn)“插件”的動態(tài)調(diào)用,具體實現(xiàn)方法上,使用“vi服務(wù)器”的動態(tài)加載技術(shù)?!皏i服務(wù)器”可實現(xiàn)前面板對象、vi和LabVIEW環(huán)境的動態(tài)控制,vi服務(wù)器的本質(zhì)是一套LabVIEW運行環(huán)境的底層管理函數(shù),如圖7所示為動態(tài)調(diào)用vi的關(guān)鍵代碼。
圖7 動態(tài)調(diào)用代碼實現(xiàn)
首先以用戶操作傳入的“項目名”為變量查找項目對應(yīng)的插件資源位置,之后使用系統(tǒng)自帶的“動態(tài)調(diào)用函數(shù)”調(diào)用該“插件”的入口vi文件。調(diào)用入口vi文件時,需要明確指定該vi的輸入變量“Notifier IN”,該變量是一個“通知器”的引用變量,表明了該vi從哪一個“通知器”讀取數(shù)據(jù)。程序初始化時會為每一個項目一一對應(yīng)創(chuàng)建與之相對應(yīng)的“通知器”,項目名即為“通知器”名,此處調(diào)用時,使用用戶操作傳入的“項目名”獲取對應(yīng)“通知器”的引用,再將該引用賦值給“Notifier IN”變量,也就指明了被動態(tài)調(diào)用的vi從哪一個“通知器”讀取數(shù)據(jù)。
“Notifier IN”變量的使用,根本上解決了“通用采集平臺”與“插件”之間數(shù)據(jù)交互的統(tǒng)一接口的問題,在“插件”代碼編寫時,預(yù)留“Notifier IN”輸入變量,此時該“插件”只知道從該變量對應(yīng)的“通知器”中去讀取數(shù)據(jù),而不知道具體是哪個,用戶操作選擇特定項目時,“Notifier IN”變量被賦值為與項目對應(yīng)的“通知器”引用,“插件”這時才確切知道從哪里讀數(shù)據(jù)。在“通用采集平臺”中,默認工作模式下,“通知器”并不工作,用戶操作選擇特定項目時,“通用采集平臺”才啟用項目對應(yīng)的“通知器”并向其中寫數(shù)據(jù),損耗性入隊(Lossy Enqueue)的寫數(shù)據(jù)方式保證了“通用采集平臺”與“插件”的獨立性,就算“插件”異常也不影響“通用采集平臺”的正常工作,否則可能發(fā)生消息堵塞??梢姡安寮迸c“通用采集平臺”之間是相互獨立的,“通用采集平臺”可獨立運行在默認的通用采集模式下,而“插件”必須依托于“通用采集平臺”才能正常工作,他們之間在用戶操作時才建立起聯(lián)系。
另一個需要考慮的問題是對不同項目使用硬件采集設(shè)備的實時動態(tài)配置。由于NI公司提供了功能強大的硬件驅(qū)動,在LabVIEW軟件端實現(xiàn)硬件的控制較為簡便,驅(qū)動提供了LabVIEW自動識別系統(tǒng)中已連接設(shè)備的功能,還提供了詳盡的硬件操作接口,例如“打開硬件資源”、“讀取數(shù)據(jù)”、“重啟設(shè)備”等。具體軟件設(shè)計上,設(shè)計獨立的模態(tài)窗口用于用戶操作配置硬件,采集開始前用戶必須自行配置硬件參數(shù),例如“采樣率”、“采樣電壓范圍”、“存盤路徑”等必要參數(shù),配置信息具有自動存儲功能,下次啟動軟件時默認參數(shù)為上一次配置參數(shù),如圖8為硬件配置窗口,包括數(shù)據(jù)輸入配置選項及數(shù)據(jù)輸出配置選項,當(dāng)系統(tǒng)沒有連接實際硬件設(shè)備時,可配置為虛擬硬件,用于軟硬件調(diào)試。
圖8 硬件配置窗口
本文所述的軟件設(shè)計方法,主要是為了解決代碼的復(fù)用性問題,提高項目開發(fā)效率。對于文本編程序言,可以通過評估復(fù)用代碼的行數(shù)在總代碼行數(shù)中的占比來衡量代碼的復(fù)用性。
對于LabVIEW這種圖形化編程語言,很難嚴格的量化代碼量,一種方法是將vi數(shù)量理解為代碼量,不過,每個vi的功能不盡相同,規(guī)模也各不相同,單個用戶vi的規(guī)模并沒有定性規(guī)定,完全隨工程師的個人編程習(xí)慣,就算對于同一個工程師編寫的程序,這種方法也只是一種大概的估算;另外還可用vi的nodes來評估代碼規(guī)模,nodes可以簡單理解為LabVIEW代碼中的輸入輸出節(jié)點的總數(shù)量,節(jié)點的概念可簡單理解為輸入輸出接口,例如簡單的加法運算包括2個輸入節(jié)點,1個輸出節(jié)點,LabVIEW中自帶的底層vi的節(jié)點數(shù)是固定的,而大部分用戶vi可分解為各種底層vi,這種方法相對更客觀。
如圖9所示,從左到右分別是項目主vi(Main.vi,簡稱Main)、“插件A”的入口vi(ProjectA-Main.vi,簡稱PA)、“插件B”的入口vi(ProjecB-Main.vi,簡稱PB)的子vi調(diào)用數(shù)和總nodes。其中“插件A”的代碼較復(fù)雜,“插件B”的代碼相對簡單,Main是“通用采集平臺”的主vi,簡單認為“通用采集平臺”的所有代碼均是可復(fù)用的。
圖9 調(diào)用子vi及nodes統(tǒng)計
在表1中,簡明展示了Main、PA、PB調(diào)用的子vi、庫函數(shù)vi的數(shù)量,及Total Nodes(總節(jié)點數(shù)),這些統(tǒng)計量一定程度反應(yīng)了各自vi的代碼量,而Main的代碼量占某個總代碼量的比例,也一定程度上反應(yīng)了代碼的復(fù)用程度(占比越高,說明可復(fù)用的Main占項目代碼量較多,代碼復(fù)用性越好)。
表1 Main、PA、PB估算代碼量及占比
本文提出了一種以“通用采集平臺”為基礎(chǔ)、采用插件式編程模式實現(xiàn)針對項目定制化的“數(shù)據(jù)采集與處理軟件”的設(shè)計方法,并給出了重要的代碼的實現(xiàn)方法。使用該方法實現(xiàn)的“數(shù)據(jù)采集與處理軟件”既有通用化采集軟件的實用性,又可滿足了特定任務(wù)的定制化需求。在項目開發(fā)上,由于“通用采集平臺”的通用化設(shè)計,極大的提高了代碼的復(fù)用性,使得該設(shè)計模式具有較大的實用價值。