Simulink 仿真需依賴 MATLAB 環境,透過 MATLAB Engine 介面可在 VC++ 應用程式中啟動 MATLAB 為後台計算引擎,實現參數傳遞、命令執行、結果取回。本文詳細說明 Engine API、VC++ 專案設定、Simulink 命令列仿真指令、資料類型轉換、Solver 選擇等實戰技巧。
標頭檔:#include "engine.h"
| 函數 | 功能 | 語法 |
|---|---|---|
engOpen | 啟動 MATLAB Engine | Engine* engOpen(const char* startcmd) (Windows 傳 NULL) |
engClose | 關閉 Engine | int engClose(Engine* ep) |
engEvalString | 執行 MATLAB 命令字串 | int engEvalString(Engine* ep, const char* cmd) |
engGetArray | 從工作區取得變數 | mxArray* engGetArray(Engine* ep, const char* name) |
engPutArray | 將變數放入工作區 | int engPutArray(Engine* ep, const mxArray* mp) |
engOutputBuffer | 設定輸出緩衝區 | int engOutputBuffer(Engine* ep, char* buf, int len) |
| Solver | 類型 | 適用場景 |
|---|---|---|
ode45 | Non-stiff, RK4/5 階 | 通用連續系統,預設 |
ode23 | Non-stiff, RK2/3 階 | 精度要求較低、速度優先 |
ode113 | Non-stiff, Adams PECE | 高精度、平滑系統 |
ode15s | Stiff, NDF 變階 | **剛性系統** (含斷路器/開關模型) |
ode23s | Stiff, Rosenbrock 2階 | 剛性、低精度需求 |
ode23t | Stiff, 梯形法則 | 剛性 + DAE 三角系統 |
ode23tb | Stiff, TR-BDF2 | 剛性、低階 |
關鍵經驗:可控整流電路故障模型屬剛性系統 (短路器模擬開路),必須選擇剛性 Solver (如 ode15s)。VC 中透過 engEvalString 設定 Solver 僅影響本次仿真,模型預設不變。雖 Simulink 仍可能警告,但實際仿真耗時可驗證 Solver 生效。
核心函數:mxCreateDoubleMatrix、mxGetPr、memcpy
// VC double[] → MATLAB mxArray (設定仿真時間)
double timespan[2] = { m_fStartTime, m_fStopTime };
mxArray* T = mxCreateDoubleMatrix(1, 2, mxREAL);
memcpy((char*)mxGetPr(T), (char*)timespan, 2 * sizeof(double));
engPutVariable(ep, "T", T); // 放入工作區
// MATLAB mxArray → VC double[] (讀取結果)
mxArray* Y = engGetArray(ep, "yout");
double result[100];
memcpy((char*)result, (char*)mxGetPr(Y), 100 * sizeof(double));
注意:mxGetPr 回傳 double* 指向資料區,memcpy 為最高效轉換方式。
Engine* ep = engOpen(NULL);
if (!ep) return FALSE;
// 1. 載入模型
engEvalString(ep, "model = 'rectifier_fault';");
engEvalString(ep, "load_system(model);");
// 2. 設定參數 (Solver, 仿真時間)
engEvalString(ep, "set_param(model, 'Solver', 'ode15s', 'StopTime', '0.1');");
// 3. 傳遞輸入資料 (若有)
engPutVariable(ep, "T", T);
engPutVariable(ep, "U", U);
// 4. 執行仿真
engEvalString(ep, "[t, x, y] = sim(model, T, options, U);");
// 5. 取回結果
mxArray* Y = engGetArray(ep, "y");
// memcpy 取出資料...
// 6. 關閉
engEvalString(ep, "close_system(model, 0);");
engClose(ep);
MATLAB_ROOT\bin\win32mxArray* 取得後需 mxDestroyArray 釋放engEvalString 開銷大,批次組合命令字串MATLAB Engine 為 VC++ 提供了強大的數學計算後台,配合 Simulink 命令列仿真,可構建「VC 前台介面 + MATLAB 後台計算」架構。掌握 Engine API、mxArray 轉換、Solver 選擇三大核心,即可高效完成混合程式開發。