Opened 9 years ago
Closed 3 years ago
#3771 closed defect (duplicate)
Wrong clock interval
Reported by: | niklwors | Owned by: | vwaurich |
---|---|---|---|
Priority: | high | Milestone: | Future |
Component: | Backend | Version: | |
Keywords: | Modelica_Synchronous, synchronous features, cpp runtime | Cc: | rfranke, bthiele, vwaurich |
Description (last modified by niklwors)
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 Changed 9 years ago by rfranke
comment:2 follow-up: ↓ 7 Changed 9 years ago by 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.
comment:3 Changed 9 years ago by niklwors
- Description modified (diff)
comment:4 in reply to: ↑ description Changed 9 years ago by bthiele
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 Changed 8 years ago by niklwors
- Cc vwaurich added
comment:6 Changed 8 years ago by lochel
- Keywords Modelica_Synchronous added
comment:7 in reply to: ↑ 2 Changed 8 years ago by vwaurich
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 Changed 8 years ago by lochel
- Owner changed from lochel to vwaurich
- Status changed from new to assigned
comment:9 Changed 8 years ago by vwaurich
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:
- compute clock equations
- compute next clock tick time
- 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 follow-up: ↓ 14 Changed 8 years ago by 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.
comment:11 Changed 8 years ago by rfranke
See also the new Modelica ticket
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 Changed 8 years ago by niklwors
- Priority changed from blocker to high
comment:13 Changed 8 years ago by bthiele
I agree. Certainly not a blocker and arguably a questionable feature in the first place.
comment:14 in reply to: ↑ 10 ; follow-up: ↓ 15 Changed 8 years ago by 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.
comment:15 in reply to: ↑ 14 Changed 8 years ago by vwaurich
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 Changed 3 years ago by AnHeuermann
- Resolution set to duplicate
- Status changed from assigned to closed
There are loads of errors with computing the Clock interval. See https://github.com/OpenModelica/OpenModelica/issues/7854
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."