question

martin.j avatar image
1 Like"
martin.j asked Lars Jacobsen commented

Bug Report - Wait For Event on Tracked Variable in object label

I have run into a problem with the Wait For Event activity that waits for a value on a Kinetic Tracked Variable on an object label. I have created a loop that will represent a decision tree, that triggers when the kinetic variable reaches its specified value (20), but sometimes under some very unclear conditions the event triggers more than once and the token loops multiple times as a consequence - More seriously, sometimes it goes into an infinite loop.

Please see attached model - SomeTestOrOther.fsm

In the Source activity I set the offset time for when i change the rate of the Kinetic Tracked Variable on the FR-Object - this has an influence on the issue.

In the first Custom Code activity I set the rate to 0.8611 - the rate seem to have an influence on the issue as well.

If the offset time is 0 there is no problem - the event triggers when the kinetic value hits 20 around 23 seconds in and the loop is triggered once. But if the offset value is 200 the loop is triggered twice at 223 sec, and if the offset time is 500 the event is triggered continously causing an infinite loop. Going to 1000 secs also causes just a double loop.

However if I chance the rate value to just 0.86, the issue at 200 sec disapears and at 500 sec it becomes just a double loop. If the rate is set to a whole integer value I have been unable to reproduce the issiue - it always loops just once as expected.

Apparently there is some issue with the event trigger, that is affected by both the time and the rate of change, which makes the error very dificult to pinpoint, and it makes my reliance on Wait For Event on label-tracked-variables somewhat dangerous.

I have tested this in versions 20.2.3 , 21.0.3 , 21.0.4 & 21.1.0 the problem persists the same in all of these.

FlexSim 21.1.0
bug reportwait for eventflexsim 21.1.0kinetic tracked variabletracked variable on label
sometestorother.fsm (34.4 KiB)
· 2
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Phil BoBo avatar image
2 Likes"
Phil BoBo answered Lars Jacobsen commented

First, this situation absolutely needs a Breathe activity. You should not be waiting for the OnChange of a tracked variable from within the execution of that tracked variable's OnChange. You use a Breathe before waiting for the event again in order to let that event finish processing.

If you put a Breathe activity of 0 time, then it will consistently behave as expected to create an infinite loop of activities in 0 time, stalling the model.

What is happening

At time 0, the token enters the Wait for Event and evaluates whether the change rule (Increase To or Through Value) is met. Because the tracked variable is not >= 20, it calculates the time when the change rule will be met, based on the current time, the value of the tracked variable, and its rate of change. It schedules an event for that time.

During that event, it evaluates whether the the change rule is met. Since the value is now 20, it has met the change rule and releases the token. You send the token right back into that listener without any time change, and then it evaluates whether the change rule is met. Since 20 >= 20, it releases the token, continuing that loop of creating events in 0 time because you didn't have any delay.

Why it is inconsistent

The calculation for the time of the event where the rule will be met is based on floating-point precision values. Sometimes, the result of a floating point value calculation is not exactly equal to its mathematical equivalent. In the case where it doesn't cause an infinite loop of events, it is because the value of the tracked variable is 19.999999999999998 at the time of the event. When this is the case, 19.999999999999998 is not >= 20, but the calculation of the time when it will become 20 can sometimes evaluate to essentially 0 (1.65e-14) because of how floating-point precision values work in calculations. This causes an infinite loop that can actually crash the program when the breathe is missing because the calculation is all happening recursively in-line without any breaks in the evaluation of the original event.

Conclusion

Although this behavior may not be intuitive, it is intentional based on the design of how the Wait for Event activity works. You need a tiny delay before you re-evaluate the OnChange rule in this particular situation.

· 4
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Lars Jacobsen avatar image
0 Likes"
Lars Jacobsen answered Joerg Vogel commented

When the "Wait for Event" happens, the token is immediately returned to the "Wait for Event" activity. Thus the current state is unchanged and the "Wait for Event" activity fires again, creating an infinite loop. If there is a short delay before the token returns to "Wait for Event", everything seems to work as expected.

· 4
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.