ROBOTIKA
1. BEADANDÓ
2001/2002 tanév 1. félév
Olyan robotot kellett készítenünk, amely képes követni tetszőleges alakú kanyarokat tartalmazó vonalat egy sík terepen. A vonal szélessége tetszőleges lehet. A programnak alkalmazkodnia kell a vonal színéhez és a mindenkori fényviszonyokhoz.
Először a mozgatáshoz szükséges makrókat definiáltuk. Utána következett a kalibrálásért felelős rész, majd pedig a vezérlés egy végtelen ciklusban.
A robotot két motor hajtja, az egyik az oldalirányú, a másik az előre-hátra mozgatásért felel. A mozgást differenciálmű és lánckerék alkalmazásával oldottuk meg.
A tájékozódáshoz a robot három fényérzékelőt használ, ezek közül a középső a követendő vonal fölött, a két szélső pedig két oldalt, a vonal melletti rész fölött kell, hogy legyen. A robot folyamatosan ellenőrzi az érzékelők állapotát, és ha valamelyik elhagyja a neki kijelölt tartományt, a robot iránykorrekciót hajt végre.

Négyféle mozgást definiáltunk: hátra, előre, jobbra, balra mozgásokat. Az A motor végzi az előre-hátra mozgatást, a B az oldalirányú forgatást.
Három szenzort használtunk, amik a robot elején helyezkedtek el. A kalibráció úgy történik, hogy a robot mindkét irányba elfordul, és közben mindhárom szenzorra megméri a minimális és a maximális értéket.
Azért volt szükséges mindhárom érzékelő kalibrálása, mert nem biztos, hogy azonos fényességet azonos értékkel reprezentálnak. A mért minimum és maximum közti tartományt három részre osztottuk. A program azt ellenőrzi, hogy az aktuális fényérték nagyobb vagy kisebb-e, mint a konstansban megadott tartományhatárok. Pl. a KOZEPS makró írja le azt a feltételt, hogy mikortól tekintünk sötétnek egy színt a középső érzékelőn, a KOZEPV pedig, hogy mikor tekintjük világosnak. A két érték közötti tartomány az esetleges becsillanások vagy a kocsi árnyéka által okozott fényerőcsökkenésből adódó tévedések kiküszöbölésére szolgál.
A kalibrációnál először a jobb és a középső érzékelőket állítjuk be. Ezt úgy tesszük, hogy addig fordul balra a robot, amíg a maximum és a minimum közti eltérés nem lesz nagyobb 5-nél. Majd ugyanezzel a módszerrel a bal érzékelőt is kalibráljuk.

A vezérléshez az egyszerű reaktív modellt választottuk. Alapértelmezésben a robot előre megy, az irányváltoztató manővereket feltételek váltják ki. Ha a manővert kiváltó feltétel hamissá válik, akkor a robot visszaáll az előre haladó állapotba.
A manőverek:
#define HATRA { Off(OUT_B); OnFwd(OUT_A); }#define ELORE { Off(OUT_B); OnRev(OUT_A); }#define JOBBRA { Off(OUT_A); OnFwd(OUT_B); }#define BALRA { Off(OUT_A); OnRev(OUT_B); } #define BAL_ERZ SENSOR_3#define KOZEPSO_ERZ SENSOR_2#define JOBB_ERZ SENSOR_1 #define KOZEPS (KOZEPSO_ERZ <= kozepso_min)#define BALS (BAL_ERZ <= bal_min)#define JOBBS (JOBB_ERZ <= jobb_min)#define KOZEPV (KOZEPSO_ERZ >= kozepso_max)#define BALV (BAL_ERZ >= bal_max)#define JOBBV (JOBB_ERZ >= jobb_max) task main(){ int bal_min, jobb_min, kozepso_min, bal_max, jobb_max, kozepso_max; int ert; SetSensor(BAL_ERZ, SENSOR_LIGHT); SetSensor(KOZEPSO_ERZ, SENSOR_LIGHT); SetSensor(JOBB_ERZ, SENSOR_LIGHT); kozepso_min = KOZEPSO_ERZ; kozepso_max = KOZEPSO_ERZ; jobb_min = JOBB_ERZ; jobb_max = JOBB_ERZ; //kalibracio BALRA; until(jobb_max - jobb_min > 5) { ert = JOBB_ERZ; if(ert > jobb_max) jobb_max = ert; else if(ert < jobb_min) jobb_min = ert; ert = KOZEPSO_ERZ; if(ert > kozepso_max) kozepso_max = ert; else if(ert < kozepso_min) kozepso_min = ert; } Wait(50); ert = JOBB_ERZ; if(ert > jobb_max) jobb_max = ert; else if(ert < jobb_min) jobb_min = ert; ert = KOZEPSO_ERZ; if(ert > kozepso_max) kozepso_max = ert; else if(ert < kozepso_min) kozepso_min = ert; JOBBRA; bal_min = BAL_ERZ; bal_max = BAL_ERZ; until(bal_max - bal_min > 5) { int ert; ert = BAL_ERZ; if(ert > bal_max) bal_max = ert; else if(ert < bal_min) bal_min = ert; ert = KOZEPSO_ERZ; if(ert > kozepso_max) kozepso_max = ert; else if(ert < kozepso_min) kozepso_min = ert; } Wait(70); ert = JOBB_ERZ; if(ert > jobb_max) jobb_max = ert; else if(ert < jobb_min) jobb_min = ert; ert = KOZEPSO_ERZ; if(ert > kozepso_max) kozepso_max = ert; else if(ert < kozepso_min) kozepso_min = ert; bal_max -= (bal_max-bal_min)/3; bal_min += (bal_max-bal_min)/2; jobb_max -= (jobb_max-jobb_min)/3; jobb_min += (jobb_max-jobb_min)/2; kozepso_max -= (kozepso_max-kozepso_min)/3; kozepso_min += (kozepso_max-kozepso_min)/2; //raall a csikra BALRA; until(KOZEPS); //elindul ELORE; SelectDisplay(DISPLAY_WATCH); while(true) { if (!BALS && !KOZEPS && !JOBBS) { // Tolat HATRA; until(BALS || KOZEPS || JOBBS); Wait(15); ELORE; } else if(!BALS && KOZEPS && !JOBBS) { // Elore } else if( BALS && !KOZEPS && JOBBS) { // Elore } else if( BALS && KOZEPS && JOBBS) { // Elore } else if(!BALS && !KOZEPS && JOBBS) { // Jobbra JOBBRA; until( KOZEPS || JOBBV); ELORE; } else if( BALS && !KOZEPS && !JOBBS) { // Balra BALRA; until(BALV || KOZEPS ); ELORE; } else if(!BALS && KOZEPS && JOBBS) { // Jobbra elore JOBBRA; until( KOZEPV || JOBBV); ELORE; } else if( BALS && KOZEPS && !JOBBS) { // Balra elore BALRA; until(BALV || KOZEPV ); ELORE; } } }