Opened 10 years ago
Closed 10 years ago
#2767 closed defect (fixed)
fmi2GetDerivatives shifts value references by -1 when calling getReal of FMU
Reported by: | Owned by: | Willi Braun | |
---|---|---|---|
Priority: | critical | Milestone: | 1.9.1 |
Component: | FMI | Version: | trunk |
Keywords: | Cc: | Willi Braun |
Description
First of all: thank you for the fast processing of #2762!
Now the exported FMU version 2.0 shall run in another environment (github.com/omuses/hqp). According to modelDescription.xml the FMU has the following variables:
valueReference name 0 y1 1 y2 2 der(y1) 3 der(y2) 4 u local!!??? 5 p 6 y1_start 7 y2_start
When the environment calls fmi2GetDerivatives, then OpenModelica calls the getReal function of the generated DIC_FMU.c with the vr's 1 and 2 -- it must be 2 and 3! Can you please check your implementation of fmi2GetDerivatives?
Btw.: it's a pitty that the fmi-functions, such as fmi2GetDerivatives are not part of the exported C-code. This would simplify debugging and potential porting to an embedded target platform.
Moreover: this week a change has been introduced that now lets the input u appear with causality "local" in modelDescription.xml!? Can you please check as well?
Attachments (1)
Change History (9)
comment:1 by , 10 years ago
comment:2 by , 10 years ago
Meanwhile I found the fmi2 functions in /usr/include/omc/c/fmi2/fmu2_model_interface.c
. It runs with debugging and with logging now.
The function fmi2GetDerivatives obtaines the vr's for derivatives with (see fmu2_model_interface.c, L791):
fmi2ValueReference vr = vrStates[i] + 1;
The double integrator example above works with:
fmi2ValueReference vr = NUMBER_OF_STATES + i;
The crash happens if fmi2Reset
is called after fmi2Terminate
. fmi2Reset calls the function setAllVarsToStart from libSimulationRuntimeC.so
, which crashes. Can it be that fmi2Terminate
frees too much memory, which should be delayed until fmi2FreeInstance
?
The remaining question is, why the evaluation of the model equations is not triggered in ContinuousTimeMode after initialization ... Shouldn't the functions fmi2SetTime/Real/ContinuousStates set a flag, which results in an evaluation of the model before the next fmi2Get... returns? What else is needed to trigger the evaluation?
comment:3 by , 10 years ago
The following patch adapts fmu2_model_interface.c
to fmu1_model_interface.c
, fixing the value references for derivatives (lines 53 and 793) and adding the evaluation of the model equations (line 790). This basically solves this ticket.
-
fmu2_model_interface.c
old new 50 50 // array of value references of states 51 51 #if NUMBER_OF_REALS>0 52 52 fmi2ValueReference vrStates[NUMBER_OF_STATES] = STATES; 53 fmi2ValueReference vrStatesDerivatives[NUMBER_OF_STATES] = STATESDERIVATIVES; 53 54 #endif 54 55 55 56 // --------------------------------------------------------------------------- … … 786 787 return fmi2Error; 787 788 if (nullPointer(comp, "fmi2GetDerivatives", "derivatives[]", derivatives)) 788 789 return fmi2Error; 790 comp->fmuData->callback->functionODE(comp->fmuData); 789 791 #if NUMBER_OF_STATES>0 790 792 for (i = 0; i < nx; i++) { 791 fmi2ValueReference vr = vrStates [i] + 1;793 fmi2ValueReference vr = vrStatesDerivatives[i]; 792 794 derivatives[i] = getReal(comp, vr); // to be implemented by the includer of this file 793 795 FILTERED_LOG(comp, fmi2OK, LOG_FMI2_CALL, "fmi2GetDerivatives: #r%d# = %.16g", vr, derivatives[i]) 794 796 }
Open issues that arose from the treatment of this ticket are the strange implementation of getReal (possibly returning fmi2Error as fmi2Real) and the crash if fmi2Reset is called after fmi2Terminate.
comment:4 by , 10 years ago
Cc: | added |
---|---|
Owner: | changed from | to
Status: | new → assigned |
Following things fixed in r22404,
- Fixed fmi2GetDerivatives.
- getReal now only returns fmi1Real/fmi2Real.
- Added LogCategories to modelDescription.xml
If you call fmi2SetDebugLogging
then you should read the log categories from the modelDescription.xml file and pass it to that function to enable logging. If you are not calling this function then loggingOn
parameter of fmi2Instantiate
function will work.
I think the only issue left is,
Moreover: this week a change has been introduced that now lets the input u appear with causality "local" in modelDescription.xml!? Can you please check as well?
Perhaps Willi will get some time to fix it.
by , 10 years ago
comment:5 by , 10 years ago
Sounds good. Looking forward to getting the next nightly build, in order to try it out!
The "local" thing was my fault. I had changed
input Real u (start = -2)
to
Real u = -2
in OMEdit, in order to get a value in the simulation (see also #2763). OMEdit automatically saved the changed model before the simulation. Meanwhile I disabled this auto saving in my Preferences of OMEdit.
The only remaining issue is the crash if fmi2Reset
is called after fmi2Terminate
. This happens if more than one simulation is performed in a process keeping the model loaded. Can it be that fmi2Terminate
releases too much memory? Or shall I open a separate ticket for this?
comment:6 by , 10 years ago
Try r22422. I tried to reinitialize the data when fmi2Reset is called.
I am not sure if it will work fine but lets give it a try. I don't have a testcase to test this scenario.
comment:7 by , 10 years ago
It works with the new nightly OpenModelica 1.9.1+dev (r22423)!
If you want to run a test case, I added the example to the HQP solver, see:
https://github.com/omuses/hqp/commit/ad90db6bc26094019e8fa515685ed2b707855df2
You might:
$ git clone https://github.com/omuses/hqp.git $ cd hqp $ ./configure $ make $ cd odc $ ./runtk dic_fmu
The last command will invoke omc to compile DIC.fmu
from DIC.mo
, run an optimization and plot the results -- there are some dependencies like gcc
and tcl-dev
for the compilation of the solver as well as omc
for the compilation of the model and optionally blt
for the plotting.
Multiple runs in the same process can be performed with the Tcl command:
$ ./odc $ time {source dic_fmu.tcl} 10
to perform 10 runs and get the time per run.
Thank's a lot!
P.S.: eventually the model specific definitions in the drivers dic_fmu.tcl
and dic_fmu_est.tcl
should go into custom annotations. Then one will be able to specify the complete optimization or estimation together with the model in Modelica.
comment:8 by , 10 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
If it works fine then its ok :).
If you have problems then open a new ticket about it and then I will try to setup the test case.
Forget the last paragraph "Moreover ..." in the ticket above. ... Attempting to work around #2763, I had removed the input keyword in OMEdit and OMEdit saved the changed model when simulating it ...
Btw.: I'm using OpenModelica 1.9.1+dev (r21721).
Now all FMU functions, except fmi2GetDerivatives, seem to return the correct values.
However, the derivatives appear to be constant during the simulation. This is because the functions
DIC_eqFunction_*
with the model equations in the exported fileDIC.c
get only called once at model initialization. Afterwards onlyDIC_output_function
is called during the simulation.The FMU simulates (and optimizes) correctly after having fixed the problems with wrong
fmi2GetDerivatives
andDIC_eqFunction_*
!Two more problems became visible though:
The function
getReal
in the exported fileDIC_FMU.c
returnsfmi2Error
per default, which results in a value of 3.0!?Attempting to instantiate the FMU a second time in the same process leads to a crash, which most likely is caused by wrong management of dynamic memory.
Please consider two generals improvements for the FMI2 export:
loggingOn
argument of the functionfmi2Instantiate
doesn't appear to do anything. Meaning that I have to manually add log messages to the exported C-Code, again and again if I change the model and re-export it.What is your preferred practice when developing and debugging the FMI2 export?