czech english

Field Robot 2012 - technologie

aneb co se na FRE vyzkoušelo?

Soutěž Field Robot Event letos byla celkem náročná, obzvláště Professional Task, kde měl robot autonomně lokalizovat vybranou růži, nabrat ji (podle zalití měl květináč s růží až 4kg) a dovézt ji zpět na start. Na přípravu jsme měli přesně měsíc, ale i tak jsme vyzkoušeli některé nové věci, o které se s vámi chceme podělit …

Hlavní článek o soutěži najdete zde, tady budeme probírat pouze technické detaily přípravy robota.
Jindy jsem se věnoval pouze programování, ale tentokrát jsem si trošku užil i mechaniky a elektroniky. Začal bych časovou osou, jak přípravy probíhaly:
  • 30. května — posílám mail, že následující den končí registrace. Všichni účast odmítnou, jenom Standa z ČZU píše, že by měl zájem. Později se přidává Milan, že by na soutěž dorazil z Británie.
  • 6. června — brainstorming se Standou ohledně nabíracího mechanismu. Závěr použít existující konstrukci ruky plánovanou na Robots Intellect, ale otočit ji o 90 stupňů do boku.
  • 13. června — Honza sehnal nový motor na ruku (vykuchaný, bez regulátoru). Přišel balíček vzorových květináčů pro nabírání. Tomáš si koupil pět RFID modulů na testování. Motor se netočí, příčinou je stará gelová baterka. Na zdroji při 12V motor jede a bere cca 2.5A. CAN modul pro servo má problém s konfirugací.
  • 15. června — poprvé v reálu používám modelářský regulátor. Na jednu stranu jede, ale na druhou ne. Tomáš mi osvěžuje paměť ohledně flashování CAN modulů (tu požadovanou konfiguraci tam přímo nastavíme).
  • 18. června — vyjasnění chování regulátoru na řízení motoru. Dřevěný prototyp protizávaží na ruku. PI regulátor na zvedání lehkých i těžkých předmětů, viz video (komentář: „Hodně zajímavá odrůda růží”).
  • 19. června — kloub na ruku z Merkuru.
  • 21. června — Honza dal profi vzhled ruce s protizávažím. Převrtání úchytu na motor ruky, atd.
  • 26. června — nový RFID vysílač a přijímač (posílání dat nakonec přes Ethernet). První testy s měřením odrazivosti u laseru.
  • 27. června — odjezd na soutěž

Modelářský DC regulátor

Někdy loni na podzim jsem si koupil dva modelářské „Univerzální DC regulátory” MDD56 pro auta/lodě/letadla. Tehdy jsem chtěl ovládat motory s odběrem až 50A (proto ta MDD56), ale projekt trošku pokulhával a regulátory ležely doma v šuplíku.
Jejich čas přišel s FRE2012. Nový motor na ruku byl úplně holý, na rozdíl od předešlého, který měl dvě spínací relátka pro pohyb nahoru a dolu. Pro určení polohy ruky byl použit potenciometr. V nové sestavě teď bylo možné dělat plynulou regulaci, takže suma sumárum chybějící relátka byla vlastně výhoda.
Po překonfigurování CAN modulu a napsání triviálního programu „posílej 10000 a pak -10000” se ruka pohla, ale pouze jedním směrem. Bohužel také patřím do většinové kategorie, která něco nejprve vykouší, a pak teprve čte manuál, takže první pokusy skončily nezdarem. V manuálu samozřejmě vše bylo napsané.
Regulátor je univerzální, tj. obousměrný či jednosměrný podle zasunuté konfigurační propojky. Defaultní nastavení je Auto N: „Obousměrný, při pohybu páky zpět se nejdříve aktivuje brzda, přechodem do N a zpět se aktivuje zpátečka”. Tj. program stačilo upravit a mezi 10000 a -10000 chvilku posílat 0.
Mohl jsem propojku posunout na druhou pozici Auto C, pro rychlý přechod z pohybu vpřed do pohybu vzad, ale už jsem před mnoha lety viděl, jak chybou ve znaménku lze softwarově zničit hardware a ta brzda jako mezifáze mi přisla rozumnější.

PI regulace

Motor s potenciometrem je téměř učebnicový příklad regulace. Na velké experimenty nebyl čas, tak jsem rovnou sáhl po PID regulátoru. Asi uvěříte, že je veliký rozdíl, jestli je ruka prázdná, nebo se pokouší zvednout či položit těžký květináč. Jako bonus se, po nastavení správných parametrů regulátoru, ruka mohla pohybovat i elegantně pomalu.
Reguloval jsem rychlost s lichoběžníkovým profilem. Pomalý náběh, pak konstantní rychlost zvedání/pokládání a zase postupné zastavení. Náběh byl parametrizovaný časem a cílové zastavení pozicí, což asi není úplně košér, ale když to fungovalo, tak jsem to tak nechal. Proporcionální složka fungovala dobře pro prázdnou ruku, ale teprve integrální složka pořádně řešila různé zátěže.
Ještě bych zmínil softwarové omezení výstupu PI regulace, které bylo úmyslně nastaveno na cca 1/3 výkonu (i tak to při jednom překlepu v kódu udělalo ránu do země, že jsem se lekl nejenom já, ale i všichni v blízkém okolí). Ruka i s tímto omezením zvedla vytouženou růži a já mohl v klidu spát, že je tam ještě dostatečně velká rezerva ve výkonu.

Nabírací vidle

Ruka s protizávažím se hýbala pěkně, ale autonomně najet k objektu a zvednout ho se postupně ukázalo jako neřešitelné. Přešel jsem do středoškolské matematiky, abych si zdůvodnil, proč je to tak těžké. Vy to asi vidíte hned, ale já to stejně proberu …
Růže jsou v květináčích, jeden vedle druhého. Horní průměr D1 je 19cm, spodní 15cm. Jelikož nabíráme cca 5cm nad zemí (květináče jsou na trávě a to není úplně rovná plocha) a výška květináče je 15cm, tak prostor pro vidle je na každé straně cca (19-15)*(2/3)/2=1.3cm.
  • H1: 15 cm, H2: 2.8 cm, H3: 12.2 cm
  • D1: 19 cm, D2: 18.2 cm, D3: 15 cm, D4: 17 cm
  • E1: 0.8 cm
1.3cm se může zdát dost, ale teď vstupuje do hry fakt, že robot nenabírá kolmo na řadu květináčů, ale otáčí se po kružnici a i vidle mají nenulovou délku (17cm) a šířku (1cm).
Závěr byl, že s milimetrovou přesností to venku v terénu nikdy nemůže vyjít! Toto poznání mne trošku uklidnilo (že mi to nejde nabrat tedy není nutně má programátorská neschopnost) a bylo třeba najít jiné řešení, tentokrát mechanické. Vidle se musí přizpůsobit buď posunem vlevo/vpravo na nějakém pojezdu, jako jsou „šuplíky” nebo se musí otáčet vlevo/vpravo při zachování kolmosti na zem. Druhé řešení bylo při použití Merkuru triviální a tak jsem ho hned zkusil a fungovalo krásně .
Teď už stačil nájezd i s chybou několika centimetrů a vidle se samy přizpůsobily tvaru květináče. V reálu to ještě úplně dokonalé nebylo. Na jednu stranu byla třeba volnost pro toleranci chyby příjezdu ke květináči, ale na druhou stranu bylo třeba vidle na začátku trošku směrovat. To nakonec zajistila malá gumička.

Laser — odrazivost

Další úlohu, kterou bylo třeba vyřešit, byla detekce vybrané růže a přesná navigace k ní. RFID (viz dále) mělo být pouze pro hrubé určení pozice. Pro přesnou lokalizaci byla k dispozici kamera a laser. Vedle předního SICK LMS100 máme na SICK Robot Day 2012 zapůjčen i nový senzor TiM3xx, který jsme plánovali ještě na robota přidělat do boku. Nový senzor je ale na USB a zatím nebyl integrovaný a jak to komentovali moji kolegové „nemáte už těch problémů dost”?!
Závěr tedy byl použít hlavní laser, který snímá 270 stupňů a vidí i vpravo dozadu, kde nabírání probíhá. První zádrhel byl vůbec laser nakonfigurovat tak, aby odrazivost posílal. Dokumentace „Operating Instructions - LMS100/111/120/151 Laser Measurement Systems” z roku 2009 byla totiž špatná (v datovém paketu "sWN LMDscandatacfg" totiž chybělo několik bajtů a laser to neakceptoval "sFA 8").
Pokud byste to někdy potřebovali, tak následující kód už funguje:
def configureScanDataOutput( self ):
    "BALMS1xxEN_8012471_T763_20090728.pdf, page 100"
    # better is LMS1xx_LMS5xx_TiM3xx_JEF300_JEF500_English.pdf, page 16
    return self.sendCmd( 'sWN LMDscandatacfg' +
    " 01 00"+ # output channel
    " 01"+ # output remission values
    " 0"+ # 8bit/16bit
    " 0"+ # unit (default)
    " 00 00"+ # no encoder data
    " 00"+ # output position data
    " 00"+ # output device name
    " 0"+ # output comment
    " 0"+ # output time (maybe we should use true??)
    " +1" # output interval
    )
Vedle toho, že laser nejprve změnu konfigurace evidentně odmítal, tak i později nebylo jasné, že už je vše správně nastavené. Data o odrazivosti totiž chodí společně s měřením vzdálenosti, ale začnou chodit až někdy. Ani to nevypadalo, že by bylo třeba měření vypínat a znova zapínat … prostě po pár minutách začala data o odrazivosti chodit a pak už chodila pořád.
Doma jsem ještě narychlo vyzkoušel, že odrazivost majáčků z Eurobota 2004(?) je opravdu v datech poznat (byla tam 255 maxima, takže OK), ale první reálné testy proběhly až v Holandsku. Vysokou odrazivost mají i jiné předměty, ale reflexní páska měla ještě jednu zajímavou vlastnost. Měření s vysokou odrazivostí se střídala s téměř nulovou odrazivostí. Co mne tedy zajímalo byla oblast velkého rozptylu na malém úseku. Pro detekci jsme používali reflexní květináč jelikož ho robot viděl spíše než majáček.
Vše vypadalo nadějně než se přiblížila večerní hodina čtvrtečního testování. Janu jsem ujistil, že na rozdíl od ostatních používáme laser a tomu tma nevadí, spíše naopak. Chyba lávky ! Laser se po tmě chová jinak. Pravděpodobně snižuje svůj výkon, už nemusí kompenzovat silné sluneční záření, a tak původní střídání hodnot okolo 0 a 255 se vytratilo. Pokud se na to máme spolehnnout, tak to vyžaduje více experimentování. Přešli jsme tedy na zálohu, RFID.

RFID vysílač a přijímač

S RFID přišel Tomáš, že v práci mají nové moduly a momentálně na nich pracují. Idea byla mít jeden vysílač a několik přijímačů a z absolutní intenzity odhadovat vzdálenost a z rozdílů směr. Měl vzniknout nový CAN modul (úpravu modulu používající I2C) a robot měl data přijímat přes CAN BUS. Bylo to ale moc čerstvé a času málo, tak jsme nakonec byli vděčni za jeden vysílač a jeden přijímač, který data přeposílal přes Ethernet.
V první fázi jsme jenom sbírali data a bylo na nich vidět, že když se robot blíží k majáčku, tak intenzita roste. Pokud mu cokoliv brání ve výhledu, třeba ruka nebo sloupek s kamerou, tak výrazně klesá.
Na obrázku je vidět měření z prvního testování v krátké řádce - s robotem jsem přijel k testovacímu poli a pak 5x projel okolo majáčku tam a zpět. Je vidět majáček po levé a pravé straně, přičemž vlevo je maximum nižší. Konečně řádky měly cca 2m, tj. tomu odpovídá i rozdíl intenzit 190 až 220.
Po špatné zkušenosti s laserem v noci jsem zkusil triviální hack. Při průjezdech měl majáček maximum asi okolo 235. Aby náhodou toto maximum neminul, tak jsem nastavil hranici pro detekci vybrané růže na 225. Robot jel řádkou, zastavil, provedl nabírací mechanismus a správnou růží nabral!!! Byla zhruba půlnoc, tj. ideální čas testování přerušit a jít spát.
Druhý den to samozřejmě tak optimistické nebylo, ale stále to bylo spolehlivější řešení než laser. Nakonec i stínění signálu sloupkem byla pro nás výhoda: robot viděl majáček jenom na straně, kam měl orientovanou ruku. V kombinaci s vhodně zvoleným prohledávacím vzorem (viz software) to fungovalo nad míru uspokojivě.

Software

Hlavní program byl hodně podobný tomu z roku 2010. Byl napsán v Pythonu a jako základ pro navigaci byl využíván laser. Každý scan 270 stupňů byl nejprve zjednodušen na pětistupňový, který reprezentoval minimum z daného intervalu (měření větší než 0, protože 0 znamená, že v daném směru laser nic nenaměřil). Pak se hledala „průrva” ve vzdálenosti jednoho metru odpovídající řádce v oblasti, kde byla nalezena naposledy, a navigovalo se směrem ke středu detekované mezery. Vcelku prosté.
Asi největší zádrhel byly možné překážky, které blokovaly řádku. V kukuřici se často stávalo, že velké listy zcela zabraňovaly průchodu a tak robot musel jet chvíli naslepo přímo do překážky. U růží takový problém nebyl, i když některé také trošku přečnívaly do uličky, ale spolehlivě určit neprůjezdnost a zároveň jet maximální rychlostí byla celkem výzva.
Protože detekce překážky úplně nefungovala, tak jsem zbaběle oddělil jednotlivé jízdy:
#    return self.ver2([-1,1]*10, searchForPot = False, detectBlockedRow = False)  # Task1
#    return self.ver2( [-3,-2,5,0,-2,4], searchForPot = False, detectBlockedRow = True ) # Task2
#    return self.ver2([-1,1,0,-1,1,0], searchForPot = True, detectBlockedRow = False)  # Task3
Pokud robot nemusel, tak překážky ignoroval a stejně tak označenou růži, kdyby náhodou ji tam cestou něco připomínalo.
Když už jsem nakousl Task 3, tak ještě pár podrobností — robot měl růži najít, nabrat a dovézt na start. Nechtělo se mi programovat žádný plánovač, který podle pozice nalezené růže rovnou pojede na start. Takové věci se špatně testují, protože jsou závislé na dalším parametru, kde byla nalezena růže. Nápad vznikl až po zjištění, že nejsme schopni detekovat růži nalevo od robota. Bylo tedy potřeba řádky systematicky projet v obou směrech = okruh. Pak už bylo jedno, kde vybraná růže je, cesta byla vždy stejná, akorát část ji jel s růží a část bez ní.
Ještě jsem nezmínil jednu změnu, která měla vliv na chování robota. Zkusil jsem integrovat 3D kompas. Řádky totiž mohly obsahovat mezery a robot měl stále pokračovat ve směru řádky, jako by jí lemovaly růže. Pro integraci byl použit Kalmanův Filtr (jen hrubé naměření směru na startu rozhodně nefungovalo).
Vše bylo fajn do okamžiku, než začalo pršet. Přidělali jsme deštník, který, jak jsme věděli z RoboOrienteeringu 2010, na kompas rozhodně vliv má. Rychlý test ukázal, že to není tak hrozné, ale dobré to nebylo (projevilo se to v mé osudové chybě v Task 2, kdy jsem robota úmyslně nastavil trošku šikmo, aby chybu kompenzoval). Co ale bylo nepoužitelné, byla situace, kdy byl deštník zavřený. Pak se dvě souběžné řádky změnily na kolmé … no je třeba udělat další měření (pokud možno v klidu) a dopadnou-li zle, tak na deštník raději použít nějakou bambusovou nebo umělou tyčku.

Robotické desatero

Před pár lety se nás studenti ptali na robotické triky „jak vyhrát soutěž?”. Tehdy jsem o tom přemýšlel a vyplodil robotické desatero. Rád bych zde udělal revizi, zda se podle něj opravdu řídím.

Team

Člověk by do soutěže neměl jít sám. Ideální je skupina do pěti lidí s jedním šéfem. Pokud je člověk sám, tak má slabé chvilky, kdy to chce vzdát — u týmu ostatní zrovna v této pesimistické fázi typicky nejsou. Problémů bude více než dost, a když nic jiného, tak je dobré se o nich s někým pobavit. A není nic lepšího, než když některé může řešit i někdo jiný .
Tak toto pravidlo vyšlo, i když to tak na začátku nevypadalo. Milan se vzdáleně staral o papírování a další formální záležitosti, Standa, když jsme se rozhodli použít Honzovu původní ruku, udělal nastavitelné nabírací vidle a byl vždy po ruce, když to bylo třeba. Janička, ačkoli žádnou roli v týmu hrát neměla (jela se spíše podívat na růže a na výstavu) viděla věci s nadhledem, takže když jsme nestíhali ujet Professional Task v časovém limitu tří minut, tak první konstatovala proč jezdíme 4 řádky, když 3 stačí. A ta její gumička ze zahradnictví také byla zásadní .
Velkou roli v týmu měl i Tomáš a Honza, ačkoliv na soutěž letos nejeli. Tomáš připravil RFID a Honza předělal pořádně ruku tak, že po celou dobu soutěže s ní nebyl jediný problém.

Motivace

Pokud členové týmu chtějí pouze získat zápočet, obhájit projekt nebo získat bod u profesora, tak to nebude fungovat. Musí na robotu opravdu chtít dělat ať se děje co se děje. To u Eduro Teamu nebyl problém: všichni jsme chtěli vyhrát.

Verze 0

Co nejdříve je třeba rozchodit minimální verzi, která bude řešit danou úlohu, i když nedokonale. Musí to být co nejjednodušší, kdy se typicky ukáže, že problémy jsou úplně někde jinde než by je člověk čekal.
Toto se nám vyplatilo hlavně při Cooperation Tasku, kdy během pěti minut obě strany získaly daleko lepší představu, čeho je druhý robot chopen a jakým směrem se ve vývoji vydat.
Mimochodem verze 0 je zároveň něco, k čemu se máte/můžete vrátit, pokud všechny ty chytré verze selžou. Věřte, člověk se cítí daleko lépe, pokud se má kam vrátit. Funkčnost verze 0 je tedy dobré neustále ověřovat.

Testování

Spolehlivost robota ověříte jedině testováním. Něco málo můžete zkusit v simulátoru nebo když je robot napojen do zásuvky, ale test co nejbližší realitě soutěže je zásadní. Třeba zjistíte, že máte už špatné baterky a je třeba je nahradit, že ten nově přidělaný díl přečnívá a robot nesplňuje daná omezení, že trávník není podlaha a pod.
(Ano testoval jsem na zahradě v hromadě květináčů, nic nefungovalo a všichni se mi smáli.)

Soupeř

Je dobré mít soupeře, na kterém můžete zkoušet vaše strategie. Oba týmy se také vzájemně hecují, jak je daleko jejich příprava na soutěž. Mám na mysli spřáteleného soupeře, se kterým se otevřeně o všem bavíte. Pokud je tým veliký, tak ho doporučuji rozdělit na dva a může-li se účastnit soutěže jenom jeden robot, tak druhého použít jako záložního.
Toto jsme na FRE 2012 neměli. FRE je vlastně dost individualistická souťěž a až na vyjímku Cooperation Tasku roboti nijak neinteragují. Pravý opak byl třeba Eurobot - tam je třeba se soupeřem počítat/trénovat.

Časový plán

Je dobré v každém okamžiku mít alespoň hrubou představu, co můžete stihnout. Doporučil bych HW a SW-freeze, tedy okamžik, kdy už na robotu vůbec nic nebudete montovat a mechanicky dodělávat, a stejně tak i s programem. Už „jenom” testujete a zjišťujete omezení vašeho řešení.
Na FRE2012 bylo tak málo času, že plán byl poměrně jednoduchý — pokud něco nebylo bezpodmínečně nutné, tak to „šlo přes palubu”.

Rozdělení zdrojů

Toto je problém v týmech, kdy několik osob pracuje nezávisle na kódu robota a diví se, když to prvně pustí společně. Robot pak nestíhá zatáčet, plánovat, analyzovat obrázky, komunikovat po USB … tj. čím dříve to zkusíte vše pohromadě, tím lépe.
S tímto jsme letos neměli problém — prostě veškeré zdroje jsem použil já.

Strategie/Modularita

Nemít, hlavně v závěru, příliš bujnou fantazii a soustředit se na dvě až tři hlavní strategie. Modularita je myšlena tak, že novou strategii můžete v případě potřeby velmi snadno poskládat už z existujících funkčních a ověřených kusů.
Tohoto jsem si poměrně užíval — stavebních kostek je už za ta léta je hotových několik, takže moje programování bylo spíše hraní si se stavebnicí.

Podpůrný tým

Není nad to, když hlavní programátor vedle programování nemusí řešit i co budete kdy jíst, jak se na soutěž dostat, jaké logo dát na týmové tričko, případně kde sehnat levná eura … k tomu se hodí podpůrný tým, což můžou být i nerobotici.
Jo jo, letošní podpora byla dobrá, díky Jani .

The Last Minute

Pokud to jen trošku jde, nic nedělejte na poslední chvíli. Před soutěží samotnou je dobré se pořádně vyspat, sepsat si startovní checklist (minimálně mně to manuální řešení kroku za krokem uklidňuje). Změny v kódu jsou v tuto chvíli už typicky fatální a nemáte příliš šanci je vyzkoušet, tj. požadovaný efekt nejspíše nepřinesou. Jediné, co můžete v této chvíli dělat, je volit mezi již otestovanými strategiemi.
Vlastně i podle této zásady jsem se celkem řídil. Na rozdíl od ostatních týmů jsem šel ve Čt spát už o půlnoci (cca v 6h jsem vstal a to jiné týmy ještě kódovaly). Zásah na poslední chvíli jsem přes velké vnitřní zápolení do kódu udělal, ale nijak mi to nepomohlo (řádka byla zkrácena o jeden metr na obou stranách, takže při přejezdu ob tři řádky by robot určitě narazil).

Závěr

Field Robot se mi letos líbil a i samotná příprava probíhala podle klasického scénáře „nic nefunguje, co budeme dělat”. Samozřejmě to nebylo tak dramatické, ale nuda to rozhodně také nebyla. Díky týmu za podporu a příští rok možná v Praze na viděnou na dalším ročníku FRE 2013!