• Rezultati Niso Bili Najdeni

Izmerjeni časi virtualnega robota pri desetih obratih okoli osi motorjev

π/2 40,53 40,53 40,69 40,58

2/3 π 30,49 30,65 30,49 30,54

π 20,61 20,56 20,54 20,57

Podobno kot za primer translatorne hitrosti, smo v simulatorju Webots izmerili čase pri rotacijskem gibanju. Za vsako različno hitrost smo izmerili le po eno časovno vrednost, saj v simulatorju ne nastopajo razlike v ponovljivosti. Rezultati so prikazani v preglednici 3.6:

Preglednica 3.6: Izmerjeni časi virtualnega robota pri desetih obratih okoli osi motorjev ω

Metodologija raziskave

44

Pri opravljanju rotacijskega gibanja se kolesi na obeh robotih vrtita z enako hitrostjo v nasprotni smeri. Ob zagonu simulacije, ali motorjev na fizičnem robotu, začneta kolesi pospeševati dokler robot (virtualni/fizični) ne doseže željene hitrosti. Ko se to zgodi, začne naprava krožiti okoli osi motorjev s konstantno kotno hitrostjo. Idealne teoretične vrednosti, ki pa so v praksi nedosegljive, so v našem primeru:

‐ 40 s pri hitrosti π/2 rad/s,

30 s pri hitrosti 2/3 π rad/s,

20 s pri hitrosti π rad/s.

Čas, ki je potreben za doseganje željene hitrosti robota, je večji od teoreične vrednosti za približno 0,6 sekunde.

45

4 Rezultati in diskusija

Rezultat raziskovalnega dela je predstavljen na sliki 4.1, kjer sta zajeta trenutka gibanja robotov. Mobilna robota se razlikujeta po obliki. Simulator Webots omogoča uporabo enostavnih geometrijskij teles. Virtualna različica predstavlja zato poenostavljen fizični model. Glavne mere, ki služijo za računanje hitrosti robotov (radij koles in medosna razdalja med kolesoma) so v obeh primerih enake. Oba sestavljena robota sta široka približno 11 cm in segata v dolžino 13 cm.

Slika 4.1: (a) Realni primer mobilnega robota. (b) Virtualni primer mobilnega robota.

Rezultati in diskusija

46

Obe različici robota se gibljeta po prostoru po istem principu:

‐ vožnja naravnost do bližnje ovire,

‐ znižanje hitrosti na ničto vrednost,

‐ zasuk za 60° okoli lastne osi,

‐ preverjanje razdalje,

‐ vožnja naravnost do naslednje ovire.

Postopek se ponavlja v nedogled in omogoča avtonomno vožnjo obeh naprav. Zasuk pri mobilnemu robotu je določen na podlagi stalnega računanja odometrije. Obem napravam lahko prilagajamo krmilni algoritem glede na potrebe.

4.1 Primerjava programske kode

Vsak izmed mobilnih robotov (fizični in virtualni) vsebuje svojo datoteko s programsko kodo. To lahko spreminjamo v uporabniškem vmesniku ali v okolju Arduino IDE. Obe kodi temeljita na programskem jeziku C++. Izdelani uporabniški vmesnik povezuje funkcije iz simulatorja s funkcijami platforme Arduino. S tem lahko uporabnik posamezne odseke kode virtualnega robota enostavno prekopira in doda h programski kodi za realni primer robota.

Kljub uporabniškemu vmesniku, ki vsebuje večino funkcij iz Arduinove platforme, pa se programiranje fizičnega mobilnega robota razlikuje od programiranja virtualne različice:

‐ prekinitvene funkcije je v simulatorju potrebno klicati znotraj neskončne zanke loop() in ne v zanki setup().

‐ Zapisovanje napetosti na DC motorjih se v simulatorju izvede s funkcijo analogWrite(), v primeru realne naprave pa s funkcijo ledcWrite().

‐ V simulatorju lahko prožimo le eno prekinitveno funkcijo za vsak kodirnik.

‐ V simulatorju moramo zunanje funkcije (npr. funkcije za štetje pulzov iz kodirnikov) definirati pred zanko loop().

‐ Branje vrednosti senzorjev na krmilniku ESP, ki so povezani na priključke adc2, opravimo s funkcijo adc2_get_raw().

4.2 Primerjava translatornega in rotacijskega gibanja

Za primerjanje gibanj med mobilnim robotom in virtualno različico smo opravili 2 preizkusa.

Sprva smo merili translatorno hitrost robotov. Primerjali smo čase pri vožnji naravnost naprej ob dosegu razdalje 100 cm. Primerjava je prikazana na sliki 4.2. Iz grafa je razvidno, da se rezultati ujemajo pri vseh hitrostih (10 cm/s, 20 cm/s in 30 cm/s). Odstopanja realnega primera so zelo majhna in težko razvidna na grafu. Časovne vrednosti odstopajo za nekaj stotink sekunde.

Rezultati in diskusija

47 Slika 4.2: Primerjava translatornega gibanja mobilnega robota z virtualno različico

Na koncu smo izvedli primerjavo med rotacijskimi gibanji mobilnih robotov. Pri izbranih kotnih hitrostih (π/2, 2/3 π in π) se vrednosti skoraj popolnoma ujemajo kot kaže slika 4.3.

Slika 4.3: Primerjava rotacijskega gibanja mobilnega robota z virtualno različico

0

Čas pri desetih obratih okoli osi motorjev [s]

Kotna hitrost [rad/s]

fizični robot virtualni robot

Rezultati in diskusija

48

Iz grafov, ki jih prikazujeta sliki 4.2 in 4.3, je razvidno ujemanje med gibanji obeh naprav.

Med razlogi je vpliven krmilni algoritem PI, preko katerega računamo napetosti na motorjih.

Glede na to, da maksimalni hitrosti obeh sovpadata, sta tudi izhodni števili iz PI člena enaki.

49

5 Zaključki

V diplomski nalogi smo dokazali koristi simulacijskih orodij, ki jih lahko uporabimo za izobraževalne in raziskovalne namene.

1) Na podlagi izbranih komponent smo z uporabo programa KiCad EDA zasnovali tiskano vezje. Na to smo spajkali komponente in sestavili mobilni robot z diferencialnim pogonom. Napravi smo v okolju Arduino IDE napisali program za avtonomno vožnjo po prostoru.

2) Na podlagi razvitega mobilnega robota smo v simulatorju Webots zasnovali virtualni model naprave z enakimi lastnostmi. Za zagotavljanje skladnosti programskih kod, smo zasnovali uporabniški vmesnik, ki povezuje glavne funkcije simulatorja s funkcijami platforme Arduino.

3) Ugotovili smo, da z ustreznim uporabniškim vmesnikom omogočimo uporabniku lažje programiranje, učenje v simulatorju in aplikacijo osvojenega znanja na realnem primeru.

4) Ugotovili smo, da so odstopanja pri translatornem in rotacijskem gibanju med realnim razvitim robotom in njegovo različico zanemarljivo majhna. Odstopanja translatorne hitrosti segajo do največ ± 2,3%. Odstopanja kotne hitrosti med napravama pa segajo do največ ± 0,6%. Reaktivnost in delovanje obeh naprav sta enaka.

V celotni diplomski nalogi smo osvojili znanje iz področja mobilne robotike, razvoja vezja, postopka spajkanja in povezovanja elektronskih komponent. Spoznali smo simulacijsko okolje Webots in ga uporabili za simuliranje obnašanja robota v prostoru. Z razvitim uporabniškim vmesnikom smo okrepili znanje na področju programiranja v jeziku C++ in globlje spoznali funkcije iz platforme Arduino.

Predlogi za nadaljnje delo

V nadaljnem bi lahko izboljšali tiskano vezje s tem, da bi drugače razporedili položaj komponent na njem. Nekaterim izvrtinam bi spremenili dimenzije, npr. izvrtini namenjeni nosilcu za baterijo bi zmanjšali širino. Spemenili bi tudi električno vezavo komponent, s tem

Zaključki

50

da bi sprostili priključke adc2. S tem bi omogočili uporabo brezžične komunikacije z napravo. Poleg IR senzorjev za določevanje razdalje bi lahko uporabljali tudi senzorje za zaznavanje talne črte. V tem primeru bi bila potrebna uporaba zmogljivejšega mikrokrmilnika ali večjega dovoda električnega toka. Pri branju vrednosti iz vseh senzorjev se krmilnik ugaša in ponovno zaganja program. Dodatno bi lahko izboljšali krmilni algoritem za premikanje robota v prostoru.

51

Literatura

[1] N. Dey in A. Mukherjee, Embedded Systems and Robotics with Open Source Tools, CRC Press, 2018.

[2] T. Bräunl, Embedded robotics: Mobile robot design and applications with embedded systems, 3. izdaja, Springer, 2008.

[3] C. Jung, C. bae Moon, D. Jung, J. S. Choi in W. Chung, ''Design of test track for accurate calibration of two wheel differential mobile robots'', International Journal of Precision Engineering and Manufacturing, vol. 15, št. 1, 2014.

[4] K. Lee, C. Jung in W. Chung, ''Accurate calibration of kinematic parameters for two wheel differential mobile robots,'' Journal of Mechanical Science and Technology, vol. 25, št. 6, 2011.

[5] M. Ben-Ari in F. Mondada, ''Robotic Motion and Odometry'' v Elements of Robotics, Springer International Publishing, 2018, str. 63–93.

[6] P. Podržaj, Linearna teorija krmiljenja sistemov, Ljubljana: Fakulteta za strojništvo, 2017.

[7] A. Visioli, Pratical PID Control, Springer, 2006.

[8] E. K. Boukas in F. M. Al-Sunni, Mechatronic systems: Analysis, design and implementation, Springer, 2012.

[9] A. K. Maini, Digital Electronics: Principles, Devices and Applications, John Wiley

& Sons, 2007.

[10] How do magnetic encoders work. Dostopno na:

https://www.designworldonline.com/faq-how-do-magnetic-encoders-work/, ogled 19.07.2021.

[11] R. S. Khandpur, Printed Circuit Boards Design, Fabrication and Assembly, McGraw-Hill, 2006.

[12] J. Varteresian, Fabricating Printed Circuit Boards, Newnes, 2002.

[13] M. Casini in A. Garulli, ''MARS: An Educational Environment for Multiagent Robot Simulations'', Modelling and Simulation in Engineering, vol. 2016, 2016.

[14] Webots tutorials. Dostopno na: https://cyberbotics.com/doc/guide/tutorials, ogled 10.05.2021.

[15] K. Mitzner, Complete PCB Design Using OrCad Capture and Layout, Newnes, 2007.

Literatura

52

Priloga A

#include <driver/adc.h>

//geometrijske mere

float l = 0.0505; //polovična razdalja med kolesoma [m]

float r = 0.016; //radij koles [m] int front_right = 0;// spremenljivka //Encoder

int encoder_channel_A_left = 5;

int encoder_channel_B_right = 4;

int encoder_channel_A_right = 3;

int encoder_channel_B_left = 6;

volatile int right_pulses = 0;

volatile int left_pulses = 0;

//spremenljivke

unsigned long previousMillis = 0;

unsigned long previousMillis2 = 0;

//PID

//odometrija

const int ledChannel1 = 0;

const int ledChannel2 = 1;

const int resolution = 8;

void setup() {

ledcSetup(ledChannel1, freq, resolution);

ledcSetup(ledChannel2, freq, resolution);

ledcAttachPin(enable_left, ledChannel1);

ledcAttachPin(enable_right, ledChannel2);

//hitrost v_ref = v_set;

w_ref = w_set;

//za zagon je potrebno pritisniti na gumb boot na ESP krmilniku while (digitalRead(0) == HIGH) {

previousMillis = millis();

} }

void loop() {

//racunanje hitrosti na kolesih v_ref_right = v_ref + l * w_ref;

v_ref_left = v_ref - l * w_ref;

w_ref_right = v_ref_right / r;

w_ref_left = v_ref_left / r;

//nastavitev smeri vrtenja if (w_ref_left >= 0.0) {

digitalWrite(input_1_left, LOW);

digitalWrite(input_2_left, HIGH);

} else {

digitalWrite(input_1_left, HIGH);

digitalWrite(input_2_left, LOW);

}

if (w_ref_right >= 0.0) {

digitalWrite(input_1_right, HIGH);

digitalWrite(input_2_right, LOW);

} else {

digitalWrite(input_1_right, LOW);

digitalWrite(input_2_right, HIGH);

}

//racunanje razdalj

esp_err_t err = adc2_get_raw(ADC2_CHANNEL_3, ADC_WIDTH_BIT_13, &front_right);

float back_voltage = analogRead(back) * 3.3 / 8191;

float left_voltage = analogRead(front_left) * 3.3 / 8191;

float right_voltage = front_right * 3.3 / 8191;

float distance_back = 26.225 * pow(back_voltage, -1.397);

float distance_left = 26.225 * pow(left_voltage, -1.397);

float distance_right = 26.225 * pow(right_voltage, -1.397);

//izpis podatkov

unsigned long currentMillis = millis();

if (currentMillis - previousMillis2 >= 200) { //izpis podatkov

Serial.print("w_actual_left ");

Serial.println(w_actual_left );

Serial.print("w_actual_right ");

Serial.println(w_actual_right );

Serial.println("______________________");

//________________________________________________________________________

previousMillis2 = currentMillis;

}

if (currentMillis - previousMillis >= 100) { dt = (currentMillis - previousMillis) / 1000.0;

w_actual_right = (float)right_pulses * 2 * PI / 29.86 / 12.000 / dt;

//29.86*12 -> faktor pretvorbe od prestavnega razmerja

w_actual_left = (float)left_pulses * 2 * PI / 29.86 / 12.000 / dt;

right_pulses = 0;

left_pulses = 0;

//right PID

float error_right = abs(w_ref_right) - abs(w_actual_right);

sum_error_right += error_right * dt;

sum_error_right = constrain(sum_error_right, -20.0, 20.0);

float rateError_right = (error_right - previousError_right) / dt;

pwm_right = (kp * error_right + ki * sum_error_right + kd * rateError_right);

pwm_right = constrain(pwm_right, 0, 255);

//left PID

float error_left = abs(w_ref_left) - abs(w_actual_left);

sum_error_left += error_left * dt;

sum_error_left = constrain(sum_error_left, -20.0, 20.0);

float rateError_left = (error_left - previousError_left) / dt;

pwm_left = (int)(kp * error_left + ki * sum_error_left + kd * rateError_left);

pwm_left = constrain(pwm_left, 0, 255);

//writing PID parameter

ledcWrite(ledChannel1, pwm_left);

ledcWrite(ledChannel2, pwm_right);

previousMillis = currentMillis; //bi moglo bit -= 100 previousError_right = error_right;

previousError_left = error_left;

//odometrija

w_previous = (w_actual_right * r - w_actual_left * r ) / (2.00 * l);

v_previous = (w_actual_left * r + w_actual_right * r ) / 2.00;

//izvedba zasuka za 60° ob zaznavanju ovire

if ((abs(fi - fi_rotate)) > (PI / 3) && vrtenje == 1) {

if (digitalRead(encoder_channel_A_left) !=

digitalRead(encoder_channel_B_left)) {

if (digitalRead(encoder_channel_A_left) != digitalRead(encoder_channel_B_left)) {

if (digitalRead(encoder_channel_A_right) !=

digitalRead(encoder_channel_B_right)) {

void count_pulses_B_right() {

if (digitalRead(encoder_channel_A_right) !=

digitalRead(encoder_channel_B_right)) { right_pulses -= 1;

} else {

right_pulses += 1;

} }