python-3.xnestedpytransitions

What is the right way to use Nested states with pytransitions?


So i've been looking around on the pytransitions github and SO and it seems after 0.8 the way you could use macro-states (or super state with substates in it) has change. I would like to know if it's still possible to create such a machine with pytransition (the blue square is suppose to be a macro-state that has 2 states in it, one of them, the green one, being another macro) :

enter image description here

Or do I have to follow the workflow suggested here : https://github.com/pytransitions/transitions/issues/332 ? Thx a lot for any info !


Solution

  • I would like to know if it's still possible to create such a machine with pytransition.

    The way HSMs are created and managed has changed in 0.8 but you can of course use (deeply) nested states. For a state to have substates, you need to pass the states (or children) parameter with the state definitions/objects you'd like to nest. Furthermore, you can pass transitions for that particular scope. I am using HierarchicalGraphMachine since this allows me to create a graph right away.

    from transitions.extensions.factory import HierarchicalGraphMachine
    
    states = [
        # create a state named A
        {"name": "A",
         # with the following children
         "states":
            # a state named '1' which will be accessible as 'A_1' 
            ["1", {
            # and a state '2' with its own children ...
                "name": "2",
                #  ... 'a' and 'b'
                "states": ["a", "b"],
                "transitions": [["go", "a", "b"],["go", "b", "a"]],
                # when '2' is entered, 'a' should be entered automatically.
                "initial": "a"
            }],
         # we could also pass [["go", "A_1", "A_2"]] to the machine constructor
         "transitions": [["go", "1", "2"]],
         "initial": "1"
         }]
    
    m = HierarchicalGraphMachine(states=states, initial="A")
    m.go()
    m.get_graph().draw("foo.png", prog="dot")  # [1]
    

    Output of 1:

    enter image description here