Opened 6 years ago
Last modified 6 years ago
#5148 new defect
Changes of integer input of FMU are ignored
Reported by: | Owned by: | Lennart Ochel | |
---|---|---|---|
Priority: | critical | Milestone: | Future |
Component: | Backend | Version: | v1.13.0-dev-nightly |
Keywords: | Cc: |
Description
When simulating an FMU with an integer input that should trigger when
condition in algorithm
block, changes are ignored but the input is passed through correctly.
How to reproduce
TestInt.mo:
model TestInt input Integer inInt; output Integer outInt; output Integer passthrough; initial equation outInt = 0; algorithm when inInt > pre(inInt) then outInt := outInt + 1; end when; equation passthrough = inInt; end TestInt;
TestInt.mos:
print(buildModelFMU(TestInt, "1.0", "me")); print(getErrorString());
input.csv:
time;inInt 0.0;0 0.7;1 0.8;2
Compile it with
$ omc TestInt.mos TestInt.mo /home/trosinenko/TestInt.fmu $ ...
Simulate with FMUChecker (tested with 2.0.3):
$ path/to/fmuCheck.linux64 -i input.csv TestInt.fmu [INFO][FMUCHK] FMI compliance checker Test [FMILibrary: Test] build date: Dec 19 2016 [INFO][FMUCHK] Called with following options: [INFO][FMUCHK] /path/to/fmuCheck.linux64 -i input.csv TestInt.fmu [INFO][FMUCHK] Will process FMU TestInt.fmu [INFO][FMILIB] XML specifies FMI standard version 1.0 [INFO][FMUCHK] Model name: TestInt [INFO][FMUCHK] Model identifier: TestInt [INFO][FMUCHK] Model GUID: {344d6ea1-babe-4fab-a4f1-a7a6ef710740} [INFO][FMUCHK] Model version: [INFO][FMUCHK] FMU kind: ModelExchange [INFO][FMUCHK] The FMU contains: 0 constants 0 parameters 3 discrete variables 1 continuous variables 1 inputs 2 outputs 1 internal variables 0 variables with causality 'none' 0 real variables 3 integer variables 0 enumeration variables 1 boolean variables 0 string variables [INFO][FMUCHK] Printing output file header "time","outInt","passthrough" [INFO][FMUCHK] Opening input file input.csv [INFO][FMUCHK] Detected separator character in input file: ; [INFO][FMILIB] Loading 'linux64' binary with 'standard32' platform types [INFO][FMUCHK] Version returned from FMU: 1.0 [INFO][FMUCHK] Initialized FMU for simulation starting at time 0 0.0000000000000000E+00,0,0 2.0000000000000000E-03,0,0 4.0000000000000001E-03,0,0 ... 7.9600000000000004E-01,0,1 7.9800000000000004E-01,0,1 8.0000000000000004E-01,0,2 8.0200000000000005E-01,0,2 ... 9.9600000000000022E-01,0,2 9.9800000000000022E-01,0,2 1.0000000000000000E+00,0,2 [INFO][FMUCHK] Simulation finished successfully at time 1 FMU check summary: FMU reported: 0 warning(s) and error(s) Checker reported: 0 Warning(s) 0 Error(s)
Changing line
when inInt > pre(inInt) then
to
when change(inInt) then
does not change behavior.
Attachments (3)
Change History (8)
by , 6 years ago
Attachment: | TestInt.mo added |
---|
by , 6 years ago
Attachment: | TestInt.mos added |
---|
by , 6 years ago
comment:1 by , 6 years ago
comment:2 by , 6 years ago
Some random observations:
- when I change types of
inInt
andpassthrough
toReal
, both expressions from the above mentioned workaround give the same stay-at-zero counter (which is not surprising becausex > pre(x)
for continuous Real variables is quite strange) - adding
+d=newInst
to the command line does not change anything
For slightly modified Test.mo:
model Test input Integer inInt; output Integer outInt, o; output Integer passthrough; initial equation outInt = 0; o = 0; algorithm when inInt > pre(inInt) then outInt := outInt + 1; end when; when passthrough > pre(passthrough) then o := o + 1; end when; equation passthrough = inInt; end Test;
... looking at the generated Test.c
after executing omc -s ../Test.mo
, I see the following
/* equation index: 9 type: SIMPLE_ASSIGN passthrough = inInt */ void Test_eqFunction_9(DATA *data, threadData_t *threadData) { TRACE_PUSH const int equationIndexes[2] = {1,9}; data->localData[0]->integerVars[3] /* passthrough DISCRETE */ = (modelica_integer)data->localData[0]->integerVars[0] /* inInt variable */; TRACE_POP } /* equation index: 10 type: ALGORITHM o := pre(o); $whenCondition2 := pre($whenCondition2); outInt := pre(outInt); $whenCondition1 := pre($whenCondition1); $whenCondition1 := false; when $whenCondition1 then outInt := outInt + 1; end when; $whenCondition2 := passthrough > pre(passthrough); when $whenCondition2 then o := o + 1; end when; */ void Test_eqFunction_10(DATA *data, threadData_t *threadData) { ... }
I see two interesting points here:
$whenCondition1
is explicitly assignedfalse
just before usage in Modelica pseudocode (so it looks not like just a bug in the fmi runtime)- the
passthrough
variable is shown asDISCRETE
, whileinInt
is just avariable
, just like non-discrete Reals from the example above. On the other hand,passthrough
is annotated as discrete by default (this is, again, logical, since it is integral type)
comment:3 by , 6 years ago
Seems like the issue #5149 about not being able to specify discrete input Integer inInt;
is really connected to this one not by mere coincidence, since the lowerKnownVarkind
function seems to be intentionally returning BackendDAE.VARIABLE()
even for inherently-discrete types, and copy-pasting type-aware code from the lowerVarkind
function leads to an error about mixed-determined system.
This issue looks quite insidious since it does not lead to compile-time or even run-time error -- just to (probably hard-to-debug) unexpected behaviors, so I humbly set the importance to critical
:)
comment:4 by , 6 years ago
Component: | *unknown* → Backend |
---|---|
Owner: | changed from | to
Priority: | high → critical |
comment:5 by , 6 years ago
I made PR: https://github.com/OpenModelica/OMCompiler/pull/2742
with your suggested changes (also set String variables to discrete).
I will run the testsuite on it to see how many models this change breaks.
Possibly related: #5149
Workaround for this bug: replace
with
Then it works (except for that one need to add something like
output Real x
andder(x) = x
equation, so it is validated in FMUChecker 2.0.4).