Programming as a behavior graph

The above program works fine and is easy to understand and maintain. However, it is common in robotics to design programs in terms of behaviors expressed as finite state machines, which are graphs of states connected together with transitions. Fig. 6.1 illustrates the behavior graph of the ball tracking program, which is a very simple example of a two states behavior.

Figure 6.1. The ball tracking behavior graph

The ball tracking behavior graph

The ellipses represent states (in which the robot is doing some basic action/perception loop) and the arrows are the transitions, expressed over conditions. The squares attached to the transition specify some action to trigger when the transition occurs.

The best way to program this kind of behavior graph in URBI is to use a conjunction of functions with at and stop commands to link everything. First, let's define the two functions related to the two states of the ball tracking program:

// Tracking state
function tracking() {
  whenever (ball.visible) {
    headPan  = headPan + ball.a * camera.xfov * ball.x
     &
    headTilt = headTilt+ ball.a * camera.yfov * ball.y;
  }
};

// Searching state
function searching() {
  period = 10s;
  {
    headPan'n  = 0.5 smooth:1s &
    headTilt'n = 1 smooth:1s
  } |
  {
    headPan'n  = 0.5 sin:period ampli:0.5 &
    headTilt'n = 0.5 cos:period ampli:0.5
  }
};

Now, we can simply "glue" the states together by stating the transitions as two at commands with stop commands to terminate the previous state:

// Transitions
at (ball.visible ~ 100ms) {
  stop search;
  speaker = found;
  track: tracking();
};

at (!ball.visible ~ 100ms) {
  stop track;
  speaker = lost;
  search: searching();
};

The advantage of rewriting the ball tracking program in terms of finite state machine behavior may not appear very clear at this stage, because the program is very simple. However, with more complex behaviors including tens of different states, each with several transitions, this is the best and safest way to program. It makes the code modular, clear and easy to maintain.

Finite state machines are a good way to describe behaviors for robots. They are certainly not perfect, but it's currently the most used technique in robotics. URBI as a programming language is also capable to describe subsumption-based architectures, hiearchical architectures or reactive architectures and many other behavior definition paradigm.