czech english

Daisy

čvrtfinalistka Eurobota 2003

Daisy byl alternativní robot připravovaný na soutěž Eurobot 2003. Daisy byla řádově jednodušší než její sestra Dana a to se opět v soutěži ukázalo jako velké plus. V celosvětové konkurenci dosáhla velmi dobrého sedmého místa.


Základní informace

Daisy byla postavena na trojúhelníkovém podvozku z Berty. Použity byly i stejné motory s převodovkami 20:1 a enkodery z počítačových myší. Řídící desku nahradila jednodušší verze postavená okolo mikrokontroleru AVR AT90S8535, který se již osvědčil u Aleny hlavně díky dosažitelnosti a poměru cena/výkon. Inteligenci pak zajišťoval iPAQ s operačním systémem WinCE. Obracečka, dvoj-kuše a veškeré další konstrukce byly vyrobeny z Merkuru, kde jednotlivými díly pohybovala čtyři serva.

Mechanika

Základní trojúhelník, který je zcela totožný s robotem Berta, rozšířila konstrukce z Merkuru. Pravidla soutěže omezovala obvod robota (přesněji konvexního obalu průmětu do roviny) na 120cm. Jelikož trojúhelníková konstrukce již zabírala 90cm, nezbylo příliš prostoru pro experimentování. Nakonec byl použit tvar kosočtverce, který měl co největší záběr.
Jádro obracecího mechanismu tvořila ruka ve tvaru L se dvěma stupni volnosti. To umožňovalo buď puk převrátit, pokud nahoře měl špatnou barvu nebo propustit, pokud byla správná. Robot se tedy při manipulaci s puky nemusel zastavovat a couvat. Jelikož L-ruka byla dost křehká, byla okolo postavena ochranná kostra. Vedle této ochrany řešila i shazování puků a jejich ideální nasměrování do L-ruky.
Z levé strany (tento robot měl směr dopředu totožný se špičkou trojúhelníka) pak ještě byla malá ochrana proti zasekávání puků pod kolečka a zároveň jejich shazování. V neposlední řadě tato konstrukce chránila i senzor Sharp GP2D120, který byl namontován uprostřed robota a koukal směrem vlevo.
Další výztuž tvořila kolébka pro kapesní počítač iPAQ, která byla připevněna k povinnému stožárku na majáček nepřítele. V posledním týdnu ještě vznikla dvouhlavňová kuše, umožňující sestřelit ping-pongovými míčky jednobarevné puky. Kuše s dosahem 5-10m byla z důvodů šetření servy vybavena dvoustupňovým kohoutkem.

Řídící hardware

Elektronika robota se skládala z několika oddělených částí. Jádrem byla deska postavená okolo mikrokontroleru AVR AT90S8535. Tento čip lze taktovat na 8MHz, má 8kB programovatelné paměti (flash), 512 bajtů SRAM a 512 bajtů EEPROM. K dispozici je osm A/D převodníků s rozlišením 10bitů, tři časovače včetně dvou PWM, 32 digitálních I/O. Čip lze snadno programovat přes paralelní port, stejně jako AT90S4433 v článku Jak programátor k robotovi přišel. Cena čipu je okolo 200Kč, tj. rozumná .
Základní deska má především vyvedeny skoro všechny dostupné piny. Některé jsou připojeny přes odpor k LEDkám, jiné přes komparátor s nastavitelnými trimry. Vše je připojené pomocí jumperů, takže danou LEDku či komparátor není nutné použít. Šest digitálních výstupů je vyvedeno na trojkonektory <zem, externích +5V, I/O pin>, pro snadné připojení serv. Konečně všechny analogové vstupy mají podobnou konfiguraci <zem, +5V, analogový vstup>, takže na připojení analogového senzoru stačí zase jenom trojkonektor.
Základní deska obsahuje patici na H-můstek L293D na řízení motorů. Pro silnější motory, což byl případ Daisy, je třeba přepojit konektory k externímu můstku. Na Daisy byl použit můstek MOST2x25.
K základní desce přibylo ještě mnoho malých přídavných destiček. Jednak to byla deska s MAX232 na seriovou komunikaci s PC, různé filtry na vyhlazení signálu ze Sharpů, destička na enkodery s LEDkami (ta byla přímo použita z Berty), destička na ovládání světelných závor.

Senzory

Zpočátku měla Daisy pouze několik senzorů CNY70 na detekci černé a bílé. Dva byly zabudovány v ruce, jeden směrem nahoru a druhý dolů, kde z jejich rozdílu se dedukovala výsledná barva puku (všechny dvoubarevné puky měly uvnitř jednu stranu černou a druhou bílou). Dalších X CNYček (původně 3, pak 5 a v závěru 4) bylo použito pro navigaci na detekci barvy podlahy.
Druhým typem senzorů byly dva Sharpy GP2D120 s dosahem zhruba 80cm a minimální vzdáleností 8cm. Protože generovaný signál senzoru byl modulován 1kHz a tato modulace se promítla i do výstupního napětí, bylo třeba mezi základní desku a senzor ještě přidat vyhlazovací filtr. V konečné konfiguraci byl jeden Sharp namontován uprostřed robota s výhledem vlevo (směr dán špičkou trojúhelníku) a druhý na servo, které bylo přiděláno na podpěře pro nepřátelský majáček.
Digitální vstupy byly nakonec využity pouze dva - jeden pro startovní kabel a druhý pro světelnou závoru detekce puku v ruce. Zapojena byla sice ještě druhá závora detekující vstupující puk do přední „brány” a tlačítko kolize pravého sloupku, ale tuto informaci software nakonec nijak nevyužil.
Mezi senzory by asi taky patřily dva enkodéry udělané z myší měřící směr a ujetou vzdálenost jednotlivých koleček. Ty byly totožné s robotem Berta.

PC

„Mozek” Daisy dělal kapesní počítač iPAQ běžící pod operačním systémem WinCE. Tento počítač komunikoval se základní deskou po seriové lince rychlosti 36400baud a zajišťoval veškeré rozhodování. Tato konfigurace se ukázala býti velice šťastnou. Program bylo možné psát přímo v C++ a kompilovat na standardním PC nebo notebooku. Přes seriovou linku se dal přímo krokovat případně snadno zkoušet různá nastavení. V okamžiku, kdy již byl trošku stabilní, tak stačilo prohodit kabel a ten samý program zkompilovat pro iPAQ. Ve většině případů tak už hned běžel v pořádku a nebylo třeba dalších zásahů.
Je třeba zmínit několik rozdílů, které nám trošku ztěžovaly život:
  1. kompilátor pro iPAQ nepodporoval šablony a vyjímky v C++
  2. na iPAQu dostanete různé výsledky pokud počítáte s float resp. double aritmetikou, zatím co notebook vždy počítal v double
  3. náš program nepodporoval textový výstup na obrazovku
  4. iPAQ má taktovací frekvenci 200MHz, což je o něco méně než běžné PC a aritmetika s plovoucí čárkou je implementovaná softwarovou emulací

Software

Základní deska

Program pro řídící desku byl psán v Céčku. Použili jsme osvědčenou techniku přístupu ke všem potřebným low level parametrům, které u Daisy byly následující:  výstup z iPAQu=(PWM pro levý a pravý motor, nastavení pozice serv, watch dog, digitální výstupy) a vstupy do iPAQu=(stav časovače, stav enkoderů, digitální vstupy, analogové vstupy). Komunikace byla bloková, kde základní deska byla slave a iPAQ byl master. Každý blok byl navíc jištěn jednoduchým kontrolním součtem. AVRko mělo za úkol pouze realizovat dané příkazy a číst aktuální hodnoty. Jedinou věc, kterou mohlo AVRko udělat bez povolení masteru, bylo vypnutí motorů pokud uplynula doba nastavená v parametru watch dog. Toto bylo velmi užitečné, když se např. vytrhnul kabel, nebo se program zaseknul.

Simulace, realita, log…

Software na iPAQu byl „o něco” složitější. Vyrůstal postupně metodou zdola nahoru, takže první část, která byla implementovaná, bylo schování komunikace se základní deskou. To umožnovala třída AbstractHardware, která měla úplně stejné parametry jako struktura posílaná po seriové lince tam a zpět. Navíc měla pouze čistě virtuální funkci synchronize. Asi by nebylo rozumné se zabývat více detaily, tak spíše k čemu to bylo dobré. Jednoduchým způsobem se pak celému programu podstrčilo cosi, co již tento interface mělo – mohla to být třída na komunikaci s AVRkem, ale stejně tak to mohl být jednoduchý simulátor nebo čtení z logu.
Tuto trojici, simulace, skutečný běh a čtení z logu, považuji za tak důležitou, že jsem se rozhodl tomu věnovat celý odstavec. Proč? Ok, když úplně začínáte, tak nic nemáte a nebo to vůbec nefunguje. Je třeba se ujistit, že chyba není v software a tak ho pustíte se simulátorem. Teď nemám na mysli žádný softwarový balík za několik tisíc dolarů, ale dvojřádkový kód, který na požadovaný PWM výstup změní hodnotu enkoderů daným směrem. To je vše. Pokud chcete něco lepšího, tak si můžete v simulátoru počítat i pozici a tu posléze nakreslit. Pokud Vám řídící program posílá nějaké nesmysly, tak to zachytíte jednoduchým krokováním.
Když simulace funguje, tak to zkusíte naostro. Teď by se už nemělo stát, že robot vyrazí opačným směrem a ublíží si o topení. Pokud k tomu však dojde, tak máte chybu v simulátoru a cyklus se opakuje. Je dobré se ujistit, že robot opravdu dostává ty příkazy, o kterých si myslíte, že mu posíláte. K tomu slouží log-file. Další klíčová věc — jméno log-file generujte automaticky. Jenom tak se Vám nestane, že si přepíšete předešlý log. Dále ho generujte vždy! To, co se vám stalo v realitě se už nemusí následujících x měsíců opakovat … říkáte, že to nevadí?! No vězte, že Murphy si vybere tu nejlepší příležitost, kdy Vám to zopakuje .
Tak konec kázaní – toto bylo jádro Daisy na které se dalo spolehnout. Řekl bych, že Daisy patří do kategorie RobotXP, kde tato trojice je asi jako unit testy v eXtreme Programming. K čemu to bylo dobré?
Robot divně pokulhával, ztrácel se až o jeden celý čtverec, ale pak se vzpamatoval.
Log ukázal, ze analogový vstup číslo 7 odpovídající CNYčku na detekci podlahy je neustále 255. CNYčko mělo utrženou nožičku a potřebovalo vyměnit. Toto se stalo asi dvě hodiny před odjezdem na Istrobota.
Daisy se chovala už pěkně a tak jsem udělal demo kamarádovi. Zatáhl za startovací kabel a robot sebou začal cukat a neustále narážel do krajních bočnic a během celých 90 sekund neopustil okolí startovní pozice.
Log vypadal rozumně, ale program běžící z dat z logu (tady bych zdůraznil, že se program běžící z logu musí chovat naprosto stejně, tj. na dané vstupy musí generovat naprosto stejné výstupy, jinak je to celé k ničemu – je dobré si tuto skutečnost ověřit a dát si pozor na problémy s náhodnými generátory, float vs. double, časování a pod.) hned po startu umístil robota do záporné pozice mimo hřiště. Chyba byla v inicializaci a projevila se pouze pokud trvalo dostatečně dlouho než jste od zapnutí programu vytáhli šňůrku a navíc v prvních 50ms jste do robota trošku strčili. Tato chyba se neprojevila několik měsíců a s logem trvalo její opravení pár sekund. Dovedete si představit jeji hledání bez logu?! Já ne.
Robot vyrazil, ale během celé jízdy neotočil jediný puk, přestože je detekoval. Odešel regulátor na serva nebo se pokazil program na desce, když jsme dvě serva rozšířili na čtyři?
Ano, zase log ukázal … že chyba byla v software a není tedy třeba koukat ani na regulátor ani kontrolovat jednotlivá zapojení. Serva zkrátka nedostala jediný příkaz se pohnout. Proč? Zase špatná inicializace modulu pro otáčení puků. Před hlavním programem jsem vždy pouštěl test hardware – tentokráte jsem to neudělal a tak se dostalo do proměnné m_lastTimeCmdChanged nesmyslně velké číslo a modul nemohl provést žádné další změny polohy ruky.
Stačí, nebo mám přidat ještě pár zkušeností s čidly Sharp, které vidí puky v libovolné vzdálenosti podle toho, jak se na ně podíváte…?

Strategie & moduly

Když základ funguje, tak je vše jednodušší. Když nefunguje, tak je třeba ho zjednoduššit a pak třeba začne fungovat. To je asi globální strategie, i když o té neměla být řeč. Příkladem může být ježdění po lomené čáře. Daisy jezdila pěkně, ale trošku do obloučků. Zkoušeli jsme různé typy řízení, ale v zatáčce jí to vždy rozhodilo a než se pořádně srovnala, tak už jela do další zatáčky. Řešení? Použili jsme to samé co Dana, která měla v zatáčkách problém se svlékáním (pásů). Prostě Daisy jezdila pouze rovně, a když chtěla zatočit, tak se nejprve otočila na místě, a pak zase jela rovně. Zde bylo daleko méně parametrů a po relativně krátkém čase to celkem dobře fungovalo.
Další softwarový balík převzatý od Dany bylo GMCL, modul pro navigaci pomocí CNYček. Pokud do robota nikdo neboural, tak tato metoda udržovala pozici robota +/- 5cm s chybou v úhlu asi do deseti stupňů. To stačilo na shazování puků, ale jak se později ukázalo, to bylo nedostatečně přesné na střílení.
Obracení puků a ježdění fungovalo nezávisle. Modul Flipper pouze sledoval, zda nebyl detekován puk, a když ano, tak podle barvy předal příkaz k převrácení či propustění puku. Mezi jednotlivými přikazy musely být 1-1.5s pauzy, aby serva stihla akce provést. Toto fungovalo velice dobře, pokud se robot pohyboval dopředu, ale selhávalo to v pravotočivých zatáčkách a při couvání. Na soutěž však tento základní koncept už měněn nebyl.
Plánování pohybu se vyvíjelo od pevně zadané cesty až po integraci mapy a střílení. Verze, která nakonec běžela na všech zápasech, měla tento program:
SeqEle seq[] = 
{
  SeqEle(SeqEle::GO_TO_WAYPOINT, 0.45, 0.45),
  SeqEle(SeqEle::GO_TO_WAYPOINT, 2.4, 0.45),
  SeqEle(SeqEle::ASK_MAP),
  SeqEle(SeqEle::GO_TO_WAYPOINT, 0.3, 0.6),

  SeqEle(SeqEle::GO_TO_WAYPOINT, 0.3, 1.05),
  SeqEle(SeqEle::RESET_MAP),
  SeqEle(SeqEle::GO_TO_WAYPOINT, 2.4, 1.05),
  SeqEle(SeqEle::ASK_MAP),
  SeqEle(SeqEle::GO_TO_WAYPOINT, 0.3, 1.05),

  SeqEle(SeqEle::GO_TO_WAYPOINT, 0.3, 1.65),
  SeqEle(SeqEle::RESET_MAP),
  SeqEle(SeqEle::GO_TO_WAYPOINT, 2.4, 1.65),
  SeqEle(SeqEle::ASK_MAP),
  SeqEle(SeqEle::GO_TO_WAYPOINT, 0.3, 1.65),

  SeqEle(SeqEle::GO_TO_WAYPOINT, 0.9, 1.65),
  SeqEle(SeqEle::RESET_MAP),
  SeqEle(SeqEle::ASK_MAP),
  SeqEle(SeqEle::GO_TO_WAYPOINT, 0.9, 0.45),
  SeqEle(SeqEle::GO_TO_WAYPOINT, 0.9, 1.65),

  SeqEle(SeqEle::GO_TO_WAYPOINT, 1.5, 1.65),
  SeqEle(SeqEle::RESET_MAP),
  SeqEle(SeqEle::ASK_MAP),
  SeqEle(SeqEle::GO_TO_WAYPOINT, 1.5, 0.45),
  SeqEle(SeqEle::GO_TO_WAYPOINT, 1.5, 1.65),

  SeqEle(SeqEle::GO_TO_WAYPOINT, 2.1, 1.65),
  SeqEle(SeqEle::RESET_MAP),
  SeqEle(SeqEle::ASK_MAP),
  SeqEle(SeqEle::GO_TO_WAYPOINT, 2.1, 0.45),
  SeqEle(SeqEle::GO_TO_WAYPOINT, 2.1, 1.65),

  SeqEle(SeqEle::GO_TO_WAYPOINT, 2.7, 1.65),
  SeqEle(SeqEle::RESET_MAP),
  SeqEle(SeqEle::ASK_MAP),
  SeqEle(SeqEle::GO_TO_WAYPOINT, 2.7, 0.45),
  SeqEle(SeqEle::GO_TO_WAYPOINT, 2.7, 1.65),
  SeqEle(SeqEle::RESET_MAP)
};
Robot měl vyjet ze startovní pozice (levý dolní roh měl souřadnice 0.0, 0.0) a jet směrem rovnoběžně s dlouhou stranou. Zároveň probíhalo mapování všech puků do vzdálenosti 60cm na levé straně. Příkaz ASK_MAP pak vygeneroval seznam nových cílů tak, aby Daisy vysbírala všechny puky po levé straně. Většinu jich totiž shodila, a tak již nebyly na původních pozicích.
Po vybrání prvních dvou řad pak Daisy nastoupila na třetí řadu, smazala si mapu (RESET_MAP) a postupovala stejným způsobem. Obdobně uklidila i pátou a šestou řadu. Tím jedno "šrafování" skončilo a přešla na uklízení v kolmém směru, tedy rovnoběžně s kratší stranou hřiště.

Detekce kolize

Právě popsaná strategie měla ještě integrovanou detekci kolize. Pokud horní Sharp uviděl druhého robota, jak překáží na cestě do aktuálního cíle (WAYPOINT), tak se tímto cílem již déle nezatěžoval a přešel na další cíl v tabulce. Stejný postup byl použit při detekci kolize pomocí virtuálního bumperu.
Pokrytí prostoru alespoň ve dvou směrech (v daném časovém limitu 90 sekund to Daisy pořádně ani nestíhala) mělo zásadní výhodu, že pokud se druhý robot zasekl např. u kraje první řady, tak část, kterou Daisy nenavštívila, byla následně doklizena ve druhém směru.

Slabiny a problémy

Detekce nepřátelského robota rozhodně nefungovala na 100%. Bylo by třeba si pamatoval minimálně poslední scan, protože servo naměřilo obzor 180 stupňů zrhuba za sekundu. Vedle nedostatku času nás od zasadních změn odrazovaly zkušenosti s dolním Sharpem na mapování puků. Tam se totiž ukázalo, že je bezpodmínečně nutné naskenovat celé puky a pak vybírat naměřená minima. Z jednoduchého měření nebylo možné určit, zda se jedná o puk ve vzdálenosti 60cm, nebo ve vzdálenosti 25cm, kdy vidíme pouze jeho okraj. Podobné problémy jsme očekávali při detekci druhého robota a na jejich analýzu už ve Francii zkrátka nedošlo.
Další výraznou slabinou bylo vzpamatování se z chyb lokalizace. Pokud do Daisy narazil silný a těžký robot a GMCL se ztratilo, tak pak se celá naplánovaná cesta stávala nerealizovatelnou. To se např. stalo v posledním zápase se Supaero, kdy po kolizi Daisy už pouze oťukávala jeden roh. Bylo potřeba jednak tuto situaci detekovat a dále začít jezdit bez znalosti pozice, nebo se dokázat samo-lokalizovat. Na detekci jsme měli vymyšlený a častečně o testovaný algoritmus, kdy pokud spodní Sharp nevidí žádnou překážku a zároveň by podle jeho pozice v mapě měl vidět bočnici stolu, tak se robot ztratil. To celkem fungovalo, ale neprošlo to dostatečným počtem testů, tak jsme to nakonec zrušili (také nebyla implementovaná náhodná jízda po hřišti, což byla velká chyba, takže by modul detekce jinak byl k ničemu).

Závěr

Daisy byl další z robotů kategorie RobotXP (tu jsem si sám vymyslel, tak jí v žádné encyklopedii nehledejte ), kterému se, s dostatkem štěstí, podařilo dosáhnout potenciálního životního maxima. Daisy zároveň patří mezi ty roboty, které si můžete udělat doma sami, takže Vás snad bude i trošku motivovat… .

Máte-li jakékoli dotazy či připomínky – kontaktujte nás. Rádi vám odpovíme.

Pošlete email redakci.
Všechny materiály, které máme k dispozici, jsou již součástí článku, na který reagujete (tj. pokud tam tedy není např. plánek na stavbu, je to proto, že nic takového nemáme).

Vaši zprávu se bohužel nepodařilo odeslat, ale můžete nám napsat sami na adresu

Vaše zpráva byla úspěšně odeslána

Pro odeslání formulář je třeba mít zapnutý javascript.