When a line is detected using the
rSense() function, another subroutine
is called to react in some way to the
presence of the line and
analyze the outcome of
the actions taken.
This new subroutine
implements the basic
algorithm of our program.
It is shown in Figure 3.
The code in Figure 3
begins by reading the line
sensors and storing them
in the variable CurState. It
then searches the robot’s
memory to see if that
state has been memorized
some time in the past.
The robot’s memory is composed
of three arrays: GoodState,
ActionTo Take, and ConfidenceLevel.
The GoodState array holds the
robot’s views of the world (the line
sensor data) that it has determined to
be important. The corresponding
element in the array Action To Take
identifies what action the robot should
take when this line sensor
configuration is detected.
The final array ConfidenceLevel
keeps track of how well this memory is
working. The use of these arrays will
become clearer as we proceed.
Referring back to Figure 3, a
for-loop is next used to search GoodState
to see if it contains the current state of
the line sensors. If it does, the variable
InMemory is set to TRUE, and the
value of the corresponding element
of Action To Take is used to compute
a subroutine name which is then
called to cause the desired action to
Most computer languages do not
have the ability to gosub to a variable
name, so if you are not using
RobotBASIC, this area of the code
could be implemented using if-
statements or a switch-case construct.
After the action is performed, the
program must decide if a rewarding
result occurred. As discussed earlier,
there are two criteria for this
evaluation. If the line sensors indicate
that the center sensor detects the line,
then the variable Reward is set to
strengthened. If the action does not
produce desirable results, then the
memory should be weakened and
eventually discarded. This evaluation
process not only allows the robot to
determine what works, it also allows it
to change its mind about what works
when the environment changes.
Obviously, the robot must be able
to determine if a particular action is
helping it achieve its goal. Our robot
will have a group of five line sensors
for collecting information about its
environment. Actions that cause the
middle sensor of the group to detect a
line will be deemed beneficial because
the goal is actually being met. If this is
the only criteria though, the system
would be simplistic at best. What is
needed is a way to evaluate if a
particular action helps achieve the
goal, even if that action does not
immediately cause the robot to see the
line with the center sensor. We will
address this problem shortly.
// genetically turn away from walls
if rFeel() then rTurn (140+Random(80))
// something got our attention
if !rFeel() then rForward 1
All this sounds complicated, but it
is easily implemented in code.
Furthermore, the programming itself
should help clarify the concepts. A real
robot could be programmed to confirm
our assertions, but RobotBASIC’s
integrated simulated robot allows us to
experiment in an environment that is
easier to control and implement.
Figure 1 shows a simplified
version of the RobotBASIC program we
used. After some initialization (which
creates the environment full of line
segments shown in Figure 2), an
endless loop causes the robot to roam
around and observe its environment.
The subroutine that performs these
actions uses the robot’s perimeter
sensors which are read with the
function rFeel() to avoid walls as it
moves around. Think of this as a
built-in reflex reaction to a hot or
SERVO 10.2013 43