Acrob robot constructs a map of a maze (Péter Dobsa, Gergely Labanc)

From RoboWiki
Revision as of 23:22, 26 June 2013 by Robot (talk | contribs) (Proces mapovania)
Jump to: navigation, search

Úvod

Našou úlohou bolo mapovať bludisko pomocou robota Acrob, pričom sa používala on-line komunikácia medzi robotom a počítačom cez bluetooth.

Naše bludisko

Bludisko bolo reprezentované v 2D priestore, a tvorila ho čierna páska na bielom povrchu. Robot mal sledovať práve tú čiaru pomocou infračervených senzorov.

[[File: |none]]

Náš robot

Acrob = Arduino Compatible Robot

Mozog robota tvorila Arduinovská doska, ktorá poháňala dva servomotory ktoré slúžili na pohybovanie robota, spracovala prečítané údaje zo senzorov a preposlala ich počítaču pomocou bluetoothového modulu. Telo robota bolo vyvynuté Slovenskou Technickou Univerzitou. Na prednú dolnú časť bol pripevnený čiarový senzor, ktorý pozostával z ôsmych nezávyslých infračervených senzorov. Na hornú časť bol primontovaný bluetoothový modul.

Na sériovú komunikáciu sme použili javovskú knižnicu RXTXcomm, pričom na prijímanie údajov stačila reakcia na preddefinovanú udalosť serialEvent, kým odosielanie príkazov bola realizovaná pomocou globálnej premennej, ktorá na začiatku dostala defaultnú hodnotu a pri každej zmene (na detekciu slúžilo jedno vlákno v pozadí) preposlal novú hodnotu a vynuloval premennú.

Zdroj: Connection.java

Sledovanie čiary

Z konštrukcie senzoru a hrúbky čiary vyplývalo, že robot je v správnej polohe na čiare, ak senzor s číslom 3 a senzor s číslom 4 nesvietia, ostatné senzory áno. Pri pohybovaní sme pozorovali práve tie svietiace, aby sme mohli robota udržať správne na čiare. Kvôli nepresnostiam na mape alebo v kolieskach smer robota bolo treba stále trochu korigovať. Tento problém rieši tento kus kódu:

   if (hodnoty[3] == 0 && hodnoty[4] == 1 && nieJeZakruta()) 
   {
     --pravyRychlost;
     ++lavyRychlost;
     forward();
   } 
   else if (hodnoty[3] == 1 && hodnoty[4] == 0 && nieJeZakruta())
   {
     ++pravyRychlost;
     --lavyRychlost;
     forward();
   } 

, kde lavyRychlost a pravyRychlost sú premenné na nastavenie otáčanina daného kolieska robota, a funkcia forward() sa slúží na realizovanie týchto zmien na základe požadovaného pohybu. Na tieto akcie používame triedu Servo, čo je súčasťou základných arduinovských knižníc. nieJeZakruta(), ako aj ďalšie procedúry v časti "zakruty", slúži na zistenie a rozpoznávanie jednotlých zákrut a križovatiek, čo je nevyhnutnou súčasťou mapovania.

Zákruty a križovatky

Ak robot pri pohybe narazil na výrazné zmeny senzorov, bolo mu jasné, že dostal sa do križovatky, respektýve do zákruty. Museli sme rozlíšiť osem rôznych stavov, a podla toho sa rozhodnúť, čo bude ďalším krokom.

  1. Rovná čiara: |
  2. Zákruta tvaru: _|
  3. Zákruta tvaru: |_
  4. Križovatka tvaru: T
  5. Križovatka tvaru: |-
  6. Križovatka tvaru: -|
  7. Križovatka tvaru: +
  8. Slepá ulička

Proces mapovania

Po štartovaní aplikácie dostaneme otázku, cez ktorý port sa chceme pripojiť k nášmu robotovi (treba si vybrať výstupný port).

Rob4.png

Po úspešnom párovaní sa zobrazí zatial biely základ mapy a dve tlačidlá (Start a Stop), ktoré ale sú zneprístupnené. Ak teraz položíme robota na čiaru správne, tlačidlo Start sa rozsvieti a po klikaní naň sa spustí mapovanie - robot sa začne pohybovať (FoxiMaxi.java). Robot sa najprv pohybuje po čiare dobrovoľne, v križovatke si vyberie cestu sám. Za tento proces zodpovedá v kóde časť volny pohyb. Namapovanú cestu reprezentuje ako graf, kde vrcholmi budú zákruty a križovatky, a hrany medzi vrcholmi budú existujúce cesty. Červenou farbou je zvýraznený vrchol, na ktorom momentálne nachádza robot, alebo ak taký vrchol neexistuje, tak naposledy navštívený. Tiež červenou sú vizualizované zatiaľ nepreskúmané cesty.

Rob.png

Volný pohyb robota sa končí v okamihu, ak narazil na vrchol, z ktorého nevedú žiadne cesty, ktoré ešte neboli preskúmané, alebo sa dostane do slepej uličky. Vtedy sa zastavý a čaká na príkaz od počítača. Počítač pomocou hľadania do šírky nájde nabližší vrchol, odkiaľ ešte vedú nejaké cesty, cez ktoré ešte neprešiel, pomocou algoritmu A* nájde najkratšiu cestu medzi nájdeným vrcholom a aktuálnym vrcholom robota (ako heuristiku používa Euklidovskú vzdialenosť vrcholov), vizualizuje cestu a pomocou tejto cesty a momentálneho smeru robota zostrojí postupnosť príkazov, podľa ktorých robot by mal by byť schopný dostať na požadované miesto. Idea posielania príkazov je taká, že každý príkaz posiela počítač len vtedy, keď príjímanie predošlého príkazu bola potrvdená. Hranicu postupnosti príkazov hlási posielaním špeciálnych bytov. Robot týchto príkazov ukladá v dátovej štruktúre queue (rad) a postupne ich vykonáva. Nájdenú cestu vykreslí modrou.

Rob2.png

private void A_Star(Vrchol start, Vrchol ciel) {

   HashSet<Vrchol> visited = new HashSet<>();
   Prioritny_Front<Vrchol> openFront = new Prioritny_Front<>();
   HashMap<Vrchol, Double> g = new HashMap<>();
   HashMap<Vrchol, Double> f = new HashMap<>();
   HashMap<Vrchol, Vrchol> cesta = new HashMap<>();

}

Keď sa nanaviguje na požadované miesto, znovu sa pustí jeho volný pohyb. Takýmto spôsobom sa zaistí, že robot v konečnom čase a systematicky prejde cez všetky vrcholy grafu a nič nevynechá, teda namapuje všetko. Keď už žiadny vrchol nevidí, z ktorej by vychádzali nenavštívené hrany tak proces mapovania sa skončí a robot sa zastavý. Teraz máme možnosť poslať ho na požadované miesto klikaním do mapy na nejaký vrchol myškou. Ako predtým, pomocou algoritmu A* zistí najkratšiu cestu a prejde na požadované miesto.

Rob3.png

Tu si môžete pozrieť ukážkové video, akor sa pohybuje robot v bludisku a ako sa postupne vykresluje mapa na obrazovke.

Aplikácia na počítači

Tu si môžete stiahnuť aplikáciu bežiacu na počítači napísané v jazyku Java, ktorý prijíma dáta od robota a zkonštruuje celú mapu.

   Projekt

Program na arduíne

Štruktúra zdrojového kódu:

  • queue - definicia štruktúry rad na ukladanie prijatých príkazov
  • globalne premenne - globálne premenné a konštanty použité v programe
  • zakruty - funckie na rozpoznávanie jednotlivých zákrut a križovatiek
  • pohyb - funkcie na nastavenie motorov na vykonávanie daného pohybu
  • senzory - nastavenie senzorov, načítanie hodnôt
  • prikazy - procedúry na prijatie postupnosti príkazov, ich vykonávanie a na voľný pohyb
  • loop - cyklicky bežiaca funkcia, slúži na zistenie v ktorom režime má robot fungovať (voľný pohyb, alebo vykonávanie príkazov)
   csocsi_pohyb.ino

Možné chyby

Chyby sa môžu nastať z dôvodu nepresnosti koliesok, motorov, senzorov a cesty. Robot je pripravený na menšie odchýlky a rozpozná že sa jedná o ten istý vrchol aj v prípade, že zamerané hodnoty sa trochu líšia, ale práve preto sa môže nastať situácia, že vrcholy ktoré sú v skutočnosti príliš blízko sa robotom nerozlišujú. Táto chyba sa zmenší, ak zväčšíme rozmery mapy teda dĺžku ciest, vrcholy rozmiestnime tak, aby neboli príliš blízko, a keď spravíme zákruty presne na pravé uhly.

Zdroje

arduino.cc

http://pharos.ece.utexas.edu/wiki/index.php/How_to_Access_Your_Serial_Port_using_Java

https://en.wikipedia.org/wiki/A*_search_algorithm