Lab: State Machines

From Tekkotsu Wiki

Jump to: navigation, search

Learning Objective: This lab will teach you how to create and run state machines, which are the way we define new robot behaviors.


Background Reading

See the Tutorial: State Machine Intro for an introduction to the concept of state machines. For more technical detail on Tekkotsu's state machine formalism, see the articles on State machine structure and State machine shorthand: transitions.

First State Machine Example: Nodes and Transitions

In this example we will write a simple state machine consisting of two nodes: a speech node and a sound node. After the speech node speaks its text, a button transition will transfer control to the sound node. After the sound node plays a bark sound, a timeout transition will transfer control back to the speech node. Copy the following lines into ~/project/

#include "Behaviors/StateMachine.h"

$nodeclass Example1 : StateNode {

    speak: SpeechNode("Press a button")
    bark: SoundNode("barkmed.wav")

    speak =B=> bark
    bark =T(2000)=> speak



Note: node instance labels like "speak" and "bark" must begin with a lowercase letter. Node classes like "SpeechNode" and "SoundNode" must begin with an uppercase letter.

Running Example 1

1. Compile the behavior:

cd ~/project

2. Now run it by typing one of:

./tekkotsu-CREATE                    (if running on a real robot)
./tekkotsu-CREATE -c mirage.plist    (if running in Mirage)
./tekkotsu-CREATE -c sim.plist       (if running in simulator mode)

3. Activate Example1 in the ControllerGUI: it will be listed under Root Control > User Behaviors.

4. Try pressing one of the robot's buttons. On the Create you can press the Play or Advance buttons, or one of the bump sensors. If you're using a simulated robot, you can simulate a button press event by typing the following to the HAL-Create> prompt:

post buttonEGID Play A

You can simulate a button release event by typing:

post buttonEGID Play D

Second Example: Defining A New Node Class

This example shows how to define a new node class to create a new type of robot action. In this case, the ReportButton node is entered via a button event and prints out the name of the button. Since this node does not complete, we use a null transition (=N=>) to proceed to the next node. Put the following code in the file ~/project/

#include "Behaviors/StateMachine.h"

$nodeclass Example2 : StateNode {

  $nodeclass ReportButton : StateNode : doStart {
    size_t button = event->getSourceID();
    if ( button < RobotInfo::NumButtons )
      cout << "Sensed the " << RobotInfo::buttonNames[button] << " button." << endl;
      cout << "Event had invalid button number: " << button << endl;

    speak: SpeechNode("Press a button")
    bark: SoundNode("barkmed.wav")
    report: ReportButton

    speak =B=> report =N=> bark =C=> speak



Note that "ReportButton" begins with an uppercase letter because it is the name of a node class, while the instance label "report" begins with a lowercase letter.

Running Example 2

1. Compile and test the Example2 behavior:

2. Press and release a button, and verify that the robot barks as expected. If using a simulated robot, use the post command described earlier to simulate a button activate or deactivate event.

3. Press and hold a button, wait for the robot to speak, and then release the button. What happens, and why? (On a simulated robot, use the post command with D as the third argument to simulate a button deactivate event, which signals button release.)

4. Modify ReportButton to also report the event type (activate or deactivate).

5. In the Tekkotsu console window, try:     post buttonEGID 999 A


  1. Draw the state machine diagram corresponding to Example2.
  2. Write a state machine the plays a sound only when the Play button is pressed, and ignores all other buttons.
  3. Write a state machine that plays a sound only when the Play button is released, not when it's pressed.

To Learn More

  • There is a list of State Machine Exercises you can try.
  • See the State Machines page for additional resources.
  • To see the C++ code generated by the state machine compiler for, do:

        cd ~/project
        cat build/*/*/ | grep -v "#line"