uses the bumper sensors as inputs.
The output of DoEscape, however,
goes to the little circle labeled “S.”
The S stands for suppresses.
Therefore, DoEscape suppresses the
output of DoWander and takes over
the motors. When DoEscape is done
with its task, it will return control to
Do Wander or whatever other behavior
has the highest currently active
priority.
In general, higher priority
behaviors are at the top of the
diagram. That doesn’t have to be
true, however. All you need to do is
look for the behavior that points to
the suppressor that has the final say
to see which one has the highest
priority. When you have all of your
behaviors coded, all you need to do in
your code’s main loop is call
everything, and each behavior will
handle itself. Listing 2 shows what
our Roomba behavioral program’s
main Arduino loop looks like. Simple,
isn’t it?
If you look at Listing 2 again,
you’ll note that I have more behaviors
there than what this article is talking
about. The code (which you can find
at the article link as
RoombaBehave1.zip) has other
behaviors stubbed in that can be
added later. I am leaving these as an
exercise for the reader. (Maybe I’ll
add some details in a later column,
we’ll see ...)
I have placed these behaviors in
ascending order of priority with the
lowest priority called first. Each of
these behaviors are modified finite
state machines (MFSM). There is a
standard way to represent FSMs in
the programming world.
SELECTED READING
"Cambrian Intelligence, The Early History
of the New AI" by Rodney A. Brooks,
MIT Press, 1999.
"Mobile Robots, Inspiration to
Implementation" by Jones and Flynn,
A K Peters LTD, 1993.
"Vehicles, Experiments in Synthetic
Psychology" by Valentino Braitenberg,
MIT Press 1986.
would block the function call until the
delay is finished. Instead — as you can
see in Listing 3 — we use the
Arduino background milliseconds
counter to determine if we are done.
If not done, the function exits, leaving
the state machine in the same state
until the next call of the behavior
function.
In the C language, a switch/case
construct is the simplest way to
implement an FSM. Note the timer
function millis(); I use this as my
background timer to know when
certain states are ready to change.
Subsumption, behaviors, finite
state machines, oh my! This all sounds
so technical, but as you can see, the
Figure 3
Figure 2
SERVO 04.2013 13