Ioniță Dragoș 332CB, e-mail: dragos.ionita2303@stud.acs.upb.ro
Proiectul constă într-o mașinuță cu două motoare, cu senzori de viteză a rotației celor două motoare și capacitatea de a urma un traseu predefinit la pornirea mașinuței (la alimentarea acesteia sau la apăsarea butonului RESET de pe Arduino).
Pe parcursul traseului, mașinuța va fi capabilă să identifice obstacolele din fața sa și să se oprească, apoi să-și schimbe direcția de mers pentru a evita coliziunea.
Mașina nu va fi controlată remote / bluetooth / wi-fi, ci va porni la apăsarea unuia din butoanele corespunzătoare pentru un traseu predefinit.
Ideea de la care am pornit a fost folosirea de senzori și întreruperi hardware pentru a crea ceva ce se aseamănă cât mai mult cu o mașină robot 'inteligentă'.
Mașina va fi pre-programată software pentru a urma orice traseu, pe orice direcție, cu viteze diferite, putând astfel simula 'coregrafii', urmând diverse pattern-uri și mișcări stânga-dreapta, înainte-înapoi, inclusiv rotiri în jurul propriei axe.
Senzorii vor fi conectați la motoare, pe șasiul mașinuței și vor măsura viteza de rotație a roților motoare.
Prin intermediul driverului L298N, se vor putea controla motoarele pentru a putea predefini traseele de urmat, iar distanțele și vitezele vor fi calculate cu ajutorul output-ului senzorilor și trimise către motoare prin intermediul driverului L298N.
Va exista si senzorul HC-SR04 ultrasonic pentru măsurarea distanței, care va fi montat în partea din față a mașinuței. Acesta va transmite distanța până la un eventual obstacol din față, iar mașinuța va reacționa, fie prin oprire și schimbarea direcției de mers, fie prin ocolirea acestuia și continuarea drumului.
RPM = (counter / diskslots) * 60.00
, unde counter este de câte ori se întrerupe fascicolul infraroșu al optocuplatorului, diskslots sunt numărul de fante din roțile encodoare ale motoarelor (20 în cazul meu), iar * 60.00 pentru a transforma in Rotații Pe Minut (RPM).
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); void setup() { sound_speed = (331.4 + 0.606 * TEMP + 0.0124 * HUMID) / 10000.0; } void loop() { // put your main code here, to run repeatedly: duration = sonar.ping(); // get the duration between sending and receiving the signal on the sensor pins distance = (duration / 2) * sound_speed ; // 343 m/s, speed of light, in transformed in cm/ms Serial.print("Distance = "); if (distance >= 400 || distance <= 2) { Serial.println("OUT OF RANGE!\n"); } else { Serial.print(distance); Serial.println(" cm"); delay(500); } delay(500); }
Pentru video-ul de la link-ul [4], pozele cu măsurătorile în urma demo-ului, unde se măsoară (eronat) 2800 RPM, din cauza curenților de fugă existenți în circuitul intern Arduino (nu folosisem condensatori pentru stabilizare aici):
Pentru video-ul de la link-ul [5], poza cu măsurătoarea îmbunătățită, de 450 RPM, pentru unul din motoare (dar încă eronate, față de referința de 200-230 RPM conform catalogului motoarelor). Aici am folosit condensatori de 10 nF. O posibilă îmbunătățire este folosirea unor condensatori de capacitate mai mică (pF):
Pentru video-ul de la link-ul [6], poza cu măsurătoarea distanței cu senzorul ultrasonic HC-SR04, pentru 30cm, 25cm, 20cm, 15cm și 10cm (rigla din video pentru referință). Se observa erori de 1, 2 cm când se stabiliează poziția senzorului pentru fiecare din cele 5 valori de mai sus:
// Pins for Motor A int en_A = 10; int in_1 = 9; int in_2 = 8; // Pins Motor B int en_B = 5; int in_3 = 7; int in_4 = 6; void demoOne() { // Turn on Motor A FORWARD digitalWrite(in_1, HIGH); digitalWrite(in_2, LOW); // Turn on Motor B FORWARD digitalWrite(in_3, HIGH); digitalWrite(in_4, LOW); delay(500); // Set Speed for Motor A at 200/255 analogWrite(en_A, 200); // Set Speed for Motor B at 200/255 analogWrite(en_B, 200); // Wait 4 seconds delay(4000); // Turn off both Motors A and B digitalWrite(in_1, LOW); digitalWrite(in_2, LOW); digitalWrite(in_3, LOW); digitalWrite(in_4, LOW); } void setup() { // put your setup code here, to run once: pinMode(en_A, OUTPUT); pinMode(en_B, OUTPUT); pinMode(in_1, OUTPUT); pinMode(in_2, OUTPUT); pinMode(in_3, OUTPUT); pinMode(in_4, OUTPUT); delay(2000); demoOne(); delay(1000); } void loop() { // put your main code here, to run repeatedly }
Proiectul încă poate fi îmbunătățit din punct de vedere software, putând fi configurat să ruleze orice traseu și să reacționeze la obstacole în moduri diferite. Marea problemă în menținerea direcției robotului o reprezintă roata directoare de pe rulmentul din spatele sașiului (cum se poate observa în demo-ul de la link-ul [8]), care nu stă mereu dreaptă și astfel traiectoria nu este dreaptă atunci când ar trebui să fie în mod normal (deoarece motoarele au aceeași turație). Mai mult, senzorul nu detectează foarte precis dacă obstacolul nu este perpendicular pe direcția de emitere a acestuia, deoarece undele nu revin pe aceeași direcție înapoi către senzor, iar asta poate duce la opriri prea târzii, după cum se poate observa în unele situații din demo-ul de la link-ul [8].
Arhiva cu codul folosit la filmarea videoclipurilor componente din compilația din demo-ul de la linkul [8]: ionita_dragos_332cb_demo_robot_v1.0.zip
https://ocw.cs.pub.ro/courses/pm/prj2021/avaduva/obstacleavoidingcar?do=export_pdf