Robotul Line Follower este un mobil cu roți autonom care urmărește un traseu reprezentat print-o linie de culoare închisă (neagră), pe un fundal de culoarea deschisă (alb). Mașina reprezintă un prototip al unui automobil care merge fără pilot pe un anumit circuit. }
Proiectul este alcătuit din următoarele componente: un cadru din plastic transparent format din 4 piese (șasiul pe care se sprijină celelalte componente, două plăcuțe pe care se sprijină roțile din spate și o plăcuță pe care este atașată roata de sprijin din față), două roți din plastic, 2 motoare de curent continuu Pololu, o roată sferică de sprijin, alte piese auxiliare pentru montarea kitului, cadru pentru 6 baterii de 1,5 V care alimentează microcontrollerul și cele 2 motare.
Schemă bloc:
Cei doi senzori sun conectați la microntroller prin pinii PC6 și PA6, driverul de motor L298 este conectat prin pinii P5, P6, P7 (PWM, ENABLE, INPUT) pentru primul motor și P4, P3, P2 (PWM, ENABLE, INPUT) pentru cel de-al doile motor.
Lista de componente:
Schema driverului:
Programul a fost realizat în C, am folosit compilatorul avr-gcc din Linux și aplicația avrboot pentru încărcarea codului pe micronotroler. În funcția init se inițializează timerul pe 16 biți (TCCR1A, TCCR1B). Algoritmul constă în verificarea culorii pe care se află fiecare senzor. Se disting astfel 4 cazuri (cele două cazuri în care un senzor este pe alb și celălalt pe negru, ambii senzori pe alb, ambii senzori pe negru). Totodată mențin un coeficient care scade viteza când robotul trece printr-o zonă cu mai multe curbe și respectiv crește viteza când se află pe un drum drept. Acest coeficient este calculat astfel: când cel puțin unul din senzori trece deasupra benzii negre atunci se decrementează, iar când ambii senzori se află deasupra zonei albe coeficientul se incrementează. Valorile care controlează vitezele celor 2 motoare sunt reținute în registrele OCR1A și OCR1B.
Am scris câte o funcție pentru fiecare manevră a robotului: moveForward, moveBackward, turnLeft, turnRight.
Fișierul line_follower.h conține următoarele macrodefiniții:
#define PWM1 PD5 #define PWM2 PD4 #define EN1 PD6 #define EN2 PD3 #define IN1 PD7 #define IN2 PD2 #define SEN1 PA6 #define SEN2 PC6 #define LF_TRUE 1 /* viteza de referință */ #define REF_SPEED 450 /* limita maxima a coeficientului de viteză */ #define MAX_COEF 20 #define INC(c) (((c) < 20)?(++(c)):(c)) #define DEC(c) (((c) > 0)?(--(c)):(c)) enum motor_t {MOTOR_1, MOTOR_2}; enum dir_t {LEFT, RIGHT, NO_DIR};
Funcția main:
int main() { unsigned int leftSen, rightSen; int curbureCoefficient = 0; init(); while(LF_TRUE) { leftSen = PINA & _BV(PA6); rightSen = PINC & _BV(PC6); if (!leftSen && !rightSen) { moveForward(1 - (curbureCoefficient / (MAX_COEF * 2)), MOTOR_1); moveForward(1 - (curbureCoefficient / (MAX_COEF * 2)), MOTOR_2); DEC(curbureCoefficient); } else if (!leftSen && rightSen) { turnRight(2 - (curbureCoefficient / (MAX_COEF * 2))); INC(curbureCoefficient); } else if (leftSen && !rightSen) { turnLeft(2 - (curbureCoefficient / (MAX_COEF * 2))); INC(curbureCoefficient); } else { moveForward(0.5, MOTOR_1); moveForward(0.5, MOTOR_2); INC(curbureCoefficient); } } return 0; }
Proiectul are o comportare acceptabilă având în vedere numărul de senzori folosiți și simplitatea algoritmului. Pentru o mai bună precizie la curbe mai dificile utilizarea a doi senzori pare insuficientă.
Nu am întâmpinat dificultăți deosebite și partea software a fost foarte simplă.
Fișierele sursă: line_follower.c și line_follower.h și fișierul Makefile.