謝道旺 何嶺松 高志強(qiáng)
摘 要:測(cè)量技術(shù)對(duì)測(cè)量系統(tǒng)的需求具有多變性,在將手機(jī)作為手持便攜式測(cè)量設(shè)備的應(yīng)用背景下,手機(jī)APP傳統(tǒng)通過安裝包升級(jí)實(shí)現(xiàn)功能更改的方式不利于測(cè)量任務(wù)的快速展開。為了突破這一限制,對(duì)測(cè)量系統(tǒng)進(jìn)行平臺(tái)化開發(fā)。在測(cè)量系統(tǒng)平臺(tái)上,提供一系列可復(fù)用的虛擬儀器控件,并允許第三方控件以插件形式加載進(jìn)來。基于響應(yīng)式編程,提出一種響應(yīng)式數(shù)據(jù)端口變量以及一種響應(yīng)式控件通訊架構(gòu)。設(shè)計(jì)響應(yīng)式編程腳本,平臺(tái)通過加載該腳本語言寫成的頁面腳本即可生成一個(gè)虛擬儀器頁面。編程腳本功能分為兩部分:一是聲明虛擬儀器控件并為其傳遞運(yùn)行參數(shù),二是描述控件間的數(shù)據(jù)響應(yīng)關(guān)系。通過采用響應(yīng)式編程方法,可以直接、清晰地描述控件之間的復(fù)雜數(shù)據(jù)響應(yīng)關(guān)系。
關(guān)鍵詞:虛擬儀器:響應(yīng)式編程;動(dòng)態(tài)可重構(gòu);測(cè)量技術(shù)
DOI: 10. 11907/rjdk.191197
開放科學(xué)(資源服務(wù))標(biāo)識(shí)碼(OSID):
中圖分類號(hào):TP319
文獻(xiàn)標(biāo)識(shí)碼:A
文章編號(hào):1672-7800(2020)001-0123-07
0 引言
虛擬儀器技術(shù)是測(cè)量技術(shù)與計(jì)算機(jī)技術(shù)相融合而產(chǎn)生的一門技術(shù)[1],是指通過將傳統(tǒng)硬件測(cè)量儀器軟件化,從而提高測(cè)量任務(wù)開展的方便性與靈活性,并降低測(cè)量成本。傳統(tǒng)基于PC的虛擬儀器發(fā)展已十分成熟,并且在各行業(yè)得到了廣泛應(yīng)用[2-5]。
隨著移動(dòng)互聯(lián)網(wǎng)的迅速發(fā)展,智能手機(jī)已經(jīng)十分普及,而且隨著智能手機(jī)硬件性能越來越強(qiáng)大,使得在智能手機(jī)終端開展測(cè)量任務(wù)成為可能。目前已有不少學(xué)者對(duì)使用手機(jī)開展測(cè)量任務(wù)進(jìn)行了研究與探討[6-12],在實(shí)際應(yīng)用中也已有不少案例實(shí)現(xiàn)了通過手機(jī)開展測(cè)量任務(wù),例如應(yīng)用商店中的噪音測(cè)量儀、指南針以及振動(dòng)測(cè)試儀器等。由于智能手機(jī)的便攜性,以及智能手機(jī)本身集成有藍(lán)牙、WiFi等無線傳輸方式,使得在智能手機(jī)上開展測(cè)量任務(wù)相比PC更加靈活與便捷。
測(cè)量任務(wù)對(duì)虛擬儀器程序的需求是多變、動(dòng)態(tài)的,程序固化的虛擬儀器將難以滿足實(shí)際測(cè)量需求。如果針對(duì)不同測(cè)量任務(wù)都開發(fā)不同APP,則工作量過大,用戶往往也接受不了太多APP的下載安裝。實(shí)際上,不同測(cè)量程序所需的部分功能模塊是可以復(fù)用的,在不同測(cè)量任務(wù)中只需對(duì)這些模塊進(jìn)行動(dòng)態(tài)調(diào)整即可。
在手機(jī)APP開發(fā)領(lǐng)域,為了應(yīng)對(duì)這種多變、動(dòng)態(tài)的業(yè)務(wù)場(chǎng)景,通常采用一種“平臺(tái)化”開發(fā)方法。例如Facbook的React Native[3]、阿里巴巴的Weex[4]等,都將APP作為一個(gè)系統(tǒng)級(jí)別的平臺(tái),然后通過編寫JS腳本的方式開發(fā)APP業(yè)務(wù)功能。由于APP的業(yè)務(wù)功能是通過加載腳本形式執(zhí)行的,因此在該平臺(tái)下可以通過在線下載腳本與資源實(shí)現(xiàn)業(yè)務(wù)功能的動(dòng)態(tài)更改,而無需更新APP。目前受到廣泛關(guān)注的小程序,也是基于相同思想。
本文提出的手機(jī)可重構(gòu)虛擬儀器也是順應(yīng)“平臺(tái)化”思想,在平臺(tái)上提供一系列常用的測(cè)量模塊控件,然后通過撰寫腳本的形式即可將這些控件有機(jī)組織起來,從而滿足不同的測(cè)量任務(wù)需求。對(duì)于平臺(tái)內(nèi)控件無法滿足的測(cè)量需求,第三方可以自行開發(fā)控件,通過插件形式加載到平臺(tái)內(nèi)。通過該解決方案,在安卓平臺(tái)上實(shí)現(xiàn)了虛擬儀器的動(dòng)態(tài)可重構(gòu),并可通過網(wǎng)絡(luò)遠(yuǎn)程下載腳本的方式實(shí)現(xiàn)虛擬儀器實(shí)例的獲取與更新。
響應(yīng)式編程( Reactive Programming,RP)是為了實(shí)現(xiàn)復(fù)雜的事件響應(yīng)系統(tǒng)而提出的一種編程思想[15],目的是簡化復(fù)雜事件響應(yīng)系統(tǒng)的開發(fā),從而避免“回調(diào)地獄”的繁瑣。響應(yīng)式編程是一種聲明式編程,其本質(zhì)上是對(duì)觀察者模式的高度封裝。例如在響應(yīng)式編程下編寫“a≥b+c”,并不是對(duì)a進(jìn)行賦值操作,而是進(jìn)行一種數(shù)據(jù)響應(yīng)關(guān)系的聲明。當(dāng)b或c的值發(fā)生變化時(shí),a值也會(huì)隨之發(fā)生變化,并保證a等于b加c的值。響應(yīng)式編程實(shí)現(xiàn)的主要方式是:搭建一種響應(yīng)式程序框架,然后通過一些簡單的API或自定義腳本語言即可搭建出復(fù)雜的事件響應(yīng)系統(tǒng)。響應(yīng)式編程在不少領(lǐng)域已經(jīng)得到了成功應(yīng)用[16-20]。虛擬儀器的軟件部分本質(zhì)上也是一個(gè)事件響應(yīng)系統(tǒng),虛擬儀器內(nèi)部控件產(chǎn)生數(shù)據(jù)事件,與數(shù)據(jù)有聯(lián)系的控件作出相應(yīng)響應(yīng)。本文將響應(yīng)式編程應(yīng)用到虛擬儀器上,在簡化虛擬儀器控件通訊模型的同時(shí),也增強(qiáng)了虛擬儀器控件間復(fù)雜數(shù)據(jù)關(guān)系的動(dòng)態(tài)重構(gòu)能力。
1 手機(jī)可重構(gòu)虛擬儀器總體設(shè)計(jì)原理
雖然測(cè)試系統(tǒng)的程序是多變的,但是系統(tǒng)包含的各種功能模塊往往是類似的,可以將這些功能模塊抽象為標(biāo)準(zhǔn)化的儀器控件,并對(duì)其進(jìn)行復(fù)用。將測(cè)試系統(tǒng)常用功能模塊封裝成一系列標(biāo)準(zhǔn)化控件,形成一個(gè)虛擬儀器控件庫,在虛擬儀器平臺(tái)上提供給用戶使用。這些控件主要包含4大類,分別是:控制類控件(如按鈕開關(guān)、旋鈕等)、顯示類控件(如波形顯示控件、儀表盤、棒圖等)、數(shù)據(jù)處理類控件(如快速傅里葉、濾波、自相關(guān)等)以及硬件類控件(如各種數(shù)據(jù)采集硬件、通訊控件等)。用戶在進(jìn)行虛擬儀器開發(fā)時(shí),只需合理地將這些控件組織起來,便可實(shí)現(xiàn)大部分功能需求。對(duì)于控件庫滿足不了的功能需求,可以自行開發(fā)符合儀器控件標(biāo)準(zhǔn)的控件并加載進(jìn)平臺(tái)使用。
手機(jī)可重構(gòu)虛擬儀器總體設(shè)計(jì)原理如圖1所示。儀器控件組織過程便是虛擬儀器重構(gòu)過程.對(duì)儀器控件的組織包括兩方面,一是儀器控件布局,二是儀器控件之間的數(shù)據(jù)響應(yīng)關(guān)系。通過以上兩方面對(duì)儀器控件進(jìn)行組織,便可將儀器控件融合為一個(gè)有機(jī)整體,得到一個(gè)可運(yùn)行的虛擬儀器頁面。
2 響應(yīng)式設(shè)計(jì)
2.1 響應(yīng)式數(shù)據(jù)端口變量
分析響應(yīng)式編程的實(shí)現(xiàn),最根本的要求是當(dāng)變量值發(fā)生改變時(shí),系統(tǒng)需要感知到數(shù)據(jù)改變事件的發(fā)生。在An-droid的開發(fā)語言Java中,數(shù)據(jù)變量類型并不存在這種特性,因此需要設(shè)計(jì)一種存在該特性且符合虛擬儀器控件之間通訊需求的變量類型。
響應(yīng)式數(shù)據(jù)端口變量模型如圖2所示。響應(yīng)式數(shù)據(jù)端口把基本數(shù)據(jù)類型封裝到一層,便于進(jìn)行管理。將虛擬儀器可能使用的數(shù)據(jù)類型都考慮進(jìn)來,封裝一系列數(shù)據(jù)類型,得到一系列數(shù)據(jù)類型的響應(yīng)式數(shù)據(jù)端口。封裝的數(shù)據(jù)類型包括Java的9種基本數(shù)據(jù)類型及其數(shù)組和二維數(shù)組,基本可以覆蓋所有虛擬儀器需要使用的數(shù)據(jù)類型。例如開關(guān)變量用到的boolean類型、信號(hào)數(shù)據(jù)用到的float數(shù)組和double數(shù)組、信息顯示用到的String類型、參數(shù)配置和類型選擇用到的int類型以及圖像信號(hào)用到的int二維數(shù)組等,這些數(shù)據(jù)類型都被響應(yīng)式數(shù)據(jù)端口的數(shù)據(jù)類型所覆蓋。
在響應(yīng)式數(shù)據(jù)端口主要屬性中,有數(shù)據(jù)類型( DataType)、端口類型(PortType)、控件ID( Controlld)以及端口名( PortName)。響應(yīng)式數(shù)據(jù)端口的核心接口有兩個(gè),分別是getData接口和setD ata接口。最核心的設(shè)計(jì)是:在setData接口被調(diào)用時(shí),除內(nèi)部數(shù)據(jù)被改變外,還會(huì)自動(dòng)向系統(tǒng)發(fā)送數(shù)據(jù)改變事件。這里需要說明的是,本文所說的“發(fā)生數(shù)據(jù)改變”并不是指數(shù)據(jù)本身一定真的改變了,而是指setData接口被調(diào)用,數(shù)據(jù)被“試圖改變”,產(chǎn)生了數(shù)據(jù)流。
考慮到虛擬儀器控件在實(shí)際使用這些響應(yīng)式數(shù)據(jù)端口時(shí),會(huì)按用途分為輸入端口與輸出端口,并且這兩種數(shù)據(jù)端口有不同行為特征,因此設(shè)置了一個(gè)屬性表征數(shù)據(jù)端口類型。當(dāng)控件獲取這些響應(yīng)式數(shù)據(jù)端口時(shí),需要表明控件本身的ID、端口名以及端口類型。
2.2 虛擬儀器控件模型
響應(yīng)式架構(gòu)下的儀虛擬器控件模型如圖3所示??丶鶕?jù)自身業(yè)務(wù)的數(shù)據(jù)通訊需要持有一些響應(yīng)式數(shù)據(jù)端口,并明確劃分出哪些是輸入端口,哪些是輸出端口??丶枰獙?shí)現(xiàn)的主要接口為數(shù)據(jù)響應(yīng)接口,該接口通過參數(shù)傳遞數(shù)據(jù)發(fā)生改變的數(shù)據(jù)端口名給控件。當(dāng)輸入數(shù)據(jù)端口的數(shù)據(jù)改變時(shí),即表明有數(shù)據(jù)流流入,此時(shí)系統(tǒng)會(huì)自動(dòng)調(diào)用控件的數(shù)據(jù)響應(yīng)接口,通過該接口觸發(fā)控件自身業(yè)務(wù)的運(yùn)行。業(yè)務(wù)運(yùn)行完成后,假設(shè)需要輸出結(jié)果,可以直接通過輸出端口進(jìn)行輸出。例如控制類控件、信號(hào)采集類控件等一些控件會(huì)有自主數(shù)據(jù)源,當(dāng)有新數(shù)據(jù)產(chǎn)生時(shí),直接通過輸出端口輸出即可。
圖4為一個(gè)FFT(快速傅里葉)控件示意圖,該控件持有1個(gè)輸入端口、3個(gè)輸出端口。輸入端口輸入信號(hào)數(shù)據(jù)數(shù)組,3個(gè)輸出端口分別輸出信號(hào)經(jīng)過FFT處理后得到的實(shí)部數(shù)組、虛部數(shù)組和幅值數(shù)組。其在數(shù)據(jù)響應(yīng)接口中實(shí)現(xiàn)的邏輯為:當(dāng)有新信號(hào)輸入時(shí),對(duì)輸入數(shù)據(jù)進(jìn)行FFT處理,并對(duì)處理結(jié)果進(jìn)行輸出。
又比如一個(gè)旋鈕控件,其只有唯一一個(gè)數(shù)據(jù)端口,也即旋鈕數(shù)值輸出端口,控件只需在旋鈕值發(fā)生改變時(shí)將新的旋鈕值輸送到該數(shù)據(jù)端口即可。
2.3 響應(yīng)式控件通訊架構(gòu)
虛擬儀器可以被歸結(jié)為一個(gè)數(shù)據(jù)流驅(qū)動(dòng)的響應(yīng)系統(tǒng),當(dāng)某個(gè)控件數(shù)據(jù)發(fā)生變化時(shí),變化會(huì)被傳播到與之相聯(lián)系的控件,控件會(huì)根據(jù)數(shù)據(jù)變化作出響應(yīng)。對(duì)于某些控件,可能會(huì)出現(xiàn)類似屏幕單擊事件之類的非數(shù)據(jù)事件,但此類事件也會(huì)轉(zhuǎn)換為數(shù)據(jù)變化事件驅(qū)動(dòng)虛擬儀器運(yùn)行。例如對(duì)一個(gè)開關(guān)按鈕的點(diǎn)擊會(huì)改變其代表開關(guān)狀態(tài)的變量,然后再由該變量值改變事件驅(qū)動(dòng)虛擬儀器運(yùn)行。這種非數(shù)據(jù)事件會(huì)被固定在單獨(dú)的控件上,在虛擬儀器重構(gòu)層面只需關(guān)心數(shù)據(jù)事件的響應(yīng)關(guān)系。
響應(yīng)式控件通訊架構(gòu)如圖5所示,框架主要組成部分包括響應(yīng)式數(shù)據(jù)端口、虛擬儀器控件和響應(yīng)式內(nèi)核??丶钟械捻憫?yīng)式數(shù)據(jù)端口需要注冊(cè)到響應(yīng)式內(nèi)核中,由響應(yīng)式內(nèi)核進(jìn)行管理。
響應(yīng)式編程腳本則負(fù)責(zé)構(gòu)建這些數(shù)據(jù)端口的數(shù)據(jù)關(guān)系,可以通過編程方式靈活地實(shí)現(xiàn)數(shù)據(jù)關(guān)系創(chuàng)建。每個(gè)數(shù)據(jù)端口可以映射成為一個(gè)數(shù)據(jù)變量,在響應(yīng)式編程腳本中可以將數(shù)據(jù)變量映射到這些數(shù)據(jù)端口上,然后使用這些變量進(jìn)行響應(yīng)式編程,也即聲明式編程,并對(duì)這些變量之間的數(shù)據(jù)關(guān)系進(jìn)行聲明。通過解釋執(zhí)行響應(yīng)式編程腳本,將編程腳本描述的數(shù)據(jù)端口之間的數(shù)據(jù)關(guān)系通過特定數(shù)據(jù)結(jié)構(gòu)保存下來。當(dāng)響應(yīng)式內(nèi)核感知到端口數(shù)據(jù)改變事件時(shí),響應(yīng)式內(nèi)核會(huì)對(duì)其進(jìn)行實(shí)時(shí)處理,以保證經(jīng)過處理之后數(shù)據(jù)端口之間滿足編程腳本所聲明的數(shù)據(jù)關(guān)系。
虛擬儀器系統(tǒng)除要保證這些數(shù)據(jù)端口之間滿足特定數(shù)據(jù)關(guān)系外,還需要控件在數(shù)據(jù)輸入端口發(fā)生數(shù)據(jù)改變時(shí)作出響應(yīng),從而驅(qū)動(dòng)虛擬儀器運(yùn)行。因此,這些控件也需要被注冊(cè)到響應(yīng)式內(nèi)核中,由響應(yīng)式內(nèi)核進(jìn)行管理。這些控件需要統(tǒng)一實(shí)現(xiàn)一些標(biāo)準(zhǔn)接口,以便內(nèi)核對(duì)控件進(jìn)行運(yùn)行調(diào)度,其中最重要的接口即是數(shù)據(jù)響應(yīng)接口。對(duì)于被注冊(cè)到響應(yīng)式內(nèi)核的控件,當(dāng)其數(shù)據(jù)輸入端口數(shù)據(jù)發(fā)生改變時(shí),控件的數(shù)據(jù)響應(yīng)接口便會(huì)被響應(yīng)式內(nèi)核調(diào)用。
在這種架構(gòu)設(shè)計(jì)下,對(duì)于控件開發(fā)者而言,在開發(fā)普通控件的基礎(chǔ)上,要想開發(fā)出適配該架構(gòu)的控件,只需根據(jù)通訊需要持有一些響應(yīng)式數(shù)據(jù)端口,然后使用這些數(shù)據(jù)端口進(jìn)行通訊即可;對(duì)于虛擬儀器使用者而言,只需通過一些簡單的聲明式編程便可將快速搭建虛擬儀器,從而實(shí)現(xiàn)將更多工作交由系統(tǒng)處理,簡化了開發(fā)者和使用者工作,契合IT開發(fā)的整體發(fā)展趨勢(shì)。
3 響應(yīng)式編程腳本
3.1 響應(yīng)式編程腳本設(shè)計(jì)
本文的響應(yīng)式編程腳本是一種針對(duì)虛擬儀器重構(gòu)任務(wù)設(shè)計(jì)的領(lǐng)域特定語言。本腳本語言設(shè)計(jì)目標(biāo)是使虛擬儀器使用者能快速按照自己的意圖實(shí)現(xiàn)虛擬儀器搭建。由于虛擬儀器使用者的編程水平可能有限,因此語法設(shè)計(jì)應(yīng)該盡量從簡。
響應(yīng)式編程腳本總體設(shè)計(jì)如圖7所示。為了使編程語法簡單明了,使用者容易上手,將腳本劃分為3大部分,分別為變量區(qū)、函數(shù)定義區(qū)以及關(guān)系聲明區(qū)。
變量區(qū)的主要作用是實(shí)例化儀器控件,并用變量把控件實(shí)例和數(shù)據(jù)端口的引用保存下來,方便后續(xù)使用。在實(shí)例化控件時(shí),通過參數(shù)列表為其傳遞運(yùn)行參數(shù),這些參數(shù)包括儀器控件本身所需的運(yùn)行參數(shù)和布局參數(shù)。如語句“varNamel=ControlName( paraml,param2,…)”是實(shí)例化一個(gè)控件名稱為“ControIName”的控件,并將其引用賦值到變量“varNamel";語句“varName4= varName2.portNane"是將控件“varName2”端口名為“portName”的數(shù)據(jù)端口引用賦值到變量“varName4”;語句“varName5=dataType(contor-lId,portName)”將數(shù)據(jù)類型為“dataType”、控件ID為“con-torlld”、端口名為“portName”的數(shù)據(jù)端口引用賦值到變量“varName5”??丶蘒D和端口名構(gòu)成的二元組可以唯一確定一個(gè)響應(yīng)式數(shù)據(jù)端口,若指定的數(shù)據(jù)端口不存在,或數(shù)據(jù)端口的數(shù)據(jù)類型與“dataType”不一致,將會(huì)報(bào)錯(cuò)。
在函數(shù)定義區(qū)定義一些函數(shù),這些函數(shù)可以被用于實(shí)現(xiàn)數(shù)據(jù)端口之間的函數(shù)綁定關(guān)系。
在關(guān)系聲明區(qū)聲明數(shù)據(jù)端口之間的數(shù)據(jù)綁定關(guān)系。如腳本中的“varName2.portNamel->varNamel.portNamel",是聲明簡單的數(shù)據(jù)端口之間一對(duì)一的綁定關(guān)系;腳本中的“varName3.porNamel=>varName4+ varName5",是聲明數(shù)據(jù)端口之間一對(duì)多的表達(dá)式綁定關(guān)系。為了方便直接通過表達(dá)式表達(dá)較復(fù)雜的數(shù)據(jù)關(guān)系,該表達(dá)式除支持單值的四則運(yùn)算外,還需要支持?jǐn)?shù)組之間的運(yùn)算以及單值與數(shù)組之間的混合運(yùn)算,并內(nèi)置一些常用函數(shù)。然而,表達(dá)式對(duì)數(shù)據(jù)關(guān)系的描述能力終究是有限的,因此為了支持更復(fù)雜的數(shù)據(jù)關(guān)系描述,該腳本還支持?jǐn)?shù)據(jù)端口之間一對(duì)多的函數(shù)綁定關(guān)系。如腳本中的“varName3.portName2=>>fun-Name( varName4,varName5)”,是聲明數(shù)據(jù)端口之間一對(duì)多的函數(shù)綁定關(guān)系,具體數(shù)據(jù)關(guān)系可以在函數(shù)里定義。
數(shù)據(jù)綁定規(guī)則為:綁定公式左邊對(duì)象是要綁定的對(duì)象,右邊對(duì)象是綁定的目標(biāo)對(duì)象,要綁定的變量所映射的數(shù)據(jù)端口必須是輸入端口。對(duì)于變量對(duì)變量的直接綁定,右邊變量所映射的數(shù)據(jù)端口必須是輸出端口,數(shù)據(jù)類型與左邊變量必須一致。對(duì)于表達(dá)式綁定,右邊表達(dá)式包含變量所映射的數(shù)據(jù)端口必須是輸出端口,表達(dá)式的運(yùn)行結(jié)果數(shù)據(jù)類型必須與左邊變量數(shù)據(jù)類型一致。對(duì)于函數(shù)關(guān)系綁定,函數(shù)實(shí)參列表包含變量所映射的數(shù)據(jù)端口必須是輸出端口,函數(shù)返回值類型與左邊變量數(shù)據(jù)類型需要一致。
3.2 響應(yīng)式編程腳本實(shí)現(xiàn)
3.2.1 數(shù)據(jù)端口一對(duì)一綁定
對(duì)于數(shù)據(jù)端口一對(duì)一綁定,以下分為響應(yīng)式內(nèi)核端與腳本解釋器端兩方面進(jìn)行說明。
在響應(yīng)式內(nèi)核端,維護(hù)如圖8所示的一個(gè)Map數(shù)據(jù)結(jié)構(gòu),Map里的Key為輸出端口,Value綁定到該端口的輸入端口集合。當(dāng)某個(gè)輸出端口數(shù)據(jù)發(fā)生改變時(shí),需要迅速查找到與其綁定的輸入端口集,因此這里使用Map數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)綁定關(guān)系。當(dāng)虛擬儀器內(nèi)發(fā)生輸出數(shù)據(jù)端口的數(shù)據(jù)改變事件時(shí),響應(yīng)式內(nèi)核根據(jù)該數(shù)據(jù)端口查詢到與其綁定的輸入端口集合,然后對(duì)集合進(jìn)行遍歷,依次調(diào)用每個(gè)數(shù)據(jù)端口的設(shè)置值函數(shù),使其數(shù)據(jù)值等于與其綁定的端口,并調(diào)用其所屬控件的數(shù)據(jù)響應(yīng)接口。通過以上步驟,便可實(shí)現(xiàn)一種深度優(yōu)先的數(shù)據(jù)流驅(qū)動(dòng)運(yùn)行模式。
在腳本解釋器端,有了上文所述的Map數(shù)據(jù)結(jié)構(gòu),實(shí)現(xiàn)數(shù)據(jù)端口一對(duì)一直接綁定的思路則變得很清晰。在腳本運(yùn)行時(shí),首先查詢到綁定目標(biāo)對(duì)象所映射的數(shù)據(jù)端口,接著在綁定關(guān)系Map里查詢到其綁定端口集合,然后查詢綁定對(duì)象所映射的數(shù)據(jù)端口,將其添加到綁定端口集合即可。
3.2.2 數(shù)據(jù)端口表達(dá)式綁定關(guān)系
將表達(dá)式映射成一種通用的表達(dá)式控件,總體方案如圖9所示。該控件在后臺(tái)工作,不在屏幕顯示。表達(dá)式控件將表達(dá)式的抽象語法樹保存下來,表達(dá)式控件本身持有數(shù)據(jù)輸入與輸出端口,但數(shù)據(jù)端口的數(shù)目與類型不是固定的。在該表達(dá)式控件的響應(yīng)接口中,從數(shù)據(jù)輸入端口獲取數(shù)據(jù)作為表達(dá)式變量值,通過表達(dá)式引擎執(zhí)行表達(dá)式控件保存的語法樹,并將執(zhí)行結(jié)果通過輸出端口輸出。
腳本解釋器運(yùn)行時(shí),通過分析表達(dá)式所引用的數(shù)據(jù)端口,可以得出表達(dá)式所包含的變量數(shù)目與類型,從而確定表達(dá)式控件輸入端口的數(shù)目與類型;然后再通過分析表達(dá)式的運(yùn)算結(jié)果類型,確定輸出端口類型;將表達(dá)式控件的輸入端口綁定到表達(dá)式所包含變量映射的數(shù)據(jù)端口,再將綁定到表達(dá)式的數(shù)據(jù)端口綁定到該控件的輸出端口即可。
3.2.3 數(shù)據(jù)端口函數(shù)綁定關(guān)系
腳本里包含的函數(shù)是為了借助通用編程語言的表達(dá)能力,實(shí)現(xiàn)更復(fù)雜的數(shù)據(jù)綁定。因此,假設(shè)自己設(shè)計(jì)該部分語言,需要實(shí)現(xiàn)一種通用語言的設(shè)計(jì)及其編譯器,工作量將十分巨大,而且無法調(diào)用已有函數(shù)。因此,本文編程腳本的函數(shù)部分選擇內(nèi)嵌Java函數(shù)的方式實(shí)現(xiàn)。
Java是一門動(dòng)態(tài)性極高的語言,可以實(shí)現(xiàn)動(dòng)態(tài)編譯。動(dòng)態(tài)編譯是指在代碼運(yùn)行過程中直接編譯一段代碼并將其加載進(jìn)來運(yùn)行,實(shí)現(xiàn)所謂的“on the fly”。
針對(duì)基于Java的動(dòng)態(tài)編譯技術(shù),本文對(duì)于函數(shù)綁定關(guān)系的實(shí)現(xiàn)思路如圖10所示。在腳本解釋器運(yùn)行時(shí),通過對(duì)Java函數(shù)的函數(shù)頭進(jìn)行語義分析,動(dòng)態(tài)生成一個(gè)與函數(shù)對(duì)應(yīng)的函數(shù)控件類代碼,每個(gè)函數(shù)對(duì)應(yīng)一個(gè)函數(shù)控件類,并通過動(dòng)態(tài)編譯加載到系統(tǒng)運(yùn)行。函數(shù)控件的輸入數(shù)據(jù)端口對(duì)應(yīng)函數(shù)參數(shù),輸出端口對(duì)應(yīng)函數(shù)返回值,數(shù)據(jù)處理業(yè)務(wù)即是該函數(shù)。將函數(shù)作為函數(shù)控件類的成員函數(shù),在函數(shù)控件類的數(shù)據(jù)響應(yīng)接口中,從數(shù)據(jù)輸入端口獲取數(shù)據(jù),作為函數(shù)的參數(shù)對(duì)函數(shù)進(jìn)行調(diào)用,然后將調(diào)用結(jié)果通過數(shù)據(jù)輸出端口輸出。
4 響應(yīng)式手機(jī)可重構(gòu)虛擬儀器平臺(tái)
本文提出的響應(yīng)式手機(jī)可重構(gòu)虛擬儀器平臺(tái)從邏輯上可分為3層,分別是交互層、內(nèi)核層及腳本解釋層,如圖11所示。界面布局容器以及與用戶的交互邏輯。針對(duì)虛擬儀器的使用特點(diǎn)設(shè)計(jì)界面布局以及交互邏輯。
內(nèi)核層是可重構(gòu)虛擬儀器的核心部分,該層負(fù)責(zé)控件管理、響應(yīng)式數(shù)據(jù)端口管理,以及數(shù)據(jù)響應(yīng)關(guān)系維護(hù)。其接受來自腳本層的控件實(shí)例化意圖、布局意圖以及數(shù)據(jù)關(guān)系聲明意圖,并將實(shí)例化控件添加到交互層。
腳本解釋層是最底層的部分,該層的職責(zé)是解釋頁面腳本意圖,并將意圖傳遞給內(nèi)核層。
5 應(yīng)用實(shí)例
如圖12所示為一個(gè)聲音監(jiān)測(cè)儀器,其包含的儀器控件類型有:按鈕控件、麥克風(fēng)控件、拖動(dòng)條控件、FFT(快速傅里葉)控件、文本控件、數(shù)字顯示控件及波形顯示控件。其運(yùn)行邏輯為:按鈕(圖中標(biāo)號(hào)8)控制麥克風(fēng)控件開關(guān),拖動(dòng)條控件(圖中標(biāo)號(hào)5)控制麥克風(fēng)數(shù)據(jù)增益倍數(shù);增益倍數(shù)通過數(shù)字顯示控件(圖中標(biāo)號(hào)4)顯示,增益后的麥克風(fēng)數(shù)據(jù)通過波形顯示控件(圖中標(biāo)號(hào)6)顯示;增益的數(shù)據(jù)傳送到FFT控件(圖中標(biāo)號(hào)2)后,將經(jīng)過FFT處理得到的頻譜繪制到波形顯示控件(圖中標(biāo)號(hào)7)中;通過增益的波形數(shù)據(jù)進(jìn)行聲強(qiáng)計(jì)算,將得到的聲強(qiáng)值顯示到數(shù)字顯示控件(圖中標(biāo)號(hào)3)中。
以下是該儀器的省略腳本:
Vars:
mic=MicVI( "micl","10, 10, 30, 30","44100",¨4096”,“O”);
fft= FftVI(“fftl”,“50, 10, 30, 30");
label= LabelVI( "lbl”,“90,10,65,30”,“聲強(qiáng)(分貝)”,“” “” “” “2"):
dg= DigitaIDisplayVI( "dgl", "160, 10, 100, 30”);
lahel2=LabeIVI( "Ib2", "90. 50, 65, 30",“增益(倍數(shù))”,“”,“”,“”,“2”);
dg2= DigitalDisplayVI(“dg2", "160, 50, 100, 30”);
label3= LabelVI( "lb3”,“90. 85, 65, 30”,“增益控制”,“”,“”,“”,“2");
sb= ScrollBarVI( "sh", "160, 85, 100, 30",“1, 10",“l(fā)”,“0.1”):
wave= WaveVI2( "wavel”,“0,120, 300, 170",…,…,“”, "-20000, 20000",“5”);
waveFft=WaveVI2( "wave2", "0, 295. 300, 170",…,“”,“”,“0.2000”,“5”);
btn=ButtonVI( "btnl", "20, 470, 260, 35",“,“1,0,O”,“停止一開始”,“50”);
t= DoubleArray(“tl”);
End
Functions:
douhle countDb( double[] data){
,,計(jì)算聲強(qiáng)函數(shù)
}
End
Relation:
mic.switch一>btn.value:
t.in=>mic.data術(shù)sb.value:
dg2.value一>sb.value;
fft.data一>t.out;
wave.dx=>1.0/44100:
wave.data一>t.out:
waveFft.dx=>44100.0/4096:
waveFft.data一>fft.amp;
dg.value=>>countDb( t.out);
End
為了說明本文提出的可重構(gòu)虛擬儀器的靈活性,以下以一個(gè)實(shí)際案例進(jìn)行說明。圖12中標(biāo)號(hào)3的數(shù)字顯示控件對(duì)應(yīng)的實(shí)例化腳本為“dg=DigitaIDisplayVI( "dgl",“160,10,100,30")”,將該行腳本替換成“bg= BarGraphVI( "bgl",“160,2,135, 46",“”,“0_30_60_90_1 20", "0, 120",“0”.“5")”;描述該數(shù)字顯示控件數(shù)據(jù)關(guān)系的腳本是“dg.value=>>countDb( t.out)”,將該行腳本替換為“bg.value=>> countDb(t.out)”。替換以上兩行腳本,便可實(shí)現(xiàn)將聲強(qiáng)顯示替換為一個(gè)棒圖進(jìn)行顯示,如圖13所示。
6 結(jié)語
本文分析了手機(jī)虛擬儀器發(fā)展現(xiàn)狀以及響應(yīng)式編程特點(diǎn),將響應(yīng)式編程引入到虛擬儀器中,并在Android平臺(tái)加以實(shí)現(xiàn)。研究表明,響應(yīng)式編程適用于虛擬儀器。基于響應(yīng)式編程的手機(jī)可重構(gòu)虛擬儀器,其控件通訊模型更為清晰,且對(duì)復(fù)雜數(shù)據(jù)關(guān)系的表達(dá)能力更強(qiáng)。但目前本文設(shè)計(jì)的虛擬儀器響應(yīng)式編程語言尚不夠完善,在后續(xù)研究中,可詳細(xì)考慮虛擬儀器實(shí)際應(yīng)用中的各種功能業(yè)務(wù)需求,設(shè)計(jì)更系統(tǒng)的腳本語法,從而進(jìn)一步提高可用性。
參考文獻(xiàn):
[1] 秦樹人.虛擬儀器——測(cè)試儀器從硬件到軟件[J].振動(dòng)、測(cè)試與診斷,2000,20(1):1-6.
[2] 張新良,馬明全.基于虛擬儀器與PCI-171IU的三軸滑臺(tái)控制系統(tǒng)設(shè)計(jì)[J].軟件導(dǎo)刊,2018,17(1):102-104.
[3] 趙寧社.遠(yuǎn)程數(shù)據(jù)采集的現(xiàn)場(chǎng)虛擬儀器控制系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)[J].國外電子測(cè)量技術(shù),2018,37(6):130-134.
[4]王銘華,李強(qiáng),陳虹麗,基于虛擬儀器的磁特性測(cè)量系統(tǒng)的設(shè)計(jì)及實(shí)現(xiàn)[J].實(shí)驗(yàn)技術(shù)與管理,2018,35( 9):127-129.
[5] 劉云龍,謝壽生,彭靖波,等.基于虛擬儀器的某型航空發(fā)動(dòng)機(jī)綜合檢測(cè)系統(tǒng)[J].計(jì)算機(jī)應(yīng)用,2018,38( Sl):260-265.
[6]田航,何嶺松,高志強(qiáng),等.基于構(gòu)件的手機(jī)可重構(gòu)虛擬儀器技術(shù)[J].計(jì)算機(jī)應(yīng)用研究,2016,33(4):1106-1110.
[7]吳玉葉,何嶺松,韋文姬,等.基于iOS的手機(jī)虛擬儀器瀏覽器的設(shè)計(jì)[J].計(jì)算機(jī)測(cè)量與控制,2017,25(11):234-238.
[8]尹愛軍,張泉,孫兵.手機(jī)移動(dòng)平臺(tái)的虛擬軸承診斷儀的開發(fā)及應(yīng)用[J].振動(dòng)、測(cè)試與診斷,2015,35(5):897-901.
[9] 陸文英,胡海榮.基于手機(jī)多傳感器數(shù)據(jù)融合的測(cè)步長算法[J].電子科技,2018,31( 12):9-13.
[10] 藺瑩,張引根,王珂,等.基于Android的健康監(jiān)護(hù)系統(tǒng)設(shè)計(jì)和開發(fā)[J].測(cè)控技術(shù),2018,37(12):51-56.
[11]MEREDITH S E, ROBINSON A, ERB P,et al.A mobile-phone-based breath carbon monoxide meter to detect cigarette smoking[J].Nicotine & Tobacco Research Official Journal of the Society for Re-search on Nicotine & Tobacco, 2014, 16( 6) : 766.
[12]MURPHY E . KINC E A. Smartphone-hased noise mapping : integrat-ing sound level meter App data into the strategic noise mapping pro-cess[J]. Science of The Total Environment, 2016, 562 : 852-859.
[13]React Native中文網(wǎng) .使用 JavaScript和 React編寫原生移動(dòng)應(yīng)用 [ EB/OL] .https : //reactnative.cn/.
[14]WEEX. Weex is a framework for building performant mohile APPswith modern web technology[ EB/OL ] . http : //,veex.apache.org/.
[15]MARCARA A , SALVANESCHI G. We have a DREAM : distributedreactive programming with consistency guarantees.[ C ] . ACM Interna-tional Conference on Distrihuted Event-based Systems . 2014.
[16] BRESSON J. Reactive visual programs for computer-aided musiccomposition [Cl.Visual Languages and Human-Centric Computing.IEEE , 2014 : 141-144.
[17]JEITSCH . WOLFCANG. Abstract categorical semantics for resource-ful functional reactive programming [J] . Journal of Logical and Alge- braic Methods in Programming, 2016, 85( 6) : 1177-1200.
[18] FREDERIC B. Mimicking quantum mechanics using reactive pro-gramming [J]. International Journal of Modern Physics C , 2011 , 22( 6) : 635-648.
[19]SCHATZ R. WIRTH C, HURNAUS D. Monaco-a domain-specificlanguage solution for reactive process control programming with hier-archical components [ J] .Computer Languages Systems & Structures ,2013 . 39( 3) : 67-94.
[20]SALVANESCHl C. PROKSCH S, AMANN S. et al. On the positiveeffect of reactive programming on software comprehension : an empiri-cal study [J].IEEE Transactions on Software Engineering, 2017, 43( 12) : 1125-1143.
基金項(xiàng)目:國家科技重大專項(xiàng)項(xiàng)目( 2015ZX04005007)
作者簡介:謝道旺(1992-),男,華中科技大學(xué)機(jī)械科學(xué)與工程學(xué)院碩士研究生,研究方向?yàn)槭謾C(jī)化移動(dòng)測(cè)量儀器;何嶺松(1962-),男,博士,華中科技大學(xué)機(jī)械科學(xué)與工程學(xué)院教授、博士生導(dǎo)師,研究方向?yàn)楣I(yè)測(cè)量與控制、計(jì)算機(jī)虛擬儀器技術(shù)、手機(jī)化移動(dòng)測(cè)量儀器;高志強(qiáng)(1986-),男,華中科技大學(xué)機(jī)械科學(xué)與工程學(xué)院博士研究生,研究方向?yàn)閿?shù)控加工優(yōu)化、遠(yuǎn)程診斷。本文通訊作者:何嶺松。