Skip to content

Challenging event coincidence and incorrect reference result in LogicalSample #4731

@henrikt-ma

Description

@henrikt-ma

After over three years of fruitful discussions in #4063, I have become aware of yet another problem with the Modelica.Clocked.Examples.Elementary.ClockSignals.LogicalSample example, this time due to effects of ideally coinciding events.

Analysis of rotational clock timing

This analysis concerns the initial period of duration 0.5, during which trigger_interval_input.y is 3. The sine_angle_input and cosine_angle_input have the same frequency and phase shift, and both have amplitude 10. As the sine_angle_input.y starts at 0, the ideal timing of rotational_clock_1 is that it ticks when sine_angle_input.y crosses a threshold which is an integer multiple of 3 away from 0. Similarly, the cosine_angle_input.y starts at 10, so the ideal timing of rotational_clock_2 is that it ticks when cosine_angle_input.y crosses a threshold which is an integer multiple of 3 away from 10.

Approximately at time 0.398 ($(1 - arcsin(6/10)/π)/2$, to be precise), sine_angle_input.y crosses its threshold at 2 * 3 = 6. At the exact same time cosine_angle_input.y is -8 (check: $6^2 + 8^2 = 10^2$), which means it is crossing its threshold at 10 - 6 * 3 = -8.

That is, an exact implementation will have the two rotational clocks ticking simultaneously near time 0.398. However, it is easy to imagine how small errors in the zero crossing detection could result in a buildup of errors in the rotational clock thresholds, and that the two events in reality become detected at slightly different points in time. Since they would ideally coincide, it is probably best to not make assumptions about which ot the two that would trigger first.

Consequences for conjunctive clock

Since time 0.234 and up to time 0.398, one of the inputs to the conjunctiveClock.combinator are {false, true} (I haven't seen a reason to question the values of these inputs before the coinciding event). Depending on the timing of the two events near time 0.398, different things will happen:

  • conjunctiveClock.u[1] ticks first: First, the combinator sees {true, true}, so the conjunctive clock ticks, and the combinator inputs are reset to {false, false}. At the second event, the combinator inputs become {false, true}.
  • conjunctiveClock.u[2] ticks first: At the first tick, nothing important changes, as the second combinator input is already true. At the second tick, the combinator sees {true, true}, so the conjunctive clock ticks and the combinator inputs are reset to {false, false}.
  • coinciding ticks: At the tick, the combinator inputs become {true, true}, the conjunctive clock ticks, and the combinator inputs are reset to {false, false}.

That is, the conjunctive clock will tick near time 0.398 in all three cases, but its internal state is not the same in all three cases. As it happens in this example, the next conjunctive clock input to tick is the u[1] coming from rotational_clock_1, approximately at tim 0.452, meaning that the difference in internal state will manifest in a difference between ticking and not ticking near time 0.452.

Comparison to reference result

Here is an excerpt from the reference result:

"time","rotational_clock_1.angle","rotational_clock_1.direction","rotational_clock_1.direction_changed","rotational_clock_2.angle","rotational_clock_2.direction","rotational_clock_2.direction_changed","sample_conjunctive.y","sample_disjunctive.y"
…
0.45120000000000005,3.0183748152159575,-1,1,-9.5335939432550845,-1,0,6.0000000002918696,5.9999999983752055
0.45150665798479134,3.0000000002918688,-1,1,-9.5393920140776682,-1,0,6.0000000002918696,5.9999999983752055
0.45150665798479134,3.0000000002918688,-1,0,-9.5393920140776682,-1,0,3.0000000002918688,3.0000000002918688
0.4516,2.9944047726371448,-1,0,-9.5411498289046843,-1,0,3.0000000002918688,3.0000000002918688
0.45200000000000001,2.9704158157703491,-1,0,-9.5486454474664288,-1,0,3.0000000002918688,3.0000000002918688
…

It is seen that sample_conjunctive.y changes from 6.0000000002918696 to 3.0000000002918688 at an event at time 0.45150665798479134, meaning that the conjunctive clock's internal state must have been {false, true} when leaving time 0.398. It is worth noting that this is not the internal state matching the ideal result with coinciding events.

Remark about the disjunctive clock

The ideally coinciding events also have consequences for the disjunctive clock, but the effects are less pronounced. That is, the times at which the disjunctive clock have ticks are approximately the same in the difference cases, but the number of ticks will be different. If the model would have included a count of the ticks, the difference would have become as apparent as for the conjunctive clock.

Metadata

Metadata

Assignees

No one assigned

    Labels

    L: ClockedIssue addresses Modelica.Clocked

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions