Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

History transition removes leaf states on parallel state machines #12

Open
gmkado opened this issue Feb 19, 2024 · 1 comment
Open

History transition removes leaf states on parallel state machines #12

gmkado opened this issue Feb 19, 2024 · 1 comment
Assignees
Labels
bug Something isn't working

Comments

@gmkado
Copy link

gmkado commented Feb 19, 2024

So far this library has been awesome, I'd really like to get this one feature working but for some reason transitioning back to a history state is mangling some of my parallel state machines.

I have four parallel state machines running under the "Main" state machine:
image

My button state machine is pretty straightforward and looks something like this:
image

When the button is released, it will transition my "Workout" state machine from "Workout__Active__Running" to "Workout__Active__Paused" and vice versa. "Workout__Active__Running" has some nested states that I'd like to restore when coming back from "Workout__Active__Paused":

image

Here's my workoutActive.scxml with the irrelevant bits removed (note that I'm using the xi:include feature so these states all get preprended with "Workout__Active__" in my generated state machine):

<scxml initial="SetUp" version="1.0" xmlns="http://www.w3.org/2005/07/scxml"    >    
    <state id="Running" initial="Running_Squeezing">        
        <transition event="HW_BUTTON_RELEASED" target="Paused" type="external" />
        <state id="Running_Squeezing" >
            ...
        </state>
        <state id="Running_Resting" >
            ...
        </state>    
        <history type="deep" id="RunningHistory" />    
    </state>
    <state id="Paused">
        <transition event="HW_BUTTON_RELEASED" target="RunningHistory" type="external" />
        <invoke srcexpr="on0301_Paused" />
    </state>
</scxml>

Something gets screwed up when trying to transition to "RunningHistory" from the "Paused" state. I've printed out the active states during the transition:

1) Main, Button, Workout, Led, Haptics, Haptics__Off, Workout__Active, Workout__Active__Paused, Led__Blinking, Led__Blinking_Off, Button__Pressed

---  TRANSITION TO HISTORY (event: HW_BUTTON_RELEASED, state: Workout__Active__RunningHistory, previously active: Workout__Active__Running_Squeezing) ---

2) Main, Button, Workout, Led, Haptics, Workout__Active, Led__Blinking, Workout__Active__Running, 
3) Main, Workout, Led, Workout__Active, Workout__Active__Running, Workout__Active__Running_Squeezing,
  1. Is right before the transition back to the history, and all seems good.
  2. It re-enters the "Workout__Active__Running" state, but for some reason "Haptics__Off", "Led__Blinking_Off", and "Button_Released" (the new button state) get removed.
  3. It re-enters the "Workout__Active__Running_Squeezing" but now the "Button", "Haptics" and "Led_Blinking" states are gone

So it seems like it is popping off the leaf states on the parallel state machines for each history state it restores.

My expected final state:

Main, Button, Workout, Led, Haptics, Haptics__Off, Led__Blinking, Led__Blinking_Off, Button__Pressed, Workout__Active, Workout__Active__Running, Workout__Active__Running_Squeezing, 

Hopefully this makes sense. Let me know if it doesn't and I'll try to provide more information.

@gmkado
Copy link
Author

gmkado commented Feb 21, 2024

I traced this back to around this area:

hsmcpp/src/HsmImpl.cpp

Lines 1235 to 1239 in 91b791d

} else if (TransitionBehavior::FORCED == event.transitionType) {
HSM_TRACE_DEBUG("forced history transitions: %d", SC2INT(event.forcedTransitionsInfo->size()));
// cppcheck-suppress misra-c2012-17.8 ; outMatchingTransitions is used to return result
outMatchingTransitions = *event.forcedTransitionsInfo;
isCorrectTransition = true;

So looks like when we enter a history state, it pushes "forced" transition events for each transition to get back to the previous states. But it does this on all active states, so my parallel states get forced into invalid states.

Should those lines be checking event.forcedTransitionsInfo.fromState to make sure they are forcing from the expected state?

@igor-krechetov igor-krechetov added the bug Something isn't working label Aug 8, 2024
@igor-krechetov igor-krechetov self-assigned this Aug 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants