I believe my problem is somehow related to this previous question but I was not able to fix my problem with their advices.
Here is a minimal non working example. I have a simple electrical circuit with a commutating switch in it (developed in openModelica). I want to modify the value of switch.control depending on the value of an input Parameter. To do that I have the following:
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;
Note: I tried many combination between parameter, input, etc...
I want to make an iterative simulation (for instance simulate 60 seconds of the system but with 60 consecutive simulations of 1 second). This is to be able to change the input value (openclose) according to another FMU simulation.
As a result I can modify the value of the input from pyFMI. (when I read it, the changed is taken into account). However, the "new value" is not taken into account neither in my equations.
Here is my pyfmi script:
# 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
Basically I simulate during 50 units of time then I change the value of the openclose
variable, then simulating again, switching again and re-simulating. As a result I obtained:
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.]
Actually, only the set made before the first call to model.simulate(...)
propagates its value in the system.
I tried to understand the annotation(Evaluate = false)
proposed here but it did not work. I'm not sure if it is related since I can actually change my value. The problem is that the equations based on this parameter seems only evaluated during initialisation :-/
Any idea/help would be very welcome...
As far as I can understand, the FMI standard says that after you initialize the model your changes to the parameters will not affect the model anymore. So, one has to use reset and re-initialize the model so the changes are picked up again. It seems to work fine with this code:
# 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
The result is:
[ 1. 1. 1. 1. 0. 0. 0. 0. 1. 1. 1. 1.]
[ 1. 1. 1. 1. 0. 0. 0. 0. 1. 1. 1. 1.]
You can see also the discussion here: http://ext5.modelon.ideon.se/5858
It might work also if you make openclose an input (no parameter) and then give an input object to the simulation (openclose, time, value) as in the example here: http://www.jmodelica.org/assimulo_home/pyfmi_1.0/pyfmi.examples.html#module-pyfmi.examples.fmu_with_input However, I haven't tried it so it might not work.