Opened 9 years ago

Closed 9 years ago

Last modified 9 years ago

#3497 closed defect (fixed)

Wrong initial system for clocked equations

Reported by: Rüdiger Franke Owned by: Lennart Ochel
Priority: high Milestone: 1.9.4
Component: Backend Version:
Keywords: Cc:

Description

Consider the following synchronous discrete-time model

model SID "Single Integrator Discrete-time"
  parameter Real dt = 0.1 "sample time" annotation(Evaluate=true);
  parameter Real p = 1 "gain for input";
  parameter Real y_start = 0 "start value for state";
  Real xd(start = y_start);
  input Real u(start = -2);
  output Real y;
equation
  when Clock(dt) then
    xd = previous(xd) + p * u * dt;
  end when;
  y = hold(previous(xd));
end SID;

OpenModelica adds the clocked equation to the initial equations and solves it. See: omc -s -d=dumpSimCode SID.mo

initialEquations: (4)
-----------------------
1: xd=y_start[Real ]
2: $PRE.xd=xd + -0.1 * p * u[Real ]
3: $var1=$PRE.xd[Real ]
4: y=$getPart($var1)[Real ]

This is wrong because the clock does not tick during initialization. Equations 2 and 3 should read:

2: $CLKPRE.xd=xd[Real ]
3: $var1=$CLKPRE.xd[Real ]

Change History (8)

comment:1 by Lennart Ochel, 9 years ago

Owner: changed from somebody to Lennart Ochel
Status: newaccepted

comment:2 by Rüdiger Franke, 9 years ago

I tried a simple hack to at least introduce the right prefix $CLKPRE:

BackEnd/Initialization.mo:2240 (replaceDerPreCref)
-      dummyder = ComponentReference.crefPrefixPre(cr);
+      dummyder = ComponentReference.crefPrefixString("$CLKPRE", cr);

BackEnd/Initialization.mo:2148 (collectInitialVars)
-      preCR = ComponentReference.crefPrefixPre(cr);  // cr => $PRE.cr
+      preCR = ComponentReference.crefPrefixString("$CLKPRE", cr);

With this hack in collectInitialVars the pre() operator does not work anymore -- one would need to distinguish clocked variables. Couldn't the clock index be added to the variables (so far it only exists for equations)? This would also help during code generation, e.g. for the interval() operator.

Moreover the clocked equation is still part with this fix; it just works with the right variables then.

Note that the test clockedTest.mos brakes after the fix, because there is another issue in the Cpp runtime that counter-works this bug. It needs to be fixed at the same time.

comment:3 by Lennart Ochel, 9 years ago

This example is now working although I didn't touch the initial equations. Rüdiger, can you please check if there is still an issue?

comment:4 by Rüdiger Franke, 9 years ago

Yes it works. But xd starts at 0.2, not at y_start=0. This is due to the wrong initial equation 2: above. The remaining result is correct, because the current Cpp runtime erronously evaluates the clocked partition twice during initialization.

ModelicaSpec33, section 16.9 Initialization of Clocked Partitions says:

The standard scheme for initialization of Modelica models does not apply for clocked discrete-time partitions. Instead, initialization is performed in the following way:

  • Clocked discrete-time variables cannot be used in initial equation or initial algorithm sections.
  • Attribute “fixed” cannot be applied on clocked discrete-time variables. The attribute “fixed” is true for variables to which the previous operator is applied, otherwise false.

comment:5 by Rüdiger Franke, 9 years ago

Commit

https://github.com/OpenModelica/OMCompiler/commit/9e5b3b0d652143f577b3025b67c6db6138c2f01f

separates clocked from discrete variables. This is required because clocked variables get different names, using the prefix $CLKPRE instead of $PRE.

omc -s -d=dumpSimCode SID.mo gives now:

initialEquations: (4)
-----------------------
1: xd=y_start[Real ]
2: $CLKPRE.xd=xd + -0.1 * p * u[Real ]
3: $var1=$CLKPRE.xd[Real ]
4: y=$getPart($var1)[Real ]

Both: the C and the Cpp runtime produce the correct simulation result for xd now -- the C runtime used to crash or produce nothing prior to #3498 and this fix.

The output y still has the wrong start value 0.2, instead of y_start=0, due to the wrong initial equation 2:. The remaining issue is to replace 2: with $CLKPRE.xd=xd.

comment:6 by Rüdiger Franke, 9 years ago

Resolution: fixed
Status: acceptedclosed

Commit c1357acebd31ba56e359671bff42d466747e16d8/OMCompiler
introduces the specific function createInitialClockedEqns for clocked partitions. It provides the correct initialization of clocked states. All other clocked variables are initialized with their start values.

Last edited 9 years ago by Rüdiger Franke (previous) (diff)

comment:7 by Martin Sjölund, 9 years ago

Milestone: 1.9.41.9.4-1.9.x

Milestone renamed

comment:8 by Martin Sjölund, 9 years ago

Milestone: 1.9.4-1.9.x1.9.4

Milestone renamed

Note: See TracTickets for help on using tickets.