#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 , 9 years ago
Owner: | changed from | to
---|---|
Status: | new → accepted |
comment:2 by , 9 years ago
comment:3 by , 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 , 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 , 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 , 9 years ago
Resolution: | → fixed |
---|---|
Status: | accepted → closed |
Commit [Changeset: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.
I tried a simple hack to at least introduce the right prefix $CLKPRE:
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 theinterval()
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.