Opened 5 years ago

Last modified 5 years ago

#5402 new defect

sample(...) operator does not work in Cpp FMU runtime

Reported by: atrosinenko Owned by: lochel
Priority: high Milestone: Future
Component: Code Generation Version: v1.14.0-dev-nightly
Keywords: cpp fmu sample Cc:

Description

When using sample operator in a model, an FMU is compiled successfully, but it does not "tick".

How to reproduce

Compile this model:

TestSample.mo:

model TestSample
  output Integer counter;
initial algorithm
  counter := 0;
algorithm
  when sample(0, 0.25) then
    counter := counter + 1;
  end when;
end TestSample;

... with the following script:
tester.mos:

print(buildModelFMU(TestSample));
print(getErrorString());

... in C and Cpp modes.

$ omc --simCodeTarget=C tester.mos TestSample.mo                     
/tmp/TestSample.fmu

$ ~/soft/FMUChecker-2.0.4/build/fmuCheck.linux64 -n 10 TestSample.fmu
[INFO][FMUCHK] FMI compliance checker Test [FMILibrary: Test] build date: Sep  1 2018
[INFO][FMUCHK] Called with following options:
[INFO][FMUCHK] /home/trosinenko/soft/FMUChecker-2.0.4/build/fmuCheck.linux64 -n 10 TestSample.fmu
[INFO][FMUCHK] Will process FMU TestSample.fmu
[INFO][FMILIB] XML specifies FMI standard version 2.0
[INFO][FMUCHK] Model name: TestSample
[INFO][FMUCHK] Model GUID: {376610ce-4dff-45b4-9f45-3324c6b1c663}
[INFO][FMUCHK] Model version: 
[INFO][FMUCHK] FMU kind: ModelExchange
[INFO][FMUCHK] The FMU contains:
0 constants
0 parameters
3 discrete variables
0 continuous variables
0 inputs
1 outputs
2 local variables
0 independent variables
0 calculated parameters
0 real variables
2 integer variables
0 enumeration variables
1 boolean variables
0 string variables

[INFO][FMUCHK] Printing output file header
"time","counter"
[INFO][FMUCHK] Model identifier for ModelExchange: TestSample
[INFO][FMILIB] Loading 'linux64' binary with 'default' platform types
[INFO][FMUCHK] Version returned from ME FMU: '2.0'

[INFO][FMUCHK] Initialized FMU for simulation starting at time 0
0.0000000000000000E+00,1
1.0000000000000001E-01,1
2.0000000000000001E-01,1
3.4999999999999998E-01,2
4.4999999999999996E-01,2
5.0000000000000000E-01,3
5.9999999999999998E-01,3
6.9999999999999996E-01,3
8.4999999999999998E-01,4
9.4999999999999996E-01,4
1.0000000000000000E+00,5
[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)
$ omc --simCodeTarget=Cpp tester.mos TestSample.mo
/tmp/TestSample.fmu

$ ~/soft/FMUChecker-2.0.4/build/fmuCheck.linux64 -n 10 TestSample.fmu
[INFO][FMUCHK] FMI compliance checker Test [FMILibrary: Test] build date: Sep  1 2018
[INFO][FMUCHK] Called with following options:
[INFO][FMUCHK] /home/trosinenko/soft/FMUChecker-2.0.4/build/fmuCheck.linux64 -n 10 TestSample.fmu
[INFO][FMUCHK] Will process FMU TestSample.fmu
[INFO][FMILIB] XML specifies FMI standard version 2.0
[INFO][FMUCHK] Model name: TestSample
[INFO][FMUCHK] Model GUID: {9b7ffb92-39d7-42ca-abff-65d03f7643cc}
[INFO][FMUCHK] Model version: 
[INFO][FMUCHK] FMU kind: ModelExchange
[INFO][FMUCHK] The FMU contains:
0 constants
0 parameters
3 discrete variables
0 continuous variables
0 inputs
1 outputs
2 local variables
0 independent variables
0 calculated parameters
0 real variables
2 integer variables
0 enumeration variables
1 boolean variables
0 string variables

[INFO][FMUCHK] Printing output file header
"time","counter"
[INFO][FMUCHK] Model identifier for ModelExchange: TestSample
[INFO][FMILIB] Loading 'linux64' binary with 'default' platform types
[INFO][FMUCHK] Version returned from ME FMU: '2.0'

[INFO][FMUCHK] Initialized FMU for simulation starting at time 0
0.0000000000000000E+00,0
1.0000000000000001E-01,0
2.0000000000000001E-01,0
3.4999999999999998E-01,0
4.4999999999999996E-01,0
5.0000000000000000E-01,0
5.9999999999999998E-01,0
6.9999999999999996E-01,0
8.4999999999999998E-01,0
9.4999999999999996E-01,0
1.0000000000000000E+00,0
[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)

What is expected

Both tick every 1/4 second.

What really happens

The Cpp FMU compiles successfully but does not work as expected. Maybe I should have used something like counter := pre(counter) + 1; but this does not work, too.

For me, this looks quite serious, since when compiler refuses to compile model (even with an internal error), it is clear that something gone wrong. But in this case nothing suspicious happens nor when compiling nor in run-time.

Change History (2)

comment:1 Changed 5 years ago by atrosinenko

Analysis (1.14.0~dev-5833-g646bc9b)

This model

model Test
  output Integer n;
//  output Real x;
equation
//  der(x) = x;
algorithm
  when {sample(0, 0.001)} then
    n := n + 1;
  end when;
end Test;

gives the following output

0.0000000000000000E+00,0
1.0000000000000001E-01,0
2.0000000000000001E-01,0
2.9999999999999999E-01,0
4.0000000000000002E-01,0
5.0000000000000000E-01,0
5.9999999999999998E-01,0
7.0000000000000007E-01,0
8.0000000000000004E-01,0
9.0000000000000002E-01,0
1.0000000000000000E+00,0

As you see, nothing happens.

How let's add a continuous state

model Test
  output Integer n;
  output Real x;
equation
  der(x) = x;
algorithm
  when {sample(0, 0.001)} then
    n := n + 1;
  end when;
end Test;

This changes output to

0.0000000000000000E+00,0.0000000000000000E+00,0
1.0000000000000001E-01,0.0000000000000000E+00,1
2.0000000000000001E-01,0.0000000000000000E+00,1
2.9999999999999999E-01,0.0000000000000000E+00,1
4.0000000000000002E-01,0.0000000000000000E+00,1
5.0000000000000000E-01,0.0000000000000000E+00,1
5.9999999999999998E-01,0.0000000000000000E+00,1
7.0000000000000007E-01,0.0000000000000000E+00,1
8.0000000000000004E-01,0.0000000000000000E+00,1
9.0000000000000002E-01,0.0000000000000000E+00,1
1.0000000000000000E+00,0.0000000000000000E+00,1

Event triggers, but only once. This seems to be because of FMU2Wrapper::getDerivatives calls _model->computeTimeEventConditions(_model->getTime());.

But why only once? It seems to be because on every time event except the very first the condition _$whenCondition1_ && !_discrete_events->pre(_$whenCondition1_) inside the OMCppTest.cpp from FMU is false since both current and previous values are true.

Now add another sample(...)

model Test
  output Integer n;
  output Real x;
equation
  der(x) = x;
algorithm
  when {sample(0, 0.001), sample(0.0001, 0.001)} then
    n := n + 1;
  end when;
end Test;

This model works as expected

0.0000000000000000E+00,0.0000000000000000E+00,0
1.0000000000000001E-01,0.0000000000000000E+00,200
2.0000000000000001E-01,0.0000000000000000E+00,400
2.9999999999999999E-01,0.0000000000000000E+00,600
4.0000000000000002E-01,0.0000000000000000E+00,800
5.0000000000000000E-01,0.0000000000000000E+00,1000
5.9999999999999998E-01,0.0000000000000000E+00,1200
7.0000000000000007E-01,0.0000000000000000E+00,1400
8.0000000000000004E-01,0.0000000000000000E+00,1600
9.0000000000000002E-01,0.0000000000000000E+00,1800
1.0000000000000000E+00,0.0000000000000000E+00,2000

comment:2 Changed 5 years ago by atrosinenko

So in this trivial "clocked" case, the workround would probably be to execute another dummy sample(...) with the same period but different phase that still increments some dummy output (in case the compiler would want to optimize it out).

Note: See TracTickets for help on using tickets.