Saturday, November 5, 2011

line tracer with programming part1

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




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


No comments:

Post a Comment