OpenModelica生成的FMU在ADEVS中初始化时_fmi2SetTime调用失败
ADEVS调用
_fmi2SetTime触发断言失败的排查与解决 问题场景
使用ADEVS离散事件模拟器仿真OpenModelica Compiler v1.20.0生成的FMU模型,编译运行后在adevs_fmi.h的status = _fmi2SetTime(c,t_now);处触发断言错误:
void adevs::FMI::init(double*) [with X = adevs::PortValue<ExchangeData*>]: Assertion `status == fmi2OK' failed.
该FMU可在OpenModelica中正常仿真,但ADEVS初始化阶段调用_fmi2SetTime失败。
排查方向与解决办法
1. 检查FMU类型与FMI版本兼容性
- ADEVS的FMI接口通常对**Model Exchange(ME)和Co-Simulation(CS)**类型有明确区分,部分版本可能仅支持其中一种。OpenModelica生成FMU时默认可能选择ME类型,若ADEVS期望CS类型则会导致调用失败。
- 解决:重新在OpenModelica中生成FMU,明确选择Co-Simulation类型;同时核对ADEVS文档确认其支持的FMI版本(需与OM生成的FMU版本一致,比如均为FMI2.0)。
2. 验证起始时间参数合法性
t_now的值可能超出FMU模型定义的时间范围,或与模型默认起始时间不匹配。OpenModelica模型默认起始时间通常为0.0,若ADEVS传入的t_now为负数、非零值,或超出FMU的modelDescription.xml中defaultExperiment定义的时间区间,会触发_fmi2SetTime失败。- 解决:
- 查看FMU解压后的
modelDescription.xml,确认defaultExperiment的startTime值; - 确保ADEVS中传入的
t_now与该值完全一致,优先使用0.0作为起始时间测试。
- 查看FMU解压后的
3. 核对FMI2标准调用顺序
- FMI2接口有严格的调用流程,若ADEVS的
init函数跳过了关键步骤(如未调用fmi2SetupExperiment就直接执行_fmi2SetTime),会导致状态错误。标准初始化流程应为:fmi2Instantiate → fmi2SetupExperiment → fmi2EnterInitializationMode → fmi2ExitInitializationMode - 解决:查看
adevs_fmi.h中的init函数实现,确认是否遵循上述顺序;若存在流程缺失,补充对应的FMI2调用步骤。
4. 统一编译环境与架构
- OpenModelica生成的FMU与ADEVS编译的可执行文件若存在架构不匹配(如FMU为64位,ADEVS编译为32位)、编译器ABI不兼容(如OM用GCC 11,ADEVS用GCC 8),会导致函数调用时返回异常状态。
- 解决:
- 确保ADEVS与FMU均为相同架构(x86_64或x86);
- 使用相同版本的编译器编译ADEVS,优先匹配OpenModelica使用的编译器版本。
5. 开启FMI日志定位具体错误
- 断言仅提示状态非OK,但未说明具体错误类型(如
fmi2Error、fmi2Discard等)。可通过开启FMI日志获取详细信息:// 在调用_fmi2SetTime前添加日志配置 fmi2SetDebugLogging(c, fmi2True, 0, NULL, fmi2True); status = _fmi2SetTime(c, t_now); // 打印返回状态 std::cout << "fmi2SetTime 返回状态: " << status << std::endl; - 根据返回的状态码对照FMI2规范,定位具体错误(如参数非法、实例未初始化等)。
内容的提问来源于stack exchange,提问作者rain
相关产品推荐
相关产品推荐

