Following the black line with a Rover.

12 replies [Last post]
Precision
Title: MiniBot
Joined: 06/21/2011
Posts:
BotPoints: 29
User offline. Last seen 7 years 22 weeks ago.

Hi, this is our first year in botball activities, and we've done fine so far until we go to the Top hat sensors. I'm a student on the team, and have been searching and learning as much as i can about this, but i can't quite grasp it. When we test it, the robot either spins in a circle, or turns to the side, and goes back and forth off of the tape, instead of traveling down the tape. Below is the code i've written so far from what i've learned, Any help would be appreciated. I know you guys probably don't do this, But please don't just Fix the code and give it to me to use, I would like to know how in steps to correct what I've done, for future preference, Thanks!

--This is not the whole code, but only the area i am having an issue in. We want the rover to travel on the black tape, as well as find the black tape when needed.--

void black_line ()//int analog(int p); ****Multiple variable/function declarations****
{
int threshold=800; // set threshold for light condition
if (analog10(2) > threshold) { // continue until not dark
LeftTurn(1000,30); // arc left
if (analog10(2) <= threshold){ // continue until dark
RightTurn(1000,30);
// arc right
}
{

}
}

}

/*
void MGD(int speed, float centimeters)//move forward distance
{
distance = centimeters * TpC;
mrp(RM,speed,(long)distance);
bmd(RM);
}
*/

int main()
{

{

black_line();
black_line();
black_line();
black_line();
black_line();
black_line();
black_line();

}

}

wmyers
wmyers's picture
Title: Advisor
Joined: 02/24/2011
Posts:
BotPoints: 54
User offline. Last seen 4 years 39 weeks ago.

Hello,

I'm unsure as to what you think your program is doing. Could you maybe clean up your code or explain what you think/intend for your robot to do? Below is information on basic line following strategies. It seems that you're following Method #1 for line following. My guess is that you might be having the robot rotate too quickly and you could be missing the line.

Given that you have one IR sensor there are two methods you can take to solving this problem.

Method 1:
i) If the sensor reading indicates a line, then move right.
ii) If the sensor reading doesn't indicate a line, then move left.

Method 2:
i) If the sensor reading doesn't indicate a white line stop.
a) Rotate left inplace until a white line is found or for a specified time period. If a line is found goto (ii).
b) Rotate right inplace until a white line if found or for twice the time period. If a line is found goto (ii).
c) Otherwise, the robot has gone too far away from the line and must do something else to get back or just give up.
ii) Drive straight.

Method 2 is the most efficient form of line following.

I hope this helps

Wesley Myers
--
YAC Advisor
Botball International Champion 2007 and 2008

Carnegie Mellon University 2012
Electrical and Computer Engineering
Computer Science and Robotics

Precision
Title: MiniBot
Joined: 06/21/2011
Posts:
BotPoints: 29
User offline. Last seen 7 years 22 weeks ago.

i have a lot of sensors, we plan to use two, and keep the black line in the middle of the two, but we need to learn how to use one first before we think about two.

Precision
Title: MiniBot
Joined: 06/21/2011
Posts:
BotPoints: 29
User offline. Last seen 7 years 22 weeks ago.

we got it working, thanks.

uhm, how do we set a speed that the servos need to move at? can't find that anywhere on the internet, just see Set_servo_ positions, which make the servos move at full speed to the position, we don't want it to move so fast, but slowly. Thanks.

wmyers
wmyers's picture
Title: Advisor
Joined: 02/24/2011
Posts:
BotPoints: 54
User offline. Last seen 4 years 39 weeks ago.

When you tell a servo to go to a position, it will go as fast as it can. If you want to slow it down, then what you want to do is tell the servo to take small steps over time to that new position.

For instance, say your current servo position is 30 and you want to get to 130. If you tell it to go to 130, then it will move as fast as possible to 130. Instead you could step it to 130 by increments of 10. Essentially think of a for loop as shown below


for(i = current_servo_position; i < new_servo_position; i+= 10)
{
set_servo_position(servo_num, i);
msleep(250);
}

Does that make sense to you? Essentially it will take 2.5 seconds for the servo to reach 130 in this instance.

Wesley Myers
--
YAC Advisor
Botball International Champion 2007 and 2008

Carnegie Mellon University 2012
Electrical and Computer Engineering
Computer Science and Robotics

Precision
Title: MiniBot
Joined: 06/21/2011
Posts:
BotPoints: 29
User offline. Last seen 7 years 22 weeks ago.

you rule man. :)

Precision
Title: MiniBot
Joined: 06/21/2011
Posts:
BotPoints: 29
User offline. Last seen 7 years 22 weeks ago.

ugh, i'm doing this:

void Dump_balls()//dump balls into tower
{
for(i = 0; i < 600; i+= 10)
Set_servo_position(LEFTSERVO,i);
Set_servo_position(RIGHTSERVO,i);
msleep(250);
}

and getting these errors:

error: 'i' undeclared (first use in this function)
and other errors that would be fixed if this one is fixed,
I guess i have to make a void for i? i figured it would know what increments was. How do i go about doing this?

Precision
Title: MiniBot
Joined: 06/21/2011
Posts:
BotPoints: 29
User offline. Last seen 7 years 22 weeks ago.

also i'm trying to imitate:

Method 2:
i) If the sensor reading doesn't indicate a white line stop.
a) Rotate left inplace until a white line is found or for a specified time period. If a line is found goto (ii).
b) Rotate right inplace until a white line if found or for twice the time period. If a line is found goto (ii).
c) Otherwise, the robot has gone too far away from the line and must do something else to get back or just give up.
ii) Drive straight.

and got this:

void black_line ()//int analog(int p); ****Multiple variable/function declarations****
{
while(1)
fd(1); //this will make the bot move forward while doing the black line left and right.
fd(3);
{
//was 2 & 3//
if(analog10(2)<650){
mav(1,-1000);
mav(3,300);
}
if(analog10(3)>650){
mav(1,300);
mav(3,-1000);
//was 15//
while(digital(14)){
Dump_balls();
sleep(2);
ao();}
// arc right
}

}

}

but what i don't understand is how you make it constantly check if it's on the line while it's moving forward like you have it in your method 2

a) Rotate left inplace until a white line is found or for a specified time period. If a line is found goto (ii).
b) Rotate right inplace until a white line if found or for twice the time period. If a line is found goto (ii).
(ii) being drive straight.

Your method 2, is the idea i had in my head when i first started working on a black line program, but i just don't know how to do it.

wmyers
wmyers's picture
Title: Advisor
Joined: 02/24/2011
Posts:
BotPoints: 54
User offline. Last seen 4 years 39 weeks ago.

For the servo code, you need to declare "i" prior to using it. "i" is an integer in this case. This can be done with "int i;" in a line prior to the for loop. Also, another problem is that you need to bracket your for loop. Do you understand what that means? I can just fix your code for you, or I can let you learn :)

Wesley Myers
--
YAC Advisor
Botball International Champion 2007 and 2008

Carnegie Mellon University 2012
Electrical and Computer Engineering
Computer Science and Robotics

wmyers
wmyers's picture
Title: Advisor
Joined: 02/24/2011
Posts:
BotPoints: 54
User offline. Last seen 4 years 39 weeks ago.

Hi,

The problem with your code is that you are always telling the robot to drive forward even if it doesn't see a line. While you don't see a line, you want to seek it. I see you are using two sensors. This algorithm desires only one IR sensor.

Another thing that I see is that you want to dump your balls when a touch sensor has been pressed. What you probably want to do is just

if(digital(14){
dump_balls();
sleep(2);
ao();
break;
}

This will make the program exit once you've dumped the balls. Plus you don't want to constantly check for the button press if you're looking for it once. Then again, I could be misinterpreting you.

Below is example code I hastily typed up. This is how the algorithm should look like. NOTE: This is not how you access everything for Botball c. You'll need to look these things up :)

void lineFollow()
{
float i;

while(1) //will run forever
{
value = SensorRaw[lightSensor];

mav(rightMotor, speed); //go straight if on the line
mav(leftMotor, speed);

i = 5.0;
while(value > notBlackLine) //while not on the line
{
i*=1.5;
rotateLeft(TURNSPEED, (int)i); //first look left
i*=1.5;
rotateRight(TURNSPEED, (int)i); //then look right
}
}
}

void rotateRight(int speed, int ticks)
{
resetEncoders();
value = SensorRaw[lightSensor];
while((rightMotorEncoderTicks > -ticks) && (value > notBlackLine))
{
value = SensorRaw[lightSensor];
mav(rightMotor, -speed);
mav(leftMotor, speed);
}
}

The robot will drive straight if it sees a line. If it doesn't see a line, then it will first seek to the left. Notice how in the rotate cases you are telling the robot to continue driving in a rotation, until it either exceeds the motor ticks or it sees a line. If it sees a line, then it will start driving in a straight line. If it does not, then it will go back and try going in the other direction. Notice how "i" is multiplied. This increases the turning distance because it increases the ticks. What this causes is a larger sweeping to occur.

Wesley Myers
--
YAC Advisor
Botball International Champion 2007 and 2008

Carnegie Mellon University 2012
Electrical and Computer Engineering
Computer Science and Robotics

wmyers
wmyers's picture
Title: Advisor
Joined: 02/24/2011
Posts:
BotPoints: 54
User offline. Last seen 4 years 39 weeks ago.

This is the fixed code.

void Dump_balls() //dump balls into tower
{
int i = 0;

for(i = 0; i < 600; i+= 10)
{
set_servo_position(LEFTSERVO,i);
set_servo_position(RIGHTSERVO,i);
msleep(250); //quarter second sleep
}
}

Wesley Myers
--
YAC Advisor
Botball International Champion 2007 and 2008

Carnegie Mellon University 2012
Electrical and Computer Engineering
Computer Science and Robotics