Python FMU变量值与输入不匹配

Python FMU变量值与输入不匹配,python,c,modelica,fmi,jmodelica,Python,C,Modelica,Fmi,Jmodelica,在我试图配置的一个简单的联合模拟中,我得到了一些奇怪的行为。我在EnergyPlus中建立了一个建筑能源模型,以测试由JModelica生成的FMU。然而,建筑能源模型将在联合仿真步骤中挂起。然后我在JModelica运行FMU,得到了一些非常奇怪的结果 Modelica代码是: model CallAdd input Real FirstInput(start=0); input Real SecondInput(start=0); output Real FMUOut

在我试图配置的一个简单的联合模拟中,我得到了一些奇怪的行为。我在EnergyPlus中建立了一个建筑能源模型,以测试由JModelica生成的FMU。然而,建筑能源模型将在联合仿真步骤中挂起。然后我在JModelica运行FMU,得到了一些非常奇怪的结果

Modelica代码是:

model CallAdd
    input Real FirstInput(start=0);
    input Real SecondInput(start=0);
    output Real FMUOutput(start=0); 
    function CAdd
        input Real x(start=0);
        input Real y(start=0);
        output Real z(start=0);
        external "C"  annotation(Library = "CAdd", LibraryDirectory = "modelica://CallAdd");
    end CAdd;
equation
    FMUOutput = CAdd(FirstInput,SecondInput);
    annotation(uses(Modelica(version = "3.2.1")));
end CallAdd;
上述代码引用了“CAdd”,它是c代码“CAdd.c”的库文件:

使用CMD中的以下两个命令将其编译成库文件:

gcc -c CAdd.c -o CAdd.o
ar rcs libCAdd.a CAdd.o
我可以使用包装器在OpenModelica中运行上述示例,效果非常好

然后,我使用JModelica将上述内容编译为FMU,用于协同仿真。JModelica编译代码是:

# Import the compiler function
from pymodelica import compile_fmu

# Specify Modelica model and model file (.mo or .mop)
model_name = "CallAdd"
mo_file = "CallAdd.mo"

# Compile the model and save the return argument, for use later if wanted
my_fmu = compile_fmu(model_name, mo_file, target="cs")
然后,我模拟了FMU,并用JModelica Python代码得到了奇怪的结果:

from pyfmi import load_fmu
import numpy as np
import matplotlib.pyplot as plt

modelName = 'CallAdd'
numSteps = 100
timeStop = 20

# Load FMU created with the last script
myModel = load_fmu(modelName+'.fmu')

# Load options
opts = myModel.simulate_options()

# Set number of timesteps
opts['ncp'] = numSteps

# Set up input, needs more than one value to interpolate the input over time. 
t = np.linspace(0.0,timeStop,numSteps)
u1 = np.sin(t)
u2 = np.empty(len(t)); u2.fill(5.0)
u_traj = np.transpose(np.vstack((t,u1,u2)))
input_object = (['FirstInput','SecondInput'],u_traj)

# Internalize results
res = myModel.simulate(final_time=timeStop, input = input_object, options=opts)
# print 'res: ', res

# Internalize individual results
FMUTime = res['time']
FMUIn1 = res['FirstInput']
FMUIn2 = res['SecondInput']
FMUOut = res['FMUOutput']

plt.figure(2)
FMUIn1Plot = plt.plot(t,FMUTime[1:],label='FMUTime')
# FMUIn1Plot = plt.plot(t,FMUIn1[1:],label='FMUIn1')
# FMUIn2Plot = plt.plot(t,FMUIn2[1:],label='FMUIn2')
# FMUOutPlot = plt.plot(t,FMUOut[1:],label='FMUOut')
plt.grid(True)
plt.legend()
plt.ylabel('FMU time [s]')
plt.xlabel('time [s]')
plt.show()
这导致了结果“FMUTime”与python“t”的对比:

除了看到这种奇怪的行为外,FMU结果中的输入“FirstInput”和“SecondInput”与python代码中指定的u1和u2不匹配。我希望有人能帮助我更好地了解正在发生的事情

最好的


Justin

根据@ChristianAndersson更新我的JModelica安装的建议,我上面问题中描述的问题已经解决

JModelica 1.17.0于2015年12月发布


JModelica-SDK-1.12.0于2016年2月发布,是根据源代码构建的,它修复了问题并为我提供了预期的结果

根据@ChristianAndersson更新我的JModelica安装的建议,上述问题中描述的问题得到了解决

JModelica 1.17.0于2015年12月发布


JModelica-SDK-1.12.0于2016年2月发布,是根据源代码构建的,它修复了问题并为我提供了预期的结果

是否有任何理由不必要地通过使用C模块来增加复杂性,只需添加两个双倍?@Olaf是的,这是一个更大模型的简单配置,其中我们使用C代码来调用python模型。抱歉,但这听起来也很奇怪。但是,由于我不太了解modelica以及它是如何与Python集成的,所以我就到此为止。自从1.17以来,已经发生了很多事情,所以我建议使用可用的SDK来尝试开发版本,这似乎是固定的,或者一直保持到1.18可用。我正在为我的论文做一个研究项目。我将尝试开发版本。谢谢你抽出时间。如果开发版本纠正了这个问题,我会更新帖子。有什么原因让你仅仅使用C模块来添加两个
双倍的
?@Olaf是的,这是一个更大模型的简单配置,其中我们使用C代码来调用python模型。对不起,这听起来也很奇怪。但是,由于我不太了解modelica以及它是如何与Python集成的,所以我就到此为止。自从1.17以来,已经发生了很多事情,所以我建议使用可用的SDK来尝试开发版本,这似乎是固定的,或者一直保持到1.18可用。我正在为我的论文做一个研究项目。我将尝试开发版本。谢谢你抽出时间。如果开发版本纠正了问题,我将更新帖子。
from pyfmi import load_fmu
import numpy as np
import matplotlib.pyplot as plt

modelName = 'CallAdd'
numSteps = 100
timeStop = 20

# Load FMU created with the last script
myModel = load_fmu(modelName+'.fmu')

# Load options
opts = myModel.simulate_options()

# Set number of timesteps
opts['ncp'] = numSteps

# Set up input, needs more than one value to interpolate the input over time. 
t = np.linspace(0.0,timeStop,numSteps)
u1 = np.sin(t)
u2 = np.empty(len(t)); u2.fill(5.0)
u_traj = np.transpose(np.vstack((t,u1,u2)))
input_object = (['FirstInput','SecondInput'],u_traj)

# Internalize results
res = myModel.simulate(final_time=timeStop, input = input_object, options=opts)
# print 'res: ', res

# Internalize individual results
FMUTime = res['time']
FMUIn1 = res['FirstInput']
FMUIn2 = res['SecondInput']
FMUOut = res['FMUOutput']

plt.figure(2)
FMUIn1Plot = plt.plot(t,FMUTime[1:],label='FMUTime')
# FMUIn1Plot = plt.plot(t,FMUIn1[1:],label='FMUIn1')
# FMUIn2Plot = plt.plot(t,FMUIn2[1:],label='FMUIn2')
# FMUOutPlot = plt.plot(t,FMUOut[1:],label='FMUOut')
plt.grid(True)
plt.legend()
plt.ylabel('FMU time [s]')
plt.xlabel('time [s]')
plt.show()