Tutorial: Parallelism and Multi-Way Transitions

From Tekkotsu Wiki

Jump to: navigation, search

Learning Goal: In this tutorial you will learn how to use transitions with multiple source or target nodes to implement fork/join operations. A fork initiates several actions in parallel, while a join synchronizes the completion of two or more actions. By using fork/join you will be abel to construct more sophisticated robot behaviors.

Contents

Doing Two Things At Once

Suppose you want your robot to move forward and play a sound at the same time. Each action is implemented by a node of its own, so what we need to do is start two nodes running at once. We can do that by specifying multiple target nodes for a transition. When the transition fires, all its target nodes are activated, and they run in parallel. Here is an example:

$nodeclass ForkExample : StateNode {

  $setupmachine{
    start: SpeechNode("start")
    start =C=> {fwd, howl}

    fwd: ForwardBy(500)
    howl: SoundNode("howl.wav")
  }

}

As you can see from the above example, there is a special syntax for specifying multiple target nodes of a transition: a list of comma-separated node labels is enclosed in curly braces. Node labels are the only thing that can go inside these braces; you cannot create a new node instance there.

Synchronizing Completion

Actions can take varying amounts of time to complete. When you initiate multiple actions simultaneously, you may want all of them to complete before going on to the next state. You can achieve this by using a CompletionTrans with multiple source nodes. For example, we may want the robot to both finish moving and finish howling before it turns left. By default, a CompletionTrans with multiple source ndoes waits for all of the source nodes to complete before it fires.

$nodeclass ForkJoinExample : StateNode {

  $setupmachine{
    start: SpeechNode("start")
    start =C=> {fwd, howl}

    fwd: ForwardBy(500)
    howl: SoundNode("howl.wav")
    {fwd, howl} =C=> turn

    turn: TurnBy(M_PI/2)
  }

}

One Node Terminating Another

Another use for a CompletionTrans is to allow the completion of one node to terminate another. We do this by supplying an optional argument to the transition telling it that only one node needs to complete in order for the transition to fire. When a transition fires, it shuts down all its source nodes, so in this way the completing node can terminate its simultaneously active siblings. For a specific example, let's have the robot move forward until the howl is complete. As soon as the howl finishes, the motion should also stop. We'll specify a really long travel distance so the motion will not terminate on its own; instead, the CompletionTrans will stop the motion when it fires. The argument of 1 to the CompletionTrans tells it that only one of source node needs to complete before it can fire.

$nodeclass TerminateExample : StateNode {

  $setupmachine{
    start: SpeechNode("start")
    start =C=> {fwd, howl}

    fwd: ForwardBy(9999)
    howl: SoundNode("howl.wav")
    {fwd, howl} =C(1)=> turn

    turn: TurnBy(M_PI/2)
  }

}

Exercises

  1. Use the Storyboard tool to draw a state machine diagram of ForkJoinExample.
  2. Use the Storyboard tool to generate an execution trace of ForkJoinExample.