Sunday, December 19, 2010

The Project - Line Following

Well, I started the building part of this project the day before yesterday, and I finished it yesterday. Now for the programming. I am intending to program it in Not eXactly C, and I've already begun an important part of what this robot will feature - line following.

Line following can be simple or complicated. You can simply put a light sensor on the front of a two power-wheel drive vehicle, and use a simple zig-zag program in that it turns one wheel until it sees the line, then it turns the other wheel until it does not see the line. It is simple and can be quite effective. However, it can be slower than more complicated line-following methods.

The second type of line following comprises not only a "turn until you see the line" state and a "turn until you don't see the line" state, but a "if you see the edge of the line" state, in which the robot does not turn but goes directly forward. Of course, one single light sensor can't really see the edge of the line, but it can use a very neat method used by the NXT 1.0 Car with Game Controller project found on nxtprograms.com (see the "How the Controller Works" section near the bottom of the page) , in that the value of the light sensor when it is on the edge is somewhere between the "on the line" light sensor value and the "off the line" light sensor value. I used a method comprising this idea, having three states, one "on the line," one "off the line" and one "on the edge of the line."

The program was written in Not eXactly C. Here is the code just for following the line.
while (true)
{
lightdisplay = NumToStr(Sensor(S3));
TextOut(40, LCD_LINE8, lightdisplay);
if (Sensor(S3) > online + 6 & Sensor(S3) <> offline - 3)
{
OnRev(OUT_B, 100);
Off(OUT_C);
}
Wait(100);

"online" and "offline" are variables that have light sensor values for when the light sensor is on the line, and when it is off the line. What this program basically does is see that if it is more than the online value but less than the offline value, it will move both motors so that the robot goes forward. However, if it is one the line, it will turn away from it, and if it is off the line, it will turn toward it. I put in all of those numbers that are being subtracted and added in a attempt to make it turn away quicker when it less darkness.

Additionally, I implemented a system that has the user set the online and offline variables before it starts following the line, the idea for which I got from Daniele Benedettelli's project Creating Cool Mindstorms NXT Robots. Here it is.

int online;
int offline;
string lightdisplay;

task main ()
{
while (ButtonPressed(BTNCENTER, false))
{
}
SetSensorLight(S3);
ClearScreen();

//Set on line light value
while (!ButtonPressed(BTNCENTER, false))
{
lightdisplay = NumToStr(Sensor(S3));
TextOut(40, LCD_LINE8, lightdisplay);
TextOut(0, LCD_LINE1, " Please place");
TextOut(0, LCD_LINE2, " center light");
TextOut(0, LCD_LINE3, " sensor on line");
TextOut(0, LCD_LINE4, "and press orange");
TextOut(0, LCD_LINE5, " button");
}
while (ButtonPressed(BTNCENTER, false))
{
}
online = Sensor(S3);
PlayTone(440, 500);
ClearScreen();

//Set off line light value
while (!ButtonPressed(BTNCENTER, false))
{
lightdisplay = NumToStr(Sensor(S3));
TextOut(40, LCD_LINE8, lightdisplay);
TextOut(0, LCD_LINE1, " Please place");
TextOut(0, LCD_LINE2, " center light");
TextOut(0, LCD_LINE3, " sensor off line");
TextOut(0, LCD_LINE4, "and press orange");
TextOut(0, LCD_LINE5, " button");
}
while(ButtonPressed(BTNCENTER, false))
{
}
offline = Sensor(S3);
PlayTone(440, 500);
ClearScreen();

What it basically does is start is variables, then put text on the screen that tells the user to place the center light sensor on the line and press the orange button, and when that is completed, puts text that tells the user to place the center light sensor off the light and press the orange button. Additionally, it displays the current light reflected value from the center light sensor as this is going on, as it does when it is actually following the line.

In total, this line-following method worked out fairly well. In case anyone wants to see it, here's the program in its entirety.

/*
12-18-2010
Line Following program by NatoNX.
Inspiration from a progect on another website and a book. Thanks!
*/

int online;
int offline;
string lightdisplay;

task main ()
{
while (ButtonPressed(BTNCENTER, false))
{
}
SetSensorLight(S3);
ClearScreen();

//Set on line light value
while (!ButtonPressed(BTNCENTER, false))
{
lightdisplay = NumToStr(Sensor(S3));
TextOut(40, LCD_LINE8, lightdisplay);
TextOut(0, LCD_LINE1, " Please place");
TextOut(0, LCD_LINE2, " center light");
TextOut(0, LCD_LINE3, " sensor on line");
TextOut(0, LCD_LINE4, "and press orange");
TextOut(0, LCD_LINE5, " button");
}
while (ButtonPressed(BTNCENTER, false))
{
}
online = Sensor(S3);
PlayTone(440, 500);
ClearScreen();

//Set off line light value
while (!ButtonPressed(BTNCENTER, false))
{
lightdisplay = NumToStr(Sensor(S3));
TextOut(40, LCD_LINE8, lightdisplay);
TextOut(0, LCD_LINE1, " Please place");
TextOut(0, LCD_LINE2, " center light");
TextOut(0, LCD_LINE3, " sensor off line");
TextOut(0, LCD_LINE4, "and press orange");
TextOut(0, LCD_LINE5, " button");
}
while(ButtonPressed(BTNCENTER, false))
{
}
offline = Sensor(S3);
PlayTone(440, 500);
ClearScreen();

//Follow line
TextOut(0, LCD_LINE3, " Following line");
while (true)
{
lightdisplay = NumToStr(Sensor(S3));
TextOut(40, LCD_LINE8, lightdisplay);
if (Sensor(S3) > online + 6 & Sensor(S3) <> offline - 3)
{
OnRev(OUT_B, 100);
Off(OUT_C);
}
Wait(100);
}
}