|
MATLAB引擎函數(shù)庫(kù)是MATLAB提供引擎方式接口的一系列程序的集合,它允許用戶(hù)用自己的C/C++語(yǔ)言或FORTRAN語(yǔ)言應(yīng)用程序中對(duì)MATLAB進(jìn)行調(diào)用,將MATLAB作為一個(gè)計(jì)算引擎使用,讓其在后臺(tái)運(yùn)行,完成復(fù)雜的矩陣計(jì)算,簡(jiǎn)化前臺(tái)用戶(hù)程序設(shè)計(jì)的任務(wù)。 在用戶(hù)啟動(dòng)MATLAB引擎時(shí),相當(dāng)了啟動(dòng)了另外一個(gè)MATLAB進(jìn)程并在后臺(tái)運(yùn)行。應(yīng)用程序通過(guò)MATLAB引擎函數(shù)庫(kù)中提供的函數(shù)完成與MATLAB引擎之間進(jìn)行數(shù)據(jù)交換和命令傳送的任務(wù)。MATLAB引擎函數(shù)庫(kù)總共提供了13個(gè)C語(yǔ)言的引擎函數(shù),它們均在頭文件engine.h中予以說(shuō)明,所以在使用它們時(shí),必須對(duì)該頭文件進(jìn)行包含。下面簡(jiǎn)要介紹引擎庫(kù)中的六個(gè)基本庫(kù)函數(shù): (1) engOpen 功能:?jiǎn)?dòng)MATLAB引擎。 語(yǔ)法:Engine* engOpen(const char* startcmd); 其中,startcmd為一字符串,用于啟動(dòng)MATLAB進(jìn)程。在Windows中,startcmd必須為NULL。 (2) engClose 功能:退出MATLAB引擎。 語(yǔ)法:int engClose(Engine* ep); 其中,ep是Engine類(lèi)型的指針。EngClose發(fā)出退出MATLAB命令,成功時(shí)返回0,否則返回l。 (3) engEvalString 功能:執(zhí)行一個(gè)用字符串表示的MATLAB表達(dá)式。 語(yǔ)法:int engEvalString(Engine* ep, const char* string); 其中,string是命令字符串,該字符串必須是一個(gè)合法的MATLAB表達(dá)式。凡可在MATLAB命令窗口中執(zhí)行的命令均可以字符串形式執(zhí)行。 (4) engGetArray 功能:從MATLAB的工作空間中拷貝一個(gè)變量。 語(yǔ)法:mxArray* engGetArray(Engine* ep, const char* name); 其中,name是從engine中得到的mxArray名。engGetArray從ep所指向的engine中讀取使用參數(shù)name指定的mxArray結(jié)構(gòu)體的內(nèi)容,正確返回時(shí)其返回值為一指向新分配的mxArray結(jié)構(gòu)體對(duì)象的指針,否則為NULL。 (5) engPutArray 功能:將mxArray結(jié)構(gòu)體類(lèi)型變量放入MATLAB的工作空間中。 語(yǔ)法:int engPutArray(engine* ep, const mxArray* mp); 其中,mp為mxArray結(jié)構(gòu)體對(duì)象的指針。engPutArray將一個(gè)mxArray結(jié)構(gòu)體類(lèi)型的變量寫(xiě)入引擎ep。如果當(dāng)前程序的工作空間中不存在指定的mxArray結(jié)構(gòu)體,則函數(shù)會(huì)自動(dòng)創(chuàng)建。若有同名的mxArray結(jié)構(gòu)體存在,它將被這一新的mxArray結(jié)構(gòu)體取代。 (6) engOutPutBuffer 功能:確定存放MATLAB輸出結(jié)果的緩沖區(qū)域。 語(yǔ)法:int engOutputBuffer(Engine* eP,char* p,int n); 使用engOutputBuffer,用戶(hù)可以為引擎指針ep所指向的引擎設(shè)置一個(gè)輸出緩沖區(qū),將MATLAB輸出到屏幕上的內(nèi)容保存在其中,其長(zhǎng)度由參數(shù)n確定,位置由字符指針p來(lái)確定。 VC++6.0集成環(huán)境中建立MATLAB引擎程序的方法 第一步,建立項(xiàng)目工程。啟動(dòng)VC++6.0集成環(huán)境,選擇File下拉式菜單中的New選項(xiàng),可有三種類(lèi)型的應(yīng)用程序創(chuàng)建工程選擇.分別為MFC AppWizard(exe)、Win32Application和Win32conso1e Application。選擇其中一種,在Project name編輯框中輸入項(xiàng)目名,按照項(xiàng)目向?qū)瓿身?xiàng)目工程創(chuàng)建。 第二步,設(shè)置編譯環(huán)境。選擇下拉式菜單Tools中的菜單項(xiàng)Options,選擇其中的Directories屬性頁(yè),在其中的Show directories下拉式選項(xiàng)框中分別選擇Include Files和Library Files,在下部的編輯框中通過(guò)瀏覽分別添加如下路徑:Include Fiels:MATLAB根目錄\extern\include MATLAB根目錄\extern\include\cpp Library Fiels:MATLAB根目錄\extern\lib MATLAB根目錄\extern\include 第三步,設(shè)置項(xiàng)目連接選項(xiàng)。選擇菜單Project中的子菜單Settings,選擇其中的屬性頁(yè)Link,在其中的Catogery下拉式選項(xiàng)框中選擇Input.在下部的Object Library modules編輯框中填寫(xiě):libeng.lib、libmx.1ib和libmat.1ib。(具體用到什么庫(kù)由你的應(yīng)用決定) 第四步,加入引擎頭文件。在準(zhǔn)備使用MATLAB引擎的類(lèi)的cpp文件中,加入“#include “engine.h””語(yǔ)句,并且在以后建立的要使用MATLAB引擎的類(lèi)中也注意加入上述語(yǔ)句。 當(dāng)完成以上述四步工作后,用戶(hù)就可以在VC++中對(duì)MATLAB引擎程序進(jìn)行編譯和調(diào)試了。 Simulink的命令行仿真方式 一般情況下,Simulink是類(lèi)似框圖圖形化的仿真方法;而在通過(guò)引擎方式將Simulink同VC相結(jié)合時(shí),仿真的每個(gè)操作是通過(guò)調(diào)用engEvalString執(zhí)行一個(gè)用字符串表示的MATLAB表達(dá)式(Simulink仿真命令)來(lái)實(shí)現(xiàn)的。因此,要掌握Simulink&VC混合編程,首先需要掌握Simulink的命令行仿真方式: [t,x,y]=sim( 'modelname ') 利用對(duì)話(huà)框參數(shù)進(jìn)行仿真,返回輸出矩陣; [t,x,y]=sim( 'modelname ', timespan, options, ut) 利用輸入?yún)?shù)進(jìn)行仿真,返回輸出矩陣; [t,x,y1,y2,...yn]=sim( 'modelname ', timespan, options, ut) 利用輸入?yún)?shù)進(jìn)行仿真,返回逐個(gè)輸出; 參數(shù)說(shuō)明: 'modelname ' 運(yùn)行的模型名(不包含擴(kuò)展名),必須在MATLAB的搜索路徑上。 timespan 指定仿真的時(shí)間區(qū)間,可以采取以下幾種格式: (1)[] 空,利用模型對(duì)話(huà)框設(shè)置時(shí)間; (2)T_final 標(biāo)量,制定終止仿真時(shí)間; (3)[T_start T_final] 二元向量,指定仿真時(shí)間區(qū)間; (4)outputTimes 任何指定輸出時(shí)間記錄點(diǎn)的向量。 options MATLAB特定的一種數(shù)據(jù)結(jié)構(gòu),具有最高優(yōu)先權(quán),可以覆蓋模型參數(shù)對(duì)話(huà)框中的設(shè)置。 ut 賦給仿真對(duì)象數(shù)入口模塊的量,具有最高優(yōu)先設(shè)置,它是形為[t,u1,u2...]的數(shù)值矩陣,每個(gè)為時(shí)間序列或輸入序列。 Simulink與VC++6.0接口中的幾點(diǎn)問(wèn)題 根據(jù)自己在將Simulink與VC++6.0相結(jié)合過(guò)程中的經(jīng)驗(yàn),在實(shí)際運(yùn)作過(guò)程中,需要注意以下幾點(diǎn)問(wèn)題: Solver的選擇 仿真要涉及常微分方程組的數(shù)值積分,為適應(yīng)計(jì)算的多樣性,Simulink提供了多種求解器。因此在解決具體的問(wèn)題時(shí),應(yīng)當(dāng)選擇合適的求解器,并且設(shè)定合適的參數(shù),以得到精確且迅速的仿真結(jié)果。比如: ode45 即Nonstiff微分方程式,應(yīng)用Runge-Kutta解法的中階解法;應(yīng)用最廣的ode23 即Nonstiff微分方程式,應(yīng)用Runge-Kutta解法之較低階的求解方式,誤差會(huì)比ode45多一點(diǎn),但執(zhí)行的效率快 ;ode113 即Nonstiff微分方程式,應(yīng)用Adams-Bashforth-Moulton解法; ode15s 即stiff微分方程式之變階數(shù)求解方式,是一種數(shù)值差分法;ode23s 即stiff微分方程式之低階數(shù)求解方式,應(yīng)用修正的Rosenbrock二階解法;ode23t 即stiff微分方程式與dae三角形法整合求解方式 ode23tb 即stiff微分方程式之低階數(shù)求解方式。 對(duì)于ode45,通常適用于連續(xù)狀態(tài)模型,而對(duì)于剛性(stiff)系統(tǒng),則需要采用如ode23s的剛性求解器。對(duì)于我們的可控整流電路故障模型,由于采用短路器模擬開(kāi)路現(xiàn)象,系統(tǒng)為剛性系統(tǒng),所以在solver選擇時(shí)需要選擇剛性求解算法。 通過(guò)VC++編寫(xiě)的應(yīng)用程序采用引擎方式通過(guò)命令行仿真設(shè)置Solver只是改變了當(dāng)前仿真的Solver,默認(rèn)設(shè)定為Simulink中的仿真參數(shù)設(shè)定。比如對(duì)于可控整流電路故障診斷系統(tǒng)這一剛性系統(tǒng),即便程序中選用了ode15s而默認(rèn)為ode45,則本次仿真確實(shí)使用ode15s求解,但仍然會(huì)報(bào)警說(shuō)應(yīng)該用剛性解法。不過(guò)對(duì)于剛性系統(tǒng),ode45可不好用,因此從仿真效果(如耗時(shí))上可以認(rèn)定程序中設(shè)定的剛性解法奏效了。 VC數(shù)據(jù)類(lèi)型與MATLAB數(shù)據(jù)類(lèi)型之間的轉(zhuǎn)換 使用VC++6.0與MATLAB通過(guò)引擎方式混合編程,不可避免地要在VC數(shù)據(jù)類(lèi)型與MATLAB數(shù)據(jù)類(lèi)型之間進(jìn)行轉(zhuǎn)換。一般來(lái)說(shuō),可以使用memcpy進(jìn)行轉(zhuǎn)換。即通過(guò)mxGetPr()獲取MATLAB數(shù)據(jù)類(lèi)型的指針,再調(diào)用memcpy,比如在命令行方式下設(shè)置仿真時(shí)間時(shí)可以如下處理: //設(shè)定仿真時(shí)間VC數(shù)據(jù)類(lèi)型àMATLAB數(shù)據(jù)類(lèi)型 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數(shù)據(jù)類(lèi)型àVC數(shù)據(jù)類(lèi)型 double test[2]; memcpy((char*)test, (char*)mxGetPr(T), 2*sizeof(double)); |
|
|