《電子技術(shù)應(yīng)用》
您所在的位置:首頁(yè) > 測(cè)試測(cè)量 > 業(yè)界動(dòng)態(tài) > LabWindows/CVI在半實(shí)物分布式仿真系統(tǒng)中的應(yīng)用

LabWindows/CVI在半實(shí)物分布式仿真系統(tǒng)中的應(yīng)用

2008-09-09
作者:李 海, 武小棟

  摘 要: 以一個(gè)通信仿真系統(tǒng)" title="仿真系統(tǒng)">仿真系統(tǒng)的開(kāi)發(fā)為例,針對(duì)傳統(tǒng)的LabWindows/CVI" title="LabWindows/CVI">LabWindows/CVI調(diào)用外部DLL的方法不能應(yīng)用于HLA系統(tǒng)的問(wèn)題,提出創(chuàng)建LabWindows/CVI的DLL和利用外部編譯器兩種解決方案將LabWindows/CVI與HLA仿真系統(tǒng)相結(jié)合。
  關(guān)鍵詞: LabWindows/CVI 虛擬儀器 半實(shí)物分布式仿真系統(tǒng) HLA RTI


  半實(shí)物仿真又稱(chēng)為硬件在回路中的仿真(Hardware-in-the-loop Simulation),是一種將實(shí)物接入仿真回路中的仿真試驗(yàn)。半實(shí)物仿真已經(jīng)成為航空航天、武器系統(tǒng)等研究領(lǐng)域不可缺少的重要手段。隨著計(jì)算機(jī)仿真技術(shù)的迅猛發(fā)展,仿真系統(tǒng)變得越來(lái)越復(fù)雜,許多復(fù)雜的仿真牽涉到一些不同類(lèi)型系統(tǒng)的仿真聯(lián)合,而這些系統(tǒng)各自的仿真環(huán)境組成了整個(gè)仿真環(huán)境。為了解決不同類(lèi)型的仿真間的互操作和仿真部件的重用,美國(guó)國(guó)防部公布了建模與仿真領(lǐng)域里的高層體系結(jié)構(gòu)HLA(High Level Architecture)。HLA正日益得到重視和廣泛的應(yīng)用,基于HLA的分布式系統(tǒng)仿真在半實(shí)物仿真中的比重日益增加[1]。而另一方面,NI公司的LabWindows/CVI集成了GPIB、VXI、PXI、RS232/485和插入式(PCI、USB)數(shù)據(jù)采集設(shè)備等通信的功能,支持DataSocket和TCP/UDP等技術(shù)與遠(yuǎn)程應(yīng)用程序通信。作為虛擬儀器開(kāi)發(fā)工具在數(shù)據(jù)采集和界面控制方面具有明顯的優(yōu)勢(shì)。所以,將LabWindows/CVI應(yīng)用于半實(shí)物分布式仿真非常有利于系統(tǒng)的快速開(kāi)發(fā)。
  本文以一個(gè)通信對(duì)抗仿真系統(tǒng)的開(kāi)發(fā)為例,分析了LabWindows/CVI應(yīng)用于基于HLA的半實(shí)物仿真系統(tǒng)所存在的問(wèn)題,并提出兩種解決方案將LabWindows/CVI與HLA仿真系統(tǒng)完美結(jié)合。
1 半實(shí)物仿真系統(tǒng)結(jié)構(gòu)
  筆者所開(kāi)發(fā)的半實(shí)物通信對(duì)抗仿真系統(tǒng)中的干擾機(jī)和通信設(shè)備均為硬件實(shí)物,而干擾機(jī)和通信設(shè)備之間的電磁環(huán)境是使用軟硬件模擬產(chǎn)生的。系統(tǒng)的簡(jiǎn)化框圖如圖1所示。


  該仿真系統(tǒng)共有七個(gè)HLA成員,HLA成員之間通過(guò)RTI發(fā)送和接收數(shù)據(jù)。各成員的主要功能如下:
  ·指揮控制成員負(fù)責(zé)仿真場(chǎng)景與系統(tǒng)參數(shù)的設(shè)置,通過(guò)HLA進(jìn)行時(shí)間推進(jìn),并不斷發(fā)送控制參數(shù)給各成員進(jìn)行多種偵察和干擾實(shí)驗(yàn)。
  ·干擾器成員、模擬器成員和地面站成員將從HLA系統(tǒng)接收到的仿真命令發(fā)送給硬件實(shí)物并根據(jù)從硬件采集到的數(shù)據(jù)進(jìn)行分析,將捕獲時(shí)間、誤碼率等信息發(fā)送給HLA中的其他成員。
  ·環(huán)境模擬成員隨著仿真推進(jìn)實(shí)時(shí)計(jì)算各設(shè)備的位置、姿態(tài)、速度、距離衰減和多普勒頻移,并控制連接各設(shè)備的微波網(wǎng)絡(luò),以模擬通信設(shè)備之間的鏈路。
  ·效能評(píng)估成員根據(jù)從實(shí)物采集到的數(shù)據(jù)計(jì)算干擾效能。
  ·視景仿真成員顯示各硬件實(shí)物在仿真場(chǎng)景中的位置、姿態(tài)和其他信息。
  由于設(shè)備的用途、使用環(huán)境各異,考察的指標(biāo)各有側(cè)重,設(shè)備實(shí)物和工控計(jì)算機(jī)之間的連接類(lèi)型也各不相同,見(jiàn)表1。借助LabWindows/CVI的數(shù)據(jù)采集和處理能力,可以使每臺(tái)工控機(jī)變成一臺(tái)虛擬儀器,完成控制數(shù)據(jù)的發(fā)送、遙測(cè)數(shù)據(jù)的采集和實(shí)時(shí)顯示功能。這些工控機(jī)程序同時(shí)又是HLA的仿真成員,在HLA的協(xié)調(diào)下工作。工控機(jī)的雙重使命使研究如何將虛擬儀器技術(shù)和分布式仿真平臺(tái)HLA結(jié)合成為必要。


2 LabWindows/CVI應(yīng)用于HLA系統(tǒng)的兩種解決方案
  LabWindows/CVI提供了多種與其他開(kāi)發(fā)工具的編程接口,其中最常用的方法是以L(fǎng)abWindows /CVI編寫(xiě)主程序" title="主程序">主程序,使用其他開(kāi)發(fā)工具編寫(xiě)DLL(Dynamic Link Library),再將DLL加入到LabWindows/CVI系統(tǒng)中使用[2]。這種方法對(duì)一般的硬件采集和處理非常簡(jiǎn)便,但是對(duì)于本文所討論的HLA系統(tǒng)無(wú)法適用。所有HLA應(yīng)用均通過(guò)RTI接口庫(kù)調(diào)用HLA所提供的功能,RTI庫(kù)一般以C++或Java類(lèi)庫(kù)的形式提供,而LabWindows/CVI只能調(diào)用使用C語(yǔ)言接口的DLL庫(kù)文件。曾經(jīng)有人嘗試過(guò)將HLA 的服務(wù)封裝成MEX(Matlab規(guī)定的C語(yǔ)言接口的DLL)[3],但一直沒(méi)有進(jìn)入實(shí)用階段。因?yàn)镽TI提供100多種仿真服務(wù),要將這些復(fù)雜的服務(wù)都以C語(yǔ)言接口的形式封裝成DLL,不但費(fèi)時(shí)費(fèi)力,而且必然削弱HLA作為面向?qū)ο蟮姆植际椒抡嫫脚_(tái)的功能。所以,必須尋找其它方法解決這個(gè)問(wèn)題。在實(shí)際開(kāi)發(fā)中,筆者先后使用以下兩種方案解決前述問(wèn)題。
2.1 基于LabWindows/CVI的DLL方法
  通常的LabWindows/CVI程序開(kāi)發(fā)是在其集成環(huán)境中編寫(xiě)C程序,最終編譯生成可執(zhí)行文件(.exe)。采用基于LabWindows/CVI的DLL方法與此不同。該方法將LabWindows/CVI程序編譯成為DLL庫(kù),然后在Visual C++編寫(xiě)的主程序中加以調(diào)用。軟件的主程序使用Visual C++編寫(xiě),可以調(diào)用RTI庫(kù)加入HLA仿真系統(tǒng),并且調(diào)用LabWindows/CVI編寫(xiě)的DLL所提供的輸出函數(shù)進(jìn)行界面顯示、數(shù)據(jù)采集與控制。當(dāng)用戶(hù)在界面上進(jìn)行操作或者數(shù)據(jù)采集完成時(shí),LabWindows的DLL程序可以借助Visual C++主程序提供的回調(diào)" title="回調(diào)">回調(diào)(callback)函數(shù)通知主程序,并將數(shù)據(jù)發(fā)送給主程序。軟件各模塊的調(diào)用關(guān)系可用圖2表示。


  要生成DLL庫(kù),需要在LabWindows/CVI中選擇菜單“Build | Target Type | Dynamic Link Library”。選擇菜單“Edit | Insert Construct | DllMain”向.c文件中加入DLL所需要的DllMain函數(shù)。
  LabWindows/CVI中最主要的工作是編寫(xiě)DLL輸出函數(shù)。例如下面的CallCVI函數(shù)顯示LabWindows的用戶(hù)面板TestUI.uir:
  int __stdcall CallCVI ()
  {
  if ((panelHandle = LoadPanelEx (0, 'TestUI.uir',PANEL,__CVIUserHInst)) < 0)
    return -1;
  DisplayPanel (panelHandle);
  RunUserInterface ();
  DiscardPanel (panelHandle);
  return 0;
  }
  這里使用LoadPanelEx函數(shù),而不是通常使用的LoadPanel函數(shù)。如果使用LoadPanel函數(shù),在Visual C++中運(yùn)行時(shí)會(huì)因?yàn)檎也坏?uir文件而報(bào)告錯(cuò)誤。在LabWindows中要實(shí)現(xiàn)DLL輸出函數(shù),需要將函數(shù)的聲明寫(xiě)到一個(gè)頭文件(.h)中,不要直接將DLL輸出函數(shù)的聲明寫(xiě)到面板對(duì)應(yīng)的.h文件中。因?yàn)樾薷拿姘鍟r(shí),LabWindows/CVI會(huì)重新生成.h文件,從而丟失手工添加的定義。建立一個(gè)export.h加入到工程中,在export.h中加入CallCVI函數(shù)的定義;再選擇菜單“Build | Target Settings”,點(diǎn)擊對(duì)話(huà)框" title="對(duì)話(huà)框">對(duì)話(huà)框中Exports框架的Change按鈕。在“DLL Export Options”對(duì)話(huà)框中,設(shè)置“Export What”為“Include File Symbols”,并選中export.h。最后選擇菜單“Build | Create Debuggable Dynamic Link Library”就可以創(chuàng)建.dll庫(kù)文件和.lib文件。將.dll、.lib、.uir文件和export.h文件拷貝到Visual C++的工程目錄下,從Visual C++菜單中執(zhí)行“Project | Add To Project | Files”,將.lib和export.h添加到工程中。在程序中調(diào)用DLL中的函數(shù)CallCVI()即可顯示LabWindows/CVI的面板。借助DLL輸出函數(shù)的參數(shù),可以實(shí)現(xiàn)從Visual C++程序向LabWindows/CVI程序發(fā)送數(shù)據(jù)。
  反過(guò)來(lái),如果希望將LabWindows/CVI程序中的用戶(hù)操作或外部輸入數(shù)據(jù)傳遞給Visual C++,可以通過(guò)由Visual C++提供回調(diào)函數(shù)來(lái)實(shí)現(xiàn)??梢孕薷那懊娴腃allCVI的定義為:
  typedef int (CVICALLBACK*VCPROC)(void*callbackData);
  static VCPROC pCallbackFunc = 0;
  
  int __stdcall CallCVI (void* pFunc)
  {
    pCallbackFunc = (VCPROC)pFunc;
    ……
  }
  這里使用typedef定義了一個(gè)回調(diào)函數(shù)類(lèi)型VCPROC。VCPROC實(shí)際上是一個(gè)函數(shù)指針,函數(shù)的參數(shù)為void類(lèi)型。函數(shù)指針VCPROC的返回值和參數(shù)可以根據(jù)實(shí)際應(yīng)用的情況靈活修改。Visual C++調(diào)用CallCVI時(shí),需要提供一個(gè)回調(diào)函數(shù)的地址作為參數(shù),如:
  CallCVI((void*)HLAProc);
  這里的HLAProc 是Visual C++程序中的一個(gè)用戶(hù)函數(shù),其參數(shù)和返回值都要與VCPROC中的定義一致。CallCVI中,LabWindows/CVI程序?qū)⒒卣{(diào)函數(shù)的地址保存在全局變量pCallbackFunc中。當(dāng)LabWindows/CVI中某個(gè)事件發(fā)生時(shí),可以調(diào)用pCallbackFunc變量中所保存的函數(shù)指針通知Visual C++程序。下面的例子中,用戶(hù)點(diǎn)擊LabWindows/CVI程序面板上的按鈕后,程序調(diào)用回調(diào)函數(shù)發(fā)送一個(gè)字符串給Visual C++,執(zhí)行加入HLA聯(lián)邦的操作:
  int CVICALLBACK ClickCallback (int panel, int control, int event, void *callbackData, int eventData1, int eventData2)
  {
  switch (event)
    {
    case EVENT_COMMIT:
      if(pCallbackFunc)
      { // 加入HLA聯(lián)邦
        (*pCallbackFunc)((void*)'Join Fed');
      }
      break;
    }
  return 0;
  }
  在Visual C++函數(shù)HLAProc函數(shù)中,可以實(shí)現(xiàn)對(duì)RTI的CreateFederation、JoinFederation等服務(wù)的調(diào)用。
  LabWindows/CVI 編寫(xiě)的DLL也可以進(jìn)行源代碼級(jí)調(diào)試,但需要做一些額外的設(shè)置。先在Visual C++中編寫(xiě)好調(diào)用DLL的程序并編譯為.exe文件,然后在LabWindows/CVI中打開(kāi)工程,選擇菜單“Run | Specify External Process”,指定Visual C++編寫(xiě)的.exe文件作為外部運(yùn)行程序。在LabWindows/CVI程序中設(shè)置斷點(diǎn)后,選擇菜單“Run | Debug Project”進(jìn)行程序調(diào)試。LabWindows/CVI將先啟動(dòng)Visual C++編寫(xiě)的程序,當(dāng)執(zhí)行到LabWindows/CVI的DLL內(nèi)部的代碼時(shí)即可進(jìn)行源代碼級(jí)跟蹤調(diào)試。
2.2 基于外部編譯器的方法
  另一種解決方案是利用Visual C++作為外部編譯器來(lái)實(shí)現(xiàn)HLA與LabWindows/CVI程序之間的相互調(diào)用。LabWindows/CVI自身編譯器的核心是David R. Hanson開(kāi)發(fā)的lcc,這個(gè)編譯器以容錯(cuò)和調(diào)試為擅長(zhǎng),但是優(yōu)化性能較弱[4]。使用外部編譯器還可以生成優(yōu)化的代碼,從而提高程序運(yùn)行效率。
  使用這種方法,先借助LabWindows/CVI生成顯示面板和硬件操作所需要的C語(yǔ)言代碼,然后把代碼和LabWindows/CVI的頭文件和庫(kù)文件添加到Visual C++的工程中進(jìn)行編譯。由于LabWindows/CVI生成的代碼與Visual C++生成的代碼是在同一個(gè)工程中,可以直接相互調(diào)用,不需要像上一種方法那樣設(shè)計(jì)DLL輸出函數(shù)和Visual C++回調(diào)函數(shù)。
  要使用外部編譯器,最主要的工作是為L(zhǎng)abWindows的面板生成對(duì)象表。在LabWindows/CVI環(huán)境中開(kāi)發(fā)程序時(shí),LabWindows/CVI會(huì)自動(dòng)為所有面板上所有控件的回調(diào)函數(shù)建立一個(gè)對(duì)象表并鏈接到程序中,運(yùn)行時(shí)利用這個(gè)對(duì)象表將.uir文件中的控件對(duì)象和控件的回調(diào)函數(shù)對(duì)應(yīng)起來(lái)。而使用Visual C++等外部編譯器,并不能自動(dòng)建立這樣的對(duì)象表,也就不能自動(dòng)識(shí)別控件對(duì)象的回調(diào)函數(shù)。因此,必須先在LabWindows/CVI中手工生成對(duì)象表,才能在外部編譯器中使用LabWindows/CVI的控件對(duì)象?;静僮鞑襟E是在設(shè)計(jì)好LabWindows/CVI面板后,從菜單中執(zhí)行“Build | External Compiler Support...”,在“External Compiler Support”對(duì)話(huà)框中設(shè)置“UIR CallBacks”為“Object File”,并輸入文件路徑和文件名callback.obj,點(diǎn)擊Create按鈕即可創(chuàng)建callback.obj文件。然后將.uir文件拷貝到與Visual C++編譯生成的可執(zhí)行文件目錄下(如Debug或Release目錄)。這里需要特別注意的是:.uir所在目錄與前一種方法是不同的。再將生成的.obj、.c和.h文件都添加到Visual C++工程中,同時(shí)還需要將cvi70/extlib/msvc目錄下的文件cvirt.lib、cvisupp.lib添加到工程中。在Visual C++中調(diào)用LabWindows/CVI程序時(shí),需要在#include部分添加對(duì)cvirte.h和userint.h的包含。在調(diào)用LabWindows/CVI生成的代碼之前,還需要調(diào)用InitCVIRTE函數(shù)進(jìn)行初始化,如:
  if (InitCVIRTE (AfxGetInstanceHandle(), 0, 0) == 0)
    return; /* 內(nèi)存不夠 */
  本文所介紹的兩種方法都可以將LabWindows/CVI與HLA系統(tǒng)結(jié)合,而且兩種方法各有特點(diǎn):基于LabWindows/CVI的DLL的方法比較獨(dú)立于外部編譯環(huán)境,對(duì)于一些不使用 C++接口的RTI(如使用Java語(yǔ)言接口的pRTI)也是適用的,比較通用,應(yīng)用范圍較廣;而基于外部編譯器的方法可以直接調(diào)用Visual C++所提供的各種功能,從而突破了LabWindows/CVI自身的ANSI C編譯器的種種局限,通信模式簡(jiǎn)單,易于編程,但這種方法不易于借助LabWindows/CVI的環(huán)境對(duì)硬件進(jìn)行調(diào)試。硬件設(shè)備開(kāi)發(fā)階段推薦使用前一種方案,而如果硬件設(shè)備已經(jīng)定型或采用現(xiàn)成商用硬件,采用后一種方法更簡(jiǎn)便。
參考文獻(xiàn)
1 周 彥,戴劍偉.HLA仿真程序設(shè)計(jì)[M].北京:電子工業(yè)出版社,2002
2 劉君華,白 鵬,湯曉君等.基于LabWindows/CVI的虛擬儀器設(shè)計(jì)[M].北京:電子工業(yè)出版社,2003
3 Pawletta, S., Drewelow, W., Pawletta, T. HLA-based simulation within an interactive engineering environment[J],Distributed Simulation and Real-Time Applications, 2000. (DS-RT 2000). Proceedings. Fourth IEEE International Workshop on, 2000;(8)
4 National Instruments Corp. LabWindows/LVI Programmer Reference Manual[M].2003

本站內(nèi)容除特別聲明的原創(chuàng)文章之外,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀(guān)點(diǎn)。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無(wú)法一一聯(lián)系確認(rèn)版權(quán)者。如涉及作品內(nèi)容、版權(quán)和其它問(wèn)題,請(qǐng)及時(shí)通過(guò)電子郵件或電話(huà)通知我們,以便迅速采取適當(dāng)措施,避免給雙方造成不必要的經(jīng)濟(jì)損失。聯(lián)系電話(huà):010-82306118;郵箱:aet@chinaaet.com。