Reaali Robootika.COM

NXT robotimaailm ja programmeerimine C-keeles

Juhend: NXT ekraani kasutamine

Ekraani saab kasutada selleks, et saada aktiivselt tagasisidet roboti töö kohta. Alljärgnevalt mõned peamised käsud NXC-s, mille abil juhtida ekraani. Siin on toodud välja ka NXT-l asuvad nupud ja heli tegemine.

ClearScreen();

 

Puhastab ekraani.

ClearLine(“Line”);

ClearLine(LCD_LINE2);

Puhastab ekraanil rea nr 2.

TextOut(“x”, “line”, “txt”, “options”);

TextOut(50, LCD_LINE3, "Hello World");

 

Kirjutab  ekraanil reale nr 3 sõnad „Hello World“.

NumOut(“x”, “line”, “val”, “options”);

TextOut(50, LCD_LINE3, 38);

 

Kirjutab  ekraanil reale nr 3 numbri 38.

ButtonPressed(“btn”,“reset”);

ButtonPressed(BTNRIGHT, FALSE);

Kontrollitakse nupuvajutust.

BTNRIGHT

BTNLEFT

BTNCENTER

BTNEXIT

Reset on TRUE/FALSE ning see nullib nupuvajutuste arvu.

PlayTone(“frequency”, “duration”);

PlayTone(440, SEC_2);

Mängib 2 sekundit tooni sagedusel 440 Hz.

Juhend: Matemaatika C-keeles

Programmide kirjutamisel on tarvis liita-lahutada-korrutada-jagada. Oma tavapärasest matemaatikas oleme harjunud kirjutama, et a + b = c.

C-keeles saab aga asju lühemalt väljendada, kõik ikka selleks et programm oleks lihtsam.

Tüüpiliselt on programmis muutuja (see on mingi arv näiteks), millele on vaja juurde liita mingi teine number.

Matemaatiliselt tavaline liitmistehe on võimalik C-keeles järgmiselt teha x += y. Hea lühike.

Tehe C-keeles Kirjeldus

liitmine

x += 2

Liidab muutujale juurde teise arvu. 

  • Olgu x alguses 1
  • Seejärel liidame x-le juurde 2 (x + 2 = 3)
  • Tulemuse kirjutame iseendasse, st. x-le omistatakse väärtus 3 ja seega x = 3

See tehe on pikemalt välja kirjutades x = x + 2

Näide 2. x += y

  • olgu x alguses 3 ja y väärtus 2
  • ülaltoodud tehe on x + y ehk siis 3 + 2 = 5
  • antud arv 5 omistatakse x-le, ja seega x = 5

lahutamine

x –= 2

Lahutab muutujast teise arvu. 

  • Olgu x alguses 5
  • Seejärel lahutame x-st arvu 2 (x – 2 = 3)
  • Tulemuse kirjutame iseendasse, st. x-le omistatakse väärtus 3 ja seega x = 3

See tehe on pikemalt välja kirjutades x = x - 2

korrutamine

x *= 2

Korrutab muutujat teise arvuga. 

  • Olgu x alguses 3
  • Seejärel korrutame x-i arvuga 2 (x * 2 = 6)
  • Tulemuse kirjutame iseendasse, st. x-le omistatakse väärtus 6 ja seega x = 6

See tehe on pikemalt välja kirjutades x = x * 2

jagamine

x /= 2

Jagab muutujat teise arvuga. 

  • Olgu x alguses 6
  • Seejärel jagame x-i arvuga 2 (x / 2 = 3)
  • Tulemuse kirjutame iseendasse, st. x-le omistatakse väärtus 3 ja seega x = 3

See tehe on pikemalt välja kirjutades x = x / 2

liitmine
ühe ühiku võrra

i++

Kahekordne pluss tähistab seda, et muutujale i liidetakse juurde üks ühik.

  • Olgu i alguses 1
  • peale selle käsu käivitamist on tehtud tehe i + 1
  • seega tulemus, i = 2

lahutamine
ühe ühiku võrra

i--

Kahekordne miinus tähistab seda, et muutujast i lahutatakse üks ühik.

  • Olgu i alguses 10
  • peale selle käsu käivitamist on tehtud tehe i - 1
  • seega tulemus, i = 9

4 tund: Kahe lülitiga roboti juhtimine

Õppematerjal:
3 tund- Lülititega roboti juhtimine
Juhend- while, until tsüklite kasutamine
Juhend- IF ELSE ja SWITCH kasutamine
Juhend- Andurite defineerimine ja lugemine

Sisuliselt on selleks tunniks 2 ülesannet.

Alljärgnevate ülesannete juurde on lisatud ka nende olekudiagrammid, mille abil on programmiosade töö selgitamine lihtsam. Samuti annavad programmist tervikliku ülevaate.

Ülesanne 2. Robotil on küljes kaks lülitiandurit.

roboti programmi olekudiagrammVariant a) Robot sõidab edasi, kuid vajutades ühte lülitit keerab sujuvalt paremale ning teise lüliti korral vasakule.

Lahendus. Iseenesest lihtne IF ELSE lausete jada. Esiteks täidetakse lõpmatult tsüklit, mille sees kontrollitakse iga tsükli käigus kas üks või teine lüliti on vajutatud.  Siin on kasutatud edasiliikumiseks OnRevSync funktsiooni, kuna antud BOT-l olid mootorid teisipidi peal.

task main(){
SetSensorTouch(S2);
SetSensorTouch(S1);
while(TRUE){
  if (Sensor(S2)){
    OnRevSync(OUT_BC, 50, -10);
  }
  else if(Sensor(S1)){
    OnRevSync(OUT_BC, 50, 10);
  }
  else{
    OnRev(OUT_BC, 50);
  }
}
}

roboti programmi olekudiagrammVariant b) Robot hakkab edasi sõitma siis kui mõlemad lülitid on korraga alla vajutatud ja lahti lastud. Üksikult kasutades toimivad lülitid paremale-vasakule keeramisena. Teistkordsel üheaegsel vajutamisel jääb robot seisma.

Lahendus.

Alguses robot seisab ja ootab kuni mõlemad lülitid on bumped (ehk vajutatud-lahti lastud).

Peale lülitite vajutamist käivitub funktsioon while, mille tingimuseks on määratud Bumped2Buttons muutuja. Kuna see muutuja on algväärtustatud eelnevalt FALSE-ks siis läheb antud tsükkel käima (kuna tingimuslauses on muutuja ees ! hüüumärk).

Seejärel toimib programm täpselt nii nagu ee on kirjeldatud eelmise variandi korral – ehk keerab paremale-vasakule-sõidab otse.

Kuid lisaks on toodud üks IF lause, mille tingimuseks on kontroll, kas mõlemad lülitid on vajutatud. Kui on alla vajutatud, täidetakse IF lause ning until-funktsioon jääb ootama, kuni lülitid on lahti lastud.

Lülitite lahti laskmisel muudetakse Bumped2Buttons väärtus TRUE-ks ning edasi läheb programm uuele tsüklile ja kontrollib tingimust. Kuna tingimus ei ole tema jaoks tõene, väljutakse while tsüklist lülitatakse mootorid välja ja jäädakse ootama taas nuppude bumped-vajutust roboti käivitamiseks.

Selle programmi loomisel tuli juba päris mitu viga ning algne versioon oli ka sutsu keerukam kui alljärgnev lõplik lahendus.

task main(){
bool Bumped2Buttons;
SetSensorTouch(S1);
SetSensorTouch(S2);
while(true){
  Bumped2Buttons = FALSE;
  until(Sensor(S1) && Sensor(S2));
  until(!Sensor(S1) && !Sensor(S2));
  while(!Bumped2Buttons){
    if (Sensor(S1)== 1){
       OnRevSync(OUT_BC, 50, -10);
    }
    else if(Sensor(S2)== 1){
       OnRevSync(OUT_BC, 50, 10);
    }
    else{
       OnRev(OUT_BC, 50);
    }
    if(Sensor(S1) && Sensor(S2)){
      until(!Sensor(S1) && !Sensor(S2));
      Bumped2Buttons = TRUE;
    }
  }
  Off(OUT_BC);
}
}

Teine variant sama ülesande lahendamiseks on alljärgnev.

2 lülitiga pöörav robot

Siin variandis ei ole kasutatud muutujat, mille alusel väljutaks teisest while-tsüklist. Siin on kasutatud ära matemaatilist loogika ning tsüklist väljumise tingimus on sisse kirjutatud while-tsükli enda tingimuseks. Tulemuseks on mõnevõrra lihtsam kood.

 

task main()
{
 SetSensorTouch(S1);
 SetSensorTouch(S2);
 while(TRUE)
 {
	until(Sensor(S1) && Sensor(S2)); //ootab nupu vajutust
	until(!Sensor(S1) && !Sensor(S2)); //ootab nupu lahti laskmist
	//While tsükli stoppimiseks, ootab kuni mõlemad nupud on alla vajutatud 
	while(!Sensor(S1) || !Sensor(S2)) 	{
		if(Sensor(S1))
		{
			OnFwdSync(OUT_BC, 75, 10);
		}
		else if(Sensor(S2))
		{
			OnFwdSync(OUT_BC, 75, -10);
		}
		else
		{
		OnFwdSync(OUT_BC, 75, 0);
		}
	}
	Off(OUT_BC);
	until(!Sensor(S1) && !Sensor(S2)); //ootab nupu lahti laskmist
 }
}

Juhend: IF ELSE ja SWITCH kasutamine

Programmeerimise enimkasutatav funktsioon on ilmselgelt IF ja IF ELSE laused. Tegemist siis tingimuste kontrolliga ning vastavalt sellele tegevuse ette võtmine.

Teise funktsioonina olen alljärgnevalt välja toonud ka SWITCH funktsiooni, kuna selle näol on tegemist nö. pika if-elseif-elseif-else lausendi jadaga.


if ("condition”) {“body” } else {“body” }

if (x == 1) {
   y = 1;
   z = 2;
 }
 else {
   y = 3;
   z = 5;
 }

Kui tingimus on tõene, täidetakse esimene käsk kui tingimus on väär täidetakse alternatiivne käsk.

IF lause sees võib ELSE IF lauseid palju olla, vaata alljärgnevat.

if (x == 1) {
   y = 1;
   z = 2;
 }
 else if (x == 2) {
   y = 3;
   z = 5;
 }
else {
  y = 6;
  z = 7;
 }

 

Sellisel juhul kontrollitakse kõigepealt IF tingimust kui see on väär minnakse edasi ja kontrollitakse ELSE IF tingimust, kui ka see on väär minnakse edasi järgmise kontrolli juurde.

Ehk siis ülaltoodud IF lauset tuleks lugeda järgmiselt: Kui x on võrdne 1-ga, pane y väärtuseks 1 ja z väärtuseks 2, kui aga x on võrdne 2-ga, pane y väärtuseks 3 ja z väärtuseks 5, või muidu pane y väärtuseks 6 ja z väärtuseks 7.


switch ("expression”) {“body” }

switch(x)
 {
        case 1:
         // tee midagi kui x on 1
         break;
        case 2:
        case 3:
         // tee midagi kui x on 2 või 3
         break;
        default:
         // tee midagi kui x pole 1, 2 või 3
         break;
 }

 

Switch kontrollib x väärtust ja vastavalt selle väärtusele teostab operatsiooni. See on sama tulemus kui ELSE IF funktsiooni jada kasutades. Kuid switch konstruktsiooni on oluliselt lihtsam kasutada võrreldes ELSE IF lausete jadaga.

Näiteks värviandurist värvi-info saamise korral, musta värvi korral tehakse ühtemoodi, punase korral teisiti jne.

Või infrapuna seekerist saabuvate numbrite 1..9 korral saan kirjeldada, mida ühel või teisel juhul tehakse.

3 tund: Lülititega roboti juhtimine

Tunniteemaks ülesanded, mille käigus tuleb roboti tööd juhtida lülitite abil. tegemist suhteliselt lihtsate ülesannetega, kuid C-keele õppimiseks täiesti piisava keerukusega.

Õppematerjal:
Juhend- Andurite defineerimine ja lugemine
Juhend- while, until tsüklite kasutamine
Juhend- IF ELSE ja SWITCH kasutamine

Tunni sisu:

Igaühel on oma BOT, millele on vastavalt esimeste ülesannete käigus ühendatud 1 lüliti ning teiste käigus kaks lülitit. Õpime kasutama funktsioone Until, While ja IF ELSE laused.

Tegelikult ei jõudnud keegi neid ülesandeid 2 tunni jooksul ära teha, mistõttu ülesanne nr 2 jääb järgmise tunni teemaks.


Ülesanne 1. Robotil on küljes üks lülitiandur pika juhtmega.

Variant a) Robot sõidab seni kuni lüliti on vajutatud.

Lahendus. Esialgu muutujaid ei kasutanud, jõuame nendeni edaspidi. Õppisime kasutama IF ELSE lauset.

task main(){
SetSensorTouch(S1);                          
while (TRUE)
{ if (Sensor(S1))
{ OnFwd(OUT_BC, 100); } else
{ Off(OUT_BC); } } }

Variant b) Robot seisab kui lüliti on vajutatud.

Lahendus. Selle ülesande lahendamisel lähtus enamik sellest, et vahetati IF ja ELSE laused omavahel ära ning suur oli poiste üllatus kui selgus, et seda on võimalik lahendada vaid ühe hüüumärgi lisamisega. Kui näiteks IF ja ELSE lausete sisu on väga mahukas, on nende vahetamine igal juhul ajamahukam ja mõningate ohtudega seotud vs. hüüumärgi lisamine.

task main(){
SetSensorTouch(S1);                          
while (TRUE)
{ if (!Sensor(S1))
{ OnFwd(OUT_BC, 100); } else
{ Off(OUT_BC); } } }

Variant c) Robot hakkab sõitma kui lülitit on korra vajutatud ja lahti lastud ning peatub kui teist korda vajutatakse/lahti lastakse (bumped).

Lahendus. Õppisime kasutama until funktsiooni, mille abil on lihtne teha lülitile bumped-tüüpi vajutuse kontroll. Esimene until ootab kuni lüliti on vajutatud ning järgmine until ootab kuni lüliti on lahti lastud.

task main(){
SetSensorTouch(S1);
while(TRUE){
  until(Sensor(S1));
  until(!Sensor(S1));
  OnRev(OUT_BC, 100);
  until(Sensor(S1));
  until(!Sensor(S1));
  Off(OUT_BC);
}
}

Ülesanne 2. Robotil on küljes kaks lülitiandurit.

Variant a) Robot sõidab edasi, kuid vajutades ühte lülitit keerab sujuvalt paremale ning teise lüliti korral vasakule.
Variant b) Robot hakkab edasi sõitma siis kui mõlemad lülitid on korraga alla vajutatud ja lahti lastud. Üksikult kasutades toimivad lülitid paremale-vasakule keeramisena. Teistkordsel üheaegsel vajutamisel jääb robot seisma.

Juhend: while, until tsüklite kasutamine

Programmeerimise peamised konstruktsioonid seisnevad tsüklites ning tingimuslausetes. Tsükkel on  tegevus mida korratakse seni, kuni etteantud tingimus vastab tsükli konstruktsioonile. Alljärgnevalt vaatame tsükleid while ning until ja seda mille poolest need erinevad.

Väga levinud on robootikas kasutada lõpmatult täidetavat tsüklit, seda läheb praktiliselt tarvis iga lõputult toimiva programmi korral.


while("tingimus")

while(x < 10)
 {
        x += 1;
        y *= 2;
 }

Kontrollitakse tingimust x<10 kui see on tõene, täidetakse while tsükli sisu ning siis kontrollitakse taas tingimust. Toimub seni kuni tingimus on väär - siis väljutakse tsüklist. Seega antud näite korral läbitakse tsüklit 9 korda, sest 10-dal korral on x = 10, seega tingimus pole tõene ja väljutakse tsüklist ehk minnakse programmiga edasi. 

while(TRUE) see on lõpmatult kestev tsükkel. Kuna TRUE tähendab seda, et avaldise väärtus on alati tõene siis selline tsükkel täidab oma sisu lõpmatu arv kordi.

Alljärgnev on näide nupu “bumped” funktsiooni teostamine:

while(!Sensor(S1));        // ootab nupule vajutamist
while(Sensor(S1));         // ootab nupu lahti laskmist


Ülalkirjeldatud bumped-funktsionaalsus töötab järgmiselt. Kui nupp on lahti siis see tähendab, et esimene tsükkel on tõene. Kui nupp vajutatakse alla, muutub esimese tsükli tingimus vääraks ning tõeseks muutub teise tsükli tingimus. Kui nuppu hoitakse all ei lähe programm edasi, kuna täidetakse teist tsüklit. Nupu lahti laskmise korral muutub tingimus vääraks ning programm läheb edasi.

 


until(EVENT_OCCURS);

until(SensorUS(S1) > 50);

until käitub vastupidiselt while tsüklile, st. see funktsioon ootab kuni tema tingimus saab tõeseks. Seda saab kasutada edukalt programmi seiskamiseks ning andurist kindla signaali ootamiseks.

Alljärgnev on näide nupu “bumped” funktsiooni teostamine, võrdle while tsükliga:

until(Sensor(S1));         // ootab nupule vajutamist
until(!Sensor(S1));        // ootab nupu lahti laskmist

Kui nupp on avatud siis esimese until funktsiooni tingimus on FALSE ja seega programm ootab selle taga. Nupu allavajutamisel muutub tingimus TRUE-ks ning programm läheb edasi, jäädes ootama teise until funktsiooni taha. Kui nüüd nupp lahti lasta ehk nupu väljund on FALSE, muutub teise until funktsiooni tingimus TRUE-ks ning programm liigub edasi

Juhend: Lihtne matemaatika

lihtne matemaatikaAegajalt tuleb robootikas ette olukordi, kus on vaja muuta mingist andurist tulev signaal märgiliselt vastupidiseks või mingil muul moel lihtsalt teisendada.

Näide 1

Kaugusandurist tulevad välja numbrid 0..100, kuid mootorile oleks vaja sisse anda vastupidine väärtus 100 .. 0. Ehk kui robot on seina lähedal siis eemaldub sellest kiiresti, kuid mida kaugemal on sein seda aeglasemalt robot liigub.

Lihtne matemaatiline tehe: 100 - algne arv = soovitud arv

 


Näide 2

lihtne matemaatikaInfrapuna otsijast (IR seekerist) tulevad välja numbrid 1..9. Nüüd oleks vaja luua keskkoht (5), mis võrdub nulliga ning 6-9 korral lasta robotil paremale keerata ning 1-4 korral lasta robotil vasakule keerata. 0 korral sõidab otse.

Lihtne matemaatika:

esmalt keskkoha arvutamiseks: algne arv – keskkoht (5) = soovitud arv

seejärel võimendus mootorile pööramise jaoks: algne arv x 25 = soovitud arv


Näide 3

lihtne matemaatikaKompassist saame relatiivse nurga mõõtmise korral väljundisse –90 .. 0 .. 90. Nüüd oleks vaja see number muundada vastupidiseks, et kui kompassist saame väljundi –90 siis roboti keeramiseks anname mootori sisendisse 90 ja vastupidi, kui kompass väljastab 90 kraadi siis roboti pööramiseks anname mootori sisendisse –90.

Lihtne matemaatika: 0 – algne arv = soovitud arv

Juhend: Mootorite peamised käsud NXC-s

Alljärgnevalt peamised NXC käsud, mille abil robot liikuma või seisma panna.

OnFwd("ports", "pwr"); OnRev(..)

OnFwd(OUT_A, 75);

Mootor A liigub edasi kiirusega 75


OnFwdSync("ports", "pwr", “turn”); OnRevSync(..)

OnFwdSync(OUT_AB, 75, -100);

Mootorid A ja B liiguvad edasi ning neid hoitakse sünkroonis. Turn ehk keeramine -100 määrab ära kummale poole keeratakse. 0 – sõidab otse, 50 – üks ratas seisab, 100 – rattad liiguvad vastassuundades.


OnFwdReg("ports", "pwr", OUT_REGMODE_SPEED); OnRevReg(..)

OnFwdReg(OUT_AB, 100, OUT_REGMODE_SPEED);

Mootorid A ja B sõidavad otse ning rakendavad lisajõudu kui ette satub takistus.


Off(OUT_AB);

Off(OUT_AB);

Lülitab mootorid A ja B välja


RotateMotor("ports", "pwr", “degrees”);

RotateMotor(OUT_A, 75, 360);

Pöörab mootorit A 360 kraadi kiirusega 75.


RotateMotorEx("ports", "pwr", “degrees”, “turn”, “sync”, “stop”);

RotateMotorEx(OUT_AB, 75, 360, 50, TRUE, TRUE);

Keerab mootoreid A ja B 360 kraadi kiirusega 75. Turn määrab ära kummale poole keeratakse (0 – sõidab otse, 50 – üks ratas seisab, 100 – rattad liiguvad vastassuundades), sync määrab et mootorid on sünkroonis ja stop määrab kas lõpus on vaja pidurdada või mitte.


Coast("ports”);

Coast(OUT_AB);

Laseb määratud mootorid vabajooksuga seismiseni.

Robotid kolmas osa

Noh mida siin veel rääkida peale selle, et mis robotid ma seekord tegin.

Seekord ma tegin “Explorer” robotid ehk “Maadeavastajad”. Ühe Exploreri tegin ainult kinni oleva sonariga ehk kaugus anduriga. Peale seda ma tegin ainult puuteanduriga. Kolmanda ma tegin mootoriga sonariga ja viimase tegin mootoriga sonariga ja puuteanduriga.
Esimese programm nägi välja selline:

task main(){
/*
DIRECTION muutuja abil määratakse kas robot
sõidab edasi või tagasi
DIRECTION = true: sõidab tagasi
DIRECTION = false: sõidab edasi
KAUGUS muutuja abil määrab robot kas peab 
tagasi sõitma
RAND muutuja abil määrab robot kas ta sõidab 
paremale või vasakule
*/
SetSensorLowspeed(S4);
bool DIRECTION;
int KAUGUS = 38;
int RAND;
while (true){
  if (SensorUS(S4) < KAUGUS){ //Kui robot näeb seina lähedamal
 kui 38 cm siis ta sõidab tagasi
    DIRECTION = true;
    if (DIRECTION){
      RAND = Random(2);
      switch (RAND)
      {
        case 0:               //Robot sõidab paremale
        RotateMotorEx(OUT_BC, 100, 332, -50, TRUE, TRUE);
        break;
        case 1:               //Robot sõidab vasakule
        RotateMotorEx(OUT_BC, 100, 332, 50, TRUE, TRUE);
        break;
        }
      }
    }
  else {
    DIRECTION = false;        //Muidu sõidab robot edasi
    OnRevSync(OUT_BC, 100, 0);
  }
}
}

 

Selle programmiga eriliselt raskusi e tulnud kuna ma sain abi oma ühest eelmisest programmist.

Nüüd tuleb siis teise roboti programm ehk ainult lülitiga:

task main(){
/*
muutuja DIRECTION määrab kas robot sõidab 
edasi või tagasi
muutuja RAND määrab suvaliselt kas robot 
pöörab tagurdades paremale või vasakule
*/
SetSensorTouch(S1);
bool DIRECTION;
int RAND;
while(true){
  if (Sensor(S1)== 1){
    DIRECTION = true;
    if(DIRECTION){
      RAND = Random(2);            //määratakse kummale poole 
sõidetakse kui tagurdatakse.
      switch (RAND)
      {
        case 0:                   //robot pöörab vasakule
        RotateMotorEx(OUT_BC, 100, 332, -50, TRUE, TRUE);
        break;
        case 1:                   //robot pöörab paremale
        RotateMotorEx(OUT_BC, 100, 332, 50, TRUE, TRUE);
        break;
        }
    }
  }
else {
     DIRECTION = false;           //robot sõidab edasi
     OnRevSync(OUT_BC, 100, 0);
     }
}
}

 

Selle programmiga mul ka erilisi raskusi ei tekkinud kuna jällegi sai kasutada eelneva programmi abi.
Minu kolmas programm oli siis pöörleva sonariga:

task main(){
SetSensorLowspeed(S4);
int VASAK; Selle muutujaga salvestan vasakule poole vaatamise kauguse
int PAREM; Selle muutujaga salvestan paremale poole vaatamise kauguse
while(true){
  if(SensorUS(S4) < 38){
  Off(OUT_BC);
    RotateMotor(OUT_A, 50, 90); robot vaatab vasakule
    VASAK = SensorUS(S4);
    RotateMotor(OUT_A, 50, -180); robot vaatab paremale
    PAREM = SensorUS(S4);
    RotateMotor(OUT_A, 50, 90); robot läheb omale kohale tagasi
    if(VASAK < PAREM){ kui vasakule vaatamise kaugus on väiksem kui 
paremale siis läheb robot paremale
      RotateMotorEx(OUT_BC, 50, -332, 50, TRUE, TRUE);
      }
    else{ kui vasak on suurem kui parem siis vasakule
      RotateMotorEx(OUT_BC, 50, -332, -50, TRUE, TRUE);
      }
    }
else{ muidu sõidab robot lihtsalt edasi
  OnRevSync(OUT_BC, 100, 0);
  }
}
}

 

Selle programmiga tekkisid mõned raskused näiteks kuidas salvestada sonari praegust näitu muutujasse.

Nüüd tuleb viimane programm mis ma tegin ehk liikuva sonari ja puuteanduriga see on umbes sama mis ainult liikuva sonariga ainult mõndades kohtades on lisatud juurde:

task main(){
SetSensorLowspeed(S4);
SetSensorTouch(S1);
int VASAK;
int PAREM;
while(true){
  if(SensorUS(S4) < 38 || Sensor(S1) == 1){
  Off(OUT_BC);
      if(Sensor(S1)==1){
        RotateMotor(OUT_BC, 50, 360);
      }
        RotateMotor(OUT_A, 50, 90);
        VASAK = SensorUS(S4);
        RotateMotor(OUT_A, 50, -180);
        PAREM = SensorUS(S4);
        RotateMotor(OUT_A, 50, 90);
        if(VASAK < PAREM){
          RotateMotorEx(OUT_BC, 50, -332, 50, TRUE, TRUE);
      }
      else{
        RotateMotorEx(OUT_BC, 50, -332, -50, TRUE, TRUE);
      }
    }
    else{
      OnRevSync(OUT_BC, 100, 0);
    }
}
}

 

Selle programmiga erilisi raskusi ei tekkinud ja sellele programmile ma filmisin ka video juurde:

Juhend: Andurite defineerimine ja lugemine

Roboti juures andurite kasutamine on seotud kahe tegevusega: a) defineerimine b) lugemine.
Selleks, et programmis andureid kasutada (lugeda), tuleb robotile kõigepealt selgeks õpetada millised andurid ja kus pordis asuvad.

Alljärgnevas tabelis on andurite initsialiseerimisega seotud funktsioonid. Erinevaid andureid tuleb erineval moel initsialiseerida.

SetSensorLight("port");

SetSensorLight(S1);
Valgussensori initsialiseerimine pordis 1.

SetSensorTouch("port")

SetSensorTouch(S1);
Puuteanduri initsialiseerimine pordis 1.

SetSensorSound("port");

SetSensorSound(S1);
Helianduri initsialiseerimine pordis 1.

SetSensorHTEOPD("port");

SetSensorHTEOPD(S1);
Hitechnic EOPD sensori initsialiseerimine.

SetSensorHTGyro("port");

SetSensorHTGyro(S1);
Hitechnic Gyro sensori initsialiseerimine.

SetSensorLowspeed("port");

SetSensorLowspeed(S1);
Ultrasonic ja Hitechnic IRSeeker, Color, Compass sensori initsialiseerimine pordis 1.

Anduritelt andmete lugemiseks kasutatavad funktsioonid on alljärgnevas tabelis. Jällegi tuleb tähele panna, et osade andurite jaoks saab kasutada sama funktsiooni lugemiseks, kuid osade jaoks on spetsiifilised funktsioonid.

Sensor("port");

Sensor(S1);
Andmete lugemine Touch, Light, Sound sensorist.

SensorUS("port");

SensorUS(S1);
Andmete lugemine Ultrasonic sensorist.

SensorHTGyro("port", “Offset”);

SensorHTGyro(S1, 2);
Andmete lugemine Gyro sensorist. Ette on antud offset ehk nulli hälve.

SensorHTEOPD("port");

SensorHTEOPD(S1);
Andmete lugemine EOPD sensorist.

SensorHTCompass("port");

SensorHTCompass(S1);
Andmete lugemine Compass sensorist.

SensorHTIRSeekerDir("port");

SensorHTIRSeekerDir(S1);
IR Seeker sensorist suuna lugemine.

SensorHTColorNum("port");

SensorHTColorNum(S1);
Värviandurist vastava värvi numbri lugemine.