vikas

Competitions Robotics 3 - The Build and a Fast Line Follower using PID

Rating: 80 votes, 4.89 average.
Last time we covered the hardware we needed to assemble our robot. This time lets assemble it quickly and get it moving. And do some hello world in robotics , which is Line Following.

We will start with the Video of what we are going to achieve -



If you are building this and already have bought the parts I will assume that you will need little help assembling it , but I would like to give some pointers so that you don’t make the mistakes which are usually made by people and things proceed fast for you.

Lets start with the PCB as it is the heart of your robot, the PCB files can be downloaded here.

Schematic and Board files in Eagle


Either get the PCB made by a PCB vendor or simply do it yourself using the Ferric chloride method ( tutorial ). This PCB is made for easy fabrication at home with all components available locally. Also this Board can easily be used for any of your own robots. And has been made with libraries compatible to orangutan so you have a good framework to fall back on.

We will first start off by assembling the electronic component and then in the end putting everything together. So starting out if you have made the PCB yourself you can TIN it yourself, doing it is quite simple and will stop your PCB from oxidizing. To do so simply put a small drop of Solder on our copper side of board and then rub it across using your hot solder head ( With Max possible temprature). This will create a very fine layer of solder on the copper.



Also you can print the top silk side on a paper cut it to size and paste it to make it look neater and to label everything.Next solder the components, start with the small ones and move to the bigger ones, this allows for easy soldering. Also use ample flux while soldering to get good joints.



To make FRC cables simply use a plier and put the cable in between it to make the connections, it works well. And with FRC cables you get a very neat robot.



So here is the final robot once again with the battery and the Orangutan Board from Pololu mounted on it -



Lets start moving –

Since we are using a framework and our PCB is built for it most of the things are already taken care of –

To move your robot forward for a second at speed 30 here is the code .

Code:
#include <pololu/orangutan.h>
 int main()
{
set_digital_input(IO_D4, PULL_UP_ENABLED);
while(is_digital_input_high(IO_D4)) {}    // Wait for user to press button
    red_led(1);                  // Indicate robot is ready
    delay_ms(1000);
    set_motors(30,30);  // Go straight 
    delay_ms(1000);       // 1 second 
    set_motors(0,0);       // Stop
    while(1) {} 
}
Now Lets do the hello world in robotics , which is line following , the code is self explanatory. If you need a introduction on PID please read here ( PID Tutorial ).

We are using the following line sensors as they give good price/performance. Other than that the allow for low ground clearance with minimal interference.

QTR-8RC Reflectance Sensor Array

Our Robot with Line Following setup -



The final robot



Now the Code -

Code:
#include <pololu/orangutan.h>
  
unsigned char qtr_rc_pins[] = {IO_C0, IO_C1, IO_C2, IO_C3, IO_C4, IO_C5};
unsigned char qtr_rc_count  = 6;       
unsigned int  qtr_rc_values[6] = {0};

// Ideas is to keep line in the center 
void follow()
{
    int position = qtr_read_line(qtr_rc_values, QTR_EMITTERS_ON);

    int center = (( (qtr_rc_count - 1) * 1000) / 2);
    int error  = position - center;

    int leftMotorSpeed = 50;
    int rightMotorSpeed = 50;

    if (error < -(center/2) )  // the line is on the left
    leftMotorSpeed = 0;  // turn left
    if (error > (center/2) )  // the line is on the right
    rightMotorSpeed = 0;  // turn right

    set_motors(leftMotorSpeed,rightMotorSpeed); 

}


float KP = 3 ,KI = 50000 , KD = 16/1;

int   integral  = 0;
int   last_proportional = 0;

void followPID()
{
    int position = qtr_read_line(qtr_rc_values, QTR_EMITTERS_ON);

    int center = (( (qtr_rc_count - 1) * 1000) / 2);

    int proportional = position - center;

    int derivative = proportional - last_proportional;

    int power_difference = proportional / KP + integral / KI + derivative * KD;
    last_proportional    = proportional;
    integral  += proportional;


    const int max = 200;
    const int max_diffrence = 20;
    const int factor_diffrence = 2;

    if(power_difference > max)
        power_difference = max;
    if(power_difference < -max)
        power_difference = -max;

    
    // if diffrence is too much robot skids 

    int leftMotorSpeed  = max;
    int rightMotorSpeed = max-power_difference;

    if(power_difference < 0)
    {
        leftMotorSpeed  = max+power_difference;
        rightMotorSpeed = max;
    }


    if(leftMotorSpeed - rightMotorSpeed > max_diffrence)
    {
        leftMotorSpeed -= (leftMotorSpeed - rightMotorSpeed)/factor_diffrence;
    } 
    else if(rightMotorSpeed - leftMotorSpeed > max_diffrence)
    {
        rightMotorSpeed -= (rightMotorSpeed - leftMotorSpeed)/factor_diffrence;
    }

    set_motors(leftMotorSpeed,rightMotorSpeed);

}



int main()
{

    set_digital_input(IO_D4, PULL_UP_ENABLED);

    while(is_digital_input_high(IO_D4)) {} // Wait for user to press button
    
    qtr_rc_init(qtr_rc_pins,qtr_rc_count, 2000, 255);  // 800 us timeout, no emitter pin

    red_led(1);
    delay(1000);

    int i;
      for (i = 0; i < 100; i++)  // make the calibration take about 2 seconds
      {
        if(i%25==0)
        {
            if((i/5)%2==0) set_motors(20,-20); 
                else set_motors(-20,20); 
        }

        if(i%5)
        {
            if((i/5)%2==0) red_led(0);
                else red_led(1); 
        }
        qtr_calibrate(QTR_EMITTERS_ON);
        delay(20);
      }
 
    set_motors(0,0); 
    red_led(1);

    while(is_digital_input_high(IO_D4)) {} // Wait for user to press button
    delay(1000);

    while(1)
    {
        //follow(); // If you want to use non PID method 
        followPID();
    }

}
The above code is for a decently advanced line follower written by me over a Sunday evening. Most of the code comes from Pololu Documentation with some customizations for my Robot. The compiler is AVR-GCC being run inside AVR Studio.

The robot does self calibration based on environment to optimizes its sensor reading for line following, this can be seen in the video. Once calibrated it waits for user input to start.

There are basically two choices available -

void follow()

This is the simple line following function which just goes left and right based on the location of the line.

void followPID()

This is a PID based line following mechanism with some of my own customization to prevent robot from skidding. Please do optimize the code if you ever use it. The built robot is quite fast , but due to the small course we are not able to see the real speed.

For the documentation of functions and idea used please refer to the link below

Pololu QTR Sensor Functions
Tags: None Add / Edit Tags
Categories
Tutorial , Robotics

Comments

  1. allbits's Avatar
    Good entry, and the robot IS fast..

    What RPM are the motors?
  2. vikas's Avatar
    Quote Originally Posted by allbits
    What RPM are the motors?
    Around 1000 RPM for 6V
  3. rao's Avatar
    So Cool, finally got to see the circular base.
    Why no RiDuino?
  4. vikas's Avatar
    Quote Originally Posted by rao
    So Cool, finally got to see the circular base.
    Why no RiDuino?
    New riduino2 is in works . which will be basically the board + motor controller.
  5. javed's Avatar
    HI GUYS HOW ARE YOU ALL
    I NEED UR HELP TO BUILD AN LINE FOLLOWING ROBOT..........................
    I DONT KNOW FROM WHERE I SHOULD START..............
    HERE IS A COMPETETION ON LINE FOLLOWING ROBOT KINDLY HELP ME PLZZZZZZ
  6. kaatan's Avatar
    You have errors in codes
  7. amitpratap's Avatar
    thanks, that was useful
    Updated 05-21-2013 at 03:59 PM by amitpratap
  8. ayu135's Avatar
    is there a list of all the small components too like the capacitors, resistors and the other things on the pcb? I couldnt find anything and i need the specific values of those components