Pololu Robotics & Electronics
Menu
My account Comments or questions? About Pololu Contact Ordering information Distributors

Pololu Forum

How to take acute angles using qtr 8A rc for a line follower

#1

Actually I want to develop an fast line follower that can take 90° and 45° more accurately,their are lot of line follower competition is going on here if only I could win these if my bot is more accurate in taking angles …also I want a sample program to run the bot on white line on black surface, currently now I m using a Audrino Uno and motor sheild,Bo motor qtr 8a rc . If any one could answer this and give a sample code

#2

Hello.

Since the line following algorithm would depend on many factors of your robot (e.g. motor driver, motors, diameter and distance apart of the wheels, battery voltage) as well as your line following course, an example program would not be practical. You might be able to use the sample code in the “Advanced Line Following with 3pi: PID Control” section of our 3pi Robot’s users guide to get an idea of how to structure your code for PID control. The LineFollower example program from our Zumo Robot’s Arduino library might also be a useful reference. However, please note that the QTR sensor functions are slightly different in our QTR sensor Arduino library.

In general, there are a lot of factors that can change how well your robot can follow a tight turn. If you are talking about sharp 90° turns (e.g. not smooth and with no radius), that is something that is commonly handled by breaking out of your main line-following algorithm. For example, when a right-angle turn is detected, the robot can be programmed to perform a pre-programmed 90° turn before going back into its line following algorithm.

By the way, “qtr 8a rc” does not match the name of any of our QTR sensors. It sounds like you are trying to refer to either the QTR-8A or QTR-8RC.

Brandon

#3

Actually some adjustments in my motor and sensors results very good progress,now my line follower following back line on white surface very smoothly …Thank yu so much …But if yu can I also want a SAMPLE CODE FOR BLACK LINE ON WHITE SURFACE …can yu plz help me for it

#4

A complete example program for line following would not be very helpful since there are many factors that are heavily dependent on your hardware (such as your motors and motor driver, as well as the size of your wheels and axle track).

Also, please note that the only difference in using our QTRSensors library with a black line on a white surface and using them with a white line on a black surface is just which version of the read line command you use. If you are using a black line on a white surface, you would use the readLineBlack() command. If you are using a white line on a black surface, you would use the readLineWhite() command.

However, as I mentioned in my previous post, the examples for our 3pi and Zumo robots that I linked to might be useful for getting an idea of how to structure your code for PID control, even with the QTR functions differing slightly.

Brandon

#5
#include <QTRSensors.h>

#define KP 0.5
#define KD 0
#define M1_MAX_SPEED 70
#define M2_MAX_SPEED 70
#define M1_DEFAULT_SPEED 50
#define M2_DEFAULT_SPEED 50
#define MIDDLE_SENSOR 4, 5
#define NUM_SENSORS  6     // number of sensors used
#define TIMEOUT       2500  // waits for 2500 us for sensor outputs to go low
#define EMITTER_PIN   2     // emitter is controlled by digital pin 2
#define DEBUG 1 // set to 1 if serial debug output needed

#define rightMotor1 3
#define rightMotor2 4
#define rightMotorPWM 5
#define leftMotor1 12
#define leftMotor2 13
#define leftMotorPWM 11
#define motorPower 8

QTRSensorsRC qtrrc((unsigned char[]) {  14, 15, 16, 17, 18, 19} ,NUM_SENSORS, TIMEOUT, EMITTER_PIN);

unsigned int sensorValues[NUM_SENSORS];

void setup()
{
  pinMode(rightMotor1, OUTPUT);
  pinMode(rightMotor2, OUTPUT);
  pinMode(rightMotorPWM, OUTPUT);
  pinMode(leftMotor1, OUTPUT);
  pinMode(leftMotor2, OUTPUT);
  pinMode(leftMotorPWM, OUTPUT);
  pinMode(motorPower, OUTPUT);
  
  
  manual_calibration(); 
}

int lastError = 0;
int  last_proportional = 0;
int integral = 0;


void loop()
{
  unsigned int sensors[6];
  int position = qtrrc.readLine(sensors);
  int error = position - 2500;

  int motorSpeed = KP * error + KD * (error - lastError);
  lastError = error;

  int rightMotorSpeed = M2_DEFAULT_SPEED - motorSpeed;
  int leftMotorSpeed = M1_DEFAULT_SPEED + motorSpeed;
  
    if (rightMotorSpeed > M1_MAX_SPEED ) rightMotorSpeed = M1_MAX_SPEED; // limit top speed
  if (leftMotorSpeed > M2_MAX_SPEED ) leftMotorSpeed = M2_MAX_SPEED; // limit top speed
  if (rightMotorSpeed < 0) rightMotorSpeed = 0; // keep motor above 0
  if (leftMotorSpeed < 0) leftMotorSpeed = 0; // keep motor speed above 0
  
   {
  digitalWrite(motorPower, HIGH);
  digitalWrite(rightMotor1, HIGH);
  digitalWrite(rightMotor2, LOW);
  analogWrite(rightMotorPWM, rightMotorSpeed);
  digitalWrite(motorPower, HIGH);
  digitalWrite(leftMotor1, HIGH);
  digitalWrite(leftMotor2, LOW);
  analogWrite(leftMotorPWM, leftMotorSpeed);
}
}

  
void manual_calibration() {

  int i;
  for (i = 0; i < 250; i++)  // the calibration will take a few seconds
  {
    qtrrc.calibrate(QTR_EMITTERS_ON);
    delay(20);
  }

  if (DEBUG) { // if true, generate sensor dats via serial output
    Serial.begin(9600);
    for (int i = 0; i < NUM_SENSORS; i++)
    {
      Serial.print(qtrrc.calibratedMinimumOn[i]);
      Serial.print(' ');
    }
    Serial.println();

    for (int i = 0; i < NUM_SENSORS; i++)
    {
      Serial.print(qtrrc.calibratedMaximumOn[i]);
      Serial.print(' ');
    }
    Serial.println();
    Serial.println();
  }
}
#6

What should I change for following white line on black surface on this program…

#7

It looks like you are using an older version of our QTRSensors library. For that version, the readLine() function accepts an optional third argument that specifies if the line is white or not. If not specified, the default is to assume it is running with a black line on a white surface (i.e. the third argument is 0). To specify a white line on a black surface, you need to make it 1. You can do this by changing your int position = qtrrc.readLine(sensors); to int position = qtrrc.readLine(sensors, QTR_EMITTERS_ON, 1);

Brandon

#8

That’s helps me a lot … Thank you so much

Now the only problem I m facing is its speed … Iy ia Lil bit slower I think the main two problems is with the weight and motor … I m using a 200rpm gear motor and by bot weight is nearly 1kg …Can yu plz suggest a motor suitable for 1kg weigh also to provide sufficient torques

#9

1kg is a relatively heavy robot for line following. If you can reduce that weight, it might help. At 1kg weight, you would probably want to use something on the scale of our 20D or 25D gearmotors. The amount of torque your motors will need depends on a couple of aspects about your robot aside from the weight, such as wheel diameter and number of drive motors. You might find the “Force and torque” blog post helpful for calculating the necessary torque.

The weight distribution of the robot can be very important as well. For example, it is common for a line following robot to use a differential drive setup with the wheels in the rear and the line sensor out in front, similar to the way I made my “Chariot” line follower. In that scenario, it is important to keep the center of gravity toward the rear of the robot; if the weight gets too far toward the front, it will be difficult for your robot to control.

Brandon