陳懷民,馬更生,吳佳楠
(西北工業大學 無人機特種技術重點實驗室,陜西 西安 710065)
在半物理仿真實驗中,我們經常需要對保存的實驗數據進行回放研究。像串口調試助手、網絡調試助手等軟件雖然可以對數據文件進行讀取和發送,然而它們僅僅是對整個文件內的數據進行整體發送,而無法按我們的需求進行一幀一幀的發送。通常我們自己開發的用于數據研究的軟件也只是針對某一特定的數據文件進行讀取,數據文件內變量個數以及類型的改變,都要導致對軟件的源程序進行修改,這樣就很繁瑣,并且對其他人員的使用、修改造成了一定的困難。
為了解決這一問題,利用LabWindows/CVI開發環境設計了數據播放器,可以按照實驗時的真實采樣過程,將實驗數據發送出去,再現實驗過程,可反復對實驗數據進行研究。通過使用ini配置文件的方式做到了通用,只需對ini文件進行簡單的相應修改,就可以播放不同格式不同數據量的文件,而無需對源程序進行修改。同時由于LabWindows/CVI可以生成MSI格式的發布(安裝)文件,可以將編制好的應用程序轉化為發布文件,這樣可以脫離LabWindows/CVI的開發環境,將發布程序安裝到任何一臺計算機上[1]。
結合所需功能,在LabWindows/CVI下搭建數據播放器界面如圖1所示。

圖1 數據播放器界面圖Fig.1 Interface chart of the data player
采用配置文件即ini文件的形式對UDP通信和數據文件的信息進行讀取。為了便于對ini文件的修改,設置了“打開配置文件”按鈕,可以方便的打開ini文件對其進行修改,然后將其載入。選擇相應的數據文件,即可進行播放,數據可以按真實實驗時的傳輸過程,將數據按采樣間隔發送出去。為了便于對數據播放位置的調整,設置了進度條即CVI中的滾動條控件,不僅可以顯示數據的播放進度,而且可以通過對滾動條的拖動改變數據的播放位置。
ini文件是Initialization file的縮寫,即初始化文件,不僅一般的應用程序可以使用ini文件,其實windows操作系統也有自己的ini文件:win.ini,保存在Windows目錄下,Windows通過該文件對當前操作系統進行配置[2]。
ini文件將各種數據分成很多以“[]”組成的節,而在每一節中又包含了很多項目,項后面緊跟著一個等號,等號后面則是該項的值。實際上,ini文件中數據的存取是采用預先約定好的“項目=值”存儲結i構,各種數據被分門別類的存儲。ini文件的通用格式可以總結為:

在設計中將UDP通信的信息以及數據的相關信息寫入ini文件,使用中只需對ini文件進行簡單的相應改動就可以讀取不同的數據文件。ini文件的設置如下:

其中在NetworkConfig中設置UDP通信的相關信息,如本地IP、本地端口號、對方IP、對方端口號。在DataConfig中按照數據文件的具體信息,在Key中填寫數據名稱,如“variable1”。 KeyValue 中 填 寫 變 量 的 格 式 , 如 “double”、“float”、“int”。各變量的排列順序完全按照數據文件內變量的排列順序。在OtherConfig中設置幀間隔(即數據的采樣間隔)和數據的存放格式。由于數據的相關信息都是已知的,所以對ini文件的修改非常容易。
對NetworkConfig和OtherConfig中的信息進行載入相對簡單,不再贅述。對數據變量及數據類型的載入,定義結構體:

在載入ini文件的過程中,根據[DataConfig]中變量的多少建立數據變量的動態鏈表[3],建立過程中對每個節點的成員進行相應賦值,datan用于區別變量在數據中的排列位置;dataname為變量的名稱;datatype為變量的數據類型;datalength為變量所占字節數;同時我們還可以得到一幀數據總的字節數length。這些和真實數據的存儲都是相同的,這樣就保證了數據的播放和采樣接收時的情況完全相同。由于建立鏈表的程序較多,這里不再贅述。動態鏈表的建立極大方便了數據的讀取和發送,對于數據變量的信息,只需按需要對鏈表進行遍歷即可得到,而且有利于以后對軟件進一步的升級。
以ASCII格式的數據文件為例說明數據的讀取。對動態鏈表進行遍歷,判斷每個變量的數據類型,根據不同類型,分配不同的字節數,將文件內的數據按順序寫入內存。程序流程圖如圖2所示。

圖2 數據文件讀取流程圖Fig.2 Flow chart of loading the data file
與ASCII格式的數據文件不同,二進制數據文件的數據無需單個讀取,只需對鏈表進行一次遍歷,分配適當大小的內存后一次性將文件內數據全部寫入內存。
為了使得不同任務之間的協調操作與運行、數據的交互等問題更加易于解決,程序中使用了異步定時器。不需要特殊的數據傳送機制,不需要建立共享存儲區或共享文件,這對于數據的讀取和發送增加了很多方便,同時增強了程序的靈活性。
異步定時器的創建:
timerid=NewAsyncTimer(playspeed, -1, 0, asynCB, 0);
timerid:控件句柄
playspeed:兩次事件的時間間隔,單位為秒
asynCB:自定義回調函數,產生相當于普通Timer控件的回調函數事件。
在回調函數asynCB中,要將數據中的一幀數據完整的經過UDP傳輸:
data=malloc(length);
memcpy (data, &wave[scrollbarposition*length], length);
UDPWrite(writerChannel, targetport, targetip, data, length);
異步定時器的時間間隔設定為數據文件的采樣間隔,這樣對于數據接收方來說,接收數據播放器的數據就如同接收實時采集的數據一樣,完全可以模擬之前實驗時的數據采集情況。
為了方便的顯示和調整文件的播放進度,使用了CVI中的滾動條控件,CVI中滾動條可以通過兩種方式得到:一種是利用函數ScrollBar_Create[4][5]創建,另一種方式是利用函數ScrollBar_ConvertFromGraph將繪圖控件轉化為滾動條。本設計選用的是第二種方式:
ScrollBar_ConvertFromGraph (panelHandle,PANEL_GRAPH_HORIZONTAL,scrollbarCB , NULL);
其中scrollbarCB是滾動條的回調函數,可以實時響應播放進度的變化并改變滾動條的位置。
滾動條有兩種顯示方式,分別為水平滾動條和垂直滾動條。本設計選用水平滾動條。
通過函數ScrollBar_GetAttribute和ScrollBar_SetAttribute分別獲得和設置滾動條的屬性值,包括滾動條的最小值、最大值、滾動條一次滾動的大小、滾動條是否與拖動的數值成比例進行設置,這些設置相對比較簡單。
滾動條的函數面板在菜單的Library中并不存在,因此首先需要注意的是應該裝載儀器驅動[6],然后將所需的函數面板文件scroll.fp添加到當前工程中。和滾動條一樣,ini文件和異步定時器的函數面板文件inifile.fp、asynctmr.fp也要添加到當前工程中。如圖3所示。

圖3 添加函數面板文件Fig.3 Chart of loading the.fp file
為了使不同的數據文件可以有更好的播放效果,設計了兩種播放方式。一種是改變播放間隔,采用這種方式可以使數據以自定義的速度發送出去,而且沒有數據的丟失,適用于采樣間隔較大、數據較少的數據文件;另一種是類似視頻播放器的方式,對數據的播放可以進行“快進”和“慢放”,快進是對數據進行抽點播放,慢放則是對數據進行重復播放。
采用ASCII格式的文件testdata.dat,其中包含3個變量,變量一是幅值為4,周期1 s的正弦變量;變量二是幅值為3,周期2 s的余弦變量;變量三是幅值為1,周期為1 s的三角波變量,采樣周期為20 ms。
播放器運行界面如圖4所示。

圖4 播放器運行界面圖Fig.4 Interface chart of data player run
數據接收界面采用CVI設計的虛擬示波器。示波器接收界面如圖5所示。

圖5 數據接收界面圖Fig.5 Interface chart of the data receive
由圖4的運行界面可以看到數據文件的相關信息,可以很清楚的知道播放進度。由圖5中3個變量的波形可以得出,接收到的收據和數據文件內的數據完全相同,說明數據播放器的設計是可用的。
以上基于LabWindows/CVI的數據播放器的設計與實現,詳細介紹了ini文件的配置和載入,數據文件的讀取和發送,簡要介紹了異步定時器和滾動條控件的使用。本設計的核心是ini文件的靈活配置以及對數據文件內的變量進行的動態鏈表的建立。在讀取不同的數據文件時,無需關注程序本身的修改,只需根據數據文件的具體信息對ini文件進行簡單的配置即可,從而節省了很多繁瑣的修改程序的過程。
[1]宋宇峰.LabWindows/CVI逐步深入與開發實例[M].北京:機械工業出版社,2003.
[2]王建新,楊世鳳,隋美麗.LabWindows/CVI測試技術及工程應用[M].北京:化學工業出版社,2006.
[3]譚浩強.C程序設計[M].3版.北京:清華大學出版社,2006.
[4]Nation Instruments Corportation.LabWindows/CVI Help[S].2006.
[5]劉君華.基于LabWindows/CVI的虛擬儀器設計[M].北京:電子工業出版社,2003.
[6]孫曉云,郭立煒,孫會琴.基于LabWindows/CVI的虛擬儀器設計與應用[M].北京:電子工業出版社,2005.