取長補短:Simulink與VC++6.0介面比較(轉)
取長補短:Simulink與VC++6.0介面比較(轉)[@more@]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根目錄externinclude
MATLAB根目錄externincludecpp
Library Fiels:MATLAB根目錄externlib
MATLAB根目錄externinclude
第三步,設定專案連線選項。選擇選單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));
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根目錄externinclude
MATLAB根目錄externincludecpp
Library Fiels:MATLAB根目錄externlib
MATLAB根目錄externinclude
第三步,設定專案連線選項。選擇選單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));
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10617731/viewspace-957352/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Mysql關於長連線短連線優劣比較MySql
- 「取長補短」的RefineDet物體檢測演算法演算法
- 抽象類 & 介面比較抽象
- Twitter與Facebook使用者增長比較
- Hibernate與 MyBatis的比較(轉)MyBatis
- ASP.NET 與 JAVA 的比較 (轉)ASP.NETJava
- 幾種儲存介面協議全面比較(轉載)協議
- Perl程式與c程式速度的比較(轉)C程式
- SAP ERP 與 Oracle ERP 比較(轉)Oracle
- Java快取機制:Ehcache與Guava Cache的比較Java快取Guava
- 【轉載】通訊長連線與短連線
- Vue與React比較VueReact
- 【Redis與Memcached比較】Redis
- RecyclerView與ListView比較View
- js與jq比較JS
- PostgreSQL與MySQL比較MySql
- Vuex與Redux比較VueRedux
- 揚長補短 浪潮雲平臺的逆襲
- Java中對HashMap的深度分析與比較(轉)JavaHashMap
- ISAPI 與CGI 的 比 較 及 其 實 現 (轉)API
- 比較 python & perl(轉)Python
- Java Comparable排序介面和Comparator比較器介面Java排序
- React與Vue模板使用比較(一、vue模板與React JSX比較)ReactVueJS
- 轉一個比較詳盡的XP登入介面製作教程
- Microsoft .NET與J2EE的比較[E] (轉)ROS
- Flutter 與 iOS 功能比較FlutteriOS
- Flutter與Swift比較 - evroneFlutterSwiftVR
- Hibernate與mybatis比較MyBatis
- Python 與 Javascript 比較PythonJavaScript
- 長連線與短連線
- PHP實現長連結轉化成新浪短連結API介面程式碼分享PHPAPI
- XML資料讀取方式效能比較XML
- GML、SVG、VML的比較 (轉)SVG
- (轉)ORACLE 中IN和EXISTS比較Oracle
- 比較perl模組的版本(轉)
- 流行語言的比較 (轉)
- 動態企業建模DEM與ERP的比較(轉)
- FreeBSD與Linux比較 哪個更“開放”?(轉)Linux