如何在Matlab脚本中加载并运行Dymola生成的FMI2格式FMU?
Matlab加载Dymola生成的FMI2格式FMU完整步骤
一、FMU预处理
- 将Dymola生成的
.fmu文件解压到本地目录,解压后会包含bin(存放平台相关DLL)、include(FMI2头文件)、modelDescription.xml(模型元信息)等文件夹及文件,后续操作均基于此解压目录。
二、正确加载DLL与FMI2头文件
你当前代码中分开加载三个头文件的方式容易出现定义重复或缺失问题,Dymola生成的FMU中,include目录下的fmi2.h已包含fmi2Functions、fmi2FunctionTypes、fmi2TypesPlatform的所有定义,直接加载该头文件即可:
% 配置路径 fmuUnzipDir = '请替换为你的FMU解压目录'; libname = 'toto'; % DLL文件名(不含.dll后缀) libfile = fullfile(fmuUnzipDir, 'bin', 'win64', [libname '.dll']); % 注意匹配Matlab位数,64位对应win64目录 headerFile = fullfile(fmuUnzipDir, 'include', 'fmi2.h'); % 加载动态链接库 if ~libisloaded(libname) % 生成包装函数m文件,后续调用更便捷 loadlibrary(libfile, headerFile, 'mfilename', 'fmi2Wrapper'); end
- 若加载报错,需先通过
mex -setup配置Matlab支持的C编译器,确保头文件与DLL的平台位数(32/64位)和Matlab一致。
三、仿真初始化流程
需严格遵循FMI2标准的初始化步骤,关键操作如下:
- 验证库加载成功
% 获取FMI版本信息,确认加载有效 fmiVersion = calllib(libname, 'fmi2GetVersion'); disp(['当前FMI版本:', fmiVersion]);
- 创建仿真实例
从modelDescription.xml中提取模型的GUID(<fmiModelDescription>标签的guid属性),调用实例化函数:
modelGuid = '{替换为你的模型GUID}'; % fmi2CoSimulation表示协同仿真模式,若为模型交换模式则用fmi2ModelExchange simInstance = calllib(libname, 'fmi2Instantiate', 'MyFMUInstance', fmi2CoSimulation, modelGuid, '', 0, 0);
- 设置仿真实验参数
startTime = 0.0; stopTime = 10.0; % 设置仿真起始与结束时间 calllib(libname, 'fmi2SetupExperiment', simInstance, 0, startTime, 0, stopTime);
- 初始化模型
进入初始化模式,可在此设置输入变量(变量的valueReference需从modelDescription.xml中查询):
calllib(libname, 'fmi2EnterInitializationMode', simInstance); % 示例:设置输入变量(替换为实际的valueReference和数值) inputRef = 123; inputVal = 5.0; calllib(libname, 'fmi2SetReal', simInstance, libpointer('int32Ptr', inputRef), 1, libpointer('doublePtr', inputVal)); calllib(libname, 'fmi2ExitInitializationMode', simInstance);
四、单步仿真运行
通过fmi2DoStep函数执行单步仿真,循环推进时间:
currentTime = startTime; stepSize = 0.01; % 自定义仿真步长 while currentTime < stopTime % 执行单步仿真 simStatus = calllib(libname, 'fmi2DoStep', simInstance, currentTime, stepSize, 1); if simStatus ~= fmi2OK error('单步仿真执行失败'); end % 示例:获取输出变量(替换为实际的valueReference) outputRef = 456; outputVal = calllib(libname, 'fmi2GetReal', simInstance, libpointer('int32Ptr', outputRef), 1); disp(['时间:', num2str(currentTime + stepSize), ' 输出值:', num2str(outputVal)]); % 更新当前时间 currentTime = currentTime + stepSize; end
五、仿真结束与资源清理
仿真完成后必须释放实例并卸载库,避免内存泄漏:
calllib(libname, 'fmi2Terminate', simInstance); calllib(libname, 'fmi2FreeInstance', simInstance); unloadlibrary(libname);
关键注意事项
- 所有模型相关的关键信息(GUID、变量
valueReference、FMI模式)必须从modelDescription.xml中提取,不可随意填写。 - 确保DLL平台位数与Matlab一致(64位Matlab对应
bin/win64下的DLL)。 - 若涉及复杂变量类型(如字符串、布尔量),需使用对应
fmi2SetXXX/fmi2GetXXX函数。
内容的提问来源于stack exchange,提问作者Clement44
相关产品推荐
相关产品推荐

