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);
Page 211
In either search, if a better value is found, it is used as the new baseline:
if (result != -1) baseline = result;
}
else baseline = result;
}
That's the basic algorithm. There is one extra feature that makes everything run a little smoother: every so often the baseline value is incremented. This means that if the robot is stuck in a dark
corner, it will eventually get dissatisfied (because of the increasing baseline) and look for something better.
To communicate with the outside world about what's going on, seek_enlightenment() shows the current light value as well as the current baseline on the display. The current value is
shown in the first and second digits of the display, while the baseline is shown in the third and fourth digits. (Remember that the letter on the right side of the display tells you which behavior is
currently active.) You can actually see the baseline increasing slowly as the program runs.
I've implemented my own light sensor processing in process_light(). I didn't use legOS's LIGHT_2 macro because the values I was getting from it were not in the range from 0 to 100.
Perhaps this is a bug that will be fixed in an upcoming release. At any rate, I implemented my own sensor data processing to produce a value from 0 to 100. You may need to adjust the
RAW_DARK and RAW_LIGHT constants for your particular light sensor.
The avoid() behavior is very simple. It just checks the touch sensors on inputs 1 and 3. If one of the touch sensors is pressed, avoid() backs the robot up and turns it a little.
Development Tips
legOS has serious programming power, but it has its rough spots, too. This section contains some helpful advice based on my own experience developing with legOS.
Development Cycle