This is an old revision of the document!
Proiectul reprezintă un robot tip mașină, autonom care va identifica si semnaliza automat obiecte de metal aflate pe un traseu predefinit. Pe acest traseu se pot afla obstacole care o vor fi ocolite in mod automat, prin stanga sau prin dreapta, in functie de spatiul disponibil, iar la intalnirea unui zid, care se va afla la final de trraseu, robotul il va identifica si isi va opri executia.
Acest proiect este util pentru că este un prim pas spre învățarea dezolvatării de roboți autonomi care repezintă un interes de actualitate în industrie, spre exemplu un robot autonom care realizează cartografierea unei zone reprezintă un astfel de interes, care prezintă o oarecare similiaritate cu proiectul ales, fiind astfel un bun model de învățare.
Schema bloc:
Modulul arduino va utiliza sevomotorul pentru a roti senzorul ultrasonic de proximitate pentru a depista obstacolele pentru a asigura menținerea traseului de parcurgere, respectiv a ocoli obstacolele și a reveniri pe traseu. Toți acești factori vor determina comenzile PWM pe care le va transmite driver-ului de motor care controlează motoarele roților ceea ce permite deplasarea corectă și autonomă a mașinii.
Modulul arduino va citi senzorii inductivi pentru a depista găsirea unui obiect de metal, pe care o va notifica prin modulul bluetooth la un monitor serial de pe calculator. Modulul bluetooth va avea rol și ca tool de debugging în dezvoltarea proiectului.
Listă componete folosite:
Schemă robot:
Codul pentru robot a fost realizat în Arduino 1.8.16, iar pentru controlul motoarelor si a servomotorului am folosit bibliotecile <AFMotor.h>, respectiv <Servo.h>. In ceea ce priveste funcțiile implementate, acestea pot fi împărțite în următoarele categorii:
A. Funcții pentru controlul direcției:
B. Funcții pentru detecțția obstacolelor:
C. Funcții pentru ocolirea obstacolelor:
După ce robotul a trecut de setup-ul senzorilor și a motoarelor, el va face busy-waiting până la primirea caracterului '1' pe interfața serială, prin bluetooth, moment în care va porni algoritmul de parcurgere automată din funcția loop(). Algoritmul de funcționare presupune în primul rând citirea în permanență a distanței până la cel mai apropiat obiect de pe traseu, astfel că în momentul apropierii de un obiect, robotul se va opri și va realiza una din rutinele de ocolire, sau va decide dacă ceea ce se află în fața sa este un zid, de la finalul traseului, caz în care își va încheia execuția. Un alt eveniment care are prioritate asupra modului normal de urmărire a traseului sau de evitare a obstacolelor o reprezintă detecția unui obiect de metal, caz în care robotul se va opri și va notifica pe moitorul serial de pe calculator găsirea acestuia, după care iși va relua execuția normală a algoritmului de parcurgere a traseului.
Algoitmul de parcurgere a traseului constă in deplasarea în linie dreaptă până ce senzorul ultrasonic depisteză un obstacol la mai puțin de 35cm, moment în care este dată comanda de oprire a motoarelor. După care senzorul va fi poziționat să depisteze distanța la care se află cel mai apropiat obstacol în stânga, respectiv în dreapta obiectului din față, iar dacă aceste distanțe sunt comparabile, diferă cu cel mult 10cm, înseamnă că obiectul din față este un zid, caz în care se încheie execuția programului, altfel robotul va decide să îl ocolească prin stânga/dreapta în funcție de spaștiul cel mai mare disponibil (disanța până la cel mai aporpiat obiect din stânga/dreapta cât mai mare), apelând una din cele 2 rutine de ocilire ce realizează un traseu în formă de trapez.
void loop() { distance = ultrasonic(); // read metal Sensors int val[3] = {0, 0, 0}; val[0] = analogRead(metalSensor[0]); val[1] = analogRead(metalSensor[1]); val[2] = analogRead(metalSensor[2]); if (val[0] <= metalThreshold || val[1] <= metalThreshold || val[2] <= metalThreshold) { Stop(); Serial.println("Gasit metal!"); forward2(400); val[0] = val[1] = val[2] = METAL_MAX; delay(wait_metal); } if (distance < 35) { Stop(); L = leftsee(); delay(800); R = rightsee(); Serial.println("Obiect detectat!"); servo.write(spoint); if (abs(distance - R) <= wallDistErr && abs(distance - L) <= wallDistErr) { Stop(); servo.write(spoint); Serial.println("Zid detectat!\nProgram ended."); delay(500); exit(0); } else { if (L > R) { backward(); delay(300); Stop(); delay(wait_time); Serial.println("Ocolire stanga."); ocolire_stanga(); } else { backward(); delay(500); Stop(); delay(wait_time); Serial.println("Ocolire dreapta."); ocolire_dreata(); } } servo.write(spoint); } else { forward(); } }
Arhiva cu codul sursa, diagrama robot, schema bloc: pm2023_linca_nicolae_robert.zip