You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
But we discovered this in a bigger state-machine where a concurrent monitoring state is trying to preempt another concurrence container. We expected this container then to finalize with outcome 'preempted'.
However, if at that moment the concurrency container already was terminating and one of the states had an outcome defined already, the resulting outcome is not 'preempted' which made our state machine end up in an undesired state.
Inspired by #53 I created a small script as well to demonstrate this:
#!/usr/bin/env python
from time import sleep
from smach import State, Concurrence
from threading import Timer
class DelayState(State):
"""Delay state for testing purposes"""
def __init__(self, delay):
State.__init__(self, outcomes=['succeeded', 'preempted'])
self.delay = delay
def execute(self, _):
# A better delay state should be able to preempt during its sleep state
sleep(self.delay)
if self.preempt_requested():
self.service_preempt()
return 'preempted'
return 'succeeded'
def test_concurrence_preempt():
cc1 = Concurrence(
outcomes=['succeeded', 'preempted'],
default_outcome='succeeded',
child_termination_cb=lambda *_: True, # Always evaluate outcome_map
outcome_map={'preempted': {'State1': 'preempted',
'State2': 'preempted'}})
with cc1:
Concurrence.add('State1', DelayState(0.1))
Concurrence.add('State2', DelayState(1.0))
t = Timer(0.3, cc1.request_preempt)
t.start()
print(f' Resulting state: {cc1.execute()}')
if __name__ == '__main__':
test_concurrence_preempt()
In this simple example State1 is already done when the concurrence container is asked to preempt and thus the resulting outcome is succeeded although preempted would be expected.
In code the case where the concurrence is asked to preempt after all states are terminated is caught already:
Might be related to #53
But we discovered this in a bigger state-machine where a concurrent monitoring state is trying to preempt another concurrence container. We expected this container then to finalize with outcome 'preempted'.
However, if at that moment the concurrency container already was terminating and one of the states had an outcome defined already, the resulting outcome is not 'preempted' which made our state machine end up in an undesired state.
Inspired by #53 I created a small script as well to demonstrate this:
In this simple example
State1
is already done when the concurrence container is asked to preempt and thus the resulting outcome issucceeded
althoughpreempted
would be expected.In code the case where the concurrence is asked to preempt after all states are terminated is caught already:
executive_smach/smach/src/smach/concurrence.py
Line 259 in d4226ba
I'll sketch-up a PR as well with a potential fix!
The text was updated successfully, but these errors were encountered: