Skip to content

02 Machine

Arushi Aggarwal edited this page Dec 11, 2025 · 2 revisions

Multiple states can be wrapped together in a Machine which is used to control the logic for transitions and links between states. Machines are also subclasses of states, meaning that they can be combined together as though they are states into a larger machine.

2.1 - Instantiation

Machines can be instantiated as follows:

set_up = SetUpState()
machine = Machine(set_up, name="Machine", rate=10)
machine.run()

The set_up state is the entrance to the machine. Transitions out of the state as defined before the machine's instantiation will define the rest of the machine.

2.2 - Board

The board is how information is passed between non-sequential states, based on the blackboard concept of behavior trees. It is passed to each state's execute function and can be edited there before the next state has access to it. Mulitple states running in parallel can also access the board, but measures are taken to ensure race conditions do not occur.

The board is structured like a python dictionary, with the following functions.

board.get(key: str, deep_copy=True)                 # get the value for the provided string key
board.set(key: str, value: any, deep_copy=True)     # set the value to the provided key
board.exist(key: str)                               # determines if the provided key already exists on the board
board.load(keypair: [str, any])                     # load multiple keys and values onto the board

2.2 - Transitions

An essential component of a behavior machine is the ability to define transitions between states based on varied conditions. Some predefined functions are available to facilitate this process.

state1 = State1()
state2 = State2()

state1.add_transition_after_elapsed(state2, duration: float)
    # --> transition from State1 to State2 after a specified duration of seconds
state1.add_transition_on_complete(state2, ignore_exeception=False)
    # --> transition from State1 to State2 once State1 has completed
    # --> if ignore_exception=False, only do so if there was no exception
state1.add_transition_on_success(state2)
    # --> transition from State1 to State2 if State1 return StateStatus.Success, otherwise ignore the transition

For a custom transition between any two states, use the state.add_transition(cond: typing.Callable[['State', Board], bool], next_state: 'State') function. Some illustrative examples are included below.

state1 = State1()
state2 = State2()

state1.add_transition(lambda state, board: state.flow_out == "a specific string", state2)
state1.add_transition(lambda state, board: state.flow_out is not None and state.flow_out[0] == 5.4, state2)
state1.add_transition(lambda state, board: board.get('key') == 10, state2)

2.3 - Visualization

The behavior machine can be visualized as a state machine graph. This can help to illustrate the connections between each individual state.

from behavior_machine.visualization import visualize_behavior_machine

visualize_behavior_machine(machine, "machine.png")

Clone this wiki locally