Open njsaisashank opened 9 months ago
@njsaisashank the API is working as expected, you cannot see the new replaced values because of the <parameterBindings> values
defined in ssd for the VFController.fmu
has more priority compared to the new start values defined in the modeldescription.xml
in the replacing fmu VFController2.fmu
, these are the parameterBindings defined in ssd
<ssd:ParameterBindings>
<ssd:ParameterBinding>
<ssd:ParameterValues>
<ssv:ParameterSet
version="1.0"
name="parameters">
<ssv:Parameter
name="trapezoid.width">
<ssv:Real
value="20"
unit="s" />
</ssv:Parameter>
<ssv:Parameter
name="trapezoid.rising">
<ssv:Real
value="10"
unit="s" />
</ssv:Parameter>
<ssv:Parameter
name="trapezoid.amplitude">
<ssv:Real
value="60" />
</ssv:Parameter>
</ssv:Parameters>
</ssv:ParameterSet>
</ssd:ParameterValues>
</ssd:ParameterBinding>
</ssd:ParameterBindings>
And this is the reason the new values are not updated, I hope you set this values using oms_setReal
API when creating the ssp.
I made a minimal example where you can see the new start values gets updated in the replaced fmus, I just extracted your ssp and made this example
from OMSimulator import OMSimulator
oms = OMSimulator()
oms.setTempDirectory("./replacesubmodel_py/")
oms.newModel("sim1")
oms.addSystem("sim1.Root", oms.system_wc)
oms.addSubModel("sim1.Root.VfController", "sim1/resources/0005_VfController.fmu")
print("info: Original VfController_Model_inside ssp")
print("info: sim1.Root.VfController.trapezoid.width : " , oms.getReal("sim1.Root.VfController.trapezoid.width")[0])
print("info: sim1.Root.VfController.trapezoid.amplitude : " , oms.getReal("sim1.Root.VfController.trapezoid.amplitude")[0])
print("info: sim1.Root.VfController.trapezoid.rising : " , oms.getReal("sim1.Root.VfController.trapezoid.rising")[0])
oms.replaceSubModel("sim1.Root.VfController", "VfController2.fmu", False)
print("info: After Replacing VfController_Model")
print("info: sim1.Root.VfController.trapezoid.width : " , oms.getReal("sim1.Root.VfController.trapezoid.width")[0])
print("info: sim1.Root.VfController.trapezoid.amplitude : " , oms.getReal("sim1.Root.VfController.trapezoid.amplitude")[0])
print("info: sim1.Root.VfController.trapezoid.rising : " , oms.getReal("sim1.Root.VfController.trapezoid.rising")[0])
# ../../install/bin/OMSimulatorPython3 oms.py
info: Original VfController_Model_inside ssp
info: sim1.Root.VfController.trapezoid.width : 20.0
info: sim1.Root.VfController.trapezoid.amplitude : 60.0
info: sim1.Root.VfController.trapezoid.rising : 10.0
info: After Replacing VfController_Model
info: sim1.Root.VfController.trapezoid.width : 40.0
info: sim1.Root.VfController.trapezoid.amplitude : 30.0
info: sim1.Root.VfController.trapezoid.rising : 20.0
Example for priority values in parameterBindings
over modeldescription.xml in the new replaced fmu
, so that new start values are not replaced
from OMSimulator import OMSimulator
oms = OMSimulator()
oms.setTempDirectory("./replacesubmodel_py/")
oms.newModel("sim1")
oms.addSystem("sim1.Root", oms.system_wc)
oms.addSubModel("sim1.Root.VfController", "sim1/resources/0005_VfController.fmu")
## set new value for trapezoid.width
oms.setReal("sim1.Root.VfController.trapezoid.width", -100)
oms.export("sim1", "replaceSubmodelError.ssp")
oms.terminate("sim1")
oms.delete("sim1")
oms.importFile("replaceSubmodelError.ssp")
print("info: After setting new value VfController")
print("info: sim1.Root.VfController.trapezoid.width : " , oms.getReal("sim1.Root.VfController.trapezoid.width")[0])
print("info: sim1.Root.VfController.trapezoid.amplitude : " , oms.getReal("sim1.Root.VfController.trapezoid.amplitude")[0])
print("info: sim1.Root.VfController.trapezoid.rising : " , oms.getReal("sim1.Root.VfController.trapezoid.rising")[0])
oms.replaceSubModel("sim1.Root.VfController", "VfController2.fmu", False)
print("info: After Replacing VfController_Model")
print("info: sim1.Root.VfController.trapezoid.width : " , oms.getReal("sim1.Root.VfController.trapezoid.width")[0])
print("info: sim1.Root.VfController.trapezoid.amplitude : " , oms.getReal("sim1.Root.VfController.trapezoid.amplitude")[0])
print("info: sim1.Root.VfController.trapezoid.rising : " , oms.getReal("sim1.Root.VfController.trapezoid.rising")[0])
info: After setting new value VfController
info: sim1.Root.VfController.trapezoid.width : -100.0
info: sim1.Root.VfController.trapezoid.amplitude : 60.0
info: sim1.Root.VfController.trapezoid.rising : 10.0
info: After Replacing VfController_Model
info: sim1.Root.VfController.trapezoid.width : -100 ## here you can see the value is not updated based on priority over values set by user
info: sim1.Root.VfController.trapezoid.amplitude : 30.0
info: sim1.Root.VfController.trapezoid.rising : 20.0
@njsaisashank the meaning for dry is
if (dryRun==true)
showwarnings, reimport the snapshot and replacing is not done
else
show warnings and replace is done
But i also found that there is a bug if we directly replace the submodel from memory without exporting to the ssp. The priority set by user is not taken into account see below
from OMSimulator import OMSimulator
oms = OMSimulator()
oms.setTempDirectory("./replacesubmodel_py/")
oms.newModel("sim1")
oms.addSystem("sim1.Root", oms.system_wc)
oms.addSubModel("sim1.Root.VfController", "sim1/resources/0005_VfController.fmu")
## set new value for trapezoid.width
oms.setReal("sim1.Root.VfController.trapezoid.width", -100)
print("info: Original VfController_Model_inside ssp")
print("info: sim1.Root.VfController.trapezoid.width : " , oms.getReal("sim1.Root.VfController.trapezoid.width")[0])
print("info: sim1.Root.VfController.trapezoid.amplitude : " , oms.getReal("sim1.Root.VfController.trapezoid.amplitude")[0])
print("info: sim1.Root.VfController.trapezoid.rising : " , oms.getReal("sim1.Root.VfController.trapezoid.rising")[0])
oms.replaceSubModel("sim1.Root.VfController", "VfController2.fmu", False)
print("info: After Replacing VfController_Model")
print("info: sim1.Root.VfController.trapezoid.width : " , oms.getReal("sim1.Root.VfController.trapezoid.width")[0])
print("info: sim1.Root.VfController.trapezoid.amplitude : " , oms.getReal("sim1.Root.VfController.trapezoid.amplitude")[0])
print("info: sim1.Root.VfController.trapezoid.rising : " , oms.getReal("sim1.Root.VfController.trapezoid.rising")[0])
# ../../install/bin/OMSimulatorPython3 oms.py
info: Original VfController_Model_inside ssp
info: sim1.Root.VfController.trapezoid.width : -100.0
info: sim1.Root.VfController.trapezoid.amplitude : 60.0
info: sim1.Root.VfController.trapezoid.rising : 10.0
info: After Replacing VfController_Model
info: sim1.Root.VfController.trapezoid.width : 40.0 ## bug here it should -100
info: sim1.Root.VfController.trapezoid.amplitude : 30.0
info: sim1.Root.VfController.trapezoid.rising : 20.0
@arun3688 I have actually created the ssp using the OMEdit. Does it mean that OMEdit uses the set_real API by default? If so, are there any settings I could change so that it doesn't do it?
@njsaisashank no OMEdit internally calls OMSimulator
API to make the ssp, setReal
is called during different modes, during initialization, instantantion and simulation, but before instantiation if you use setReal
it means you are setting a new value for the variable and it will be used for the simulation. e.g
from OMSimulator import OMSimulator
oms = OMSimulator()
oms.setTempDirectory("./replacesubmodel_py/")
oms.newModel("sim1")
oms.addSystem("sim1.Root", oms.system_wc)
oms.addSubModel("sim1.Root.VfController", "sim1/resources/0005_VfController.fmu")
## set new value by user for trapezoid.width
oms.setReal("sim1.Root.VfController.trapezoid.width", -100)
oms.instantiate("sim1")
oms.initialize("sim1")
oms.simulate("sim1")
So this is how it works, and by default if nothing is set by the user or value is not modified, then the default values does not come in parameterBindings
in SystemStructure.ssd
, I have not used OMEDit to test this so i am not sure, but you can use OMSimulator from command Line as well
@njsaisashank I tested the example with OMEdit and i found that if you just opened the parameter dialogue of an fmu and even if you don't change any values it gets updated in the ssd file which should not be the case and that is why there is a difference from the command line and OMEdit, this need to be fixed in OMEdit
Yes, I think that is the case. I think it would work only if the fmus are added and connections are given and saved without modifying anything else.
Anyway, thanks a lot for the help.
@njsaisashank this commit https://github.com/OpenModelica/OMSimulator/pull/1264 will fix the replaceSubModel()
API when replacing submodel directly from memory without exporting to a ssp file see example https://github.com/OpenModelica/OMSimulator/blob/master/testsuite/simulation/replaceSubmodel14.py and https://github.com/OpenModelica/OMSimulator/blob/master/testsuite/simulation/replaceSubmodel13.py
However still the OMEdit issue exists and we will try to fix it
@arun3688 I have opened an issue in the OMSimulator repository like you mentioned and also I am sharing the ssp file, the python script and also the fmu file that needs to be replaced for your reference. Please look into it. replaceSubModel.zip