Line follower is not doing what it should.

Hey everyone. Me and some of my friends built and programmed a robot for a local robot competition. The problem is however that it doesn't do exactly what the code says it should. Or at least our programming is not that advanced to make it do that.

As you can see in the video below it is following the line as it should, but when the line stops at the end, it should turn 80° and drive to the second line and follow that to the goal. But, the robot, no matter how long we tell it to turn, it always turns 180° and points directly to the line it came from, and begins to follow the same line back. We can't seem to find a solution to this problem, and we have tried to troubleshoot this way too long now. So we hope that you may be in the capability and condition to help us. The code is listed below the video.

Specs:
it is basically a Boe-Bot from parallax using to two parallax servo motors and thier wheels.
Under it is 3 QTI sensors measuring black or white.

Thank you in advance!

//By Martin Søndergaard Andersen. 20/12 - 2012
//Code for two wheeled servo motor robot.
//Arduino UNO (tested)
//2x Parallax servo motors to do continous rotation.
//Boe-Bot by Parallax.
//Stillstand:
// speedLeft = 5;
// speedRight = -6;

#include <Servo.h>

//Integers:
int timercontinue;
int seconds;
int speedLeft;
int speedRight;
int sensorPoint = 120;
int a; // Turning rate
int velocity; //Turning speed

//Motors/Servos
Servo motorLeft;
Servo motorRight;

//Code begins
void setup() {
 delay(4900);

// seconds = 0;
 speedLeft = 5;
 speedRight = -6;
 
 timercontinue = 1;
  
 Serial.begin(9600);
 motorLeft.attach(9);
 motorRight.attach(10);
 delay(100);
  
}

void loop() { 
 motorLeft.writeMicroseconds(map(speedLeft,-100,100,1300,1700)); 
 motorRight.writeMicroseconds(map(-speedRight,-100,100,1300,1700));
 delay(15);

  Serial.println(" ");
  Serial.println("SpeedLeft: ");
  Serial.println(speedLeft);
  
  Serial.println(" ");
  Serial.println("SpeedRight: ");
  Serial.println(speedRight);

  lineFollower ();
 if (analogRead(A0) < sensorPoint && analogRead(A1) < sensorPoint && analogRead(A2) < sensorPoint) {
    motorLeft.writeMicroseconds(map(speedLeft,-100,100,1300,1700)); 
    motorRight.writeMicroseconds(map(-speedRight,-100,100,1300,1700));
    speedLeft = 90;
    speedRight = -90;
    delay(580);
    motorLeft.writeMicroseconds(map(speedLeft,-100,100,1300,1700)); 
    motorRight.writeMicroseconds(map(-speedRight,-100,100,1300,1700));
    speedLeft = 100;
    speedRight = 100;
    delay(1000);
    motorLeft.writeMicroseconds(map(speedLeft,-100,100,1300,1700)); 
    motorRight.writeMicroseconds(map(-speedRight,-100,100,1300,1700));
    drive();
  if (analogRead(A0) > sensorPoint or analogRead(A1) > sensorPoint or analogRead(A2) > sensorPoint) {
    motorLeft.writeMicroseconds(map(speedLeft,-100,100,1300,1700)); 
    motorRight.writeMicroseconds(map(-speedRight,-100,100,1300,1700));
       lineFollower(); 
    }
  }
}

void drive () {
  motorLeft.writeMicroseconds(map(speedLeft,-100,100,1300,1700)); 
  motorRight.writeMicroseconds(map(-speedRight,-100,100,1300,1700));
  speedLeft = 100;
  speedRight = 100;
}

void turnRight() {
 speedLeft = velocity+a;
 speedRight = velocity; 
}

void turnLeft() {
 speedLeft = velocity;
 speedRight = velocity+a; 
}

void lineFollower () {
 // A1 < sensorPoint then TurnRight.
  if (analogRead(A0) < sensorPoint && analogRead(A1) > sensorPoint && analogRead(A2) < sensorPoint) {
    speedLeft = 100;
    speedRight = 100;
   drive();
  } 
  else if(analogRead(A0) > sensorPoint && analogRead(A1) > sensorPoint && analogRead(A2) < sensorPoint ) {
    velocity = -30;
    a = 70;
    turnRight();
   } 
   else if (analogRead(A0) < sensorPoint && analogRead(A1) > sensorPoint && analogRead(A2) > sensorPoint) {
     velocity = -30;
       a = 70;
     turnLeft();
   }
    else if (analogRead(A0) < sensorPoint && analogRead(A1) < sensorPoint && analogRead(A2) > sensorPoint) {
     velocity = -30;
       a = 70;
     turnLeft();
   }
    else if (analogRead(A0) > sensorPoint && analogRead(A1) < sensorPoint && analogRead(A2) < sensorPoint) {
     velocity = -30;
       a = 70;
     turnRight();
   }
   else if (analogRead(A0) > sensorPoint && analogRead(A1) > sensorPoint && analogRead(A2) > sensorPoint) {
     speedLeft = 30;
     speedRight = 30;
     drive();
   }
 }

void Stop() {
  speedLeft = 5;
  speedRight = -6;
}

But, the robot, no matter how long we tell it to turn, it always turns 180°

So, you've discovered that open control systems don't work. Congratulations. Now, add some feedback so the robot learns how far it has turned.

void loop() { 
 motorLeft.writeMicroseconds(map(speedLeft,-100,100,1300,1700)); 
 motorRight.writeMicroseconds(map(-speedRight,-100,100,1300,1700));
 delay(15);

You want to charge ahead on every pass through loop, and then look to see if you should have? Great idea. Not!

  if (analogRead(A0) < sensorPoint && analogRead(A1) > sensorPoint && analogRead(A2) < sensorPoint) {

What information is "sensorPoint" supposed to convey? I can tell you that what it does convey is nothing.

void turnRight() {
 speedLeft = velocity+a;
 speedRight = velocity; 
}

void turnLeft() {
 speedLeft = velocity;
 speedRight = velocity+a; 
}

Why is a a global variable? It should be an input to these functions. But, what you should really have is one function, turn(), that takes two arguments.

Yes i know there is something wrong with the code and that's why i'm asking for help. But, that doesn't mean you have to answer in a very arrogant way. I would very much appreciate if you could tell me what is wrong with the code, and make an example of how i can make it better, instead of just making fun of it.

Oh, and the "sensorPoint" is the threshold where the sensors se either black or white meaning if it is under 120 it is seen as white, but if it is over 120 it is seen as black.

Thanks.
Martin.

I would very much appreciate if you could tell me what is wrong with the code, and make an example of how i can make it better, instead of just making fun of it.

The point I was trying to make is that fixing the problem is not just a matter of rewriting some code. You need additional hardware if you are going to reliably turn 80 degrees.

You need to think about the order of operations. If you stop at a stop light, then go, then look, you'll be driving a pretty banged up car before long.

That is what you are having your robot do. Your code should have NO delay()s in it. Move at a reasonable speed, based on the deviation between the course you are on and the course that you are following. You should be checking how far off course you are, and adjusting speed based on that value, not just blasting off in some direction, hoping not to veer too far off course while your eyes are closed. Which they are while delay() is doing it's thing.

In the past I have taken issue with Paul over his style but in this case he has 110% of my admiration for studying your long and undocumented code in enough detail to make any comments.

I certainly wasn't prepared to take that much trouble.

May I respectfully suggest that if you want assistance you take the trouble to understand where your problem is and ask a much more focused question.

...R