For this lab, you will build a mobile robot out of LEGOs and program it using the language Interactive C, which can be downloaded from the web. Versions of IC are available for Windows, Macintosh, and Linux. Documentation is available here:
More advanced examples of IC programs and other documentation is available on the robotics lab computers in the subdirectory /usr/local/InteractiveC6/lib/handyboard.
Since we don't have enough Handyboards for everyone, you'll have to work with a partner on this lab. You'll need the following equipment:
Please note that if you damage your Handyboard, you'll have to replace it (cost: $300), so treat them gently and with respect. We have several thousand LEGO pieces available in the lab, so please try to keep them organized in their bins. Thanks!
Familiarize yourself with the Handyboard and Interactive C by reading the handout A First Robot and the following sections of the yellow reference manual:
Your first task is to build a robot. Everyone will start with the same basic design, but you are free to choose a different design, or to modify or redo it completely. You may need to substitute some parts in order to complete the assembly. The handout A First Robot gives step by step instructions for building a basic robot. Some alternative designs are available on the web:
You may need to modify these designs a bit to get a good working vehicle. Here are photos of some other LEGO vehicles that may provide ideas and inspiration as well.
Connect two light sensors to your robot and run the program below. This program simply reports the current values of the sensors. Test the sensor responses under a variety of different lighting conditions. You'll notice that higher brightness levels correspond to lower sensor readings.
int LEFT_EYE = 3; /* analog port number of left light sensor */ int RIGHT_EYE = 4; /* analog port number of right light sensor */ void main() { while (1) { printf("L=%d, R=%d\n", analog(LEFT_EYE), analog(RIGHT_EYE)); sleep(0.1); } }
To use the light sensors with the motors, we need a way to transform the light sensor readings into appropriate motor speeds. The following function will do this.
int MAX_LIGHT = 10; /* maximum brightness level of environment */ int MIN_LIGHT = 200; /* minimum brightness level of environment */ int normalize(int light) { int output = 100 - ((light - MAX_LIGHT) * 100 / (MIN_LIGHT - MAX_LIGHT)); /* keep output within range 0 to 100 */ if (output < 0) output = 0; if (output > 100) output = 100; return output; }
This function maps sensor readings less than or equal to MAX_LIGHT (corresponding to high brightness levels) to motor speed 100, and readings greater than or equal to MIN_LIGHT (corresponding to low brightness levels) to motor speed 0. Modify your main program so that it reports normalized light sensor readings, and then test out the sensors. You should experiment with different values of MAX_LIGHT and MIN_LIGHT, in order to find the most appropriate values for your environment.
Write control programs for your robot that implement the following types of creatures. An example program is provided here to get you started.
Creature #1: Timid
Timid is capable of moving forward in a straight line. It has one threshold
light sensor, pointing up. When the light sensor detects light, the creature
moves forward, otherwise, it stays still. Your program should use the
Handyboard knob and Interactive C's knob() function to adjust the
threshold of the light sensor. The threshold should be set initially to
ambient light. That way, when the creature can "see" the light, it will move.
When it enters a shadow (which can be cast by a hand or another object) it
stops. If whatever is casting the shadow is moved, the creature will move
again. Therefore, Timid could be viewed as a shadow seeker. Remember that
brighter light equates to lower values on the light sensors, so you may want to
use the normalize function above to make the sensor readings more
intuitive.
Creature #2: Indecisive
Indecisive is similar to Timid, except, it never stops: its motors are
always running, either in forward direction, or in reverse direction,
controlled by the threshold light sensor. When the light sensor detects light,
it moves forward, otherwise, it moves backwards. When you run this creature,
you will notice that it tends to oscillate back and forth at shadow edges.
Thus, Indecisive could be viewed as a shadow edge seeker.
Creature #3: Paranoid
Paranoid is capable of turning. Its threshold light sensor is pointed up
and is attached on an arm that extends forward a few inches from the body. When
the sensor detects light, it moves forward. When the sensor enters a shadow,
it reverses while turning. Soon the sensor will swing around, out of the
shadow. When that happens, it resumes its forward motion. Paranoid could be
viewed as a shadow-fearing creature.
Creature #4: The Seeker
Now, using a pair of light sensors and a pair of touch sensors, program your
robot to seek light while avoiding obstacles. (Note, the light sensors
generally work better when they are angled slightly away from the the front of
the robot.) If you wish, you can try implementing your solution in the
subsumption style. A simple example of how to do this in Interactive C is
provided here. This code is just a starting
point. Feel free to modify the given behaviors and to add your own behaviors.
For example, you may want to add some state so that you can detect when the
robot is stuck. You should test your robot using a series of progressively
more difficult situations, in which the starting location and orientation of
the robot is arbitrary:
You should use the same Interactive C program for each situation. Finding the light means having the robot touch the base of the light source. The light source will be significantly brighter than the ambient light.