Reaali Robootika.COM

NXT robotimaailm ja programmeerimine C-keeles

Presidendi Lossis

Jõudsime Robomiku finaalis 3. kohale ning esikohtadele oli organiseeritud vastuvõtt Presidendi juures.

President Toomas-Hendrik Ilves ja robootika

See oli äärmiselt mõnus ja meeldejääv sündmus. Alguses tehti meile ringkäik Lossis ja tutvustati sealseid ruume ning elukorraldust. Ajaloost, K.Päts on olnud 9 korda President, sellist resümeed on vähestel ette näidata. Lossi seinakate on mitmes ruumis kaunis elegantne ja peen kangas (mitte värv ega tapeet). Kogu majesteetlik mööbel on eesti käsitööliste tehtud ja hästi säilinud või renoveeritud.

Ainult üks mõistatus jäi kogu sellest käigust – et miks Venemaa relvakambrist pole võimalik kätte saada Eesti Vabariigi esimese presidendi Konstantin Pätsi ametiketti? Ja keegi ei teadvat miks ja kui kauaks see seal asub?

Aitäh President, et leidsid oma väga tihedas graafikus aega meie vastuvõtuks ning innustamaks noori insenere jätkama sellega millega nad tegelevad.

Robomiku võistluse roboti programm

Robomiku võistlusel saavutasime 3. koha.

Koos reavahede ja kommentaaridega tuli kokku ligi 200 rida koodi.

Kuna palusin poistel kommentaarid juurde panna siis peaks olema arusaajale inimesele täitsa loetav kood. Kuna kasutasime mitte kõige uuemat versiooni NXC-st siis seetõttu on LineLeader anduriga suhtlev library siia eraldi included. Uuemasse softi (15. märts 2011) on juba kõik need uute andurite driverid sisse kirjutatud.

/*
autor: Ramses Sepp 20/03/11
robomiku 2011 kevad karupäästmise programm
selles programmis:
* sõidab robot mööda joont LineLeader anduri abil
* leiab rohelisi ja hõbedasi teibiribasid mis on kannatanud ja annab nendest märku
* tuvastab IR abil karu ja annab temast märku
* robotil on haarad mille abil ta kannab karu majast välja
*/

#include "LL-Lib.nxc"
#define IR_TOUCH S1
#define I2C_SENSOR S2
#define COLOR S3
#define LIGHT S4
#define LL_ADDR 0x04

long endTime;
bool haaradLahti = FALSE;
bool mulOnKaru = FALSE;
task DriveOnTheLine();
task KeeraRobotit180();
task KeeraRobotit();

//funktsioon ArvutaKiirus tagastab väärtuse, mis jääb -100 ... 100 vahele
int ArvutaKiirus(int x, int min, int max)
{
if (x < min)
   return min;
else if (x > max)
   return max;
else
   return x;
}

//alamprogramm HaaradLahti avab haarad ning seejärel robot sõidab edasi
task HaaradLahti()
{
RotateMotorEx(OUT_A, -100, 6840, 0, FALSE, TRUE);
haaradLahti = TRUE;
//endTime muutujat kasutatakse selleks 
//et robot sõidaks peale haarade lahti tegemist 2 sekundit edasi
endTime = CurrentTick() + 1000;
ExitTo(DriveOnTheLine);
}

//alamprogramm HaaradKinni sulgeb haarad ning siis käivitub roboti pööramine
task HaaradKinni()
{
RotateMotorEx(OUT_A, 100, 6840, 0, FALSE, TRUE);
mulOnKaru = TRUE;
haaradLahti = FALSE;
ExitTo(KeeraRobotit180);
}

//alamprogramm KeeraRobotit180 keerab robotit 180 kraadi 
//kuni ta on joone keskel
task KeeraRobotit180()
{
int onJoonel;
//hakkame mootoreid keerama, et robot liiguks joonelt ära
RotateMotor(OUT_BC, 40, 360);
OnFwdReg(OUT_B, 40, OUT_REGMODE_SPEED);
OnFwdReg(OUT_C, -40, OUT_REGMODE_SPEED);
Wait(1000);
while (TRUE)
   {
   OnFwdReg(OUT_B, 40, OUT_REGMODE_SPEED);
   OnFwdReg(OUT_C, -40, OUT_REGMODE_SPEED);
   //loeme LL andurist kas robot on joone keskel
   onJoonel = LL_Read (I2C_SENSOR, LL_ADDR, LL_READ_AVERAGE);
   //kui robot on joone keskel siis käivitub uuesti põhiprogramm
   if (onJoonel < 50 && onJoonel > 40)
      {
      Off(OUT_BC);
      ExitTo(DriveOnTheLine);
      }
   }
}

//alamprogramm KeeraRobotit keerab robotit 180 kraadi
task KeeraRobotit()
{
RotateMotor(OUT_BC, 50, 360);
RotateMotorEx(OUT_BC, 50, 1100, 100, TRUE, TRUE);
Off(OUT_BC);
ExitTo(DriveOnTheLine);
}

//alamprogramm DriveOnTheLine on joone jälgimise, kannatanute tuvastamise
//ja karu kandmise programm
task DriveOnTheLine()
{
int steering;
int b_speed;
int c_speed;
int rohelisedMehed;
int hobedasedMehed;
bool naebKaru;
int karuKaugus;
bool onSoitnud2Sek = FALSE;
int baasKiirus;

//lõpmatu tsükkel mille sees toimub enamus programmist
while (TRUE)
   {
   rohelisedMehed = Sensor(COLOR);
   hobedasedMehed = Sensor(LIGHT);
   naebKaru = !Sensor(IR_TOUCH);
   karuKaugus = SensorUS(I2C_SENSOR);
   
   //kui värviandur näeb rohelist või hõbedast meest põrandal
   //annab heliga märku
   if (rohelisedMehed == 3 || hobedasedMehed > 70)
      {
      PlaySound(SOUND_DOUBLE_BEEP);
      }
      
   //kui IR_sensor näeb karu, haarad on kinni ja mul ei ole karu 
   //siis annab sellest heliga märku:P
   if (naebKaru && !haaradLahti && !mulOnKaru)
      {
      Off(OUT_BC);
      PlaySound(SOUND_UP);
      ExitTo(HaaradLahti);
      }
   
   //kui haarad on lahti, ei näe karu ja on sõitnud 2 sekundit 
   //siis paneb haarad kinni
   if (haaradLahti && !naebKaru && onSoitnud2Sek)
      {
      Off(OUT_BC);
      ExitTo(HaaradKinni);
      }
   
   //kui robot on haarad lahti teinud siis ta sõidab 2 sekundit joonel edasi
   //enne kui hakkab kontrollima kas on tarvis haarasid kinni panna
   if (haaradLahti)
      {
      if (endTime < CurrentTick())
         {
         onSoitnud2Sek = TRUE;
         }
      }
   
   //steering muutujasse kirjutatakse LineLeaderist steering väärtus
   //mida kasutatakse mootorite juhtimisel
   steering = LL_ReadSteering(I2C_SENSOR, LL_ADDR);
   
   //see If lause on vajalik, et steering oleks vahemikus -127 ... 127
   if(steering > 127)
      {
      steering = steering - 256;
      }

   // kui robot sõidab üles siis on baasKiirus 40, allaminekul 30
   if (mulOnKaru)
      {
      baasKiirus = 30;
      steering = steering / 3;
      }
   else
      {
      baasKiirus = 40;
      }
   /*
   mootoritele õige kiiruse andmine
   igal juhul ei saa olla mootori kiirus suurem kui 100
   igal juhul ei saa olla mootori kiirus väiksem kui -100
   */
   b_speed = ArvutaKiirus(baasKiirus + steering, -100, 100);
   c_speed = ArvutaKiirus(baasKiirus - steering, -100, 100);
   
   //kuna mootorid on tagurpidi siis peame muutma väärtused vastasmärgiliseks
   b_speed = 0 - b_speed;
   c_speed = 0 - c_speed;
   
   OnFwdReg(OUT_B, b_speed, OUT_REGMODE_SPEED);
   OnFwdReg(OUT_C, c_speed, OUT_REGMODE_SPEED);
   }
}

task main()
{
SetSensorLight(LIGHT);
SetSensorColorFull(COLOR);
SetSensorLowspeed(I2C_SENSOR);
SetSensorTouch(IR_TOUCH);
Wait(SEC_5);

LL_Write_KP(I2C_SENSOR, LL_ADDR, 40, 32); //katsetada 0...100 //alla:40
LL_Write_KI(I2C_SENSOR, LL_ADDR, 0, 32);  //jääb nulliks
LL_Write_KD(I2C_SENSOR, LL_ADDR, 5, 32);  //katsetada 0..20 //alla:5

StartTask(DriveOnTheLine);
}

Robomiku finaal 3. koht

Üle Eesti tuli kokku 22 võistkonda erinevatest koolidest, kes kõik katsusid jõudu ühe Karupäästmise ülesandega. www.robomiku.ee

Nimelt robot pidi liikuma mööda musta joont läbi keerulise kolmekorruselise maja, tuvastama majas olevaid kannatanuid ning ülemiselt korruselt karumõmmi majast välja tooma.

Ütlen kohe ette ära, et karu jäigi majja, kuid meie tiim sai karu sellegipoolest kõige kaugemale. Esimene ja teine koht läksid aga Narva kuna nemad jõudsid oma robotiga põlevast majast ka välja – kuigi ilma karuta.

Vaata 3. koha ehk siis meie roboti videot:

Robomikufinaal–Robojalg 3. koht

8. tund: mäng NXT ekraanile 1. osa

Esimene pool tunnist kulus Robomiku kevadise võistluse tutvustamiseks mis toimub Tartus 22. märtsil.

Selgus, et nii Ramsesel kui ka Jaanil oli juba ette valmistatud oma nägemus Robomiku võistlusrobotist.

Teine pool tunnist aga kulutasime selle peale, et alustada ühe mängu programmeerimisega NXT ekraanile. Ma viibisin nädal aega Redmondis ning seal oli aega NXT-le üks mäng ajaviiteks välja mõelda.

Mäng

Ekraanil põrkab pall üles-alla ja paremale-vasakule ning NXT ekraani alumises servas on väravavaht mida saab nooltega paremale-vasakule liigutada.

Väravavaht peab alati palli põrke all olema, et pall üles tagasi põrkaks. Kui pall kukub ekraani alt välja on mäng läbi. Lisaks saab valida 3-e erineva raskusastme vahel ning need mõjutavad palli liikumise kiirust ja punktiarvestust. Raskema mängu korral saab rohkem punkte.


Jagasime ülesande etappideks ning selle tunni aeg kulus õppimisele, kuidas liigutada väravat nooleklahvide abil paremale vasakule.

/*
Leivo Sepp, 23.02.2011
See on mäng, kus tuleb nooltega liigutada väravat paremale/vasakule nii,
et ekraanil põrkav pall ei kukuks mängualast välja vaid põrkaks vastu väravat.
*/

//värava muutuja koos palli esialgse asukohaga
int Joon = 50;

//joone liigutamise alamprogramm liigutab parema-vasaku klahvi abil 
//väravat ekraani allservas edasi-tagasi
task JooneLiigutamine()
{
while (TRUE)
   {
   if (ButtonPressed(BTNRIGHT, TRUE))
      {
      Joon += 4;
      }
   else if (ButtonPressed(BTNLEFT, TRUE))
      {
      Joon -= 4;
      }
   ClearLine(LCD_LINE8);
   TextOut(Joon, LCD_LINE8, "=");
   
   //wait on vajalik, et värav liiga kiiresti ei liiguks
   Wait(150);
   }
}

task main()
{
//siit kutsutakse välja ja käivitatakse alamprogramm JooneLiigutamine
Precedes(JooneLiigutamine);
}

Robomiku võistluse video 2011 jaanuar

Alljärgnevalt video 7.jaanuaril 2011 toimunud Robomiku võistlusest.

Parima koha sai tiim, kes kasutas pallide viskamiseks tennisepalli loopimise põhimõtet. Võrreldes tavaliste laskjatega kes lasid meetri kanti, lasid meie robot ning võitja ca 5m. Kaotus on valus, kuna meie robot jäi vaid 5cm-ga võitjale alla. NB! Tartus osalemise korral oleksime meie võitjad olnud Naeratus 

Kuna olime võitjast veidike maas, otsustasime oma robotile panna ühe kollase lisakummi juurde. Selle käigus aga selgus, et teised kummid (punased), mis robotit koos hoiavad on pisut välja veninud ning robot ei püsi enam koos.

Ühe proovilasu tegime ning see oli vähemalt 6m peale, seega raudne võidulask. Finaal-võistluse voorus ei pidanud meie robot siiski pingele vastu ning võidulasu tegi teine robot.

Kokkuvõtteks: Lego Mindstorm NXT võiks jääda nö. nutikate lahenduste jaoks. Tehtud palliviskamise ülesande korral jääb roboti piiriks alati Lego plastmassosade füüsiline vastupidavus.

Pallilaskja tutvustav video

Siin video robotist millega käisime seekord Robomikul võistlemas. Parimates katsetes saime palliviskekauguseks 6,5 meetrit.

Pallilaskja NXT Mindstorm robot

Talvine robotite võistlus Robomiku, ettevalmistus

Selleks korraks on ette nähtud ehitada robot, mis tulistab suuri siniseid ja punaseid palle. Või kui täpsem olla, siis robotil peab olema ehitatud laadur, mis teeb pallide osas valiku – st. punaseid palle peab tulistama, sinised seevastu kõrvale eraldama. http://www.robomiku.ee/ 

IMAG0068Kuna praegu on veel 1 päev võistluseni siis videot ma meie roboti kohta üles ei pane, kuna ma arvan lihtsalt, et meil on liiga hea ideega robot mille teised jõuaksid hea tahtmise korral maha kopeerida.

imagePildi panen kuna see ei anna detailset infot roboti toimimispõhimõtte kohta. Kui oma esimesi katsetusi tegime kõikvõimalike erinevate moodustega siis õnnestus pall tulistada 20 ja 30 cm kaugusele. Vaadates ja ka ise proovides ütlesin poistele, “tulemus on rahuldav siis kui lasete palli sinna raamaturiiulini” (kuhu on ca 5m). Selle peale muidugi arvati et ma olen hull, kuna oli selge, et üle 50 cm või noh pingutustega 1 m – rohkem küll võimalik pole.

Täna võin öelda, et maksimaalse kauguse saimegi 6,5 m, kuid keskmiselt jääb veidike alla 6m, kuna kummid hakkasid veidi välja venima ning kasutada tohib ainult Lego robootika enda komplekti kumme. Seega ei tohi minna Piritale purjepoodi, et sealt mõne vinge kummiga naasta.

Robootika: Sleepless in Tallinn

Sellest on nüüd aastaid tagasi kui ma mõnest progemisest nii haaratud olin, et ööl ega päeval vahet polnud. Kas kardinad liikusid ise ette ja eest ära? Ah et juba jälle päev?

Tegelikult olin haaratud robootikast. Sügisest alates olen taas juhendanud robootikaringi ning täpselt nädal tagasi saime kätte koolivaheajal toimuva robomiku võistluse korralduse. Seega viimase nädalaga tegid poisid valmis kaks erineval põhimõttel töötavat võistlusrobotit.

Võistlus on pealtnäha lihtne: on üks suur ovaalne 60cm laiune rada, mille sisering on tähistatud 5cm laiuse musta joonega ning väline serv 5cm laiuse punase joonega. Võidab see, kes kiiremini kolm ringi läbib.

Poiste käe ja tiheda mõttetöö abil valmisid Valgusrobot ja Värvirobot. Esimene neist kasutab kahte valgusandurit ning püüab nende abil maksimaalselt kiiresti mustal joonel sõita. Teine robot kasutab värviandureid ning püüab nende abil võimalikult kiiresti ühest rajaservast teise sik-sakitades ringitada.

Praktiliselt tulid robotid ühekiired, kuigi üks neist läbib oluliselt pikema teekonna.

Valgusroboti pluss:
1. Robot läbib peaaegu lühima tee ehk siis siseringi

Valgusroboti miinus:
1. Andurite kalibreerimisele vaatamata töötavad need veidi ebakindlalt erinevates valgustingimustes. Selle asemel on hea kasutada Hitechnicu EOPD andureid, kuid neid on mul vaid üks – ja siis ei hakanud seda kasutama.
2. Robot kaotab joone väga kergelt kui kiirust tõsta.

Värviroboti pluss:
1. Värviandurid töötavad kiiresti ja erakordselt täpselt kõikides valgusoludes.
2. Otsesõites võib robot arendada päris suurt kiirust (kass üllatus korduvalt selle roboti tegutsemise peale)

Värviroboti miinus:
1. Juhuslikkuse printsiibil võib ette tulla olukord, kus robot paneb täie lauluga risti joone peale. sellisel juhul on üsna kindel väljasõit.

Kuidas kõik need miinused eemaldada ja teha väga kiire ringirobot, seda ma tean. Aga nii noortelt kõrgemat matemaatikat, loogikat, abstraktset mõtlemist, alamprogramme jms nädalaga selgeks õppida oleks ilmselt palju tahta. Ja vingeid programme, millest nad midagi aru ei saa, pole mõtet neile kirjutada.

Sest võistlusel võidakse poiste käest küsida, “kuidas sinu tehtud programm töötab”. Ja selle peale oleks ju päris lahe kui 11-12 aastane hakkaks selgitama õpetajale “uurisin siin väheke Calculus printsiipe robotite juhtimisel ning mõtlesin joonejälgija juures kasutada sellest tulenevalt PID-controlleri tööpõhimõtet” või “värviroboti juures otsustasin järskude tagasipöördenurkade juures võtta kasutusele gyroskoop-anduri, et selle abil vastavalt pöördenurgale tasakaalustada roboti esialgne suund, tagades sellega sujuva ja kiire sõidu”.

Ülaltoodud kaks olidki ideed mis mind hommikuni arvuti taga ja ilmselt kauemgi oleks hoidnud kui Kaja poleks ajanud mind Lasnamäe Spordihalli lätti võistlema minejatele köieharjutusi ja ronimisjuhendamist tegema.

PID Controlleri tööpõhimõte joonejälgijale minu vabas sõnastuses: “analüüsides läbitud teed ja võttes arvesse käesolevat hetke joone ning andurite suhtes, ennustame kuhu ja kui kiiresti peab robot järgnevalt liikuma”.
Wiki page on PID Controllers