SMACH Documentation


Outcome Semantics

For all SMACH containers, the interface to contained states is defined via state outcomes. A state's potential outcomes are a property of the state instance, and must be declared before it is executed. If a SMACH plan is written by hand, all potential outcomes are declared on construction and the consistency of the state transitions can easily be checked without executing it.

State outcomes may cause different things to happen in different types of containers, but what happens after an outcome is emitted is irrelevant from perspective of the state. In this sense, outcomes can be considered "local" to a given state.

For example, a state might provide outcomes such as 'succeeded', 'aborted', or 'preempted' and as far as the state is concerned, this is the way that it interacts with the task-level state flow. In the context of a state machine, these outcomes would be associated with other states, thus forming a transition. In the context of another container, however, they might be treated differently. Outcomes simply acts as a common interface between states and containers.

User Data

SMACH containers each have a flat database used to coordinate and pass data between different states. This becomes useful when states compute some result or return some sensor information. This allows such data to be held at the execution level, and made available to other tasks or procedures.

Similarly to outcomes, the userdata keys that are set and retrieved in each state are described by the state's input keys and output keys. These are also a property of the state instance, and must be declared prior to execution. The declaration of all of these interactions prevents errors and aides in debugging when the SMACH plans become complex.

For information on the user data API see Manipulating Userdata in SMACH.


Preemption propagation is built into SMACH. The State base class includes an interface for coordinating preempt requests between containers and contained states. Each container type has its own well-defined behavior for responding to a preempt request. This allows the system to both cleanly respond to termination signals from an end user and be able to be canceled programmatically by a higher-level executive.


SMACH containers can provide a debugging interface which allows a developer to (over ROS) set the full initial state of a SMACH tree. This is visualized with the SMACH Viewer. This includes both the initial state labels of each container as well as the contents of the user data structures at each level.


"State" can mean different things in different contexts. In SMACH, a "state" is a local state of execution, or equivalently a "state" corresponds to the system performing some task. This is different from formal state machines, where each state describes not what the system is doing but rather describes a given configuration of the system. This allows the user to focus on what the system is executing and the results from said execution, as opposed to naming the points between execution. States in SMACH correspond more to states in structured programming. For more on this distinction, as well as how to visualize states in SMACH, see State Diagrams VS Flow Charts.

Provided State Classes





State base interface.



A state which has three commonly used pre-defined outcomes.

succeeded, preempted, aborted


A state that subscribes to a ROS topic and blocks while a condition holds.

valid, invalid, preempted


A state that executes a condition callback.

true, false


A state which acts as a proxy to a simple actionlib action.

succeeded, preempted, aborted


There are several container types that are provided by the SMACH library. Different containers provide different execution semantics, but they can all be treated like states in other containers. Containers may have their own ways of specifying transitions for contained states, since "transition" means different things in different contexts.

All SMACH containers have the following properties:

  • They contain a dictionary of states where objects implementing the smach.State interface are keyed by string labels.

  • They contain a userdata structure that all of their children can access.
  • In order to modify the structure of a container, it must be opened (see below).

Opening Containers for Construction

This is done either by using Python's with keyword, or by calling open() and close() on the container object. The with keyword can be used either with the container object itself, or on the container's opened method.

Adding States to Containers

SMACH containers provide static methods for adding children. These methods access the currently open container and add the states accordingly.

Provided Container Classes







Wiki: smach/Documentation (last edited 2013-09-02 10:11:28 by FelixKolbe)