【问题标题】:FMU FMI simulation, no evaluation of some equations after initializationFMU FMI 模拟,初始化后不评估某些方程
【发布时间】:2015-08-08 08:52:58
【问题描述】:

我相信我的问题与this previous question 有某种关系,但我无法根据他们的建议解决我的问题。

这是一个最小的非工作示例。我有一个简单的电路,里面有一个换向开关(在 openModelica 中开发)。我想根据输入参数的值修改 switch.control 的值。为此,我有以下几点:

model MinimalNonWorkingExemple

 parameter Modelica.Blocks.Interfaces.RealInput openclose;
 Modelica.Electrical.Analog.Ideal.IdealCommutingSwitch switch;
 Modelica.Electrical.Analog.Basic.Ground G;

equation
 connect(switch.p, G.p);
 connect(switch.n2, G.p);
 connect(switch.n1, G.p);

 switch.control = if openclose > 0.5 then true else false;
end MinimalNonWorkingExemple;

注意:我尝试了参数、输入等之间的多种组合...

我想做一个迭代模拟(例如模拟 60 秒的系统,但在 1 秒内连续模拟 60 次)。这是为了能够根据另一个 FMU 模拟来改变输入值(openclose)。

因此,我可以修改来自 pyFMI 的输入值。 (当我阅读它时,已将更改考虑在内)。但是,我的方程式中也没有考虑“新值”。

这是我的 pyfmi 脚本:

# Import the load function (load_fmu)
from pyfmi import load_fmu
import numpy as np 
from pylab import *

def simulate(model, res, startTime,finalTime, initialState):
 if res == None:
    opts=model.simulate_options()
    opts['initialize']=True
 else:
    opts=model.simulate_options()
    opts['initialize']=False

 for s in initialState:
    model.set(s[0],s[1])

 res = model.simulate(start_time = startTime, final_time=finalTime, options=opts)
 return res


 #main part
 model = load_fmu('MinimalNonWorkingExemple.fmu')
 switchClose = ['openclose', [0.0]]
 switchOpen = ['openclose', [1.0]]

 #Simulate an FMU
 res = simulate(model, None, 0, 50, [switchOpen])

 v = res["openclose"]
 v2 = res["switch.control"]

 res = simulate(model, res, 50, 100, [switchClose])
 v = np.concatenate((v,res["openclose"]))
 v2 = np.concatenate((v2,res["switch.control"]))

 res = simulate(model, res, 100, 200, [switchOpen])
 v = np.concatenate((v,res["openclose"]))
 v2 = np.concatenate((v2,res["switch.control"]))

 print v
 print v2

基本上我在 50 个单位时间内进行模拟,然后更改 openclose 变量的值,然后再次模拟,再次切换并重新模拟。结果我得到:

 openclose:      [ 1.  1.  1.  1.  0.  0.  0.  0.  1.  1.  1.  1.]
 switch.control: [ 1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.]

实际上,只有在第一次调用 model.simulate(...) 之前创建的集合才会在系统中传播其值。

我试图理解annotation(Evaluate = false) 提议的here,但没有奏效。我不确定它是否相关,因为我实际上可以改变我的价值。问题是基于此参数的方程似乎只在初始化期间评估:-/

非常欢迎任何想法/帮助...

【问题讨论】:

  • 似乎我们完全删除了 if 方程并仅放入基于 openclose > 0.5 的选定分支。但是,如果你不给出完整的模型是很难调试的。您可以尝试将 if 方程重写为 if 表达式: switch.control = if openclose > 0.5 then true else false;
  • 感谢您的解释,我认为您是对的。改变方程的形式不会改变任何东西:-/我修改了我的原始帖子以提供一个最小的非工作示例。我希望它能帮助我们了解如何解决这个问题。谢谢

标签: openmodelica fmi pyfmi


【解决方案1】:

据我所知,FMI 标准规定,在您初始化模型后,您对参数的更改将不再影响模型。因此,必须使用重置并重新初始化模型,以便再次获取更改。 这段代码似乎可以正常工作:

# Import the load function (load_fmu)
from pyfmi import load_fmu
import numpy as np 
from pylab import *

def simulate(model, res, startTime,finalTime, initialState):
  if res == None:
    opts=model.simulate_options()
    opts['initialize']=True
  else:
    model.reset()
    opts=model.simulate_options()
    opts['initialize']=True

  for s in initialState:
    model.set(s[0],s[1])

  res = model.simulate(start_time = startTime, final_time=finalTime, options=opts)
  return res


#main part
model = load_fmu('MinimalNonWorkingExemple.fmu')
print model.get_description()
model.set_log_level(7)
switchClose = ['openclose', [0.0]]
switchOpen = ['openclose', [1.0]]

#Simulate an FMU
res = simulate(model, None, 0, 50, [switchOpen])

v = res["openclose"]
v2 = res["switch.control"]

res = simulate(model, res, 50, 100, [switchClose])
v = np.concatenate((v,res["openclose"]))
v2 = np.concatenate((v2,res["switch.control"]))

res = simulate(model, res, 100, 200, [switchOpen])
v = np.concatenate((v,res["openclose"]))
v2 = np.concatenate((v2,res["switch.control"]))

print v
print v2

结果是:

[ 1.  1.  1.  1.  0.  0.  0.  0.  1.  1.  1.  1.]
[ 1.  1.  1.  1.  0.  0.  0.  0.  1.  1.  1.  1.]

您还可以在此处查看讨论: http://ext5.modelon.ideon.se/5858

如果您将 openclose 设为输入(无参数),然后将输入对象提供给模拟(openclose、时间、值),也可能会起作用,如下例所示: http://www.jmodelica.org/assimulo_home/pyfmi_1.0/pyfmi.examples.html#module-pyfmi.examples.fmu_with_input 但是,我没有尝试过,所以它可能不起作用。

【讨论】:

  • 嗨,再次感谢您的帮助。重置和恢复模型的状态是我已经尝试过的一种解决方法,但在某些情况下它会失败。 (例如,对于以下 openmodelica 模型:Modelica::Mechanics::MultiBody::Examples::Systems::RobotR3::fullRobot 出现以下错误:params[i] = model.get(i) File "fmi.pyx", line 227, in pyfmi.fmi.ModelBase.get (src/pyfmi/fmi.c:4099) File "fmi.pyx", line 3612, in pyfmi.fmi.FMUModelBase2._get (src/pyfmi/fmi.c:31666) pyfmi.fmi.FMUException: Type not supported. 所以我虽然它不是正确的解决方案。
  • 我也尝试了 input object 解决方案,但结果与原始帖子中的相同...如果重置是唯一的方法,我会这样做但是在模拟过程中需要大量时间。 但是,在我看来,在 modelica 中引入 volatile variable 的概念以充分利用 FMU 和更普遍地进行联合仿真很重要。 你怎么看?再次感谢
  • 编辑:保存、重置和恢复方式适用于一些简单的模型。对于更复杂的模型,例如之前评论中提到的 FullRobot,它会失败:-/ 在避免恢复和保存错误后(无法设置枚举类型和 keyError 问题)我获得了两种不同的模拟,具体取决于我在一次调用 model.simulate(...) 或两次连续调用中执行此操作...我想我会提出另一个问题,但如果能够从 FMU 修改特定变量会很棒:) 非常感谢你的帮助
猜你喜欢
  • 2014-08-09
  • 2022-12-11
  • 1970-01-01
  • 2017-04-03
  • 1970-01-01
  • 1970-01-01
  • 2010-12-08
  • 1970-01-01
  • 2022-10-02
相关资源
最近更新 更多