Univerzita Karlova v Praze Matematicko-fyzikální fakulta
ˇ BAKALÁRSKÁ PRÁCE
David Marek ˇ Rízení robota e-puck v Pythonu Kabinet software a výuky informatiky
Vedoucí bakaláˇrské práce: RNDr. František Mráz, CSc. Studijní program: Informatika Studijní obor: Obecná Informatika
Praha 2011
Rád bych podˇekoval vedoucímu bakaláˇrské práce RNDr. Františku Mrázovi za odborné vedení, cenné rady a zapujˇ ˚ cení e-puck robota.
Prohlašuji, že jsem tuto bakaláˇrskou práci vypracoval samostatnˇe a výhradnˇe s použitím citovaných pramenu, ˚ literatury a dalších odborných zdroju. ˚ Beru na vˇedomí, že se na moji práci vztahují práva a povinnosti vyplývající ze zákona cˇ . 121/2000 Sb., autorského zákona v platném znˇení, zejména skuteˇcnost, že Univerzita Karlova v Praze má právo na uzavˇrení licenˇcní smlouvy o užití této práce jako školního díla podle §60 odst. 1 autorského zákona.
V Praze dne 22. kvˇetna 2011
Podpis:
ˇ Název práce: Rízení robota e-puck v Pythonu Autor: David Marek Katedra: Kabinet software a výuky informatiky Vedoucí bakaláˇrské práce: RNDr. František Mráz, CSc., Kabinet software a výuky informatiky Abstrakt: V pˇredložené práci studujeme ovládání miniaturního e-puck robota. Pro programování robota jsme zvolili programovací jazyk Python, díky možnostem rychlého vývoje a interaktivního ovládání. Zamˇerˇ ujeme se na dálkové ovládání robota z uživatelského poˇcítaˇce pomocí Bluetooth a na mechanismy, které zajistí robustní komunikaci. Uživatel knihovny dostává na výbˇer, zdali si zvolí synchronní anebo asynchronní komunikaci. Pˇri vývoji synchronní komunikace jsme dávali duraz ˚ na interaktivitu a transparentnost. Pˇri asynchronní komunikaci klademe duraz ˚ na spolehlivost. Dále jsme vytvoˇrili nˇekolik ukázkových programu, ˚ které ilustrují použití knihovny. Klíˇcová slova: rˇ ízení robota, Python, e-puck
Title: Controlling e-puck robot in Python Author: David Marek Department: Department of Software and Computer Science Education Supervisor: RNDr. František Mráz, CSc., Department of Software and Computer Science Education Abstract: In the present work we study controlling a miniature e-puck robot. We have chosen to use the Python programming language because it is very easy to use for rapid development and interactive control. We focus on how to control the robot remotely from PC via Bluetooth. An important aspect of controlling the robot remotely is the mechanism enabling robust communication. The user can choose between synchronous and asynchronous communication. The former is primarily used for interactive controlling because of its transparency. The latter is a right choice for reliable communication. The work also contains a few example programs to present how to use the library. Keywords: robot programming, robot control, Python, e-puck
Obsah Úvod 1
2
3
4
3
Teorie 1.1 E-puck robot . . . . . . . . . . . . . . . . . 1.2 Synchronní / asynchronní komunikace . 1.2.1 Synchronní komunikace . . . . . . 1.2.2 Asynchronní komunikace . . . . . 1.2.3 Komunikace v e-puck knihovnˇe . 1.3 Existující práce . . . . . . . . . . . . . . . . 1.3.1 Webots . . . . . . . . . . . . . . . . 1.3.2 Cyberbotics’ Robot Curriculum . . 1.3.3 Learning Computing With Robots 1.3.4 Evorobot* . . . . . . . . . . . . . . 1.3.5 Pyro . . . . . . . . . . . . . . . . . 1.4 Specifikace e-puck knihovny . . . . . . . 1.4.1 Firmware . . . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
6 6 8 9 9 10 11 11 12 12 12 13 14 14
Implementace 2.1 BTcomDM firmware . . . . . 2.1.1 Pˇríkazy . . . . . . . . . 2.1.2 Provedené úpravy . . 2.2 Synchronní komunikace . . . 2.3 Asynchronní komunikace . . 2.3.1 Odeslání pˇríkazu . . . 2.3.2 Zpracování odpovˇedi ˇ 2.3.3 Casový limit . . . . . . 2.4 Ovládání robota . . . . . . . . 2.5 Výkon knihovny . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
16 16 17 17 18 19 20 21 21 22 23
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
Uživatelská dokumentace 3.1 Pˇripojení robota . . . . . . . . . . . . 3.1.1 Pˇríprava . . . . . . . . . . . . 3.1.2 Pˇripojení . . . . . . . . . . . . 3.1.3 Pˇrehled možných chyb . . . . 3.1.4 Nahrání firmware BTcomDM 3.1.5 Instalace knihovny . . . . . . 3.2 Ukázkový program . . . . . . . . . . 3.2.1 Vysvˇetlení zdrojového kódu . 3.2.2 Synchronní verze . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
25 25 25 26 26 26 27 27 28 30
Pˇríklady kontrolních programu˚ 4.1 Braitenberg Vehicle . . . . . 4.1.1 Zdrojový kód . . . . 4.1.2 Vysvˇetlení programu 4.2 Ovládání LED . . . . . . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
32 32 32 34 35
. . . . 1
. . . .
. . . .
. . . .
. . . .
4.3
4.2.1 Zdrojový kód . . . . 4.2.2 Vysvˇetlení programu Detekce obliˇceje . . . . . . . 4.3.1 Zdrojový kód . . . . 4.3.2 Vysvˇetlení programu
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
36 38 39 40 42
Závˇer
44
Pˇrílohy
46
Literatura
47
2
Úvod ˇ Slovo robot pochází od cˇ eského spisovatele Karla Capka, který jej poprvé použil ve své divadelní hˇre R.U.R. V cˇ eštinˇe už po staletí existovalo slovo robota, které znamená nucenou práci. Roboti jsou nyní našimi neocenitelnými pomocníky, zatím nejˇcastˇeji ve formˇe prumyslových ˚ nebo medicínských robotu, ˚ kteˇrí provádˇejí delikátní práce s neuvˇerˇ itelnou pˇresností. Dnes už kdokoli, kdo má zájem o robotiku, muže ˚ získat vlastního robota. Prodává se dokonce stavebnice Lego s rˇ ídící jednotkou a nˇekolika senzory, díky které si robota mohou postavit i dˇeti. Pro ty, kdo by chtˇeli robota už hotového, existuje napˇríklad e-puck [4] robot. Jedná se o drobného robota, obsahujícího velkou škálu senzoru. ˚ Díky nim je ideální pro zkoušení rozliˇcných experimentu˚ (práce s kamerou, pohyb mezi pˇrekážkami atd.). Dosud ovšem jediná možnost, jak e-puck robota ovládat, byla, bud’ napsat program v jazyku C a nahrát jej do robota, anebo použít komerˇcní software pro dálkové ovládání. Cílem této práce je vytvoˇrit svobodnou uživatelsky pˇrívˇetivou a intuitivní knihovnu v programovacím jazyku Python pro ovládání e-puck robota. Bude umožnovat ˇ ovládání všech cˇ ástí robota z PC pˇres Bluetooth spojení z operaˇcního systému Linux. Díky tomu pujde ˚ využít výkonu osobního poˇcítaˇce pro vytváˇrení programu, ˚ které by nebylo možné uskuteˇcnit v robotovi kvuli ˚ jeho výpoˇcetním omezením. Ovládací program v PC také umožnuje ˇ používat externích knihoven. Souˇcástí práce bude i firmware BTcomDM, modifikovaná verze oficiálního firmwaru BTcom. Díky nˇemu bude možné používat asynchronní komunikaci a také bude obsahovat mechanismy pro zajištˇení robustní komunikace. Mezi zmˇenami je i nˇekolik úprav ve funkˇcnosti (signalizace nízkého stavu baterie anebo získání hodnot z mikrofonu). ˚ Práce by mˇela sloužit pro potˇreby studentu˚ zajímajících se o programování e-puck robota. Pro seznámení s knihovnou a možnostmi robota tedy bude soucˇ ástí knihovny i nˇekolik ukázkových programu. ˚ Jejich úˇcelem je ukázat jakým zpusobem ˚ je možné robota ovládat a co vše dokáže.
3
Pˇrehled kapitol Teoretická cˇ ást V první cˇ ásti práce jsou pˇredstaveny podklady a teoretické informace vázající se k tématu. Po pˇreˇctení této cˇ ásti by mˇely být jasné všechny pojmy a cˇ itatel by mˇel mít dostateˇcné informace o problematice programování robota pro napsání vlastního programu. V kapitole 1.1 je pˇredstaven e-puck robot. Je zde popsán úˇcel robota, okolnosti jeho vzniku a také všechny senzory a akˇcní cˇ leny. Také se zde uživatel dozví, jaké jsou možnosti programování robota. Pˇri dálkovém ovládání robota je velmi duležitá ˚ komunikace mezi ním a pocˇ ítaˇcem, na kterém je spuštˇen ovládací program. Kapitola 1.2 pˇredstavuje rozdíly mezi komunikací synchronní a asynchronní. Vysvˇetluje jaké jsou výhody a nevýhody obou rˇ ešení a jak se s nimi e-puck knihovna vyrovnává. V kapitole 1.3 cˇ itatel zjistí, že tato práce není jediným pokusem o knihovnu pro ovládání robota. Bude pˇredstaveno nˇekolik programu, ˚ které slouží k ovládání anebo simulaci robota. Také budou pˇredstaveny knihy, které mohou sloužit pro rozšíˇrení informací uvedených v této práci, popˇr. jako zdroj inspirace pro kontrolní programy. ˇ Nakonec bude pˇredstavena specifikace knihovny (ˇcást 1.4). Citatel se dozví jakými problémy trpˇel puvodní ˚ firmware a jaké jsou nutné zmˇeny, které bylo tˇreba vykonat. Dále jsou zde uvedena všechna vylepšení, díky kterým se knihovna snaží soupeˇrit s konkurencí.
Praktická cˇ ást V druhé cˇ ásti práce bude pˇredstavena implementace knihovny. Bude vysvˇetleno, jak byly použity mechanismy pˇredstavené v teoretické cˇ ásti, díky kterým muže ˚ být komunikace asynchronní. Také budou pˇredstaveny pˇrídavky ke standardním možnostem robota. V kapitole 2.1 je popsán firmware BTcomDM, posílání pˇríkazu˚ robotovi a také zde jsou uvedeny všechny zmˇeny, které byly vykonány na firmware robota. Synchronní komunikace je pˇredvedena v cˇ ásti 2.2 i s krátkou ukázkou jak zasílat pˇríkazy. Asynchronní komunikace je druhým zpusobem ˚ jak robotovi zasílat pˇríkazy, je o poznání složitˇejší než synchronní komunikace a tedy je jí vˇenováno ˇ více místa v cˇ ásti 2.3. Citatel se dozví co vše se dˇeje na pozadí pˇri posílání asynchronních zpráv. 4
Jak funguje samotné ovládání robota je popsáno v cˇ ásti 2.4. Ovládání se liší podle komunikace. Pˇri synchronní je transparentní a jednoduché, pˇri asynchronní je na druhou stranu spolehlivé, i když pˇrináší do komunikace jednu vrstvu navíc.
Pˇríklady V cˇ ásti 3 je návod pro práci s e-puck robotem. Ten zaˇcíná u pˇripojení robota k poˇcítaˇci a konˇcí zasíláním pˇríkazu. ˚ Také je zde uveden ukázkový program a následnˇe rozebrán rˇ ádek po rˇ ádku. Následují pˇríklady kontrolních programu˚ v kapitole 4. Jde o pˇríklad ovládání robota a vyhýbání se pˇrekážkám (Braitenberg vehicle v sekci 4.1), dále možnost zmˇeny programu pomocí selektoru na robotovi (pˇríklad 4.2) a nakonec využití kamery a externích knihoven pro detekci obliˇceju˚ (pˇríklad 4.3).
5
1. Teorie V této cˇ ásti bych rád uvedl všechny základní souˇcásti, na kterých má práce stojí, a také bych se rád zmínil o zpusobech, ˚ jak rˇ eší ovládání robota jiní. Nejprve je nutné zjistit, jaké vlastnosti má robot e-puck, abychom pak dále mohli posoudit do jaké míry využíváme jeho pˇredností a také zhodnotit využitelnost práce v praxi. Popis e-puck robota je v sekci 1.1. Také je nutné zmínit zpusoby ˚ komunikace, jaká úskalí pˇrináší oddˇelení kontrolního programu od hardware a jak se dají mírnit rizika z tohoto plynoucí, tím se zabývá sekce 1.2. V sekci 1.3 se podíváme na jiné projekty, které se zabývají ovládáním robota. Nakonec v cˇ ásti 1.4 je k nalezení specifikace vytvoˇrené e-puck knihovny.
1.1
E-puck robot
E-puck je miniaturní robot stvoˇrený pro výukové úˇcely na akademické úrovni. Vytvoˇren byl v EPFL (Ecole Polytechnique Fédérale de Laussanne) v roce 2004. Celý projekt je založen na principu otevˇreného hardware a open source, což znamená, že všechny dokumenty a schémata jsou dostupná pod svobodnou licencí umožnující ˇ komukoli využívat e-puck robota na maximum a vyvíjet pro nˇej software nebo napˇr. hardwarové nadstavby.
Obrázek 1.1: E-puck robot E-puck robot byl vytvoˇren s nˇekolika kritérii [10]: • Stolní velikost – možnost experimentovat s robotem pˇrímo u poˇcítaˇce je velmi výhodná pro studenty. Pokud se za optimální velikost pracovní plochy považuje 10-ti násobek velikosti robota, tak e-puck se svým pru˚ mˇerem 75mm je ideální pro použití na stole.
6
• Široké spektrum použití – robota je možné použít nejen pro výuku robotiky, ale také napˇríklad pro výuku zpracování obrazu nebo zvuku, programování vestavˇených systému, ˚ automatizace atd. Toho je docíleno velkým spektrem senzoru. ˚ • Uživatelská pˇrívˇetivost – pˇri vytváˇrení rozhraní by vždy mˇel být kladen duraz ˚ na jednoduchost. Rozhraní by mˇelo být intuitivní a dukladnˇ ˚ e zdokumentované, aby se zrychlil proces uˇcení. • Možnost dálkového ovládání – robot v sobˇe obsahuje Bluetooth modul, který se pro nˇej chová jako sériové zaˇrízení, pˇres které dokáže komunikovat s poˇcítaˇcem. Souˇcástí robota je velká škála senzoru˚ a akˇcních cˇ lenu. ˚ Srdcem robota je mikrokontrolér s obvodem dsPIC. Skládá se z 16bitového procesoru dsPIC 30F6014A a jednotky pro zpracování signálu. Procesor má frekvenci 64 MHz, 8 kB RAM a 144 kB flash pamˇeti. Robot obsahuje následující senzory: • Infraˇcervené (IR) senzory – po obvodu robota je 8 IR senzoru. ˚ Mˇerˇ í bud’ vzdálenost od pˇrekážek, anebo intenzitu okolního svˇetla. Jedná se o základní senzory využívané pro pohyb mezi pˇrekážkami. • Akcelerometr – 3D akcelerometr slouží k získání vektoru zrychlení robota. Muže ˚ být použit pro spoustu experimentu˚ (mˇerˇ ení náklonu, zrychlení, detekce nárazu, pádu, . . . ). • 3 mikrofony – mikrofony jsou 3, aby se daly použít k triangulaci zdroje zvuku. Velikost dat získaných z mikrofonu˚ je ovšem na kapacity robota pˇríliš a proto je nutné použít jednotku pro zpracování signálu (DSP). Bez jejího použití mužeme ˚ získat alesponˇ namˇerˇ enou hlasitost. • Barevná kamera – v pˇrední cˇ ásti robota je kamera s rozlišením 640x480, bohužel kvuli ˚ pamˇet’ovým omezením robota je možné získat pouze cˇ ást obrazu. I tak je ale možné ji použít pro experimenty s poˇcítaˇcovým vidˇením. Samotné senzory by samozˇrejmˇe byly bez užitku, kdyby robot nemˇel žádné akˇcní cˇ leny. Studenti mohou využít následujících komponent: • 2 krokové motory – slouží pro pohyb robota, mají rozlišení 1000 kroku˚ za jedno otoˇcení kola. • Reproduktor – ve spojení s mikrofony muže ˚ sloužit pro dorozumívání s jinými roboty, také jde o výhodný zpusob ˚ interakce s uživatelem. 7
• 8 LED – diody jsou rozmístˇené po obvodu robota. Slouží jako vizuální rozhraní pro uživatele, anebo pro jiného robota. • Zelená dioda uvnitˇr robota – hlavním jejím posláním je zkrášlit robota, ale také muže ˚ být použita pro interakci s jinými objekty. • Pˇrední dioda u kamery – tato LED nevytváˇrí rozptýlené svˇetlo, ale paprsek, který je možné použít dohromady s kamerou pro odhadování vzdálenosti k pˇrekážkám, když IR senzory nestaˇcí. Ovládání e-puck robota je možné rˇ ešit nˇekolika zpusoby. ˚ V první rˇ adˇe existuje kompatibilní GCC kompilátor, takže je možné psát rˇ ídící program, který bude vykonáván pˇrímo uvnitˇr robota, v programovacím jazyku C. Výrobce navíc dodává knihovnu s intuitivním rozhraním pro ovládání všech souˇcástí. Tento pˇrístup má ovšem nˇekolik nevýhod. Cyklus vývoje programu je pomalý, kvuli ˚ každé zmˇenˇe v programu je tˇreba spustit kompilaci na poˇcítaˇci, dále nahrát program do robota a teprve pak je možné zmˇenu vyzkoušet. Dalším problémem je výkon robota, který nemusí staˇcit pro složitˇejší výpoˇcty. Lepším zpusobem ˚ se tedy zdá využívat program v robotovi pouze pro vykonávání pˇríkazu, ˚ které jsou naplánovány v poˇcítaˇci. To je pˇrístup, kterým se zabývá tato práce. Získáme tím jednu obrovskou výhodu, kterou je výpoˇcetní síla stolního poˇcítaˇce, na druhou stranu s ní ovšem musíme pˇrijmout i bˇrímˇe problému˚ s komunikací.
1.2
Synchronní / asynchronní komunikace
Pojem komunikace ve svˇetˇe poˇcítaˇcu˚ oznaˇcuje pˇredávání dat mezi dvˇema programy nebo zaˇrízeními. Pˇríkladem muže ˚ být komunikace mezi webovým prohlížeˇcem a http serverem pˇri stahování stránky, poˇcítaˇcem a tiskárnou pˇri tisku, atd. Prubˇ ˚ eh komunikace je vždy velmi podobný, jedna strana pošle zprávu obsahující požadavek, druhá strana zprávu pˇrijme a zpracuje. Pokud ke zpracování potˇrebuje další informace, pošle odesílateli jako odpovˇed’ žádost o jejich dodání a tak si zúˇcastnˇené strany vymˇení role a situace se opakuje. Pˇrenos zprávy ovšem muže ˚ zabrat netriviálnˇe mnoho cˇ asu a tak je tu problém, co bude dˇelat odesílatel zprávy, zatímco cˇ eká na odpovˇed’. Tady dochází k rozdˇelení na synchronní (nebo také blokující) a asynchronní (neblokující) komunikaci. Popisem synchronní komunikace se zabývá sekce 1.2.1, popisem asynchronní komunikace sekce 1.2.2. A nakonec je v sekci 1.2.3 popsáno jak byly tyto principy uplatnˇeny v praxi.
8
1.2.1
Synchronní komunikace
Pˇri synchronní komunikaci program po odeslání zprávy pozastaví vykonávání dalších instrukcí a cˇ eká dokud nedostane odpovˇed’. Tento pˇrístup je velmi jednoduchý na implementaci (vˇetšinou se jedná o zavolání metody, která bude cˇ ekat, dokud neobdrží zprávu), není problém s inkonzistencí dat (než bude program pokraˇcovat v cˇ innosti, obdrží všechny informace). Pˇrekážkou pro synchronní komunikaci jsou ovšem ztráty zpráv pˇri pˇrenosu. Muže ˚ dojít k chybˇe pˇri pˇrenosu dat a ke ztrátˇe odeslané zprávy nebo pˇríchozí odpovˇedi. Stejnˇe tak se muže ˚ stát, že adresát zprávy na ni nijak neodpovˇedˇel. V takovýchto pˇrípadech lehce dojde k tzv. dead-locku, kdy bude odesílatel cˇ ekat na zprávu, která nikdy nepˇrijde, a tak nebude moci pokraˇcovat v dalších výpoˇctech. ˇ strávený cˇ ekáním na odDochází také k mrhání procesorovým cˇ asem. Cas povˇed’ by mohl být smysluplnˇe využit. Typickým pˇríkladem je grafické rozhraní, kde je potˇreba zaruˇcit interakci a nereagování na akce uživatele je ukazatelem špatnˇe napsané aplikace. Ale nemusí jít jen o složité aplikace s grafickým rozhraním, cˇ as strávený cˇ ekáním lze využít napˇríklad pro zpracování již pˇrijatých dat a díky tomu zvýšit jejich prutok. ˚
1.2.2
Asynchronní komunikace
Pokud je po programu požadována interaktivita, anebo komunikace není jeho jediným úkolem a musí zvládat napˇríklad obsluhovat více blokovaných spojení, tak synchronní komunikace pˇrestává staˇcit. Asynchronní komunikace rˇ eší nˇekteré problémy komunikace synchronní. Po odeslání zprávy program pokraˇcuje ve vykonávání instrukcí, neˇceká na odpovˇed’. Muže ˚ si ale kdykoli zkontrolovat, zda-li už nepˇrišla odpovˇed’ a pak ji teprve naˇcíst a zpracovat. Speciálním pˇrípadem je komunikace rˇ ízená událostmi (event-driven), kdy je pro zpracování události pˇrijetí zprávy urˇcena funkce, která je automaticky spuštˇena, bez pˇrímé intervence programátora. Asynchronní komunikace velmi zjednodušuje vyˇrešení problému˚ se ztrátou zpráv. Protože program se musí sám podívat jestli nepˇrišla odpovˇed’, tak si také muže ˚ pamatovat, kdy byla odeslána zpráva a pokud odpovˇed’ nedorazí do urˇcitého cˇ asu, tak zprávu prohlásí za ztracenou a muže ˚ se pokusit ji poslat znova. I asynchronní komunikace má své problémy. Odpovˇedi na zprávy nemusí pˇrijít ve stejném poˇradí, v jakém byly odeslány. Tento problém musí rˇ ešit naˇ pˇríklad protokol TCP/IP. Rešením je zprávy posílat s poˇradovým cˇ íslem a toto cˇ íslo pˇridat i k odpovˇedi. Pak je velmi snadné pˇríchozí zprávy seˇradit podle 9
poˇradí, v jakém jsou požadovány.
1.2.3
Komunikace v e-puck knihovnˇe
V této práci je uživateli knihovny dána možnost vybrat si mezi komunikací synchronní a asynchronní. Synchronní komunikace je urˇcena pro rychlé prototypování a interaktivní ovládání robota. Uživatel muže ˚ zadávat pˇríkazy a dívat se, jak na nˇe robot reaguje. Tady je výhodná transparentnost synchronního pˇrístupu. Naopak pro psaní kontrolních programu˚ je vˇetší duraz ˚ kladen na spolehlivost. Knihovna zajistí, že pˇríkaz opravdu dojde, v nejhorším pˇrípadˇe upozorní uživatele na skuteˇcnost, že robot je neovladatelný (muže ˚ se stát, tˇreba pokud mu dochází baterie). Výhodou je, že firmware v e-pucku robotovi je z duvodu ˚ hardwarových omezení napsán synchronnˇe. Na zaˇcátku je vždy zavolána funkce pro cˇ tení z Bluetooth spojení, zablokuje vykonávání dalších instrukcí a cˇ eká, dokud nedojde pˇríkaz, který by se mohl zpracovat. Po provedení pˇríkazu robot pošle odpovˇed’ a opˇet zaˇcne cˇ ekat na pˇríkazy z poˇcítaˇce. Tedy vždy platí, že robot bud’ zpracuje zprávy v takovém poˇradí v jakém byly poslány, anebo pˇrípadnˇe nˇekteré z nich vynechá. Pˇri asynchronní komunikaci tedy staˇcí mít frontu pˇríkazu˚ a kontrolovat, že je robot postupnˇe vykonává. To je také duvod ˚ proˇc jsou zprávy opatˇreny kódem pˇríkazu a poˇradovým cˇ íslem. Kód pˇríkazu je jeden znak, který urˇcuje o jaký pˇríkaz se jedná (napˇr. zmˇena rychlosti nebo nastavení LED). Poˇradové cˇ íslo je v podstatˇe také jeden znak, jeho cˇ íselná hodnota v ASCII kódování urˇcuje poˇradové cˇ íslo zprávy. Z toho samozˇrejmˇe vyplývá, že poˇradová cˇ ísla nejsou unikátní. Ovšem mezi dvˇema zprávami, které potenciálnˇe mohou mít stejný kód i stejné poˇradové cˇ íslo, musí být posláno tolik jiných zpráv (poˇradí je urˇceno znaky anglické abecedy, takže by jich muselo být 52), že pravdˇepodobnost zámˇeny tˇechto dvou je velmi malá (musely by se ztratit všechny zprávy mezi nimi a v takovém pˇrípadˇe už je komunikace opravdu velmi nestabilní). Díky pˇridaným informacím ke zprávˇe není problém poslat napˇr. více zpráv, které mˇení rychlost robota, za sebou. Je zajištˇeno, že budou provedeny všechny pˇríkazy postupnˇe a robot skonˇcí v oˇcekávaném stavu. Ukázkovou situací muže ˚ být robot, který stojí pˇred pˇrekážkou, chceme aby se otoˇcil a pokraˇcoval v jízdˇe dopˇredu. Pokud by se ztratil první pˇríkaz, tak robot pojede dále proti pˇrekážce, pokud by se ztratil druhý pˇríkaz, tak se bude robot pouze toˇcit na místˇe. Díky danému poˇradí pˇríkazu˚ se nemusíme takovýchto situací bát.
10
1.3
Existující práce
Existuje mnoho prací, které se zabývají ovládáním robota. V sekci 1.3.1 bude ukázán komerˇcní simulátor Webots. K nˇemu vznikla také kniha Cyberbotics’ Robot Curriculum (sekce 1.3.2). Další kniha, která se zabývá robotikou a programovacím jazykem Python je Learning Computing With Robots (sekce 1.3.3). U Webots nekonˇcí seznam existujících simulátoru, ˚ Evorobot* (sekce 1.3.4) je úzce zamˇerˇ ený na evoluci a využívá k tomu e-puck robota. A nakonec nesmíme zapomenout na projekt Pyro (sekce 1.3.5), který slouží pro psaní vysokoúrovnových ˇ programu˚ pro ovládání robota v Pythonu a obsahuje dokonce nˇekolik simulátoru. ˚
1.3.1
Webots
Webots [17] je vývojové prostˇredí a simulátor pro programování robotu. ˚ Nabízí podporu nejen pro e-puck robota, ale i pro rˇ adu dalších robotu˚ a umožnuje ˇ roboty programovat v nˇekolika jazycích (C++, Java, Python). Napsané programy je možné spouštˇet a testovat v simulátoru. To je samozˇrejmˇe velmi výhodné pro rychlé ladˇení programu. Ovšem výsledek v simulátoru se muže ˚ od skuteˇcného chování robota velmi lišit. Pˇri psaní programu˚ je nutné myslet na to, že senzory v robotovi jsou nespolehlivé, jejich hodnoty bývají zatíženy chybou a tak se na nˇe nedá stoprocentnˇe spolehnout. Webots simulátor se snaží virtuální senzory pˇriblížit realitˇe a tak i hodnoty, které obdrží robot v simulátoru neodpovídají pˇresnˇe simulované realitˇe. Výhodou Webots je tedy kvalitní simulátor, pokud se ovšem podíváme na ovládání skuteˇcného robota, tak tady se od mé práce v mnohém neliší. Webots umožnuje ˇ dva zpusoby ˚ jak rˇ ídit skuteˇcného robota. Prvním je kompilace programu a nahrání do robota. Ta funguje pouze pokud je program napsán v jazyku C. Druhé, zajímavˇejší, rˇ ešení je použít dálkové ovládání pomocí Bluetooth. Zde už mohou být programy napsány v libovolném podporovaném jazyce. Do robota je tˇreba nahrát upravený firmware. Zde ovšem nemohu porovnávat, protože Webots šíˇrí firmware pouze v binární podobˇe, nejsou dostupné zdrojové kódy a v dokumentaci není k nalezení pˇresnˇejší informace. Všechny funkce jsou ovšem volány synchronnˇe. Tím se dostáváme k hlavní nevýhodˇe Webots. Jedná se o komerˇcní projekt. Zdarma je pouze cˇ asovˇe omezená verze a nejsou dostupné zdrojové kódy (právˇe napˇr. firmwaru).
11
1.3.2
Cyberbotics’ Robot Curriculum
Pokud jsme se bavili o Webots, tak stojí za zmínku také kniha Cyberbotics’ Robot Curriculum [9]. Autorem je Olivier Michel, dále byla rozšíˇrena na EPFL, nyní je dostupná na Wikibooks [18]. Kniha je urˇcena všem, kteˇrí mají zájem o robotiku. Skládá se ze dvou cˇ ástí. V první pojednává o teoretických základech (umˇelá inteligence, robotika, e-puck robot), ve druhé už se snaží cˇ tenáˇre nauˇcit, jak se ovládají roboti. Kniha pro výuku programování robota používá e-puck robota a simulátor Webots. Vysvˇetluje principy, které se pˇri programování robotu˚ používají. Postupuje od jednoduchých pˇríkladu˚ jako je pohyb s robotem, vyhýbání se pˇrekážkám, následování cˇ áry, pˇres využití všech senzoru˚ robota (akcelerometr, kamera), až ke složitˇejším technikám. V kapitole pro pokroˇcilé cˇ tenáˇre se zabývá odometrií, plánováním cesty, rozpoznáváním tvaru, ˚ strojovým uˇcením a dalšími metodami vyvíjení kontrolního programu (genetické algoritmy, particle swarm optimization, . . . ). Tato kniha je výborným doplnkem ˇ pˇríkladu˚ uvedených v této práci. Muže ˚ být zdrojem zajímavých a podnˇetných pˇríkladu˚ a experimentu. ˚
1.3.3
Learning Computing With Robots
Jedná se o další knihu, která se vztahuje k programování robotu. ˚ Learning Computing With Robots [8] ovšem není psána o e-puck robotovi, ale o jednoduchém robotovi Scribbler [16]. Kniha se spíše zabývá výukou programování v programovacím jazyku Python a robota používá pro ukázku zajímavých pˇríkladu. ˚ Kniha se tedy dá chápat jako úvod pro ty, kdo se chtˇejí nauˇcit Python, aby mohli dále pokraˇcovat ve výuce programování robotu. ˚
1.3.4
Evorobot*
Evorobot* [5] je software vyvinutý pro provádˇení experimentu˚ na evoluci kolektivního chování a komunikace, založený na e-puck robotovi. Skládá se z nˇekolika cˇ ástí: • evoluˇcní algoritmus, • simulátor neuronové sítˇe, • simulátor robota a prostˇredí, • grafické rozhraní a pˇríkazy pro analýzu experimentu, ˚ 12
• nástroje pro testování a vyvíjení robota a • Evorobot* firmware pro nahrání do robota a následné ovládání pomocí programu z PC. Evorobot* tedy slouží k vytváˇrení neuronové sítˇe pro ovládání robota, její vyvíjení v simulovaném prostˇredí a následnou adaptaci a testování na skuteˇcném hardware. Souˇcástí programu je nˇekolik experimentu˚ ukazujících možnosti evoluˇcního vývoje ovládání robota.
1.3.5
Pyro
Pyro [11] je zkratka pro Python Robotics, jedná se o projekt jehož cílem je vytvoˇrit prostˇredí pro zkoumání pokroˇcilých témat z umˇelé inteligence a robotiky bez starostí o nízkoúrovnové ˇ problémy hardware. Pyro je napsán v Pythonu, každý experiment se skládá z nˇekolika cˇ ástí: • simulátor svˇeta, • simulátor hardware robota, • ovládací program robota. Simulátor funguje jako server a zpracovává celý experiment. Na výbˇer je nˇekolik simulátoru, ˚ od jednoduchého 2D, pˇres 3D prostˇredí se simulací fyziky, až po simulaci soutˇeže RoboCup [14]. Simulátory mohou být také diskrétní, je tedy možné simulovat i problémy zapadající spíše do oblasti umˇelé inteligence. Pyro napˇríklad obsahuje simulaci svˇeta Wumpus [15]. Další souˇcástí je simulace robota, pyro podporuje nˇekolik rodin robotu: ˚ • Pioneer [1] – Pioneer, Pioneer2, PeopleBot robots, • Khepera [7] – Khepera, Khepera 2 a Hemisson robots, • AIBO [2] a • Roomba [6]. Nakonec nejduležitˇ ˚ ejší souˇcástí je samotný mozek robota, jedná se o program napsaný v Pythonu, který robota rˇ ídí. Zde je upˇrednostnˇena velká míra abstrakce tak, aby stejný program mohl být testován na více robotech. Pyro navíc obsahuje moduly pro ruzné ˚ pˇrístupy k ovládání robota (koneˇcné automaty, neuronové sítˇe, posilované uˇcení, fuzzy logika, evoluˇcní algoritmy, . . . ). Smutnou skuteˇcností ovšem je, že Pyro neobsahuje podporu pro e-puck robota. 13
1.4
Specifikace e-puck knihovny
Cílem této práce je poskytnout knihovnu, která bude dostateˇcnˇe jednoduchá na používání, aby mohla být využita pro výuku ovládání robota. S tím se pojí nˇekolik dalších vlastností, které zjednodušují proces uˇcení. První duležitou ˚ vlastností je otevˇrenost zdrojových kódu. ˚ Uživatel je povzbuzován, aby do nich nahlédl. Jsou dukladnˇ ˚ e okomentovány a mˇely by cˇ tenáˇrum ˚ ukázat vzor, jak muže ˚ komunikace s robotem probíhat. Stejnˇe tak ukázkové kontrolní programy jsou urˇceny pro pˇredvedení možných zpusob ˚ u˚ ovládání robota. Uživatel si muže ˚ vybrat, zda-li má být komunikace synchronní nebo asynchronní. Synchronní komunikace slouží k experimentování s robotem, ve spojení s Pythonem se jedná o velmi jednoduchý a rychlý zpusob ˚ jak robotovi pˇredávat pˇríkazy. Jedná se o jednu z výhod e-puck knihovny. V pˇrípadˇe psaní složitˇejších programu˚ ovšem e-puck knihovna nezustává ˚ v niˇcem pozadu za konkurencí. Nabízí spolehlivou asynchronní komunikaci, díky které se muže ˚ uživatel spolehnout, že pˇríkazy posílané robotovi budou opravdu provedeny. Tohoto ovšem nebylo dosaženo bez úsilí, asynchronní komunikace samotná není dokonalá a nedokáže vyˇrešit všechny problémy. Je nutné, aby s ní spolupracoval firmware v robotovi.
1.4.1
Firmware
Puvodní ˚ BTcom firmware funguje velmi pˇrímoˇcaˇre, jedná se o jednu nekoneˇcnou smyˇcku, ve které naˇcítá pˇríkazy, zavolá pˇríslušné funkce a odešle odpovˇed’. Díky tomu, že je program takto prostý, je jednoduché provozovat synchronní komunikaci. Program naˇcítá pˇríkazy pˇresnˇe tak, jak mu pˇrijdou, jeden po druhém. Na každý odpoví a teprve pak se pˇresune na zpracování dalšího pˇríkazu. Problém ovšem nastane pokud dojde k poruše spojení a nˇejaký pˇríkaz nedorazí. Puvodní ˚ firmware nedokázal problémy tohoto typu rozpoznat. Navíc pokud robot pracuje v binárním režimu, tak posílá pouze data, bez jakéhokoli oznaˇcení pˇríslušnosti k pˇríkazu, nebo informace o povaze dat. Proto bylo provedeno nˇekolik úprav, v puvodním ˚ stavu se totiž jednalo o témˇerˇ neˇrešitelný problém rozpoznat, ke kterému pˇríkazu data pˇrísluší. Upravený firmware obsahuje nˇekolik mechanismu˚ pro zabezpeˇcení spolehlivé komunikace. V kapitole 2.1.1 je popsáno jak bylo potˇreba upravit pˇríkazy, aby se daly svázat s patˇriˇcnou odpovˇedí. K pˇríkazum ˚ napˇr. pˇribylo porˇ adové cˇ íslo.
14
V cˇ ásti 2.1.2 jsou popsány další zmˇeny firmware. Binární pˇríkazy v odpovˇedi posílají nejprve hlaviˇcku obsahující kód pˇríkazu, poˇradové cˇ íslo a velikost pˇrenášených dat. Dále firmware získal možnost upozornit na nízký stav baterie rozsvícením LED. Možná se zpusob, ˚ jakým je toto upozornˇení provedeno zdá podivný, protože rozsvícení diod zaˇcne baterii vybíjet ještˇe víc, ovšem ve chvíli, kdy dojde k upozornˇení, už je baterie vybitá tak, že komunikace s robotem je velmi problémová a složitˇejší pˇríkazy už stejnˇe není schopen vykonat.
15
2. Implementace Hlavní souˇcástí této práce je samozˇrejmˇe samotná implementace knihovny. Duležitou ˚ zmˇenou je úprava firmware robota. V sekci 2.1 je pˇredstaven upravený firmware BTcomDM, který je používán pro ovládání robota. Jsou zde také uvedeny zmˇeny, které bylo nutné provést pro zabezpeˇcení spolehlivé asynchronní komunikace. Pro rychlé testování pˇríkazu˚ a interaktivní ovládání robota je urˇcena synchronní komunikace. V kapitole 2.2 je popsáno, jak synchronní komunikace vypadá a k cˇ emu všemu muže ˚ sloužit. Implementace asynchronní komunikace je pˇredstavena v sekci 2.3. Jedná se o pˇredstavení mechanismu, ˚ díky kterým je možné provádˇet komunikaci asynchronnˇe. K asynchronní komunikaci také patˇrí zpracování odpovˇedi a znovuodeslání ztracených pˇríkazu. ˚ Nakonec je pˇredstavena pro uživatele ta nejzajímavˇejší cˇ ást a to rozhraní pro komunikaci s robotem (sekce 2.4). Jedná se o most mezi uživatelem a tˇrídami, které se starají o komunikaci. Dochází zde k pˇrevodu pˇríkazu˚ do srozumitelné formy pro robota a naopak také k pˇrevádˇení odpovˇedí od robota do formátu cˇ itelného pro uživatele.
2.1 BTcomDM firmware Robot e-puck v sobˇe obsahuje programovatelný mikroprocesor. Vˇetšinou se vývoj programu pro robota omezuje na psaní programu právˇe pro tento mikroprocesor. Takový program je pak ovšem, co se výpoˇcetního výkonu týˇce, velmi limitován. My se ovšem od tohoto zpusobu ˚ vývoje odkloníme a budeme používat dálkové ovládání. Programátor píše program, který bˇeží na PC, a pouze jednotlivé pˇríkazy jsou posílány do robota ke zpracování. Je tedy potˇreba, aby v robotovi byl software, který dokáže pˇrijímat pˇríkazy, zpracovávat je a odesílat odpovˇedi. K tomuto úˇcelu byl upraven tvurci ˚ robota poskytovaný firmware BTcom. Jedná se o jednoduchý program, který spoleˇcnˇe se standardní knihovnou dodávanou k e-puck robotovi zpˇrístupnuje ˇ všechny senzory a akˇcní cˇ leny robota pomocí jednoduchého protokolu pˇres Bluetooth rozhraní. Upravená verze BTcomDM není zpˇetnˇe kompatibilní s pu˚ vodním BTcom a tedy programy napsané pro puvodní ˚ verzi firmware nemohou využívat výhod upravené verze.
16
2.1.1
Pˇríkazy
Pˇríkazy je možné posílat v textovém nebo binárním režimu. Textový režim slouží k posílání jednoduchých dat jako je ovládání led diod nebo nastavení rychlosti motoru. ˚ Binární režim slouží k získávání vˇetších dat, jako jsou napˇríklad snímky z kamery. Pˇríklad jak muže ˚ vypadat pˇríkaz poslaný robotovi: Da,100,100\r. Zde se jedná o textový pˇríkaz, první znak urˇcuje typ pˇríkazu, písmeno „D“ je pˇríkaz pro zmˇenu rychlosti kol. Druhé písmeno je tzv. timestamp, jedná se právˇe o kontrolní znak, který urˇcuje poˇradí pˇríkazu˚ a odlišuje pˇríkazy stejného typu. Dále následují dvˇe cˇ ísla, první urˇcuje rychlost levého kola, druhé rychlost pravého kola. Nakonec je znak konce rˇ ádku, který urˇcuje konec pˇríkazu. Binární pˇríkazy se také rozlišují písmenem, avšak aby bylo rozpoznání zjednodušeno (pˇresnˇeji rˇ eˇceno, aby staˇcilo jedno porovnání), tak kód pro binární pˇríkazy je záporný. Firmware pˇreˇcte kód pˇríkazu jako 8-bitové cˇ íslo se znaménkem. Pokud je záporné, tak automaticky pˇredpokládá, že vše co následuje je binární pˇríkaz. Protože data v pˇríkazu nejsou nijak kódována, tak není napˇr. možné pˇredpokládat, že se v pˇríkazu neobjeví cˇ íslo 10, které v ASCII tabulce reprezentuje znak konce rˇ ádku. Z toho duvodu ˚ jsou pˇríkazy ukonˇceny bytem 0. Odpovˇedi v binárním režimu zaˇcínají hlaviˇckou, která obsahuje identifikaci a velikost následující odpovˇedi. Díky tomu nemusí být nˇejak speciálnˇe ukonˇcovány. Hlavní výhodou binárního režimu tedy je úspora dat pˇri pˇrenosu a možnost vyhnout se kódování odpovˇedi a posílat ji jako surová data.
2.1.2
Provedené úpravy
Provedené úpravy se snaží vyˇrešit problémy stávajícího rˇ ešení a také umožnují ˇ použití asynchronní komunikace. Ke každému pˇríkazu poslanému robotovi se pˇridává cˇ asový otisk, jedná se o 8–bitové cˇ íslo, které urˇcuje poˇradí pˇríkazu v sérii. Ve své odpovˇedi pak robot uvede jak kód oznaˇcující typ pˇríkazu, na který odpovídá, tak také došlý otisk. Díky tomu je možné témˇerˇ jednoznaˇcnˇe (otisk se samozˇrejmˇe opakuje po urˇcité dobˇe znova) svázat odpovˇed’ se zaslaným pˇríkazem. Pokud tedy nˇejaké cˇ íslo chybí v posloupnosti pˇrijatých odpovˇedí, je jasné, že tato odpovˇed’ nedorazila. Odpovˇedi na binární pˇríkazy nyní vždy obsahují hlaviˇcku, která je pro všechny stejná a obsahuje samozˇrejmˇe kód pˇríkazu, na který odpovídá, a také jeho timestamp, ale hlavnˇe obsahuje i velikost dat, která budou následovat. Pˇri binární komunikaci totiž není možné rozpoznat konec pˇrenosu dat. V puvodní ˚ 17
verzi firmware se poˇcítalo s tím, že po každém odeslaném pˇríkazu bude uživatel cˇ ekat na jeho odpovˇed’ a tedy bude vˇedˇet jakého formátu jsou data, která oˇcekává. Pˇri asynchronní komunikaci bychom nemˇeli o pˇríchozích datech nic pˇredpokládat. Pokud známe jejich velikost, mužeme ˚ je nejprve naˇcíst a až pak hledat pˇríkaz, kterému patˇrí. Do firmware byly také pˇridány nové pˇríkazy. Robot obsahuje 3 mikrofony, ale není jednoduché nasnímaná data odeslat do PC kvuli ˚ jejich velikosti. Pro programy, které jsou spouštˇeny pˇrímo v robotovi, ovšem existuje knihovna umožnující ˇ provádˇení FFT (rychlé Fourierovy transformace). Ta byla pˇridána do BTcomDM firmwaru a díky ní je možné jedním pˇríkazem zapnout snímání dat z mikrofonu, na nasnímaných datech provést transformaci a odeslat je do PC. Dalším problémem, se kterým se musí uživatel e-puck robota potýkat, je kapacita baterie a nepˇrítomnost jakéhokoli ukazatele jejího stavu. Tento problém byl alesponˇ cˇ ásteˇcnˇe vyˇrešen, do kontrolního programu v robotovi bylo pˇridáno pˇrerušení, které je aktivováno právˇe tehdy, když napˇetí na baterii již není dostateˇcné pro bezproblémový provoz. Pˇri vyvolání tohoto pˇrerušení jsou zapnuty všechny LED na obvodu robota a tak uživatel dostane vizuální upozornˇení, že je tˇreba baterii vymˇenit.
2.2
Synchronní komunikace
Hlavním cílem synchronní komunikace je umožnit uživateli knihovny jednoduché zasílání pˇríkazu, ˚ u kterého není kladen duraz ˚ na ošetˇrování chyb spojení. Poˇcítá se s tím, že uživatel bude využívat synchronní komunikaci pro experimentování s robotem a interaktivní ovládání. Hlavní výhodou synchronní komunikace je její jednoduchost. Jak lze vidˇet ve zdrojovém kódu 2.2, pˇríkaz lze pˇredat robotovi zavoláním pouze jedné metody, která navíc i vrátí odpovˇed’ od robota. V tomto pˇrípadˇe se jedná o získání rychlosti motoru. ˚ Díky tomu lze robota ovládat i z interpretu Pythonu, cˇ ímž se výraznˇe zkrátí doba potˇrebná pro testování nových nápadu. ˚ Tam, kde je normálnˇe potˇreba napsat zdrojový kód, zkompilovat aplikaci a následnˇe ji pustit, tady staˇcí pouze pustit Python, importovat knihovnu, vytvoˇrit spojení (což jsou 2 rˇ ádky kódu) a pak už nám nic nebrání v posílání pˇríkazu. ˚ Každé zavolání pˇríkazu odešle robotovi zprávu (bližší popis zprávy v cˇ ásti 2.1.1) a následnˇe zablokuje (zavoláním metody read na sériové spojení) další vykonávání pˇríkazu, ˚ dokud neobdrží odpovˇed’. Uživatel si tedy musí sám dávat pozor, zda-li se mu nˇejaký pˇríkaz neztratil. Na druhou stranu hlavní výhodou synchronní komunikace je, že uživatel vždy pˇresnˇe ví, co se dˇeje. 18
1
>>> from epuck import Controller
2
>>> controller = Controller(’/dev/rfcomm0’)
3
>>> controller.get_speed()
4
(0,0)
Zdrojový kód 2.2: Pˇríklad synchronní komunikace
2.3
Asynchronní komunikace
Asynchronní komunikace se snaží co nejvíce usnadnit ovládání robota, skrýt nˇekteré složitˇejší mechanismy komunikace pˇred uživatelem a pˇritom zajistit spolehlivou komunikaci. Krátká ukázka asynchronní komunikace je ve zdrojovém kódu 2.3. 1
>>> from epuck import Controller
2
>>> controller = Controller(’/dev/rfcomm0’, asynchronous=True)
3
>>> request = controller.get_speed()
4
>>> request.get_response()
5
(0,0)
Zdrojový kód 2.3: Pˇríklad asynchronní komunikace Základním požadavkem asynchronní komunikace je oddˇelení volání pˇríkazu od jeho provedení. Provedení totiž muže ˚ trvat delší dobu a to se muže ˚ ukázat v nˇekterých aplikacích jako klíˇcový problém. Pˇríkazy tedy neˇcekají na odpovˇed’, ovšem jak se pak uživatel dostane k odpovˇedi? Zavolání pˇríkazu nemuže ˚ vrátit odpovˇed’, ale na druhou stranu muže ˚ vrátit uživateli odkaz na objekt s potenciální odpovˇedí. Díky tomu se pak muže ˚ tázat, zda-li odpovˇed’ pˇrišla a nakonec ji také i získat. Ukázka je ve zdrojovém kódu 2.4. Pro vysvˇetlení, jak tento odkaz funguje, bude potˇreba osvˇetlit vnitˇrnosti asynchronní komunikace.
19
1
# Zaslani prikazu
2
request = controller.get_speed()
3
# Kontrola, zda-li uz prisla odpoved
4
while not request.response_received():
5
# Program zde muze delat cokoli jineho,
6
# zatimco ceka na odpoved
7
# Ziskani odpovedi
8
value = request.get_response()
Zdrojový kód 2.4: Ukázka oddˇelení zaslání pˇríkazu a vyzvednutí odpovˇedi Asynchronní komunikace už od zaˇcátku spojení s robotem probíhá v samostatném vláknˇe, které je nezávislé od vlákna, ve kterém bˇeží program uživatele. Toto komunikaˇcní vlákno zastává tˇri funkce: 1. odesílání pˇríkazu, ˚ 2. zpracování pˇríchozí komunikace a 3. kontrola chyb. Pˇríchozí komunikace je získávána pomocí sériového pˇripojení vytvoˇreného knihovnou pySerial [12]. Pˇripojení podporuje standardní metody pro práci se sokety a je tedy možné používat funkci select operaˇcního systému, která dokáže kontrolovat více pˇripojení a oznámit pˇrijetí dat na libovolném z nich. První pˇripojení, které je kontrolováno, tedy je sériové pˇripojení s robotem. Další spojení slouží k získávání nových pˇríkazu. ˚
2.3.1
Odeslání pˇríkazu
Pˇri odesílání je pˇríkaz zavolán ve vláknu s uživatelským programem, ovšem samotná zpráva robotovi musí být odeslána z vlákna asynchronní komunikace. V opaˇcném pˇrípadˇe by uživatelský program byl zpomalen pˇrenosem k robotovi, navíc asynchronní vlákno má vˇetší pˇrehled o spojení s robotem a tedy napˇr. nedojde ke kolizi mezi posíláním a pˇrijímáním dat. Je tedy nutné pˇredat informaci o novém pˇríkazu mezi vlákny. V uživatelském vláknu je pˇríkaz zaˇrazen do fronty pro odchozí pˇríkazy, asynchronní vlákno je pak následovnˇe informováno o novém pˇríkazu, nakonec je vytvoˇren odkaz na pˇríkaz, který je vrácen uživateli. Žádná z tˇechto instrukcí není blokující, tedy odeslání pˇríkazu nestojí uživatele témˇerˇ nic. Dokonˇcení odesílání už probíhá v asynchronním vláknu. Funkce select je pˇrerušena informací o novém pˇríkazu. Následnˇe je pˇríkaz odebrán z fronty, 20
odeslán robotovi a zaˇrazen do fronty odeslaných zpráv. Zde cˇ eká na pˇríchozí odpovˇed’. Uživatel stále vlastní odkaz na tento pˇríkaz, i když se pˇresunul.
2.3.2
Zpracování odpovˇedi
Pokud se robot rozhodne odeslat odpovˇed’ na pˇríkaz, tak se to asynchronní vlákno dozví díky funkci select, která oznaˇcí spojení, pˇripravené pro cˇ tení. Následuje tedy pˇreˇctení a zpracování odpovˇedi. Nejprve je potˇreba rozhodnout, zda-li se jedná o binární nebo textovou odpovˇed’. Na to staˇcí pˇreˇcíst první znak, ten urˇcuje, na který pˇríkaz robot odpovídá. Další znak urˇcí timestamp, díky nˇemu už je možné jednoznaˇcnˇe najít pˇríkaz, kterému odpovˇed’ patˇrí, ve frontˇe odeslaných. Odpovˇed’ pak už je pouze pˇredána pˇríkazu, který si ji uloží. Pˇríkaz je následnˇe odebrán z fronty odeslaných pˇríkazu. ˚ Pokud si uživatel uložil odkaz na tento pˇríkaz, tak stále má možnost získat odpovˇed’. V opaˇcném pˇrípadˇe už na objekt nic neukazuje a tedy bude smazán. Dost cˇ asto je tˇreba odpovˇed’ ihned použít pro další zpracování a následující pˇríkazy na ní nezáleží. Pak se zdá nutnost neustále kontrolovat, zda už od robota nˇeco pˇrišlo, nepˇrirozená. Lepší možnost je rˇ íct knihovnˇe, co se má vykonat po pˇrijetí odpovˇedi a nechat ji, at’ se o vše postará sama. Z tohoto duvodu ˚ má každý pˇríkaz navíc parametr callback, pˇres který se muže ˚ knihovnˇe pˇredat funkce, která bude spuštˇena po pˇrijetí odpovˇedi. Ukázka je ve zdrojovém kódu 2.5. 1 2 3 4 5
>>> def zpracovani_rychlosti(vysledek): ... leva, prava = vysledek ... # Prace s vysledkem ... >>> controller.get_speed(callback=zpracovani_rychlosti)
Zdrojový kód 2.5: Ukázka použití callback funkce Pˇri psaní callback funkcí je duležité ˚ pamatovat na to, že knihovna volá tyto metody ve stejném vláknˇe, v jakém provádí vše ostatní. Proto by callback funkce nemˇela být výpoˇctovˇe nároˇcná. Popˇrípadˇe by si mˇela pro složitˇejší výpoˇcty vytvoˇrit vlastní vlákno.
ˇ 2.3.3 Casový limit Muže ˚ se stát, že pˇríkaz k robotovi nedorazí. Tato skuteˇcnost se tˇežko rozpoznává. Robotovi zabírá vykonání pˇríkazu delší dobu, anebo o pˇríkazu vubec ˚ 21
neví? Kdy už se má pˇríkaz považovat za ztracený? Pro vyˇrešení tˇechto problému˚ slouží cˇ asový limit. Pro každý pˇríkaz má robot pˇridˇelen cˇ asový limit, ˇ v kterém musí odpovˇedˇet. Casový limit je vždy pˇredán funkci select, která vlákno zablokuje právˇe na tuto dobu. Po uplynutí dojde ke kontrole stáˇrí pˇríkazu. ˚ Každý pˇríkaz, který už je ve frontˇe pˇríliš dlouho, je oznaˇcen za ztracený a poslán znova. Je omezen poˇcet pokusu˚ o zaslání pˇríkazu, po jejich vyˇcerpání je uživateli oznámena chyba (vyhozena výjimka). Robot je v takovém pˇrípadˇe nejspíše neovladatelný. ˇ Casový limit je jednotný pro všechny pˇríkazy a nastavuje se pˇri vytváˇrení instance objektu Controller (pˇríklad ve zdrojovém kódu 2.6). Je možné nastavit dva parametry: • timeout – cˇ asový limit v sekundách (je možné zadat i desetinné cˇ íslo), • max_tries – maximální poˇcet pokusu˚ o zaslání pˇríkazu pˇred oznámením chyby uživateli. Pokud uživatel tyto hodnoty nezmˇení, tak v základním nastavení je cˇ asový limit pro každý pˇríkaz pul ˚ sekundy a je povoleno až 10 opakování. 1 2 3 4
c = Controller(’/dev/rfcomm0’, asynchronous=True, timeout=0.5, max_tries=5)
Zdrojový kód 2.6: Nastavení cˇ asového limitu a maximálního poˇctu pokusu˚
2.4
Ovládání robota
Pokud je zajištˇena komunikace s robotem, tak samotné jeho ovládání už je velmi jednoduché. Pˇri vytváˇrení ovladaˇce robota musí uživatel specifikovat, zda-li chce komunikaci synchronní anebo asynchronní. Hlavní zmˇena, kterou pozná, je v návratové hodnotˇe pˇríkazu. ˚ Pˇri synchronní komunikaci pˇríkazy vrací rovnou výsledek, pˇri asynchronní dostane nejprve odkaz na pˇríkaz. Z toho duvodu ˚ není možné psát programy, které budou fungovat se synchronní i asynchronní komunikací. Zaslání pˇríkazu je pouhé zavolání funkce a pˇredání správných parametru. ˚ Ovladaˇc se sám stará o vytvoˇrení pˇríkazu, pˇridá k nˇemu timestamp, zakóduje parametry a pˇredá k odeslání. Stejnˇe tak ovladaˇc zpracovává pˇríchozí odpovˇedi, než vydá uživateli výsledek. U jednoduchých pˇríkazu, ˚ jako je tˇreba nastavení rychlosti motoru, ˚ jde 22
pouze o získání dvou cˇ ísel z rˇ etˇezce. U složitˇejších pˇríkazu˚ už se muže ˚ jednat o netriviální cˇ innost, napˇríklad pˇri získání fotky je potˇreba pˇrevést fotku z formátu, který používá robot, do formátu standardní knihovny Pythonu.
2.5
Výkon knihovny
Pro dálkové ovládání robota je duležité ˚ jak rychle mužeme ˚ reagovat na podnˇety z prostˇredí. Vyzkoušíme si tedy nˇekteré základní pˇríkazy a budeme stopovat jak rychle se provádˇejí. Nejprve zaˇcneme zjištˇením údaju˚ ze senzoru˚ pˇrekážek. Kód 2.7 (pouze relevantní cˇ ást) mˇerˇ í kolikrát za sekundu je možné získat údaje z IR senzoru. ˚ Program jsem nechal bˇežet 500 sekund. Nejlepší výsledek bylo 50 zavolání pˇríkazu, nejhorší výsledek bylo jen 30 zavolání pˇríkazu, v prumˇ ˚ eru bylo posláno 39 pˇríkazu. ˚ To je tedy v prumˇ ˚ eru 25ms na jednu iteraci. 1 2 3 4 5 6 7 8 9
start_time = time.time() count = [0] while True: prox = c.get_proximity_sensors().get_response() count[-1] += 1 if time.time() - start_time > 1: print count count.append(0) start_time = time.time()
Zdrojový kód 2.7: Stopování rychlosti senzoru˚ pˇrekážek Zkusíme, jak moc se od sebe liší ruzné ˚ pˇríkazy. V kódu 2.8 budeme získávat fotku z kamery. Pro barevné fotky s rozmˇery 40x40 je možné za sekundu v pru˚ mˇeru získat 3 snímky. Tady musíme zapoˇcítat i pˇrevod z módu RGB565 do formátu používaného knihovnou PIL. Pokud nám bude staˇcit pouze cˇ ernobílý obrázek stejných rozmˇeru, ˚ tak za sekundu jsme schopni jich získat v prumˇ ˚ eru 5. Staˇcilo nám tedy jen pár pokusu˚ abychom zjistili, že možný poˇcet zaslaných pˇríkazu˚ za sekundu se dramaticky liší v závislosti na typu pˇríkazu anebo jeho parametrech. Duležité ˚ je také si uvˇedomit, že pˇri asynchronní komunikaci po zavolání pˇríkazu nemusíme cˇ ekat na odpovˇed’ a mužeme ˚ tedy ihned volat další pˇríkaz. To s sebou nese jedno riziko, pokud budeme posílat nové pˇríkazy rychleji, než je stíhá robot vykonávat, tak nám muže ˚ pˇretéct fronta pˇríkazu, ˚ která není nekoneˇcná. Každé zavolání pˇríkazu, který potˇrebuje nacˇ íst data, nám tuto frontu vyprázdní, protože se vždy musejí provést všechny 23
1 2 3 4 5 6 7 8 9
start_time = time.time() count = [0] while True: c.get_photo().get_response() count[-1] += 1 if time.time() - start_time > 1: print count count.append(0) start_time = time.time()
Zdrojový kód 2.8: Stopování rychlosti kamery pˇredchozí pˇríkazy a teprve pak je možné získat data, ale i tak je dobrým zvykem omezit maximální rychlost smyˇcky programu krátkou pauzou.
24
3. Uživatelská dokumentace Interakce uživatele s knihovnou se skládá ze dvou cˇ ástí. V té první se jedná o pˇripojení robota k poˇcítaˇci a uvedení jej do provozuschopného stavu. Soucˇ ástí této inicializace je vytvoˇrení spojení mezi poˇcítaˇcem a robotem a nainstalování firmware do robota. Vysvˇetlení jak se vše provádí je k nalezení v kapitole 3.1. V druhém kroku už je robot pˇripojený a tedy už mu mužeme ˚ posílat pˇríkazy. Pˇredchozí kapitola uvádí ukázky komunikace s robotem, ale až v kapitole 3.2 nalezne cˇ itatel ucelený zdrojový kód, který se stará o ovládání robota od vytvoˇrení prvotního spojení až po zastavení motoru˚ po skonˇcení programu.
3.1
Pˇripojení robota
Pro využívání knihovny je nutné mít robota pˇripojeného k PC. Robot se chová jako standardní Bluetooth zaˇrízení. Poskytuje pouze jedinou službu a to sériovou komunikaci. Je tedy potˇreba nakonfigurovat sériový port, pˇres který bude knihovna s robotem komunikovat.
3.1.1
Pˇríprava
E-puck robot s poˇcítaˇcem komunikuje pomocí Bluetooth. Pro pˇripojení robota k poˇcítaˇci na operaˇcním systému Linux je tedy tˇreba mít nainstalovánu podporu Bluetooth. Vˇetšinou jsou to balíˇcky bluez-firmware a bluez-utils, dále je potˇreba mít software pro správu PIN (bluez-pin, bluez-gnome a bluetooth-applet, ...). Nejprve je potˇreba zjistit adresu robota. Lze využít utilitu hcitool: $ hcitool scan Scanning ... 10:00:E8:52:C6:3E
e-puck_1055
Adresa robota se použije pˇri nastavení virtuálního sériového portu v souboru /etc/bluetooth/rfcomm.conf: rfcomm0 { bind yes; device 10:00:E8:52:C6:3E; # Adresa robota channel 1; comment "e-puck_1055";
# Komentar
}
25
Tím jsme nakonfigurovali zaˇrízení /dev/rfcomm0.
3.1.2
Pˇripojení
Zaˇrízení reprezentující spojení s robotem jsme nakonfigurovali, nyní zbývá pˇripojit robota: $ sudo rfcomm connect rfcomm0 Connected /dev/rfcomm0 to 10:00:E8:52:C6:3E on channel 1 Press CTRL-C for hangup
Je duležité, ˚ aby uživatel, který bude ovládat robota, mˇel právo pˇrístupu k zaˇrízení /dev/rfcomm0. Po tˇechto pˇríkazech by už mˇelo být vytvoˇrené spojení s robotem a je možné mu zaˇcít posílat pˇríkazy pomocí knihovny. V prubˇ ˚ ehu pˇripojení se systém muže ˚ dotázat na PIN, který je potˇreba pro spárování zaˇrízení pomocí Bluetooth.
3.1.3
Pˇrehled možných chyb
Pˇri pˇripojení se mužou ˚ vyskytnou chyby, nejˇcastˇejší jsou tyto: • Can’t connect RFCOMM socket: Connection refused – Nejspíše nebˇeží žádná aplikace, která by se na heslo zeptala. • Can’t open RFCOMM device: Permission denied – Uživatel nemuže ˚ pˇristupovat k zaˇrízení /dev/rfcomm0. • Can’t create RFCOMM TTY: Address already in use – Možná pˇríˇcina je už pˇripojené zaˇrízení. Bud’ už bˇeží rfcomm, anebo jiná aplikace, která s roˇ botem udržuje komunikaci. Rešením je zavˇrít aplikace komunikující s robotem, popˇr. zkusit následující pˇríkazy: $ rfcomm release rfcomm0 $ rfcomm connect rfcomm0
3.1.4
Nahrání firmware BTcomDM
Knihovna komunikuje s E-puck robotem pomocí posílání textových pˇríkazu. ˚ Je tˇreba do robota nahrát firmware BTcomDM. Ten je dodáván s knihovnou. K jeho nahrání slouží skript epuckupload [3]. Staˇcí se rˇ ídit pomocí README a do robota nahrát soubor BTcomDM.hex. Pˇríklad použití:
26
$ epuckupload -f BTcomDM.hex rfcomm0
Po spuštˇení pˇríkazu je tˇreba robota restartovat (modré tlaˇcítko na horní stranˇe). Teprve pak se zaˇcne nahrávat nový firmware.
3.1.5
Instalace knihovny
Knihovna je dodávána v balíˇcku v pˇríloze. Podporuje standardní instalaci, takže je možné ji nainstalovat pomocí skriptu setup.py. $ tar -xvf epuck-0.9.1.tar.gz $ cd epuck-0.9.1/ $ sudo python setup.py install
Také je možné ji nainstalovat z webového repositáˇre PyPI (Python Package Index) [13] pomocí programu easy_install. $ easy_install epuck
3.2
Ukázkový program
Pro ovládání robota slouží modul epuck a objekt Controller. Ovládání robota je velmi jednoduché. Ukážeme si triviální program, který pˇrikáže robotovi, aby jel dopˇredu. Zárovenˇ ale bude kontrolovat, zda-li pˇred robotem není žádná pˇrekážka. Pokud by mˇel robot narazit, tak jej zastaví a skonˇcí. Na tomto programu rozebereme jednotlivé pˇríkazy:
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3 4
"""Go forward, stop in front of an obstacle."""
5 6
import time
7 8
from epuck import Controller
9 10
# Input larger than the threshold means there is an obstacle.
11
threshold = 300
12 13
# Create the controller. Robot is connected to /dev/rfcomm0
14
# and the communication will be asynchronous.
27
15
controller = Controller(’/dev/rfcomm0’, asynchronous=True)
16 17
# Set the speed of left and right wheel to 100.
18
controller.set_speed(100, 100)
19 20
# Ask for the values of proximity sensors
21
sensor_request = controller.get_proximity_sensors()
22
# Wait until the robot returns them.
23
sensor_values = sensor_request.get_response()
24 25
# Continue while there is nothing in front of the front left
26
# and front right sensor.
27
while (sensor_values[’L10’] < threshold) \ and (sensor_values[’R10’] < threshold):
28 29
# Wait for a while
30
time.sleep(0.1)
31
# Read new values
32
sensor_request = controller.get_proximity_sensors()
33
sensor_values = sensor_request.get_response()
34 35
# Stop the robot
36
controller.set_speed(0, 0)
Zdrojový kód 3.9: Jednoduchý asynchronní program pro ovládání robota
3.2.1
Vysvˇetlení zdrojového kódu
Zdrojový kód 3.9 tvoˇrí celý program pro ovládání robota. Rozebereme si jej tedy rˇ ádek po rˇ ádku, abychom vˇedˇeli, co která cˇ ást dˇelá. První vˇecí, kterou je tˇreba vždy uˇcinit, je import knihovny:
8
from epuck import Controller
Nyní máme importovanou tˇrídu Controller, která slouží ke komunikaci s robotem. Staˇcí už jen vytvoˇrit samotné spojení:
15
controller = Controller(’/dev/rfcomm0’, asynchronous=True)
Vytvoˇrení spojení je jednoduché, první parametr je cesta k pˇripojenému robotovi (jak pˇripojit robota je popsáno v kapitole 3.1). Druhý parametr je nepovinný a urˇcuje, zda-li má komunikace probíhat asynchronnˇe. V tomto pˇrípadˇe 28
chceme asynchronní komunikaci, pokud bychom druhý parametr vynechali, tak by komunikace byla synchronní. Nyní už mužeme ˚ zadávat pˇríkazy:
18
controller.set_speed(100, 100)
Zde nastavíme rychlost robota na 100 tiku˚ za sekundu. V tomto pˇrípadˇe nám staˇcí pouze vykonat pˇríkaz a nepotˇrebujeme získat odpovˇed’ od robota. V pˇrípadˇe zmˇeny rychlosti robot pouze pošle potvrzení, protože používáme asynchronní komunikaci, toto potvrzení bude zpracováno automaticky. Pokud ovšem chceme i odpovˇed’, tak se pˇríkaz skládá ze dvou kroku: ˚
20
# Ask for the values of proximity sensors
21
sensor_request = controller.get_proximity_sensors()
22
# Wait until the robot returns them.
23
sensor_values = sensor_request.get_response()
Nejprve pošleme pˇríkaz a uložíme si návratovou hodnotu. Ta reprezentuje odpovˇed’, která pˇrijde na zaslaný pˇríkaz. Druhým krokem pak je získání této odpovˇedi. Když už jsme získali nˇejaké data od robota, mužeme ˚ pˇristoupit k jejich zpracování (v tomto pˇrípadˇe to jsou hodnoty z IR senzoru): ˚
27 28
while (sensor_values[’L10’] < threshold) \ and (sensor_values[’R10’] < threshold):
Kontrolujeme zde, zda-li robot nestojí pˇred pˇrekážkou. Bližší popis je v dokumentaci metod. V pˇrípadˇe, že pˇred robotem nic není, mužeme ˚ program na chvíli uspat, zatímco se robot posune o kus dál a my mužeme ˚ znova zkontrolovat senzory:
29
# Wait for a while
30
time.sleep(0.1)
31
# Read new values
32
sensor_request = controller.get_proximity_sensors()
33
sensor_values = sensor_request.get_response()
29
Vzhledem k tomu, že kontrola probíhá v nekoneˇcné smyˇcce tak krátká pauza slouží k nevytˇežování procesoru PC na 100% a k zabránˇení zahlcení robota pˇríkazy. Pokud narazí robot na pˇrekážku, tak jediné, co mu zbývá pˇred koncem programu, je zastavit motory:
36
controller.set_speed(0, 0)
3.2.2
Synchronní verze
Nyní si ukážeme, jak by vypadal stejný program napsaný synchronnˇe (zdrojový kód 3.10).
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3 4
"""Go forward, stop in front of an obstacle."""
5 6
import time
7 8
from epuck import Controller
9 10
# Input larger than the threshold means there is an obstacle.
11
threshold = 300
12 13
# Create the controller. Robot is connected to /dev/rfcomm0
14
# and the communication will be synchronous.
15
controller = Controller(’/dev/rfcomm0’, asynchronous=False)
16 17
# Set the speed of left and right wheel to 100.
18
controller.set_speed(100, 100)
19 20
# Ask for the values of proximity sensors
21
sensor_values = controller.get_proximity_sensors()
22 23
# Continue while there is nothing in front of the front left
24
# and front right sensor.
25
while (sensor_values[’L10’] < threshold) \
26
and (sensor_values[’R10’] < threshold):
27
# Wait for a while
30
28
time.sleep(0.1)
29
# Read new values
30
sensor_values = controller.get_proximity_sensors()
31 32
# Stop the robot
33
controller.set_speed(0, 0)
Zdrojový kód 3.10: Jednoduchý synchronní program pro ovládání robota
Prvním rozdílem je nastavení synchronní komunikace na rˇ ádku 15. Dále pak vždy pˇri získávání dat z robota mužeme ˚ vynechat jeden rˇ ádek a nechat pouze volání pˇríkazu, které rovnou vrací výsledek (ˇrádky 21 a 30). Další pˇríklady kontrolních programu˚ jsou k nalezení v kapitole 4.
31
4. Pˇríklady kontrolních programu˚ Velmi duležitou ˚ souˇcástí dokumentace knihovny je ukázka jejího použití pro vyˇrešení komplexního problému. Samotný popis jednotlivých metod vˇetšinou nestaˇcí uživateli k napsání vlastního programu. Je potˇreba pˇredvést jak se knihovna používá od vzniku programu až do jeho ukonˇcení. Zámˇerem této práce není pouze vytvoˇrit knihovnu pro ovládání robota, ale také pˇredvést k cˇ emu se dá robot použít a ukázat jak lze rˇ ešit nˇekteré cˇ asté úkoly. Proto v této kapitole bude k nalezení hned nˇekolik kompletních programu˚ demonstrujících vlastnosti e-puck robota a použití e-puck knihovny. Úˇcelem ukázkových programu˚ není uživatelum ˚ diktovat jakým zpusobem ˚ mají využívat knihovnu. Jde pouze o inspiraci. Jak bude vidˇet, tak nˇekteré ukázkové programy rˇ eší ovládání velmi odlišnˇe. Po pˇreˇctení by však kdokoli znalý programování mˇel být schopen velmi rychle napsat ovládací program dle svých pˇredstav.
4.1
Braitenberg Vehicle
Braitenberg vehicle je experiment provedený italsko-australským vˇedcem Valentinem Braitenbergem. Ve svých experimentech zkoumal evoluˇcní vývoj jednoduchých agentu˚ a senzoricko-motorické interakce mezi robotem a prostˇredím, bez potˇreby vnitˇrní pamˇeti nebo reprezentace prostˇredí. V elementární formˇe jsou senzory pˇrímo napojeny na akˇcní cˇ leny. Napˇríklad namˇerˇ ené hodnoty svˇetla na senzorech ovlivnují ˇ rychlost motoru. ˚ Robot pak muže ˚ vykazovat i pomocí triviálního programu na první pohled komplexní chování. Pokud má robot dva senzory a dvˇe kola a ty jsou spolu propojeny tak, že levý senzor zvyšuje rychlost levého kola se zvyšující se intenzitou a naopak pravý senzor zvyšuje rychlost pravého kola se snižující se intenzitou, pak robot muže ˚ vykazovat komplexní chování ve chvíli, kdy bude kroužit okolo zdroje svˇetla.
4.1.1
Zdrojový kód
Ukážeme si trochu komplikovanˇejší program, který se, v závislosti na senzorech pˇrekážek, snaží s robotem uhýbat pˇrekážkám. Program je o nˇeco delší, protože je potˇreba normalizovat hodnoty na vstupech a upravit podle nich rychlost motoru. ˚
32
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3 4
import time
5
import signal
6
import sys
7 8
from epuck import Controller, WrongCommand
9 10
c = Controller(’/dev/rfcomm0’, asynchronous=True)
11 12
bias = 200
13
too_close = 2000
14
max_speed = 1000
15
min_speed = -1000
16 17
# Signal handler to cleanup after shutdown
18
def handle_signal(signum, frame):
19
r = c.set_speed(0,0)
20
r.join()
21
sys.exit(0)
22 23
# SIGINT is interrupt signal sent by CTRL+C
24
signal.signal(signal.SIGINT, handle_signal)
25 26
while True:
27
# Read values from proximity sensors
28
r = c.get_proximity_sensors()
29
r = r.get_response()
30 31
left_sensors = r[’L10’] + r[’L45’] + r[’L90’] + bias
32
right_sensors = r[’R10’] + r[’R45’] + r[’R90’] + bias
33 34 35 36 37
left_speed = left_sensors if right_sensors < too_close \ else -left_sensors right_speed = right_sensors if left_sensors < too_close \ else -right_sensors
38 39
if left_speed > max_speed: left_speed = max_speed
40
if left_speed < min_speed: left_speed = min_speed
41
if right_speed > max_speed: right_speed = max_speed
33
42
if right_speed < min_speed: right_speed = min_speed
43 44
try: c.set_speed(left_speed, right_speed)
45 46
except WrongCommand: pass
47 48 49
time.sleep(0.1)
Zdrojový kód 4.11: Program pro robota, který se snaží vyhýbat pˇrekážkám.
4.1.2
Vysvˇetlení programu
Rozebereme si nyní program. Je tˇreba pˇredeslat, že struktura programu je velmi jednoduchá. Použít pro ovládání robota nekoneˇcnou smyˇcku je tradiˇcní rˇ ešení, mˇel by ovšem existovat zpusob, ˚ jak robota zastavit. Tady se jedná o interaktivní rˇ ešení, kdy robota muže ˚ zastavit uživatel zasláním pˇrerušení SIGINT (zmáˇcknutí CTRL + C). Ve zdrojovém kódu 4.12 vytváˇríme metodu handle_signal, která zastaví robota a ukonˇcí program. Pˇríkaz pro zastavení je pˇredán pomocí systémových pˇrerušení zaslaných ovládacímu programu. 17
# Signal handler to cleanup after shutdown
18
def handle_signal(signum, frame):
19
r = c.set_speed(0,0)
20
r.join()
21
sys.exit(0)
22 23
# SIGINT is interrupt signal sent by CTRL+C
24
signal.signal(signal.SIGINT, handle_signal)
Zdrojový kód 4.12: Zpracování pˇrerušení Dále následuje nekoneˇcná smyˇcka a v ní na prvním místˇe naˇctení hodnot ze senzoru˚ (zdrojový kód 4.13). Všechen další kód je závislý na datech ze senzoru˚ pˇrekážek. Pro jednodušší práci jsou data rozdˇelena podle strany robota, na které leží senzor, levá nebo pravá. K obˇema hodnotám senzoru˚ je pˇriˇctena promˇenná bias. Jejím posláním je posunout hodnoty senzoru˚ v místˇe bez pˇrekážek od nuly, protože rychlost robota bude pˇrímo záviset na tˇechto hodnotách a v místech bez podnˇetu˚ pro senzory by robot uvázl. 34
26
while True:
27
# Read values from proximity sensors
28
r = c.get_proximity_sensors()
29
r = r.get_response()
30 31
left_sensors = r[’L10’] + r[’L45’] + r[’L90’] + bias
32
right_sensors = r[’R10’] + r[’R45’] + r[’R90’] + bias
Zdrojový kód 4.13: Naˇctení a normalizování hodnot ze senzoru˚ Namˇerˇ ené hodnoty ze senzoru˚ projdou už jen velmi drobnými úpravami (zdrojový kód 4.14), veskrze jde hlavnˇe o jejich normalizaci pro použití jako argument pˇríkazu pro zmˇenu rychlosti robota. V pˇrípadˇe, že pˇrekážka je pˇríliš blízko robota a tak by nebyl schopen se jí vyhnout (nebo je pˇrímo pˇred ním), jedna rychlost zmˇení znaménko a robot se tak zaˇcne otáˇcet na místˇe jako tank. left_speed = left_sensors if right_sensors < too_close \
34
else -left_sensors
35
right_speed = right_sensors if left_sensors < too_close \
36
else -right_sensors
37 38 39
if left_speed > max_speed: left_speed = max_speed
40
if left_speed < min_speed: left_speed = min_speed
41
if right_speed > max_speed: right_speed = max_speed
42
if right_speed < min_speed: right_speed = min_speed
Zdrojový kód 4.14: Normalizace vstupu˚ ze senzoru˚ Nakonec už je pouze robotovi zaslán pˇríkaz pro zmˇenu rychlosti, dojde k malé pauze, aby ovládací program nevytˇežoval PC a cyklus se opakuje. Pauza zapˇríˇcinuje. ˇ že bude provedeno v prumˇ ˚ eru 7 iterací cyklu za jednu sekundu. Pokud ji odstraníme, tak nedojde k zlepšení chování robota, pˇrekážku uvidí ve velmi podobné vzdálenosti, ovšem bude provedeno v prumˇ ˚ eru 39 iterací. Což je dohromady 78 pˇríkazu˚ poslaných robotovi za sekundu a dále samozˇrejmˇe logika programu v Pythonu.
4.2
Ovládání LED
Robot disponuje osmi diodami. Ukážeme si program, který umí z diod vytvárˇ et nˇekolik svˇetelných efektu. ˚ V tomto pˇrípadˇe je nejzajímavˇejší zpusob, ˚ jakým 35
je koncipován ovládací program a také možnost pˇrepínaˇcem na robotovi nastavit specifický podprogram. Ovládací program je reprezentován tˇrídou Disco. Provádí dvˇe vˇeci: • posílá pˇríkazy pro ovládání diod dle zvoleného efektu, • kontroluje asynchronnˇe hodnotu na hardwarovém pˇrepínaˇci na robotovi a mˇení podle ní efekt. Program konˇcí v pˇrípadˇe, že na hardwarovém pˇrepínaˇci je speciální hodnota (pˇrepínaˇc má 16 poloh, poslední je vyhrazena pro vypnutí robota).
4.2.1
Zdrojový kód
1
#!/usr/bin/python
2
# -*- coding: utf-8 -*-
3 4
import time
5 6
from epuck import Controller, WrongCommand
7 8 9
class Disco(object): """Test leds.
10 11
Tests a few effects with leds.
12
The effect can be changed by turning selector.
13 14
Turning selector values:
15
0 -- Two rotating lights.
16
1 -- Two rotating light in opposite directions.
17
2 -- Blinking front led.
18
15 -- Turn the effects off.
19 20
"""
21
def __init__(self):
22
logging.basicConfig(level=logging.WARNING)
23
self.c = Controller(’/dev/rfcomm0’, asynchronous=True)
24
self.state_request = None
25
# Get first state
26
self.state = self.c.get_turning_selector() \
27
.get_response()
28
36
29
def init_vars(self):
30
"""Initialize vars used for effects."""
31
self.prev_i, self.i = 0, 0
32
self.prev_j, self.j = 4, 4
33 34
def init_state(self):
35
"""Initialize state."""
36
self.init_vars()
37
# Turn off all leds
38
self.c.stop()
39
self.c.set_front_led(0)
40 41
def get_state(self):
42
"""Get the value of turning selector."""
43
# The get_state has been called for the first time
44
if self.state_request is None:
45
self.state_request = self.c.get_turning_selector()
46
# The response has been received
47
elif self.state_request.response_received():
48
new_state = self.state_request.get_response()
49
# New state
50
if new_state != self.state:
51
self.state = new_state
52
self.init_state()
53
# Check the turning selector
54
self.state_request = self.c.get_turning_selector()
55 56
def run(self):
57
"""Do a step in the chosen effect."""
58
if self.state == 0 or self.state == 1:
59
self.c.set_led(self.prev_i, 0)
60
self.c.set_led(self.i, 1)
61
self.c.set_led(self.prev_j, 0)
62
self.c.set_led(self.j, 1)
63 64
elif self.state == 2: self.c.set_front_led(self.i)
65 66
def update(self):
67
"""Update the vars used for chosen effect."""
68
if self.state == 0:
69
self.prev_i = self.i
37
70
self.prev_j = self.j
71
self.i = (self.i + 1) % 8
72
self.j = (self.j + 1) % 8 if self.state == 1:
73 74
self.prev_i = self.i
75
self.prev_j = self.j
76
self.i = (self.i + 1) % 8
77
self.j = (self.j - 1) % 8 elif self.state == 2:
78
self.i = 0 if self.i else 1
79 80 81
def main_loop(self):
82
"""Main loop."""
83
self.init_vars()
84
while self.state != 15:
85
# Update the state.
86
self.get_state()
87
# Do a step in the effect.
88
self.run()
89
# Update the effect.
90
self.update()
91
# Wait.
92
time.sleep(0.1)
93 94
# Turn off all leds.
95
self.init_state()
96 97
d = Disco()
98
d.main_loop()
Zdrojový kód 4.15: Program pro vytváˇrení efektu˚ s LED a využití hardwarového pˇrepínaˇce
4.2.2
Vysvˇetlení programu
Program se chová jako stavový automat. Po startu se nachází ve stavu 0 (pˇrepínaˇc ukazuje na cˇ ernou teˇcku), kdy na zaˇcátku svítí dvˇe diody naproti sobˇe na obvodu robota a diody se pak rozsvˇecují a zhasínají, takže ve výsledku se zdá, že svˇetla obíhají dokola, okolo robota. Ve chvíli, kdy uživatel otoˇcí pˇrepínaˇc po smˇeru hodinových ruˇciˇcek, do polohy 1, dojde k zmˇenˇe stavu. Opˇet na zaˇcátku budou svítit dvˇe diody naproti 38
sobˇe, ale svˇetla se budou pohybovat proti sobˇe. V dalším stavu robot bliká pˇrední diodou. To jsou tedy tˇri efekty, které jsou v programu zabudované. Pro pˇridání dalších staˇcí upravit nˇekolik metod: • run – je potˇreba dopsat akci, která se má stát pˇri každém kroku algoritmu, • update – dochází k zmˇenˇe hodnot pro další krok. Nejzajímavˇejší z hlediska práce s robotem je metoda get_state (zdrojový kód 4.16). Metoda kontroluje, zda-li došlo ke zmˇenˇe stavu. Po zavolání pˇríkazu get_turning_selector ovšem neˇceká na odpovˇed’. Místo toho jen zkontroluje, zda-li odpovˇed’ už došla. Pokud nedošla, tak metoda konˇcí a pˇri dalším zavolání také jen kontroluje, zda již nedorazila odpovˇed’. Po získání nového stavu dojde k patˇriˇcné zmˇenˇe a opˇet, jako na zaˇcátku, bude zaslán pˇríkaz get_turning_selector. def get_state(self):
41 42
"""Get the value of turning selector."""
43
# The get_state has been called for the first time
44
if self.state_request is None: self.state_request = self.c.get_turning_selector()
45 46
# The response has been received
47
elif self.state_request.response_received():
48
new_state = self.state_request.get_response()
49
# New state
50
if new_state != self.state:
51
self.state = new_state
52
self.init_state()
53
# Check the turning selector
54
self.state_request = self.c.get_turning_selector()
Zdrojový kód 4.16: Získání nového stavu
4.3
Detekce obliˇceje
Jednou z velkých výhod e-puck knihovny je jednoduchá integrace s jinými knihovnami. Ukážeme si program, který integruje dokonce dvˇe knihovny naráz. První z nich je knihovna Tkinter, jednoduchá knihovna pro vytváˇrení grafického rozhraní, která se dodává s Pythonem. Druhou použitou knihovnou je OpenCV, knihovna pro poˇcítaˇcové vidˇení (Computer Vision). Využijeme je pro 39
vytvoˇrení grafické aplikace, která zobrazuje aktuální obrázek z kamery robota a vyznaˇcuje nalezené obliˇceje.
Obrázek 4.17: Detekce obliˇceju˚ v praxi Algoritmus pro hledání obliˇceju˚ je použit z knihovny OpenCV a tedy není zámˇerem této kapitoly vysvˇetlovat jej. Byl pouze využit pro ukázku možností e-puck knihovny.
4.3.1
Zdrojový kód
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3 4
import time
5 6 7
from Tkinter import * from ImageTk import PhotoImage
8 9
import cv
10
import ImageDraw
11
import Image as Img
12 13
from epuck.controller import Controller
14 15
c = Controller(’/dev/rfcomm0’, timeout=5, asynchronous=True)
16 17
# Set camera properties
18
c.set_front_led(1)
19
c.set_camera(Controller.GREYSCALE_MODE, 55, 55, 8)
20 21
# Create the application layout
22
root = Tk()
23
img_face = Label(root)
40
24
img_face.pack()
25 26
# Load face definitions
27
cascade = cv.Load(’haarcascade_frontalface_alt.xml’)
28 29
def show_photo():
30
# Get the photo
31
img = c.get_photo() \
32
.get_response() \
33
.resize((100, 100), Img.ANTIALIAS)
34 35
# Convert the photo for OpenCV
36
cv_img = cv.CreateImageHeader(img.size, cv.IPL_DEPTH_8U, 1)
37
cv.SetData(cv_img, img.tostring())
38 39
# Find any faces in the image
40
storage = cv.CreateMemStorage(0)
41
cv.EqualizeHist(cv_img, cv_img)
42
faces = cv.HaarDetectObjects(cv_img,
43
cascade,
44
storage,
45
1.2, 2,
46
cv.CV_HAAR_DO_CANNY_PRUNING)
47 48 49
if faces: for f in faces:
50
# Draw a border around a found face.
51
draw = ImageDraw.Draw(img)
52
draw.setfill(0)
53
draw.rectangle([(f[0][0], f[0][1]),
54
(f[0][0] + f[0][2],
55
f[0][1] + f[0][3])])
56 57 58
# Show the image with faces
59
image = PhotoImage(img)
60
img_face.config(image=image)
61
img_face.img = image
62 63
# Run this function again in 10ms
64
img_face.after(10, show_photo)
41
65 66
# Get first photo and run the main loop
67
show_photo()
68
root.mainloop()
Zdrojový kód 4.18: Grafická aplikace pro detekci obliˇceju˚
4.3.2
Vysvˇetlení programu
Program se skládá z nˇekolika cˇ ástí, které využívají jednotlivé knihovny, na zaˇcátku (zdrojový kód 4.19) je tˇreba nastavit kameru robota. Pro detekci oblicˇ eju˚ se používá cˇ ernobílých fotek, takže bylo možné zvˇetšit velikost fotografie. Dále je nutné vytvoˇrit grafické okno pomocí knihovny Tkinter a naˇcíst data pro knihovnu OpenCV, která používá pro detekci obliˇceju. ˚ 17 18 19
# Set camera properties c.set_front_led(1) c.set_camera(Controller.GREYSCALE_MODE, 55, 55, 8)
20 21 22 23 24
# Create the application layout root = Tk() img_face = Label(root) img_face.pack()
25 26 27
# Load face definitions cascade = cv.Load(’haarcascade_frontalface_alt.xml’)
Zdrojový kód 4.19: Nastavení kamery a vytvoˇrení okna Hlavní cˇ ást je ve funkci show_photo, která je pravidelnˇe volána hlavní smyˇckou knihovny Tkinter. V ní pak dochází k zpracování a zobrazení obrázku z robota. Nejprve (zdrojový kód 4.20) je získána fotka, ta je následnˇe zvˇetšena pro lepší prohlížení. 29 30 31 32 33
def show_photo(): # Get the photo img = c.get_photo() \ .get_response() \ .resize((100, 100), Img.ANTIALIAS)
Zdrojový kód 4.20: Získání fotografie a její zvˇetšení Výsledek je pˇreveden do formátu obrázku˚ pro OpenCV. Dále je zavolán algoritmus pro detekci obliˇceju, ˚ nalezené obliˇceje jsou zakresleny do fotky (zdrojový kód 4.21). 42
35 36 37
# Convert the photo for OpenCV cv_img = cv.CreateImageHeader(img.size, cv.IPL_DEPTH_8U, 1) cv.SetData(cv_img, img.tostring())
38 39 40 41 42 43 44 45 46
# Find any faces in the image storage = cv.CreateMemStorage(0) cv.EqualizeHist(cv_img, cv_img) faces = cv.HaarDetectObjects(cv_img, cascade, storage, 1.2, 2, cv.CV_HAAR_DO_CANNY_PRUNING)
47 48 49 50 51 52 53 54 55 56
if faces: for f in faces: # Draw a border around a found face. draw = ImageDraw.Draw(img) draw.setfill(0) draw.rectangle([(f[0][0], f[0][1]), (f[0][0] + f[0][2], f[0][1] + f[0][3])])
Zdrojový kód 4.21: Zpracování fotky pomocí OpenCV Nakonec už je fotka naposledy pˇrevedena, tentokrát do formátu pro Tkinter, a zobrazena (4.22). Funkce after slouží k periodickému volání metody show_photo každých 10ms. Díky tomu by se mˇel obraz aktualizovat témˇerˇ v reálném cˇ ase (samozˇrejmˇe je snímání fotky v robotovi znatelné na cˇ asové prodlevˇe). 58 59 60 61
# Show the image with faces image = PhotoImage(img) img_face.config(image=image) img_face.img = image
62 63 64
# Run this function again in 10ms img_face.after(10, show_photo)
Zdrojový kód 4.22: Pˇrevedení a zobrazeni fotky pomocí Tkinter
43
Závˇer Ve své práci jsem splnil všechny cíle, které jsem si vytyˇcil. Vznikla knihovna, která je intuitivní, umožnuje ˇ rychlé prototypování ovládacích programu˚ nebo interaktivní ovládání robota z interpretu. Na druhou stranu knihovna nabízí i podporu pro vytváˇrení robustních aplikací, kde se mužeme ˚ spolehnout, že každý zaslaný pˇríkaz bude proveden. Uživatel dostává možnost si vybrat mezi transparentní synchronní komunikací, nebo asynchronní komunikací, u které nemusí cˇ ekat na pˇrijetí odpovˇedi. Tady se jedná o velkou výhodu pro vytváˇrení aplikací, které mohou pracovat s došlými daty, zatímco cˇ ekají na další, nebo jde pouze o interaktivitu aplikace, kde není pˇrípustné, aby docházelo k prodlevám, zatímco program cˇ eká na odpovˇed’. Dalším úspˇechem je pˇrepracování firmware BTcom, napsaného v jazyku C a nahrávaného pˇrímo do robota, který je standardnˇe dodáván s e-puck robotem. S novou verzí BTcomDM je možné velmi pˇresnˇe párovat zaslané pˇríkazy a došlé odpovˇedi. Díky provedeným zmˇenám bylo možné vytvoˇrit kontrolní mechanismy zabranující ˇ ztrátˇe pˇríkazu. ˚ Každý pˇríkaz má nyní danou cˇ asovou lhutu, ˚ do které musí dojít odpovˇed’, jinak je považován za ztracený a odeslán znova. Pokusil jsem se i vyˇrešit nˇekteré základní problémy, které provázejí e-puck robota. Situaci, kdy robot pˇrestává reagovat, protože mu dochází baterie, byla vyˇrešena optickou signalizací. Jedná se na první pohled o drobnou zmˇenu, ovšem pro programování robota jde o neocenitelnou pomucku. ˚ Obzvlášt’ když si student robota pujˇ ˚ cuje v poˇcítaˇcové laboratoˇri a tak si nikdy nemuže ˚ být jistý, kdy byl naposledy dobíjen. Pro uživatele knihoven neexistuje nic horšího, než když mají dokumentaci jednotlivých metod, ale nedoˇctou se jak tyto spojit dohromady a vytvoˇrit tak ucelený program. Proto jsem jako souˇcást práce napsal nˇekolik ukázkových programu, ˚ které ukazují jak snadné je knihovnu používat a integrovat s jinými knihovnami. Ovládání robota jde triviálnˇe propojit s grafickým rozhraním pomocí knihovny Tkinter, s fotkami získanými z kamery robota jde pracovat pomocí Python Imaging Library (PIL) a díky tomu je možné použít libovolnou knihovnu pro práci s obrázky (napˇr. OpenCV pro poˇcítaˇcové vidˇení). Provedl jsem mˇerˇ ení rychlosti knihovny. Zjistil jsem, že možný poˇcet pˇredaných pˇríkazu˚ za sekundu záleží na složitosti pˇríkazu. Pro jednoduché pˇríkazy bylo dosaženo rychlosti okolo 40 pˇríkazu˚ za sekundu. Za dostateˇcnou se považuje rychlost pˇres 10 pˇríkazu˚ za sekundu a tedy e-puck knihovna v tomto
44
ohledu obstála bez problému. ˚ I pˇres pˇridané ovˇerˇ ovací podprogramy je rychlost nadprumˇ ˚ erná, což ukazuje, že knihovna je dobˇre použitelná. Možnosti dalšího rozvoje knihovny jsou v oblasti integrace se simulátory. Obˇcas je výhodnˇejší testovat nejprve kód v simulátoru a teprve pak jej pˇrenést do robota. Nabízí se možnost pˇrepsat komunikaˇcní vrstvu knihovny tak, aby pˇríkazy neodesílala do robota, ale pˇrevádˇela je na pˇríkazy pro simulátor. Další možností je nad knihovnou postavit vyšší vrstu, která ji bude používat pro ovládání e-puck robota. Napˇríklad projekt Pyro má jednotné rozhraní pro ovládání všech podporovaných robotu, ˚ ale e-puck zatím podporován není.
45
Pˇrílohy Pˇriložené CD Na pˇriloženém CD jsou k nalezení: • zdrojové kódy epuck knihovny, • zdrojové kódy a zkompilovaná verze firmware BTcomDM, • dokumentace epuck knihovny, • ukázkové pˇríklady kontrolních programu, ˚ • elektronická verze bakaláˇrské práce, • videa s ukázkami chování robota.
46
Literatura [1] Adept MobileRobots: http://www.mobilerobots.com/researchrobots/ ResearchRobots.aspx. [2] AIBO: http://support.sony-europe.com/aibo/. [3] E-puck bootloader for Linux: http://svn.gna.org/viewcvs/e-puck/trunk/tool/ bootloader/computer_side/multi_platform/. [4] E-Puck Education Robot: http://www.e-puck.org. [5] Evorobot*: http://laral.istc.cnr.it/evorobotstar/. [6] iRobot: http://www.irobot.com/. [7] K-Team Mobile Robotics: http://www.k-team.com/. [8] Kumar, D. (editor): Learning Computing with Robots. Institute for Personal Robots in Education, 2007. [9] Michel, O.; Rohrer, F.; Heiniger, N.: Cyberbotics’ Robot Curriculum. http://en.wikibooks.org/wiki/Cyberbotics%27_Robot_ Curriculum, Naposledy navštíveno 19. 5. 2011. [10] Mondada, F.; Bonani, M.; Raemy, X.; aj.: The e-puck, a Robot Designed for Education in Engineering. Proceedings of the 9th Conference on Autonomous Robot Systems and Competitions, 2009: s. 59–65. [11] Pyro: http://pyrorobotics.org. [12] pySerial: http://pyserial.sourceforge.net/. [13] Python Package Index: http://pypi.python.org/pypi. [14] RoboCup: http://www.robocup.org/. [15] Russell, S. J.; Norvig, P.: Artificial Intelligence: A Modern Approach. Prentice Hall, 2002. [16] Scribbler: http://www.parallax.com/tabid/455/Default.aspx. [17] Webots: http://www.cyberbotics.com. Commercial Mobile Robot Simulation Software. [18] Wikibooks: http://en.wikibooks.org/. 47