歡迎您光臨本站 註冊首頁

取長補短:Simulink與VC++6.0介面比較

←手機掃碼閱讀     火星人 @ 2014-03-26 , reply:0

Simulink與VC應用程序介面一個顯著的特點就是Simulink模擬必須依賴於 MATLAB系統,目前為止,MATLAB提供引擎方式將Simulink同VC應用程序的編程結合起來。要通過引擎方式將Simulink與VC結合起來首先要掌握VC與MATLAB通過引擎方式混合編程以及Simulink命令行模擬兩方面的內容。

MATLAB引擎方式函數庫

MATLAB引擎函數庫是MATLAB提供引擎方式介面的一系列程序的集合,它允許用戶用自己的C/C++語言或FORTRAN語言應用程序中對MATLAB進行調用,將MATLAB作為一個計算引擎使用,讓其在後台運行,完成複雜的矩陣計算,簡化前台用戶程序設計的任務。

在用戶啟動MATLAB引擎時,相當了啟動了另外一個MATLAB進程並在後台運行。應用程序通過MATLAB引擎函數庫中提供的函數完成與MATLAB引擎之間進行數據交換和命令傳送的任務。MATLAB引擎函數庫總共提供了13個 C語言的引擎函數,它們均在頭文件engine.h中予以說明,所以在使用它們時,必須對該頭文件進行包含。下面簡要介紹引擎庫中的六個基本庫函數:

(1) engOpen

功能:啟動MATLAB引擎。

語法:Engine* engOpen(const char* startcmd);

其中,startcmd為一字元串,用於啟動MATLAB進程。在Windows中,startcmd必須為NULL。

(2) engClose

功能:退出MATLAB引擎。

語法:int engClose(Engine* ep);

其中,ep是Engine類型的指針。EngClose發出退出MATLAB命令,成功時返回0,否則返回l。

(3) engEvalString

功能:執行一個用字元串表示的MATLAB表達式。

語法:int engEvalString(Engine* ep, const char* string);

其中,string是命令字元串,該字元串必須是一個合法的MATLAB表達式。凡可在MATLAB命令窗口中執行的命令均可以字元串形式執行。

(4) engGetArray

功能:從MATLAB的工作空間中拷貝一個變數。

語法:mxArray* engGetArray(Engine* ep, const char* name);

其中,name是從engine中得到的mxArray名。engGetArray 從ep所指向的engine中讀取使用參數name指定的mxArray結構體的內容,正確返回時其返回值為一指向新分配的mxArray結構體對象的指針,否則為NULL。 (5) engPutArray

功能:將mxArray結構體類型變數放入MATLAB的工作空間中。

語法:int engPutArray(engine* ep, const mxArray* mp);

其中,mp為mxArray結構體對象的指針。engPutArray將一個 mxArray結構體類型的變數寫入引擎ep。如果當前程序的工作空間中不存在指定的mxArray結構體,則函數會自動創建。若有同名的mxArray 結構體存在,它將被這一新的mxArray結構體取代。

(6) engOutPutBuffer

功能:確定存放MATLAB輸出結果的緩衝區域。

語法:int engOutputBuffer(Engine* eP,char* p,int n);

使用engOutputBuffer,用戶可以為引擎指針ep所指向的引擎設置一個輸出緩衝區,將MATLAB輸出到屏幕上的內容保存在其中,其長度由參數n確定,位置由字元指針p來確定。

VC++6.0集成環境中建立MATLAB引擎程序的方法

第一步,建立項目工程。啟動VC++6.0集成環境,選擇File下拉式菜單中的 New選項,可有三種類型的應用程序創建工程選擇.分別為MFC AppWizard(exe)、Win32Application和Win32conso1e Application。選擇其中一種,在Project name編輯框中輸入項目名,按照項目嚮導完成項目工程創建。

第二步,設置編譯環境。選擇下拉式菜單Tools中的菜單項Options,選擇其中的Directories屬性頁,在其中的Show directories下拉式選項框中分別選擇Include Files和Library Files,在下部的編輯框中通過瀏覽分別添加如下路徑:Include Fiels:MATLAB根目錄\extern\include

MATLAB根目錄\extern\include\cpp

Library Fiels:MATLAB根目錄\extern\lib

MATLAB根目錄\extern\include

第三步,設置項目連接選項。選擇菜單Project中的子菜單Settings,選擇其中的屬性頁Link,在其中的Catogery下拉式選項框中選擇Input.在下部的Object Library modules編輯框中填寫:libeng.lib、libmx.1ib和libmat.1ib。(具體用到什麼庫由你的應用決定)

第四步,加入引擎頭文件。在準備使用MATLAB引擎的類的cpp文件中,加入「#include 「engine.h」」語句,並且在以後建立的要使用MATLAB引擎的類中也注意加入上述語句。

當完成以上述四步工作后,用戶就可以在VC++中對MATLAB引擎程序進行編譯和調試了。

Simulink的命令行模擬方式

一般情況下,Simulink是類似框圖圖形化的模擬方法;而在通過引擎方式將 Simulink同VC相結合時,模擬的每個操作是通過調用engEvalString執行一個用字元串表示的MATLAB表達式(Simulink模擬命令)來實現的。因此,要掌握Simulink&VC混合編程,首先需要掌握Simulink的命令行模擬方式:

[t,x,y]=sim('modelname')

利用對話框參數進行模擬,返回輸出矩陣;

[t,x,y]=sim('modelname', timespan, options, ut)

利用輸入參數進行模擬,返回輸出矩陣;

[t,x,y1,y2,...yn]=sim('modelname', timespan, options, ut)

利用輸入參數進行模擬,返回逐個輸出;

參數說明:

'modelname' 運行的模型名(不包含擴展名),必須在MATLAB的搜索路徑上。

timespan 指定模擬的時間區間,可以採取以下幾種格式:

(1)[] 空,利用模型對話框設置時間;

(2)T_final 標量,制定終止模擬時間;

(3)[T_start T_final] 二元向量,指定模擬時間區間;

(4)outputTimes 任何指定輸出時間記錄點的向量。

options MATLAB特定的一種數據結構,具有最高優先權,可以覆蓋模型參數對話框中的設置。

ut 賦給模擬對象數入口模塊的量,具有最高優先設置,它是形為[t,u1,u2...]的數值矩陣,每個為時間序列或輸入序列。

Simulink與VC++6.0介面中的幾點問題

根據自己在將Simulink與VC++6.0相結合過程中的經驗,在實際運作過程中,需要注意以下幾點問題:

Solver的選擇

模擬要涉及常微分方程組的數值積分,為適應計算的多樣性,Simulink提供了多種求解器。因此在解決具體的問題時,應當選擇合適的求解器,並且設定合適的參數,以得到精確且迅速的模擬結果。比如:

ode45 即Nonstiff微分方程式,應用Runge-Kutta解法的中階解法;應用最廣的ode23 即Nonstiff微分方程式,應用Runge-Kutta解法之較低階的求解方式,誤差會比ode45多一點,但執行的效率快 ;ode113 即Nonstiff微分方程式,應用Adams-Bashforth-Moulton解法; ode15s 即stiff微分方程式之變階數求解方式,是一種數值差分法;ode23s 即stiff微分方程式之低階數求解方式,應用修正的Rosenbrock二階解法;ode23t 即stiff微分方程式與dae三角形法整合求解方式 ode23tb 即stiff微分方程式之低階數求解方式。

對於ode45,通常適用於連續狀態模型,而對於剛性(stiff)系統,則需要採用如ode23s的剛性求解器。對於我們的可控整流電路故障模型,由於採用短路器模擬開路現象,系統為剛性系統,所以在solver選擇時需要選擇剛性求解演算法。

通過VC++編寫的應用程序採用引擎方式通過命令行模擬設置Solver只是改變了當前模擬的Solver,默認設定為Simulink中的模擬參數設定。比如對於可控整流電路故障診斷系統這一剛性系統,即便程序中選用了ode15s而默認為ode45,則本次模擬確實使用ode15s求解,但仍然會報警說應該用剛性解法。不過對於剛性系統,ode45可不好用,因此從模擬效果(如耗時)上可以認定程序中設定的剛性解法奏效了。

VC數據類型與MATLAB數據類型之間的轉換

使用VC++6.0與MATLAB通過引擎方式混合編程,不可避免地要在VC數據類型與MATLAB數據類型之間進行轉換。一般來說,可以使用memcpy進行轉換。即通過mxGetPr()獲取MATLAB數據類型的指針,再調用 memcpy,比如在命令行方式下設置模擬時間時可以如下處理:

//設定模擬時間VC數據類型àMATLAB數據類型

double timespan[2];

timespan[0] = (double) m_fStartTime;

timespan[1] = (double) m_fStopTime;

T = mxCreateDoubleMatrix(1, 2, mxREAL);

memcpy((char *) mxGetPr(T), (char *) timespan, 2*sizeof(double));

engPutVariable(ep, "T", T);

// MATLAB數據類型àVC數據類型

double test[2];

memcpy((char*)test, (char*)mxGetPr(T), 2*sizeof(double));

[火星人 ] 取長補短:Simulink與VC++6.0介面比較已經有443次圍觀

http://coctec.com/docs/linux/show-post-190226.html