vikas
Competitions Robotics 3 - The Build and a Fast Line Follower using PID
by
, 04-25-2011 at 02:16 AM (322463 Views)
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 dont 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 .
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 ).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) {} }
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 -
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.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 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