Opened 9 years ago

Closed 3 years ago

#3771 closed defect (duplicate)

Wrong clock interval

Reported by: Niklas Worschech Owned by: Volker Waurich
Priority: high Milestone: Future
Component: Backend Version:
Keywords: Modelica_Synchronous, synchronous features, cpp runtime Cc: Rüdiger Franke, Bernhard Thiele, Volker Waurich

Description (last modified by Niklas Worschech)

For the following example it appears the clock interval calculation is not correct

model TestClock
Integer nextInterval(start=1);
Clock c = Clock(nextInterval,210);
equation 
  when c then
    nextInterval = previous(nextInterval) + 1;
  end when;
end TestClock;

For the next clock interval the following equation is generated:
_clockInterval[0] =(_$CLKPRE_P_nextInterval / 210.0) * 1.0 / 1.0;

I think to calculate the next clock interval, instead of the previous interval value the current interval value should be used.
In the cpp runtime the next clock interval is calculated after the evaluation of the corresponding clock equations

_$CLKPRE_P_nextInterval = _nextInterval;
nextInterval = (1 + _$CLKPRE_P_nextInterval);

_clockInterval[0] = (_$CLKPRE_P_nextInterval / 210.0) * 1.0 / 1.0;

At time=0 when the clock ticks for the first time, previous(interval)=1 but it should be interval = 2 to calculate the correct next clock interval.

Change History (16)

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

See ModelicaSpec33, section 16.3 Clock Constructors:

"The clock starts at the start of the simulation tstart or when the controller is switched on. Here the next clock tick is scheduled at
interval1 = previous(intervalCounter)/resolution = interval.start/resolution.
At the second clock tick at time tstart+interval1, the next clock tick is scheduled at
interval2 = previous(intervalCounter)/resolution, and so on."

comment:2 by Niklas Worschech, 9 years ago

Maybe the problem is the order of the equations.

_$CLKPRE_P_nextInterval = _nextInterval;
nextInterval = (1 + _$CLKPRE_P_nextInterval);
_clockInterval[0] = (_$CLKPRE_P_nextInterval / 210.0) * 1.0 / 1.0;

or the way how the previous value of nextInterval is stored.

comment:3 by Niklas Worschech, 9 years ago

Description: modified (diff)

in reply to:  description comment:4 by Bernhard Thiele, 9 years ago

There is a similar example in the Section 16.3 in the MLS:

Integer nextInterval(start=2);
 // first interval = 2/100
equation
Clock(interval)
when Clock(nextInterval, 100) then
// interval clock that ticks at 0, 0.02, 0.05, 0.09, ...
nextInterval = previous(nextInterval) + 1;
end when;

So, the spec example assumes that the previous interval value is used to define the next time instants where the clock ticks. Running that with Dymola I got a different result (clock ticks at 0, 0.03, 0.07) which surprised me. I think the example is correct and Dymola wrong. However, the "Dymola" interpretation seems to be identical with the interpretation that is described in this ticket.

comment:5 by Niklas Worschech, 9 years ago

Cc: Volker Waurich added

comment:6 by Lennart Ochel, 9 years ago

Keywords: Modelica_Synchronous added

in reply to:  2 comment:7 by Volker Waurich, 9 years ago

Replying to niklwors:

Maybe the problem is the order of the equations.

_$CLKPRE_P_nextInterval = _nextInterval;
nextInterval = (1 + _$CLKPRE_P_nextInterval);
_clockInterval[0] = (_$CLKPRE_P_nextInterval / 210.0) * 1.0 / 1.0;

or the way how the previous value of nextInterval is stored.

$CLKPRE.y and $CLKPRE.nextInterval have to be assigned after the tick is completed, i.e. at the end of the partition equations, since $CLKPRE.nextInterval is used to compute the next clock time. Putting the $CLKPRE at the end of the partition equations and not at the beginning could help. I will try this.

comment:8 by Lennart Ochel, 9 years ago

Owner: changed from Lennart Ochel to Volker Waurich
Status: newassigned

comment:9 by Volker Waurich, 9 years ago

I separated the previous(var) = var equations from the clocked equations in SimCode in order to realise the following workflow during a tick and to handle the initial point of time correctly:

  1. compute clock equations
  2. compute next clock tick time
  3. assign previous-variables

The model fom modelica spec p 194 should be simulated correctly according to the spec(but not according to dymola)

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

The example uses a feature that is not supported in the current Cpp runtime: an integer clock with varying intervalCounter. The major use case for integer and real clocks is intervals with fixed length. The backend even relies on known constant intervals for sub-clock conversion, in order to be able to do clock inference.

The work around for this example is to use a clock with boolean condition (event clock). See the reformulation of the example in #3772.

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

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

See also the new Modelica ticket

https://trac.modelica.org/Modelica/ticket/2022

Is the questionable formulation of a periodic clock with variable interval, instead of an event clock with boolean condition, really a blocker for OpenModelica?

comment:12 by Niklas Worschech, 9 years ago

Priority: blockerhigh

comment:13 by Bernhard Thiele, 9 years ago

I agree. Certainly not a blocker and arguably a questionable feature in the first place.

Last edited 9 years ago by Bernhard Thiele (previous) (diff)

in reply to:  10 ; comment:14 by Volker Waurich, 9 years ago

Replying to rfranke:

The example uses a feature that is not supported in the current Cpp runtime: an integer clock with varying intervalCounter. The major use case for integer and real clocks is intervals with fixed length. The backend even relies on known constant intervals for sub-clock conversion, in order to be able to do clock inference.

The work around for this example is to use a clock with boolean condition (event clock). See the reformulation of the example in #3772.

It is indeed supported in OMC as descripted by the spec. Try ClockInterval.mo in ccpruntime testsuite.

in reply to:  14 comment:15 by Volker Waurich, 9 years ago

Replying to vwaurich:

Replying to rfranke:

The example uses a feature that is not supported in the current Cpp runtime: an integer clock with varying intervalCounter. The major use case for integer and real clocks is intervals with fixed length. The backend even relies on known constant intervals for sub-clock conversion, in order to be able to do clock inference.

The work around for this example is to use a clock with boolean condition (event clock). See the reformulation of the example in #3772.

It is indeed supported in OMC as descripted by the spec. Try ClockInterval.mo in ccpruntime testsuite. At least for the branch niklwors commited recently

comment:16 by Andreas Heuermann, 3 years ago

Resolution: duplicate
Status: assignedclosed

There are loads of errors with computing the Clock interval. See https://github.com/OpenModelica/OpenModelica/issues/7854

Note: See TracTickets for help on using tickets.