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

Pololu Forum

PID line follower cant take Acute angles turns

Hi I built a line follower for competition and it works very well for straight and curves but it doesnt take acute angles.

The parts used for my bots are

1.Chassis self built
2.Arduino nano
3.QTR 8rc
4.TB6612FNG
5.N20 motors 300rpm

can anyone help me with the code please
below is my code

#include <QTRSensors.h>

#define KP 0.2
#define KD 2
#define M1_MAX_SPEED 255
#define M2_MAX_SPEED 255
#define M1_DEFAULT_SPEED 255
#define M2_DEFAULT_SPEED 255
#define MIDDLE_SENSOR 4
#define NUM_SENSORS  8     // number of sensors used
#define TIMEOUT       3500  // 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 A2
#define rightMotor2 A1
#define rightMotorPWM 11
#define leftMotor1 A4
#define leftMotor2 A5
#define leftMotorPWM 10
#define motorPower A3

QTRSensorsRC qtrrc((unsigned char[]) { 2,3,4,5,6,7,8,9} ,NUM_SENSORS, TIMEOUT, QTR_NO_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[8];
  int position = qtrrc.readLine(sensors);
  int error = position - 3500;

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

Hello, mythicalbeast.

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.

-Jon

what if i want to make sharp angle turns.what code will i have to write?can you please help with code

It is difficult to provide any help without more specific detail about your particular maze. How sharp of an angle does your robot need to turn? Are those angles all the same throughout your course or will they vary? (If the angle does not change, you can probably still follow the general advice I mentioned in my last post.) It might help to post a picture that shows all of your maze.

-Jon