Saturday, January 30, 2016

Line Follower | PID Algorithm | Arduino Code

 I've been lately working on making a line follower that can run on any track be it black line on white background or vice versa and recently won a line follower event at my college. Some people asked me for the code and hence writing a post on the same. There are obviously minor adjustments to made and other tweaks but the code is perfectly running and the PID tuning done after long hours of trial and testing. Here is the list of hardware and software used.

NOTE that the PID constants that I have tuned for my bot may or may not work for your bot so if you're going to use the code then make sure you tune the constants properly.

HARDWARE:-

1. Line Sensor Array


I have used a line sensor array consisting of 7 IR leds. The reason for using such an array is that sharper turns can be detected easily using the 7 sensors and overshooting of the bot from the path gets reduced. One can also use just two led's on either side of the line but it'll work only for acute turns and not obtuse or right angled turns. The thing with line follower is that even if you tune it with  perfect constants it'll still wobble a bit while running, so the 7 IR's sort help in reducing oscillations also.

One important thing I experienced is that DO NOT place the motors and the sensor array nearer to each other. There should be enough distance between the motors and the sensor placing. Hence, I placed it in the front and the motor at the back. The reason behind this is that this will give enough amount of time for motors to react as the sensors detect sharp turns.

2. L298 and 200 rpm motors


As I have explained in the previous post the l293d is an inefficient driver when it comes to handling large currents and moreover there's considerable amount of voltage drop at the PNP and NPN transistors inside. Check it here


There's no specific reason as to why I chose 200 rpm motors. They were just lying around in my room so I used them, although increasing the rpm may increase the difficulty in making it perfectly follow the line.

3. Generic wheels and Chassis

4. 11.1 v Li-po battery

5. Arduino Uno



Basic sensing:-


There's no specific reason as to why I chose PID as a control strategy. I found this through other similar bots that this is one of the best strategies to efficiently follow the line. Before I get into PID this is how I assigned values to the sensor readings.



i) The mean position sensor is assigned an integer value of error=20.
ii) Same way the other six sensor are calibrated for values from 35(rightmost sensor) to 5.

There final error generated is,

final_error=error-20;

PID Algorithm:-

1.Proportional Term,Kp :- 
Proportional term generates output according to the final error generated in previously. But the problem is when the bot is at the Center IR the output is zero.

Output=Kp*(final_error);

2.Derivative Term,Kd:-
Derivative term dampens the system meaning it'll lessen the oscillations or wobbling occurring while it is following the path. Again this term wont help when final_error will be zero.

Output=Kd*(final_error-prev_error);

prev_error=final_error


3. Integral Term,Ki:-
Integral term does what the the other two terms can't do, it integrates the error over time when the error is zero.(Previous values aren't zero).It's nothing but summing of all values.

integral+=error;
Output=Ki*(integral);

Final output is ,

Output=Kp*(final_error)+Kd*(final_error-prev_error)+Ki*(integral);

This output is fed accordingly to the left or right motor respectively through PWM.

PID Tuning:-

This is the most cumbersome and time-consuming part of the whole process of making a Line-follower. There's no strict method to tune it. However, here are few steps i found on the net:

i) Make all the constants 0 and start with the Kp term randomly and see how he bot behaves. If the bot overshoots the path then increase Kp or if it's too oscillatory then decrease Kp.

ii) Next come over to Kd, and make it such that the wobbling is lowered and bot turns perfectly.

iii) Though I have not been able to master this term but this term is to make the go fast on a straight track as the error is zero on a straight track and the bot accelerates quickly.




Code:-
See for the bot_code.ino file here:

Please do subscribe to posts by mail.

Cheers!





3 comments:

  1. kartic listion i have used this code but i cant understand abount the moter logic pin function .. which wire shold i connect to this one kindly explain mee
    and you have used uin setup loop just 5 sensor as a input why not 7 snsor while you have i=use =d in loop 7..
    pinMode(A0,INPUT);
    pinMode(A1,INPUT);
    pinMode(A2,INPUT);
    pinMode(A3,INPUT);
    pinMode(A4,INPUT);



    int m11 = 13;
    int m12 = 12;
    int PWM_m1 = 11;
    int PWM_m2 = 10;
    int m21 = 6;
    int m22 = 8;
    int Mmax =250;
    int l3 =2;
    int r3 =A5;
    int l2 =A0;
    int l1 =A1;
    int c = A2;
    int r1 =A3;
    int r2 =A4;
    int fwdspeed =180;
    int basespeed =150;
    float kp =6;
    int ki =0;
    float kd = 0;
    void fastforward();
    float raw_output,raw2_output,proportional,derivative,integral,integrand,rate;
    int output,L1,L2,C,R1,R2,R3,L3,final_error,M1,M2,motor_speed1,motor_speed2,error,preverror;
    void setup() {
    // put your setup code here, to run once:
    pinMode(A0,INPUT);
    pinMode(A1,INPUT);
    pinMode(A2,INPUT);
    pinMode(A3,INPUT);
    pinMode(A4,INPUT);
    pinMode(3,OUTPUT);//MOTOR LOGIC ;
    pinMode(m11,OUTPUT);
    pinMode(m12,OUTPUT);
    pinMode(m21,OUTPUT);
    pinMode(m22,OUTPUT);
    pinMode(PWM_m1,OUTPUT);
    pinMode(PWM_m2,OUTPUT);


    ReplyDelete