hsm.core.StateMachine

class StateMachine(name)

Bases: Container

State machine controls actions and transitions.

To provide the State Pattern-like behavior, the formal state machine rules may be slightly broken, and instead of creating an internal transition for every action that doesn’t require a state change, event handlers may be added to states. These are handled first when an event occurs. After that the actual transition is called, calling enter/exit actions and other transition actions. Nevertheless, internal transitions are also supported.

So the order of calls on an event is as follows:

  1. State’s event handler

  2. condition callback

  3. before callback

  4. exit handlers

  5. action callback

  6. enter handlers

  7. after callback

If there’s no handler in states or transition for an event, it is silently ignored.

If using nested state machines, all events should be sent to the root state machine.

Note

StateMachine extends State and therefore it is possible to always use a StateMachine instance instead of the State. This wouldn’t be a good practice though, as the State class is designed to be as small as possible memory-wise and thus it’s more memory efficient. It is valid to replace a State with a StateMachine later on if there’s a need to extend a state with internal states.

Note

For the sake of speed thread safety isn’t guaranteed.

Example Usage:

state_machine = StateMachine('root')
state_on = State('On')
state_off = State('Off')
state_machine.add_state('Off', initial=True)
state_machine.add_state('On')
state_machine.add_transition(state_on, state_off, events=['off'])
state_machine.add_transition(state_off, state_on, events=['on'])
state_machine.initialize()
state_machine.dispatch(Event('on'))

Methods

add_handler

Add a new event callback.

add_state

Add a state to a state the container.

add_states

Add multiple states to the Container.

add_transition

Add a transition from self to target_state

call_transition_cbs

Calls the registered transition callbacks.

dispatch

Dispatch an event to a state machine.

get_active_states

get_initial_states

initialize

Initialize states in the state machine.

is_active

is_substate

Check whether the state is a substate of self.

register_transition_cb

Adds a transition callback to this container.

ros_subscribe

set_initial_state

Set an initial state in a state machine.

unregister_transition_cb

Adds a transition callback to this container.

Attributes

history_state

Get the history state of this Container.

initial_state

Get the initial state in a state machine.

leaf_state

Get the current leaf state.

root

Get the root state in a states hierarchy.

add_handler(events, func, prepend=False)

Add a new event callback.

Parameters:
  • trigger (str) – name of triggering event

  • func (callable) – callback function

add_state(state, initial=False)

Add a state to a state the container.

If states are added, one (and only one) of them has to be declared as initial.

Parameters:
  • state (State) – State to be added. It may be an another Container

  • initial (bool) – Declare a state as initial

add_states(*states)

Add multiple states to the Container.

Parameters:

states – A list of states to be added

add_transition(events, target_state, *args, **kwargs)

Add a transition from self to target_state

All callbacks take two arguments - state and event. See parameters description for details.

It is possible to create conditional if/elif/else-like logic for transitions. To do so, add many same transition rules with different condition callbacks. First met condition will trigger a transition, if no condition is met, no transition is performed.

Parameters:
  • target_state (State, None) –

    Target state. If None, then it’s an internal transition

  • events (Iterable of Hashable) – List of events that trigger the transition

  • condition (Callable) –

    Condition callback - if returns True transition may be initiated.

    condition callback takes two arguments:

    • state: Leaf state before transition

    • event: Event that triggered the transition

  • action (Callable) –

    Action callback that is called during the transition after all states have been left but before the new one is entered.

    action callback takes two arguments:

    • state: Leaf state before transition

    • event: Event that triggered the transition

  • before (Callable) –

    Action callback that is called right before the transition.

    before callback takes two arguments:

    • state: Leaf state before transition

    • event: Event that triggered the transition

  • after (Callable) –

    Action callback that is called just after the transition

    after callback takes two arguments:

    • state: Leaf state after transition

    • event: Event that triggered the transition

call_transition_cbs(from_state, to_state)

Calls the registered transition callbacks. Callback functions are called with two arguments in addition to any user-supplied arguments: - userdata - a list of active states

dispatch(event)

Dispatch an event to a state machine.

If using nested state machines (HSM), it has to be called on a root state machine in the hierarchy.

Parameters:

event (Event) – Event to be dispatched

property history_state

Get the history state of this Container.

Returns:

Leaf state in a hierarchical state machine

Return type:

State

property initial_state

Get the initial state in a state machine.

Returns:

Initial state in a state machine

Return type:

State

initialize()

Initialize states in the state machine.

After a state machine has been created and all states are added to it, initialize() has to be called.

If using nested state machines (HSM), initialize() has to be called on a root state machine in the hierarchy.

is_substate(state)

Check whether the state is a substate of self.

Also self is considered a substate of self.

Parameters:

state (State) – State to verify

Returns:

True if state is a substate of self, False otherwise

Return type:

bool

property leaf_state

Get the current leaf state.

The state property gives the current, local state in a state machine. The leaf_state goes to the bottom in a hierarchy of states. In most cases, this is the property that should be used to get the current state in a state machine, even in a flat FSM, to keep the consistency in the code and to avoid confusion.

Returns:

Leaf state in a hierarchical state machine

Return type:

State

register_transition_cb(transition_cb, *args)

Adds a transition callback to this container.

property root

Get the root state in a states hierarchy.

Returns:

Root state in the states hierarchy

Return type:

State

set_initial_state(state)

Set an initial state in a state machine.

Parameters:

state (State) – Set this state as initial in a state machine

unregister_transition_cb(transition_cb, *args)

Adds a transition callback to this container.