張培忠,高 坤,寧金貴
(中國人民解放軍63850部隊,吉林 白城 137001)
導彈半實物仿真技術是一項涉及多學科、多專業的復雜系統工程,其中穩定、實時、可靠的仿真軟件是一個重要組成部分。在導彈半實物仿真過程中,由于在仿真回路中接入了實物部件,要求仿真設備軟硬件的時間尺度與實物部件的時間尺度(自然時間尺度)一致,也就要求整個仿真系統是實時運行的。一般半實物仿真系統都以實時操作系統作為運行平臺,例如YH-Astar仿真工作站,該工作站是基于Intel處理器和Windows 2000+RTX操作系統,這就要求設計的導彈仿真程序也能夠在RTX實時環境中運行。
YH-Astar仿真工作站采用YHSim一體化建模與實時仿真軟件,該軟件雖然功能強大,但不是通用商業軟件,升級維護不便,且不支持圖形模塊化建模,程序代碼兼容性、可移植性不足,導致用戶建模、校模、驗模效率偏低[1-2]。然而,Matlab/Simulink是目前計算機仿真應用最為廣泛的軟件,支持圖形模塊化建模,程序代碼兼容性、移植性好,技術資料豐富,便于升級維護,許多專用的仿真系統都支持Simulink模型,方便了用戶的使用[3]。從軟件功能的通用性、兼容性、完善性等多方面考慮,有必要利用Simulink開發導彈半實物仿真軟件[4]。但是,用Simulink開發的仿真程序還不能直接拿到RTX實時環境中運行,需要經過實時性改造和移植,才能獲得實時、穩定運行的仿真程序。
常用Windows系列操作系統不是實時系統,RTX(Real-Time Extension)是美國Ardence公司開發的基于Windows NT/2000/XP操作系統的硬實時擴展子系統。RTX給Windows系統增加一個實時子系統RTSS(Real-Time Subsystem)和實時HAL(Hardware Abstract Level)擴展,以實現硬實時功能。圖1為RTX的工作原理圖。
RTSS在概念上與其他Windows子系統(如Win32、POSIX等)類似,它擁有自己的執行環境和API(Application Programming Interface),擴展了自己的線程調度機制,RTX-RTSS中執行的程序都具備比Win32程序更高的優先權,包括Windows管理的中斷及延時過程調用DPCs等。RTSS還支持 IPC(Inter Process Communication)對象,這些IPC對象可以被RTSS進程和Win32進程操作,從而實現實時進程和非實時進程之間的通信與同步。
RTX HAL擴展起著中斷隔離的作用,Windows不能屏蔽RTSS管理的中斷,但在RTSS進程運行時,可以屏蔽Windows的中斷。RTX HAL還提供高精度的時鐘和定時器,時鐘分辨率可以達到100 ns,定時器最小周期為1 μs,同時也支持 Windows 的非實時時鐘和定時器。RTX HAL的其他特征還有:提供了RTX和Windows之間的軟件中斷機制、異常處理以及對系統確定性的擴展。
RTX還支持單處理器系統和多處理器系統。在多處理器系統中,RTX可以運行于“共享”方式或“獨占”方式。“共享”方式是指RTX與Windows程序共享一個處理器,其他處理器全部由Windows程序占用;“獨占”方式是指RTX獨占一個處理器,保證了其實時功能。
RTX API是基于Win32的應用程序接口,使開發者能夠利用Win32開發經驗、現有代碼、開發工具來編寫實時應用程序。Win32和RTSS都支持RTX API。RTX API包含Win32 API的部分函數,稱為RTXAPI的函數集。RTX API是為了實時應用而經過仔細挑選的函數集,但不包括Win32的一類函數,如GUI函數,這類函數通常用于實時性要求不高的場合。實際上,那些實時應用不必要的、對確定性執行不適用的Win32函數都沒包括在RTX API中。因此,通常采用Win32與RTSS相結合方式開發實時軟件,將有實時性要求的事務放在RTSS進程中處理,而將人機界面等對實時性要求不高的事務放在Win32進程中處理,RTSS進程與Win32進程通過共享內存的方式相互溝通,如圖2所示。
RTX為用戶和開發人員提供了實時系統運行環境(RTX Runtime)和實時系統開發環境(RTX SDK)。用戶可以像開發其他Windows應用程序一樣,用Visual Studio開發RTX應用程序。安裝RTX后,在Visual Studio集成開發環境下,增加開發RTSS軟件的應用程序向導RTX AppWizard,類似于MFC AppWizard。用戶使用該向導,可定制所需的應用程序框架,包括定時器、中斷、事件管理、端口IO及RTSS動態鏈接庫等。用戶在該框架基礎上添加程序代碼,編譯鏈接后即可生成RTX應用程序。
Matlab/Simulink是國際上仿真領域最常用的商業化計算機工具軟件包。它提供了一個圖形模塊化、動態建模、仿真和綜合分析的集成環境,無需用戶手工編寫大量的程序代碼,只要通過簡單的圖形模塊化鼠標操作,就可以構造出復雜的、可靠的、易讀的仿真程序,顯著提高了仿真程序的開發效率和質量[5]。雖然 Matlab/Simulink沒有硬件接口及實時仿真功能,但它的S-函數機制和Real-Time Workshop組件為開發實時仿真軟件提供了有效的技術途徑。
首先用Matlab/Simulink建立仿真模型,這期間需要編寫S-函數,用以實現仿真程序與仿真設備硬件接口之間的聯接,并將該S-函數加入到Simulink仿真模型中。Simulink仿真模型設計完成后,通過Real-Time Workshop將仿真模型編譯成C語言代碼,最后對該C語言代碼進行實時性改造[6],再移植到Windows+RTX實時環境中,完成實時仿真程序設計。
Simulink是Matlab產品系列中非常重要的一個組件,是用圖形模塊化建模、分析和仿真各種動態系統的交互環境,包括連續系統、離散系統和連續離散混合系統。Simulink提供了許多實現不同功能的圖形化模塊庫,每種模塊庫包含了多種功能模塊,用戶也可以設計自己的專業模塊庫并加入其中,以擴充Simulink的功能。由于Simulink采用圖形模塊化、交互式操作方式,用戶建模時只需使用鼠標拖放不同模塊庫中所需要的功能模塊圖標,并將它們連接起來,就可以創建仿真模型,從而使復雜、繁瑣的仿真模型設計問題簡單化。用戶還可以把若干個功能塊組合成子系統,建立起分層的、多級的復雜仿真模型,使仿真模型的組成結構清晰、明了,邏輯關系易讀,提高了仿真建模、校模、驗模的效率和質量。
Simulink圖形模塊化的“編程”方法使得用戶從編寫繁雜語句代碼的勞動中解放出來。但是,創建一個Simulink仿真模型的時候,就等于在編程,必須考慮數值計算的問題。首先,應當選擇對指定模型的微分方程求解所使用的最佳算法,Simulink提供了多種微分方程的數值解法,有各自的特點和適用場合,不同的解法通過Simulation/Configuration Parameters頁中的求解器(Solver)選項設置。其次,要對模型中的變量進行分析,考慮是否需要進行過零檢測,某些變量在過零時會出現不連續狀態,如自由下落的物體著地后,會被彈起來,速度會發生跳變,這類變量,如果在動態系統仿真中不對其進行過零檢測,很可能會導致不正確的結果。最后,要避免出現代數環,對不能去掉的代數環進行處理。
半實物仿真程序需要與仿真設備及實物部件之間進行通迅,Simulink本身不具備這個功能,用戶可以通過編寫S-函數,來實現仿真程序與硬件接口的聯接。
S-函數(System Function)是采用計算機編程語言方式描述的一個功能模塊,它是Simulink建模的有力擴充,它提供了增強和擴展Simulink功能的強大機制,同時也是使用Real-Time Workshop實現半實物仿真的關鍵。在用戶使用Simulink建模時,S-函數的使用方法同其他功能模塊一樣,可以采用Matlab、C、C++、FORTRAN以及Ada等高級語言編寫S-函數。
S-函數有兩種類型,一種是M文件S-函數,用Matlab語言來編寫;另一種是ME X文件S-函數,用C、C++、Ada 或 Fortran 語言編寫編譯而成。本文采用C語言編寫MEX文件的S-函數。C語言編寫MEX文件的S-函數是一些符合特定語法結構的回調函數,每個回調函數都對應著一個預先指定的具體任務,各個回調函數在總仿真流程中所處的位置及功能如圖3所示。Matlab提供了C語言編寫MEX文件的S-函數的模板文件sfuntmpl_doc.c,該文件定義了各回調函數的結構,并有詳細注釋。用戶參考回調函數的注釋,依據模板文件中的回調函數結構,用C語言編寫MEX文件的S-函數。
Real-Time Workshop(簡稱RTW)是Matlab的重要組成部分,是一個基于Simulink圖形模塊化的仿真模型轉化成程序代碼的工具。用戶使用RTW可以直接從Simulink圖形模塊化的仿真模型生成優化的、可移植的、用戶定制的C或Ada程序代碼,并根據不同的目標配置生成可以在多種環境下運行的程序。
在用RTW生成程序代碼之前,需要對圖形模塊化的仿真模型進行一些必要的設置。包括:(1)設定仿真模型的內部參數,如各積分項的初始條件等;(2)設定Simulink仿真參數,通過Simulation/Configuration Parameters菜單設置,包括Start time、Stop time、Solver等;(3)設定RTW代碼,指定RTW系統目標文件、模板聯編文件和聯編命令文件。
RTW生成的程序代碼不能直接用于Windows+RTX實時環境中,還需要對該程序代碼進行實時性改造,再移植到RTX實時環境中。為此,先將RTW生成文件設置為grt.tlc,模板聯編文件和聯編命令文件保持默認設置。各項參數設置完后,點擊“Build”生成C語言代碼。生成的C語言代碼文件默認保存在 Matlab 安裝目錄下的 workmodel_grt_rtw 目錄下(model為模型名稱),包括:model.mk、model.mak、model.bat、model.h、model.c、model_data.c、model_types.h、model_private.h、rt_nonfinite.c、rt_nonfinite.h、rtmodel.h、rtwtypes.h、rtw_proj.tmw。用 VC++ 6.0打開其中model.mak 文件,會創建一個Win32控制臺(Win32 Console Application)類型的工程。此工程包括上百個Matlab提供的C源文件和頭文件,在安裝目錄Matlab ROOT twclibsrc下,這些C源文件提供了模型運行中的函數支持,比如仿真運算、積分器等Matlab庫函數。工程的主文件為 grt_main.c,它與用戶模型無關,也是Matlab提供的,在Matlab ROOT twcgrt目錄下。
利用RTW將Simulink圖形模塊化的仿真模型轉化成了C語言程序代碼,這是一種在Win32環境下運行的通用程序代碼,還不具備實時性,沒有仿真步長度量及推進功能,需要對其進行實時性改造和移植。
分析Simulink圖形模塊化的仿真模型的C語言程序代碼(主要是grt_main.c和model.c文件)可以發現,仿真程序的流程依據圖4進行的。仿真過程分為三部分:(1)初始化部分,主要由MODEL()、MdlInitializeSizes()、 MdlInitializeSampleTimes()、MdlStart()函數組成;(2)幀循環部分,主要是rt_OneStep()函數,該函數主要包括了MdlOutputs()、MdlUpdate()函數;(3)仿真結束處理部分MdlTerminate()。其中,需要實時處理的部分只有幀循環部分rt_OneStep()函數及其MdlUpdate()函數、MdlOutput()函數,其他的初始化和仿真結束后的數據記錄、清理等工作都不需要實時處理。
RTX實時程序通常采用Win32進程與RTSS進程相結合的方法(見圖2),將需要實時處理的事務放在RTSS進程中,其他部分放在Win32進程中。文獻[1]和[2]介紹的半實物仿真程序設計就是采用這種方法,他們首先對RTW生成的模型代碼進行實時性分離,將需要實時運行的部分(rt_OneStep()函數及其MdlOutputs()函數、MdlUpdate()函數)放到RTSS進程中,其他部分如初始化、仿真結果記錄等放在Win32進程中。但是,這種方法由Win32進程和RTSS進程共同完成仿真,要求Win32進程和RTSS進程共享仿真模型的數據空間,主要是共享SimStruct數據結構。SimStruct是一個非常復雜的數據結構,其封裝了仿真模型的所有動態信息,內部有大量的指針變量以及指針嵌套結構。鑒于Win32環境和RTSS環境存儲器的編址方式不同,共享的、同一物理存儲單元在Win32環境和RTSS環境的邏輯地址不同,因此要實現SimStruct數據結構的共享就非常困難。
新設計的實時性改造方案是:將全部仿真程序(包括初始化、幀循環、仿真停止處理)都放在RTSS進程運行,Win32與RTSS仿真程序及其數據結構無關。Win32進程僅負責共享內存的創建、RTSS進程的載入,負責RTSS仿真過程的控制及仿真結果的顯示功能,并通過共享內存向RTSS進程發送控制命令、讀取RTSS仿真數據及狀態信息;而RTSS進程則獨立運行全部仿真程序,并通過共享內存接收Win32進程的控制命令及參數,用定時器控制幀周期,在完成每一幀的計算后,將仿真結果存入共享內存,供Win32進程讀取顯示。經過實時性改造及代碼移植后,仿真程序框架結構如圖5所示。
依據圖5的仿真程序結構編制仿真程序。用 VC++ 6.0創建一個RTSS Application類型的工程,在該工程中加入RTW生成的代碼文件,將主程序文件替換為Matlab的grt_main.c文件,然后對該文件代碼進行修改。修改的內容主要有:(1)在main()函數中加入RtOpenSharedMemory()函數,用于打開由Win32主程序建立的共享內存;(2)調用RtCreateTimer()和 RtSetTimerRelative()函數,創建定時器并設置時間間隔(即幀周期);(3)編寫定時器回調函數代碼,將單步仿真程序rt_OneStep()移到該函數中;(4)去掉原代碼中幀循環部分,改為檢查共享內存中控制命令字節程序;(5)刪除原程序中有關顯示及數據記錄的函數,如printf()、rt_StartDataLogging()、rt_UpdateTXYLogVars()、rt_StopDataLogging()等。該工程編譯連接后生成可執行文件,擴展名為.rtss。
用VC++ 6.0建立Win32 Console 或MFC類型的Win32工程,加入以下程序代碼:(1)調用 RtCreateSharedMemory()函數創建共享內存,并進行共享內存的初始化,如設置仿真幀周期等;(2)通過CreateProcess()函數運行RTSSrun程序,進而載入并運行由RTSS工程生成的.rtss程序;(3)查詢共享內存的RTSS狀態字節,等待RTSS進程的“就緒”狀態,然后寫“允許仿真”命令;(4)進入幀循環階段,讀共享內存,存儲、顯示仿真過程的有關數據;(5)設置“結束仿真”命令;(6)仿真結束,存儲數據,調用RtUnmapSharedMemory()函數釋放共享內存。
以某型導彈的飛行彈道實時仿真為例,編制基于RTX實時環境的導彈仿真程序,驗證上述方法的可行性。具體步驟是:(1)用Simulink對導彈飛行彈道進行圖形模塊化仿真建模;(2)用RTW工具生成C語言程序代碼;(3)編寫S-回調函數;(4)對C語言程序代碼進行實時性改造,并移植到RTX實時環境中;(5)在程序中增加幀周期測量代碼;(6)在RTX實時環境下運行并分析運行結果。采用的軟件版本為Matlab 7.0/Simulink4.0。
基于Matlab/Simulink的導彈質心動力學仿真模型見圖6所示,導彈繞質心轉動力學仿真模型見圖7所示,為了縮短文章篇幅,本文省略了導彈質心運動學仿真模型、導彈繞質心轉動的運動學仿真模型、幾何關系方程仿真模型、導彈空氣動力學仿真模塊。將上述各個子模塊按輸入/輸出信號的對應關系連接起來,構成導彈飛行彈道方程總的仿真模型,見圖8所示。
打開Matlab的 “Configuration Parameters”屬性頁,將“Real-Time Workshop”選項卡中的“RTW system target file”設置成“grt.tlc”,點擊“Build”按鈕,則開始生成導彈飛行仿真模型的C語言程序代碼,并編寫S-回調函數。
按照本文3.2、3.3、3.4部分介紹的方法,對代碼進行實時性改造和移植。本實例Win32程序采用的是MFC類型的應用程序,在其中定義共享內存數據結構。Win32工程和RTSS工程編譯連接后,分別生成RTmain.exe和RTX.rtss文件。將RTX.rtss拷貝到RTmain.exe所在的目錄,執行RTmain.exe程序,即可載入并運行仿真程序。
RTmain.exe程序的運行結果見圖9和圖10。圖9左右側圖形分別是該程序運行后得到的“V-t”和“y-t”曲線,圖10左右側圖形分別是單幀運行時間和幀周期圖線。從程序運行結果可見:(1)對于導彈飛行彈道的解算,實時仿真程序的單幀運行時間僅30 μs左右,運行速度非常快,說明實時仿真程序的代碼質量較高;(2)幀周期時間非常準確,通常情況下偏差在0.2 μs以內;(3)用其他進程進行抗干擾測試,例如在運行仿真程序的同時還播放視頻,仿真幀周期也很穩定,統計的最大偏差為0.7 μs。
使用Matlab/Simulink/RTW軟件工具進行圖形模塊化設計仿真模型,并將圖形模塊化仿真模型轉換成C語言程序代碼,對其進行實時性改造和移植,獲得在Windows+RTX實時環境下運行的仿真程序。通過研究得出以下結論:
1) Simulink圖形模塊化建模功能簡化了編程過程,提高了仿真建模、校模、驗模的效率和質量,便于開發復雜系統的實時仿真程序;
2) 對圖形模塊化仿真模型轉換成C語言程序代碼,并對C語言程序代碼進行實時性改造和移植后,仿真程序可以在RTSS中實時、穩定、可靠運行;
3) 由Win32程序監控仿真過程,不參與實時仿真計算,與實時仿真程序RTSS之間分工明確,數據耦合簡單,保證了RTSS中仿真模型可靠、實時運行,且抗干擾能力強。