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

Tuning Line-Follower PID constants


#1

Hi!
I built a line following robot but it has some problems.Could you help me please?. It has 6 pololu qtr8a analog sensors and an atmega 168 controller. It follows the line well but it wabbles and at high speeds and it loses the line. If you could help me to tune the pid a litte bit to follow the line corectly i will be very grateful. Here is the video


and the code is below. I mention that i tried to modify the pid constants but with no succes.
Thank you anticipated!

#include <PololuQTRSensors.h>

    #define NUM_SENSORS             6  // number of sensors used
    #define NUM_SAMPLES_PER_SENSOR  4  // average 4 analog samples per sensor reading
    #define EMITTER_PIN             12  // emitter is controlled by digital pin 2

    // sensors 0 through 5 are connected to analog inputs 0 through 5, respectively
    PololuQTRSensorsAnalog qtra((unsigned char[]) {0, 1, 2, 3, 4, 5},
      NUM_SENSORS, NUM_SAMPLES_PER_SENSOR, EMITTER_PIN);
    unsigned int sensorValues[NUM_SENSORS];


    int MOTOR1_PIN1 = 5;

    int MOTOR1_PIN2 = 6;

    int MOTOR2_PIN1 = 11;

    int MOTOR2_PIN2 = 10;

    int buton = 2;

    unsigned int last_proportional = 0;
    long integral = 0;





    void setup() {

      pinMode(MOTOR1_PIN1, OUTPUT);

      pinMode(MOTOR1_PIN2, OUTPUT);

      pinMode(MOTOR2_PIN1, OUTPUT);

      pinMode(MOTOR2_PIN2, OUTPUT);
     
      pinMode(buton, INPUT);


      delay(500);
     
      int i;
      pinMode(13, OUTPUT);

      while(digitalRead(buton)==LOW)

    {digitalWrite(13, HIGH);
    delay(500);
    digitalWrite(13,LOW);
    delay(500);}

    delay(2000);

    digitalWrite(13, HIGH);    // turn on LED to indicate we are in calibration mode
      for (i = 0; i < 400; i++)  // make the calibration take about 10 seconds
      {
        qtra.calibrate();       // reads all sensors 10 times at 2.5 ms per six sensors (i.e. ~25 ms per call)
      }
      digitalWrite(13, LOW);     // turn off LED to indicate we are through with calibration



       


    while(digitalRead(buton)==LOW)
    {digitalWrite(13,LOW);}


    delay(1500);
     

    }





    void loop() {


    unsigned int position = qtra.readLine(sensorValues);

    // The "proportional" term should be 0 when we are on the line.
    int proportional = ((int)position) - 2500;

    // Compute the derivative (change) and integral (sum) of the
    // position.
    int derivative = proportional - last_proportional;
    integral += proportional;

    // Remember the last position.
    last_proportional = proportional;

    int power_difference = proportional*4 + integral/10000 + derivative*7;

    // Compute the actual motor settings.  We never set either motor
    // to a negative value.
    const int max = 255;
    if(power_difference > max)
        power_difference = max;
    if(power_difference < -max)
        power_difference = -max;

    if(power_difference < 0)
      go(max+power_difference, max);
    else
        go(max, max-power_difference);
       

     

    }


    void go(int speedLeft, int speedRight) {

      if (speedLeft > 0) {

        analogWrite(MOTOR1_PIN1, speedLeft);

        analogWrite(MOTOR1_PIN2, 0);

      }

      else {

        analogWrite(MOTOR1_PIN1, 0);

        analogWrite(MOTOR1_PIN2, -speedLeft);

      }



      if (speedRight > 0) {

        analogWrite(MOTOR2_PIN1, speedRight);

        analogWrite(MOTOR2_PIN2, 0);

      }

      else {

        analogWrite(MOTOR2_PIN1, 0);

        analogWrite(MOTOR2_PIN2, -speedRight);

      }

    }

#2

Hello.

I split your post into its own thread because it was not very related to the thread you added it to. I have made a number of forum posts in the pasts with suggestions on how to tune PID constants for line followers, so I suggest you start off by searching the forum a bit. Here is one such thread:

I suggest you eliminate the integral term from your PID calculation and tune the Kp and Kd terms until it can follow a straight or gently curving line without oscillating (you might want to try a much higher Kd term relative to Kp; the constants I used on my 3pi line follower were Kp = 1/7 and Kd = 4). Note that PID line following will not necessarily work well on lines that abruptly change direction, so you might want to implement some special cases that override the PID following if the line is lost for more than some period of time.

- Ben


#3

Thank you very much! I will try to do that and return with the results.