Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to change parameter values using replaceSubModel in OMSimulator Python #1262

Open
njsaisashank opened this issue Oct 6, 2023 · 8 comments

Comments

@njsaisashank
Copy link

@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

@arun3688
Copy link
Contributor

arun3688 commented Oct 6, 2023

@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])

Output

# ../../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])

Output

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

@arun3688
Copy link
Contributor

arun3688 commented Oct 6, 2023

@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

@njsaisashank
Copy link
Author

@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?

@arun3688
Copy link
Contributor

arun3688 commented Oct 6, 2023

@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

@arun3688
Copy link
Contributor

arun3688 commented Oct 6, 2023

@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

@njsaisashank
Copy link
Author

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.

@njsaisashank
Copy link
Author

Anyway, thanks a lot for the help.

@arun3688
Copy link
Contributor

@njsaisashank this commit #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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant