Closed eidekrist closed 5 months ago
It is easy enough to just move the setup()
call to after initial values have been set, and I'll do that, but I suspect that the root cause of the problem is that your FMUs don't quite conform to the FMI specification. Let me explain why I think so.
First, note that the run-single
command doesn't go via cosim::simulator
. The (perhaps poorly named) variable simulator
in run_single.cpp
, which your link refers to, is in fact of type std::shared_ptr<cosim::slave>
. It points to a cosim::fmi::v1::slave_instance
or a cosim::fmi::v2::slave_instance
, depending on which FMI version your FMUs use.
Here is how the initialisation functions map to FMI functions for the two versions. For FMI 1,
cosim::fmi::v1::setup()
does not call any function in the FMUcosim::fmi::v1::start_simulation()
calls:
fmiInitializeSlave()
In other words, it doesn't really matter when setup()
is called, because it doesn't interact with the FMU code in any way. So this makes me think that your FMU uses FMI 2, despite the fact that you mention an initialize()
method. Is this correct?
For FMI 2,
cosim::fmi::v2::setup()
calls:
fmi2SetupExperiment()
fmi2EnterInitializationMode()
cosim::fmi::v2::start_simulation()
calls:
fmi2ExitInitializationMode()
Here, there could in principle be an issue, because certain types of variables cannot be set after fmi2EnterInitializationMode()
has been called – specifically, variables for which the initial
attribute in the model description is approx
. But the kind of variable that you mention sounds very much like something that has causality = parameter
, which always implies initial = exact
, and so it must be possible to set it after fmi2EnterInitializationMode()
has been called. Could it be that your FMUs are not entirely conforming to this part of the spec?
Well, this is embarrassing. My FMUs are using FMI version 1, and after reading your comments and taking a nice little dive into the code I've come to the same conclusion as you:
it doesn't really matter when setup() is called
I'm also not able to reproduce the behavior I originally described, so this must be down to a good old user error. Apologies!
cosim run OspSystemStructure.xml
will set user defined initial values beforecosim::simulator::setup()
is called.cosim run-single MyFmu.fmu foo=bar
will set user defined initial values aftercosim::simulator::setup()
is called, see run_single.cpp:275.cosim::simulator::setup()
eventually calls the FMIinitialize()
method which means, in the latter case, that the FMU will be initialized before the desired initial values have been set.I have a number of FMUs which are vitally dependent on a variable having a certain value before
fmi::initialize()
is called, the prime example being the path of a resource file not known at FMU generation time. Being able to usecosim run-single
for debugging would be great. Until now I've had to create a simple OspSystemStructure.xml and usecosim run
for this purpose.