Page 221 - The Unofficial Guide to Lego Mindstorms Robots
P. 221

210


          When arbitrate() has determined the motor command, it uses motor_control() to interpret the command and to
          actually set the direction and speed of the outputs. This design is very similar to the design of the NQC RoboTag program,
          from Chapter 9.

          The cruise() behavior is simple; it just sets its command variable to COMMAND_FORWARD ad infinitum.

          The next behavior, seek_enlightenment(), is not so simple. The basic idea, however, goes like this:

              if I'm seeing darker stuff than I've just been seeing
                  look to either side for something brighter

          seek_enlightenment() implements this with the idea of a baseline. The initial baseline is taken straight from the light
          sensor reading:

              baseline = process_light(SENSOR_2);

          The behavior  then enters an endless loop, examining the value of the light sensor.  If it falls too far below the  baseline,
          seek_enlightenment() asserts control and searches for brighter light:

              current = process_light(SENSOR_2);
              if (current < (baseline - FUDGE)) {

          To search for brighter light, seek_enlightenment() first sets a new baseline from the current light value:

              baseline = current;

          Then the robot turns left or right, more or less randomly using the system clock:

              if (sys_time % 2 == 0) seek_command = COMMAND_LEFT;
              else seek_command = COMMAND_RIGHT;

          A helper function, wait_for_better(), is used to wait for a brighter light than the new baseline:

              result = wait_for_better(baseline, 1000);

          It's entirely possible that the robot will not find any brighter light. In this case, it times out (after 1000 milliseconds) and returns
          -1. In this case, the robot will turn back in the opposite direction and search for brighter light:

              if (result == -1) {
                  if (seek_command == COMMAND_LEFT) seek_command = COMMAND_RIGHT;
                  else if (seek_command == COMMAND_RIGHT) seek_command = COMMAND_LEFT;

          The wait_for_better() helper function is again used with a longer timeout:

              result = wait_for_better(baseline, 2000);
   216   217   218   219   220   221   222   223   224   225   226