OpenModelica导出FMU后在OpenModelica、导入FMU及FMPy中结果不一致的排查咨询
OpenModelica导出FMU后在OpenModelica、导入FMU及FMPy中结果不一致的排查咨询
我太懂你花两天抠这个问题的崩溃感了!跨工具的FMU兼容性问题真的是模型工程师的噩梦,尤其是明明在原工具和自身导入FMU都正常,换个工具就出问题的情况。结合你给出的伪代码和描述,我从几个方向帮你拆解可能的原因,还有对应的排查步骤:
核心问题的可能诱因
1. 离散事件逻辑的工具解析差异
你用的when语句属于离散事件触发逻辑,这部分恰恰是FMI规范里不同工具最容易出现实现偏差的地方:
- OpenModelica作为FMU的导出方,自己导入时会完全兼容自身的事件触发时序、检测逻辑,但FMPy对FMI 2.0规范里离散事件的处理细节可能不一样。比如你的
signal2是在signal1 >=1时赋值为当前time,FMPy可能没正确捕捉到这个事件的触发时机,导致signal2一直停留在异常初始值,进而影响signal3的计算。 - 另外,FMPy对
when语句里直接使用time变量的场景,可能有特殊的处理逻辑,比如在事件触发时是否同步了最新的time值给signal2,这个细节很容易被忽略。
2. der()的兼容性大坑
你怀疑der()是问题点,这个方向完全没错:
- FMI规范对导数的计算和暴露有严格要求,尤其是涉及离散变量的导数(比如
signal4 = der(...)依赖signal2这种离散赋值的变量)。离散变量的导数在事件点之外是0,事件点上是脉冲信号,FMPy对这种脉冲导数的解析逻辑和OpenModelica可能完全不同,甚至可能直接忽略这部分计算。 - 还要检查OpenModelica导出FMU时,是否把
der()相关的变量设置为可观测的输出变量。有时候导出时默认会隐藏内部导数变量,导致FMPy根本无法正确获取或计算它。
3. FMU导出的配置细节
别小看导出时的那些复选框,很多问题都出在这里:
- 检查OpenModelica的FMU导出设置:是否勾选了支持离散事件的相关选项?有没有选择正确的FMI接口类型(虽然你说CS和ME都试了,但ME模式对事件的处理复杂度更高,兼容性可能更差)。
- 确认
signal2、signal3这些关键变量是否被标记为输出变量。如果FMPy无法访问signal2的正确值,signal3的计算自然会出错。
4. 事件检测的精度与仿真配置
- 浮点数比较的容差问题:你用的
signal1 >=1触发条件,OpenModelica可能用了宽松的精度阈值,而FMPy用了严格的精确比较,导致明明signal1已经到1了,FMPy却没检测到事件触发。可以试试把条件改成signal1 >= 1 - 1e-6这种带容差的形式,再测试。 - 仿真步长的影响:如果FMPy用了固定步长仿真,很可能会跳过
signal1 >=1的触发点,导致when语句从未执行。建议切换成支持事件检测的变步长求解器(比如CVode),并确保开启了事件检测功能。
快速排查步骤
- 先简化模型测试:把
der()相关的signal4去掉,只保留when语句和signal3的逻辑,导出FMU后用FMPy测试。如果这时候正常了,那问题100%出在der()的部分;如果还是异常,就聚焦在when语句的事件处理上。 - 监控中间变量:把
signal2也设为输出变量,在FMPy里直接看signal2的数值。如果signal2一直是0,说明when语句没触发;如果signal2是正确的time值,但signal3还是0,那就是signal3=signal2+10的等式没被正确执行。 - 开启FMPy的事件日志:在FMPy的仿真配置里打开事件日志功能,看看日志里有没有记录
signal1 >=1的事件触发。如果完全没记录,那就是事件检测的问题;如果有触发记录但变量值没更新,那就是变量赋值的同步问题。
备注:内容来源于stack exchange,提问作者Sepi
相关产品推荐
相关产品推荐

