Thursday, December 23, 2010

The Project - Location Recognition

A second part of this project I worked on a few days ago and a bit today. I'm planning to put down a long tape line around parts of the house. The robot will follow that line using one light sensor. Also, I'm planning to put in smaller lines as markers at four points next to the first line. The first point will have one little line, the second two, the third three and the fourth four. The robot will hopefully use its second light sensor to count the small lines and find out where it is.

To do this, I have the robot basically check to see the light value of its second light sensor is near the already saved "on line" variable. When it sees a line, it waits until it does not see the line, adds 1 to a variable called "line_count" and then moves on. It then runs 600 checks for more lines, waiting one thousandth of a second between each line. This leads to 6 seconds all together. If it sees a line, waits until it does not see the line and adds 1 to line_count. If it does not see a line, then it waits a thousandth of a second and tries again. At the end of the loop, it saves sets another variable "location" to the same value as the line_count variable. Here is the code I used:

task get_location ()
{
line_count=0;
while (true)
{
if ((Sensor(S2) < (online + 20)) && (Sensor(S2) > (online - 20)))
{
until (Sensor(S2) > (online + 30))
{
}
PlayTone(600, 200);
line_count=0;
line_count++;
repeat (600)
{
if ((Sensor(S2) < (online + 20)) && (Sensor(S2) > (online - 20)))
{
until (Sensor(S2) > (online + 30))
{
}
PlayTone(600, 200);
line_count++;
Wait(10);
}
else
{
Wait(10);
}
}
}
location=line_count;
}
}

It translates the location variable to readable locations on the NXT screen through this piece of code running in the main task:

// display robot location
TextOut(0, LCD_LINE4, "Location");
if (location == 0)
{
TextOut(0, LCD_LINE5, "Unknown");
}
if (location == 1)
{
TextOut(0, LCD_LINE5, "Kitchen");
}
if (location == 2)
{
TextOut(0, LCD_LINE5, "To Entryway");
}
if (location == 3)
{
TextOut(0, LCD_LINE5, "Entryway");
}
if (location == 4)
{
TextOut(0, LCD_LINE5, "To Kitchen");
}

I'm planning to add a fifth instance so that if it counts more than 4 lines, it puts out a line of text saying "error."

This project may be nearing completion (depending on what else I decide to implement). Stayed tuned.

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);
}
}

The Project

Yes...there's a big project in the makings. I hope to put aspects of it here occasionally, and if we're fortunate, I'll get it done before Christmas.

Speaking of Christmas, Happy Birthday, Jesus!

Nato

Four Wheel Drive Car Super Addition V3

Well, I know you are supposed to see it here first, but I put pictures of FWDCSA V3 on NXTLog a long time ago. Sorry. Here's some pictures.
General View














Top View















Bottom View, with Wheels Turned