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 )
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 , 9 years ago
follow-up: 7 comment:2 by , 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 , 9 years ago
Description: | modified (diff) |
---|
comment:4 by , 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 , 9 years ago
Cc: | added |
---|
comment:6 by , 9 years ago
Keywords: | Modelica_Synchronous added |
---|
comment:7 by , 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 , 9 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:9 by , 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:
- 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)
follow-up: 14 comment:10 by , 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.
comment:11 by , 9 years ago
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 by , 9 years ago
Priority: | blocker → high |
---|
comment:13 by , 9 years ago
I agree. Certainly not a blocker and arguably a questionable feature in the first place.
follow-up: 15 comment:14 by , 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.
comment:15 by , 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 , 3 years ago
Resolution: | → duplicate |
---|---|
Status: | assigned → 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."