czech english

FireAnt

fandorama článek/blog o stavebnici robota

FireAnt je stavebnice chodícího robota od americké firmy Orion Robotics. Jedná se o šestinohého robota, postaveného z 25 (!) serv se zpětnou vazbou. Celý robot je pak ovládan deskou s Arduinem. Blog update: 23/5 — The Ant End

Toto je další z fandorama článků/blogů (na přesné formě bychom se domluvili s přispěvovateli). Balík se stavebnicí by měl dorazit příští týden. Motivace je vytvoření „zahradního robota”. Je to trošku „šílený česko-francouzko-kanadský projekt”, ale uvidíme. Pro představu, jak si hrál někdo jiný s chodícími roboty na zahradě/poli viz starší článek o robotických farmách.
Pokud máte zájem, aby na tomto místě vznikl článek nebo blog, kde bych sepisoval první zkušenosti se stavbou a oživením robota, tak zde je odpovídající fandorama link:

Odkazy:



Blog

31. říjen 2013 — Balíček dorazil!

Dnes ráno konečně dorazil balíček, no spíše balík, se stavebnicí robota. Tímto jsou splněny nutné předpoklady tohoto fandorama projektu, které bych jinak neměl ve své moci.
Chtěl bych také poděkovat prvnímu přispěvovateli … vždy potěší zpráva, že alespoň někoho by budoucí článek/blog zajímal. První fotografie:

5. listopad 2013 — FAQ

Vypadá to, že moc lidí tento potenciální článek nezaujal. Ještě zbývá 25 dní, tak bych zde zmínil několik upřesňujících dotazů a odpovědí:

Co přesně je cílem tohoto fandorama článku?

Moje původní představa byla série dvou až tří článků o „slugs killer”, tedy „autonomním ohnivém mravenci, zabijáku slimáků”. Měl by dělat i další zahradní práce, ale slimáci trápí i mne a přišlo mi to jako dobře definovaný cíl. Aby byl i ten „milník”, tak jsme se domluvili na účasti na Field Robot 2014 v kategorii Free Style. Tento článek měl být první krůček, tj. cca do vánoc rozchodit ovládání robota z PC (za mne z Pythonu, jak jinak ).

Jaké je na robotovi Arduino?

Po pravdě netuším a s Arduinem jsem zatím nikdy nic nedělal. Jestli je něco na tom čipu napsané, tak už nejsem schopen to přečíst. Podle obrázků to matchuje na:
DaVinci je deska s regulovaným napětím, čipem 32kB Flash, 2kB RAM, 1kB EEPROM. Servo deska má 32 kanálový ovladač serv, 2x UART, 56kB Flash, 256kB EEPROM, LEDky a „Speaker”.

Co je na robotovi zajímavého?

Asi nejvíce mne zaujala serva. Slibují The Orion Shield also supports position and force feed back (PPF) using the new Orion Robotics servo HV-220., tj. serva by měla posílat zpět informaci o skutečné poloze a síle, jak těžko se ta poloha drží. Něco podobného co před lety nabízel megarobot.net. Jak to bude fungovat v realitě ale ještě nevím. Minimálně video s nabráním plechovky s kolou mají pěkné .

14. listopad 2013 — un-depressed

Přiznám se, že jsem předevčírem krabici se stavebnicí robota strčil na hromadu pod „pracovní stůl” s myšlenkou, že to holt pořeším někdy později, když o to nikdo nemá zájem :-(. Fandorama mne v tomto případě zatím spíše demotivovavla než motivovala. Velmi mne tedy potěšil včerejší příspěvek a zvýšení šance na úspěch. Zbývá zhruba ještě 14 dní tak uvidíme. Zatím jsem si nainstaloval potřebné prostředí, rozchodil USB driver a při napájení desky trefil polaritu, takže se ozvalo pípnutí a svítila zelená LEDka. Na blikání s LEDkou, tedy můj první test s Arduino deskou, ale ještě nedošlo.
p.s. psal jsem Orion Robotics, co je tam za defaultní firmware a jestli to vlastně nemá něco dělat „samo od sebe”, ale nedostal jsem ještě žádnou odpověď …

21. listopad 2013 — nohy

Minulý pátek a včera jsem si chvíli hrál na konstruktéra. Byla to celkem příjemná kompenzace k dekódování videa . Přemýšlel jsem, co bych o tom mohl psát a napadaly mne pouze hlášky z filmu Pelíšky o „naprosto stejné krabičce sirek”. Stavebnice mi totiž hodně připomínala Merkur, akorát bych si asi vybral tu americkou.
Člověk si u toho může opakovat angličtinu — šroubky, matičky, podložky, vše je baleno po deseti s nálepkami „Screw 3M8”, „Nuts 3M” a pod. V této fázi jsem udělal snad jenom jednu chybu a to když jsem přehlédl, že vedle šroubků a matiček 3M tam jsou ješte o trošku menší (2.5M). Nebyla fatální. Prostě to jen k sobě nešlo .
První trošku větší zklamání byly 20mm distanční sloupky. Ještě bych rád chvíli věřil, že to byl záměr, ale … ty závity jsou fakt mizerné. Šroubek tam zastrčíte 4mm (tj. půlku velikosti), aniž by jste ho jednou otočili! Jsem zvědav, co mi na to kapitalisti napíšou. Zatím stačí problémový (bylo jich špatných asi 5) distanční sloupek otočit — z jedné strany se totiž přichytává rovnou ke konstrukci a z druhé přes podložku přidržuje servo (krok 5 v návodu).
Jinak díly jsou moc pěkně udělané a to jak výřezy, tak povrchová úprava. Už teď je mi skoro „mravence” líto ho pouštět do bahna, ale je to jeho osud. Přes zeď jsem slyšel Vášnivý tanec, tak jsem si říkal, že to by mohla být pěkná aplikace … no jsem zvědav co ty servo-nohy dokážou.

26. listopad 2013 — tělo

Do konce fandorama projektu zbývají 4 dny, tak už zase pomalu začínám pochybovat, že projde. O víkendu jsem si chvíli stavěl, tak alespoň malá obrázková galerie odpovídající krokům z návodu …
Opět tam byl drobný problém s distančními sloupky (tentokrát 25mm dlouhými) — závit byl u jednoho jenom cca 4mm, tj. šroubek nešel dotáhnout. Robotického nadšence by to asi nemělo rozhodit, ale u profi stavebnice mne to trošku mrzelo. A samozřejmě to byl první sloupek, který jsem ten den montoval…

29. listopad 2013 — Fandorama

Nejprve díky třetímu stoupenci, který tento článek podpořil, a já už nemusím řešit dilema, jak na robotovi pracovat a „netutlat to” . Poprosil bych ho touto cestou o kontakt — uvádějte prosím do zprávy pro příjemce svůj mail. Domluvil bych se pak se všemi co by vás na stavebnici FireAnt nejvíce zajímalo.
Dostali jsme na toto téma zatím dva mailové příspěvky. V prvním mailu byl nápad, že by podobný mravenec mohl i sbírat kameny (zkusil bych to, ale nevím do jaké velikosti/váhy to zvládne) a že je velká podobnost stavebnice s tím, co nabízí Lynxmotion. Jaká je vazba mezi Orion Robotis a Lynxmotion ale zatím nevím … nějaké náznaky jsou na jejich fóru.
Druhý mail byl spíše k Fandoramě: „Myslím trochu ptákovina (na web jsem se podíval), poněvadž odpověď na otázku "O jaké články bude největší zájem?" je víc než nasnadě: O nejlevnější.” Nevím, máte stejný pocit? Mimochodem Fandorama je k dispozici pro všechny a není ani nutně vázaná pouze na https://robotika.cz … i když to tak zatím moc nevypadá .
p.s. z jiného soudku: pokud by vás zajímaly LEGO robotické stavebnice, tak je teď (do soboty) celkem pěkná výstava v NTK Galerii v Praze
LEGO Kobra
LEGO Kobra
… omlouvám se za mizernou fotku z telefonu. LEGO Kobra se umí plazit a i vás uštknout .

2. prosinec 2013 — čas BLINKat

Dnes ráno jsem si chtěl na mravencovi vyzkoušet nějaký triviální prográmek. Příklad BLINK, tedy blikání LEDkou, je rovnou součástí Arduino balíčku. Začít programování jednočipů tímto příkladem doporučujeme už léta. Není to až tak o programu, i když i na něm se člověk naučí nastavit výstupy a základní časování, jako o rozchození nástrojů.
S instalací driveru jsem před časem tročku zápasil (Windows 7, 64bit), ale nakonec fungoval přímo driver od FTDI (arduino-1.0.1\drivers\FTDI USB Drivers). Když jsem viděl COM6, tak jsem si myslel, že už mám vyhráno, ale … nemám. Zasekl jsem se teď na processing.app.SerialException: Serial port 'COM6' already in use. Try quiting any programs that may be using it., podle doporučení na StackOverlow nainstaloval Process Explorer, zabil Nokia SYNC, Android ADB, ale ještě si netroufl na iusb3mon.exe, i když ten je možná důvod (???).
Večer budu zase raději montovat, to má větší šanci na úspěch …

3. prosinec 2013 — ložiska

Dnes jsem reklamní brožury nejprve použil jako výstavku, než jsem se shrnul pryč z kuchyňského stolu . Je to takový průřez minulých čtrnácti dnů …
Sylvio psal, že je u kroku 31, takže evidentně zaostávám. Když navíc uvážím, že mne čeká „rozborka & sborka” (ještě nemám baterku a ona má být tak trošku zabudovaná do těla robota), tak paralelní slalom asi prohraji. No uvidíme, kdo mravencovi první trhne nohou (ne utrhne nohu).
Na rozdíl od programování šla stavba teď celkem pěkně. Mile mne potěšila ložiska — původně jsem si myslel, že ty „tablety” jsou nějaké magnety. Upevňuje se tak druhá strana těla (krok 20 a celkem dost mizerná fotka).
Jinak asi nic extra napínavého … včera jsem si pořídil AKU šroubovák/vrtačku na dodělání jedné střechy a fakt bych nevěřil, co jsou e-shopy schopný prodávat :-(. Jedna baterka byla zničena a dopředný chod vůbec nefungoval, jenom zpětný … ale to dost odbočuji. Představoval jsem si, že kdyby byl mravenec schopen tu vrtačku unést, tak by mohl horní část střechy montovat za mne, ha ha ha. Takový Ferda mravenec, kdyby robotí jméno Ferda nebylo už použito.

4. prosinec 2013 — šestinožka

Dostal jsem se včera ke kroku 35 a je to fakt monstrum, které zabírá půlku pracovního stolu! S montováním klepet a ocasu bych asi počkal, až bude fungovat základní pohyb.
Momentálně se rozhoduji, které baterky a nabíječku, a při té příležitosti jsem narazil na tento článek o stavbě FireAnta. Když si ho přečtete, tak zjistíte, že „Zenta” je norský autor návrhu šestinožky A-Pod a Lynxmotion design převzal (více detailů je pak na jejich fóru).

5. prosinec 2013 — baterka

Tedy přesněji Li-Po akumulátor … připadám si jako křupan, kterého snadno oškubou :-(. Zase se mnou trošku cloumá vztek, ale noste si voltmetr do obchodu?! Je to jak když jsem v pondělí zjistil, že nová AKU vrtačka se točí jenom v jednom směru a jedna baterka je vadná … možná bych měl počkat do rána, až se trošku uklidním, ale to by jste z toho zase nic neměli . Tak popořádku.
První problém byl, jaký akumulátor vůbec pořídit. V návodu není nic. Jediná, ale asi dost významná nápověda byla u specifikace serv: … high voltage (7.4V), digital servo. LiPo-lky mi doporučil Dan … jsou lehčí, ale bacha na vybití! 7.4V znamená 2 články. Podpora na Orion Robotics mlčela … měl jsem projít jejich fóra a bylo by … viz poznámka o HobbyKing 2200mAh 2S 30C LiPo (dnes mi to potvrdil i Nathan z Orion Robotics).
No nic, v mezičase už jsem trošku jiný LiPo akumulátor pořídil (2S, ale 3300mAh — snad to FireAnt unese). Pominu-li špatný konektor v prvním pokusu, tak teď, s novým konektorem a novou nabíječkou … nic! Ta zkur… špatná baterka má 6V a to je už tak málo, že to odmítá nabít (BATTERY CHECK CELL LOW VOL). Supr. Jsem zvědav, co mi zítra v obchodě řeknou …
  • k Arduino desce se vůbec nepřipojím (zatím stále předpokládám chybný driver).
  • primární ovládání ohnivého mravence je přes kabel s PS2 (nemám a neplánuji pořizovat).

8. prosinec 2013 — 8.4V

Jak to dopadlo v pátek v obchodě? Prodavač si vzal nabíječku i s akumulátorem, na pár sekund místo LiPo nastavil NiMH (jaký proud si nevybavuji) a pak přepnul zpět na LiPo a už se to v pohodě nabíjelo . Baterka je prý dobrá (po hmatu je tvrdá) a že jakmile by začala měknout, tak se jí nepokoušet ani nabíjet — uvolňují se plyny a mohla by explodovat!
V práci jsem jí nechal ještě několik hodin dobíjet. Ano, hodin. Překvapilo mne, jak dlouho to trvá, ale v závěru nabíjecího cyklu se tam pouští už jenom 0.2A a je to tedy očekávané. Teď už má baterka 8.4V .

9. prosinec 2013 — datasheets

Asi je pomalu čas klesnout na dno a začít pěkně od nuly. The DaVinci deska je „Arduino compatible”, což si teď překládám jako „obsahuje ATmegaXY” :-(. Mám i pocit, že asociace s názvem Arduino desky Leonardo je zavádějící. Jedna má ATmega32U4 a druhá ATmega328P. Kdyby nic jiného, tak jedna má 26 general purpose I/O lines zatímco druhá pouze 23 …
Čemu se dá věřit? Datasheets. Důležitý je jednočip ATmega328P a možná se bude hodit i převodník FT232RL.
… o 3 hodiny později …
To jsem teda blázen :-(. Na Arduino drivery jsem se už vykašlal a šel jsem přímo po FTDI. Konkrétně je tam VID_0403&PID_A559 … je to tedy trošku upravena EEPROMka a „defaultním” FTDI driverům se to nějak bránilo. Pak jsem četl Application Note 073, kde píšou: In order that Windows successfully match a device with the driver, the VID and PID programmed into the device must be listed in the driver INF file. The following sections of FTDIBUS.INF show text in bold that must be amended to match the desired VID and PID combination... … hm, takže si sám musím upravovat drivery?! Nejprve jsem to udělal pouze u ftdiport.inf, ale to nepomohlo … ale pak jsem místo instalovat ze zadaného místa vybral FTDI a novější driver pro sériový port a vznikl COM7. Hmm, znova problém, že už COM používá někdo jiný. Zabil jsem co se dalo, ale žádná změna.
Zkusil jsem dalši USB port na počítači. Znova COM7, ale This device cannot start. (Code 10).. Update driveru z vybraného místa nepomohl, ale vybrat už z nainstalovaných ano. Před tím jsem ale editoval jak ftdiport.inf tak ftdibus.inf a smazal všechny ostatní záznamy: When changing FTDIBUS.INF to match a new VID and PID combination, all references to these default values must be removed from the file..
Další změnu, kterou jsem provedl, byl způsob puštění arduino.exe. Mám namapovaný disk a začínám mít velké podezření, že si s tím nějak neporadí.
Vznikl COM8 — šel otevřít a deska začala pípat (stejně jako po resetu). To je dobrá zpráva!
Binary sketch size: 4,826 bytes (of a 28,672 byte maximum)
processing.app.debug.RunnerException: Couldn’t find a Leonardo on the selected port.
Check that you have the correct port selected.  If it is correct,
try pressing the board's reset button after initiating the upload.
	at processing.app.debug.AvrdudeUploader.uploadViaBootloader(AvrdudeUploader.java:153)
	at processing.app.debug.AvrdudeUploader.uploadUsingPreferences(AvrdudeUploader.java:67)
	at processing.app.Sketch.upload(Sketch.java:1671)
	at processing.app.Sketch.exportApplet(Sketch.java:1627)
	at processing.app.Sketch.exportApplet(Sketch.java:1599)
	at processing.app.Editor$DefaultExportHandler.run(Editor.java:2380)
	at java.lang.Thread.run(Thread.java:619)
Reset vypadá, že ovládá přímo přes USB (mimochodem je dost nepřístupný, schovaný pod servo-deskou), takže předpokládám „non-Leonardo” problém.
Binary sketch size: 4,826 bytes (of a 28,672 byte maximum)
processing.app.debug.RunnerException: Serial port 'COM8' already in use.
Try quitting any programs that may be using it.
	at processing.app.debug.AvrdudeUploader.uploadViaBootloader(AvrdudeUploader.java:158)
	at processing.app.debug.AvrdudeUploader.uploadUsingPreferences(AvrdudeUploader.java:67)
	at processing.app.Sketch.upload(Sketch.java:1671)
	at processing.app.Sketch.exportApplet(Sketch.java:1627)
	at processing.app.Sketch.exportApplet(Sketch.java:1599)
	at processing.app.Editor$DefaultExportHandler.run(Editor.java:2380)
	at java.lang.Thread.run(Thread.java:619)
Supr :-( …toto se mi podařilo, když jsem zkoušel RST tlačítko na servo-desce … je čas jít do práce …

10. prosinec 2013 — Duemilanove

Severní pól je dobyt! (a ta potvora naprogramována)
Pokud si myslíte, jako já před pár dny, že „Leonardo” má cokoliv společného s „DaVinci” tak se šeredně pletete. Nemá. Co tedy odpovídá DaVinci řídící desce, v rámci „Arduino kompatibility”, jsem nakonec zjišťoval podle použitého čipu ATmega328P. Vzal jsem to od shora a první na to seděla deska „Duemilanove” a šla naprogramovat s příkladem arduino-1.0.5\examples\01.Basics\Blink\Blink.ino . To by vypadalo jako dobrá zpráva, ale LEDka neblikala a deska přestala i pípat. S tím jsem včera ráno končil.
Večer jsem zkusil jiný příklad: 02.Digital\toneMelody, kde jsem změnil výstupní pin na 3 (původně tam byl myslím 8) a deska začala pípat. Hurá! Další krok byl 03.Analog\AnalogInOutSerial, kde jsem změnil vstupní analogový pin na A2, který by podle Orion_Servo_Shield_R0406.pdf měl měřit napětí na baterce. Na straně PCčka jsem otevřel putty terminál na COM8, 9600 a začal chrlit:
sensor = 377     output = 93
sensor = 377     output = 93
sensor = 377     output = 93
sensor = 376     output = 93
…
Na řadě jsou teď znova LEDky a tlačítka. Jestli jsem dosavadní prográmky pochopil, tak digitální piny se číslují přímo a analogové zprostředkovaně přes define A0, A1, … Ještě je tu jemná schizofrenie propojení dvou desek (DaVinci a ServoShield), kde schéma zapojení mám pouze u jedné.
p.s. ještě jsem se pokusil vrátit na desku původní firmware (support se podle mne mýlil a deska byla předprogramovaná na ovládání kabelem pomocí herní konzole PS2). Zdrojáky jsou ke stažení z FireAnt stránky, ale nešly mi zkompilovat. Chyběly Arduino knihovny, které bylo třeba buď jednotlivě naimportovat, nebo snáze rovnou nakopírovat do adresáře arduino-1.0.5\libraries.

11. prosinec 2013 — první pohyb

Včera večer se mravenec (Fourmis de Feux) konečně pohnul . K prvnímu kroku to má ještě daleko, ale nějak se začít musí. Rozchodil jsem si příklad s LEDkama 01.Basics\Blink (analogový pin A0 je červená a A1 zelená), pak s tlačítkama 02.Digital\Button (digitální piny 2 a 4) a pak si troufl to zkombinovat se servem. Jak to dopadlo je vidět na tomto hodně mizerném videu. Zem (černý kabel) musí být na vnější straně desky a čísla Arduino pinu jsou tam přímo napsaná (použil jsem pin 10).
Pokud by vás zajímal i ten dost triviální zdroják, tak jsem to dal rovnou na github.
Třída BMServo je v balíčku ke stažení od Orion Robotics. Klasicky jsem se trošku bál, co se stane, když tam pošlu 0 a jaké jednotky to vůbec má, ale vypadá to, že servo.setAngle(value,time) nastavuje znaménkový úhel v desetinách stupně, 0 je střed a čas je v milisekundách.
Ve zdrojovém kódu BMServo jsem našel i funkce queryFBAngle() a jiném příkladu queryForce(), ale ta je k dispozici přes SPI pouze u Servo Shield desky. To jsem vlastně ještě nepsal — ovládat lze 32 serv s tím, že 8 je prodrátovaných/přímo řízených z DaVinci desky a zbylých 24 přes SPI komunikaci přímo na servo desce. Tam jsem ale zdrojový kód zatím nenašel a možná ani není veřejně k dispozici.
Ještě mne včera trošku uvedl do reality Jirka: ,,Arduino compatible'' znamená, že má stejně rozmístěné piny, takže na to můžeš nasadit různé arduino shieldy. Co se procesoru týče, nejsou stejná ani dvě opravdová arduina

12. prosinec 2013 — BMServo vs. SPI

Dnes ráno jsem zkoušel ovládat servo přes SPI a zatím dost tápu :-(. U BMServo to bylo jednoduché:
BMServo servo( ARDUINO_SERVO_PIN );
servo.begin();
…
  servo.setAngle( angle, 1000 );
  servo.update();
U SPI se komunikuje přes Orion knihovnu a skoro to vypadá, že už je tam nějak předprogramované to chození? (nebo se mi deska stále resetuje a proto se to samo cyklí, ale to bych „slyšel” — mám tam na začátku pípnutí). Jelikož se ovládá hodně serv současně, tak Orion.setAngle() je pouze nastavovací a teprve Orion.execute() něco dělá. Nějakou roli tam ještě určitě hraje Orion.time(ms), ale zatím nevím jakou.
Orion.begin();
Orion.tone(NOTE_C6,100);
Orion.setAngle( SPI_SERVO_PIN, angle );
Orion.setServoMin( SPI_SERVO_PIN, -900 );
Orion.setServoMax( SPI_SERVO_PIN, 900 );
…
  Orion.setTime( 100 );
  Orion.setAngle( SPI_SERVO_PIN, 900 ); // nebo -900
  Orion.execute();
OK, tak teď jsem to už snad pochopil. Ten Orion.setTime(ms) je to samé jako time parametr u servo.setAngle(angle, time), tj. jak rychle do požadované polohy má přejít … jen je to stejný parametr pro všech 24 serv. Když jsem ten čas totiž změnil na 1000 (1s), tak se to začalo chovat rozumně a ano, resetuje se mi deska … jedu ze slabého zdroje. Chcete-li detaily, tak viz servo_test.ino.

13. prosinec 2013 — teleoperation

… aneb každý den není posvícení. Sigh. Dnes jsem chtěl vyzkoušet jednoduchý příklad se zpětnou vazbou na servech. Jedno servo by bylo jako vstup a druhé jako výstup. Na cvičení jsme před mnoha lety zadávali podobný úkol — zapojte potenciometr a servo + naprogramujte jednočip tak, že otáčení potenciometrem se bude otáčet i to servo. Spousty zábavy s touto „teleoperací” .
Orion serva mají zpětnou vazbu, resp. předpokládám, že je tam možnost přečíst právě aktuální odpor na referenčním potenciometru (v servu). Klíčová je tato řádka:
Orion.setAngle( OUT_SERVO_PIN, Orion.queryFBAngle( IN_SERVO_PIN ) );
tj. aktuální polohu IN serva předej jako požadavek na OUT servo. Celý kód pak najdete na githubu. Zkusil jsem to na přední packy a zvedáním jedné druhá šla dolu . To je vlastně očekávané chování, protože serva jsou symetrická.
Druhý pokus byla první a druhá noha na stejné straně robota. A bang - servo šlo do extrému, bouchlo do konstrukce a vůbec to nevypadalo pěkně. Tak jsem si přidal do kódu LEDky, tlačítko a „pseudo-kalibrační” rutinu … a výsledek? LEDky svítí, přepnou se po kalibraci, ale už to nedělá vůbec nic :-(. Dokonce i když jsem kalibraci zrušil a vypnul/zapnul desku, tak stále nic. Celkem dobrá předehra k pátku 13 … . Dnes tedy žádné video.

14. prosinec 2013 — Orion.queryFBAngle()

Kalibrační proceduru jsem ještě nerozchodil, ale o malý kousek jsem se zase posunul dál. Už tuším, proč se včera servo chovalo tak agresivně! Přidal jsem do kódu Orion.setServoMin() a Orion.setServoMax(), což možná byl důvod proč se servo předtím nehýbalo vůbec, a hlavně jsem přidal podmínku na povolený úhel, který mi vrací Orion.queryFBAngle(). Detaily změn najdete zde.
Pokud byly úhly nějaké podezřelé, tak jsem si je nechal vypisovat na konzoli (přes USB-serial) a po resetu jsem typicky dostal tento výstup:
TeleOperation test …
                      -1704
-1704
-1704
-1704
-1704
a na rovinu, úhel -170 stupňů snad to servo ani nedá a pokud dá, tak je to hodně extrémní poloha.
Pokusil jsem se i natočit, co že to vlastně dělám, ale kamera je vybitá a s tím foťákem v temném koutku … ostatně uvidíte sami. Asi nejvtipnější na tom pár sekundovém snímku je, jak mi nejde zapnout napájení — v jedné ruce foťák a tou druhou to nějak nešlo . No nic, pro představu to snad stačí.

16. prosinec 2013 — Kosinova věta

Lomikare, Lomikare … aneb už došlo na středoškolskou matematiku. Včera jsem si celkem dlouho hrál s 3-DOF nohou. Naprogramoval jsem si jednoduchou komunikaci Pyhon-Arduino a při tom přemýšlel, jak někteří dokáží takové věci dělat bez testů a bez logování. Je to jak stavět barák bez lešení. Nějaké problémy? Hned několik.

Komunikační protokol a logování

Protokol jsem si vymyslel celkem jednoduchý — nechtělo se mi pouštět v této fázi do složitější struktury s kontrolním součtem, ale možná to byla chyba. Úhly v desetinách stupně jsem si zjednodušil na stupně a bajt beru znaménkově, tj. teoreticky jsou možné úhly -128 až 127 stupňů. Zúžil jsem to ještě na -120 až 120 a získal tak „řídící bajty”:
const unsigned char START_BLOCK = 0x80;
const unsigned char END_BLOCK = 0x81;
const unsigned char STOP_SERVO = 0x82;
const unsigned char SERVO_OUT_OF_RANGE = 0x83;
Arduino pošle START_BLOCK, pak stavy jednotlivých serv a ukončí paket END_BLOCK. Python na to odpoví START_BLOCK, příkazy pro jednotlivá serva a END_BLOCK. Nesymetrické jsou STOP_SERVO a SERVO_OUT_OF_RANGE a samozřejmě, že jsem v tom udělal chybu (na jednom místě je omylem prohodil, když jsem rutinu z Python přepisoval do Céčka). Pokud je poloha serva třeba 130 stuňů, tak aby seděly jednotlivé pozice se posílá SERVO_OUT_OF_RANGE. A naopak když Python neví, do jaké polohy servo poslat, tak STOP_SERVO vypíná generování pulzů.
A kde pomohl log fa131215_124600.log? Z Arduina mi chodilo nějak málo serv. Chyba byla v typu pole s čísly pinu, který není int, ale char.

Chyba ve firmware Servo Shield??

Teď zpětně si vybavuji, že mi serva zlobila od začátku, ale nezdokumentoval jsem to hned a teď už jen tápu. Při prvních pokusech to byla určitě chyba záměny STOP_SERVO a SERVO_OUT_OF_RANGE, kdy šlo servo do polohy -126 stupňů, ale pak to zlobilo i když jsem posílal přímo konkrétní pozice.
Po opravě jsem ale dostával stále podobnou chybu (teď si myslím, že šlo servo do druhého extrému). Spíše ze zoufalství jsem odstranil nastavovací cyklus v setup():
/*  int i;
  for( i = 0; i < NUM_SERVOS; i++ )
  {
    Orion.stopPulse( servoPins[i] ); // it is by default, but this way it is more clear
    Orion.setServoMin( servoPins[i], SERVO_MIN );
    Orion.setServoMax( servoPins[i], SERVO_MAX );
  }*/
a ono to začalo fungovat správně!!! Mám teorii, že to šlo do polohy zadané přes Orion.setServoMax(), ale více jsem to nezkoumal. Zatím. Při sepisování, co se vše včera dělo, mi teď došla ještě jedna věc — když nastavíte požadovanou polohu serva, tak nastavujete i za jak dlouho tu polohu má dosáhnout. Prima, ale co když je předešlá poloha nedefinovaná? Nebo co když zadáte čas nula? Možná získáme nějaké informace na fóru.
Čas se pomalu naplnil, tak Kozinovu větu vám nechám za domácí úkol .
P.S. Zdrojáky na toto téma jsou na obvyklém místě.

17. prosinec 2013 — Piano

Opět tuším, že cíl je v nedohlednu, tak zase „verze 0”. Mělo to být překvapení, ale než bych to pořádně rozchodil, tak už bude nutné dělat něco
FireAnt a Piano
FireAnt a Piano
jiného (třeba vánoční úklid).
Malé testovací prográmky pro Arduino většinou začínají pípnutím. Je to dobrá indikace, že se deska resetovala, i když se člověk zrovna nedíval. Podle volby tónu si můžete rozlišit i programy: pokud si nejste 100% jistý, že máte nahraný nejnovější kód, tak změníte úvodní tón.
O tohoto pípání už byl jen malý myšlenkový krůček k „pípání na piánu”, na které jsem v pre-historii hrával. Je to pěkný milník na otestování transformace XYZ do prostoru úhlů serv a jak moc to funguje snadno posoudí každý . Co přesně měl mravenec zahrát si ještě nechám pro případ, kdybych to opravdu někdy dotáhl, ale první lekci bych zveřejnil, ať z toho také něco máte. Video je tedy zde.
P.S. pokud nemáte čas a chcete rovnou výsledek, tak Veselé vánoce

19. prosinec 2013 — Ocas a klepeta

Dnes zase jen obrázkově …

21. prosinec 2013 — Force

Občas je skleróza výhodou (opětovné sledování filmů, čtení knížek a pod.), ale v programování robotů to u mne mnohdy vede ke vzteku. Je pravda, že nalezení opakovaných chyb je snazší, ale … a taky by nebylo o čem psát, kdyby hned vše fungovalo, že je to tak?
Hraji si teď s analýzou hodnot získaných pomocí dotazu queryForce(). Mělo by z toho být (zatím teoreticky) poznat, zda je noha robota ve vzduchu, jak moc je zatížená a pod. Přešel jsem tedy na jednoduchou komunikaci s posíláním stavové a příkazové struktury — používal jsem to např. na ATmega8 board nebo u robota Daisy.
A na co jsem za ta léta už zapomněl? Proč nemám rád 16bitová čísla a makra. Postupné rozcházení komunikace jsem si ale celkem užil, tak heslovitě zopakuji. Třeba to také někdo někdy použije:
Nejprve jsem naprogramoval mravence, aby posílal RobotStatus strukturu, včetně kontrolního součtu (jenom triviální součet bajtů aby celkově to vyšlo 0). Na straně PC jsem si v Pythonu jenom napsal for-cyklus:
for i in xrange(1000):
    com.read(1)
… prostě přečti prvních 1000 bajtů a nic víc. com je logovaný COM port.
V druhém kroku jsem ladil část na PC, tj. přehrával jsem si log dokud, neseděl kontrolní součet a výsledná čísla nedávala alespoň trošku smysl.
Ve třetím kroku mravenec pošle data, ale čeká na příkazovou strukturu. Pokud nesedí velikost nebo kontrolní součet, tak rozsvítí červenou LEDku a pípá. Na straně PC se zase snažím rozchodit posílání struktury, dokud mravenec nepřestane pípat. Přijatá data jsou na robotovi pouze parsovaná, ale jinak je ignoruji.
V posledním, čtvrtém, kroku data na robotovi i provádím. Kontrolní součty a packety by v té době už měly sedět v obou směrech a data dávat celkem smysl …
Tak kde se to zadrhlo? No vypadalo to pěkně, až do okamžiku než jsem provedl čtvrtý krok. Noha sebou zuřivě cukla a vypínač byl naštěstí po ruce. Důvod? Indiáni. Byl jsem líný a na straně robota přečetl celou strukturu jako blok bajtů, ale při odesílání indiány (tedy pořadí bajtů u 16ti bitových čísel) dělal ručně. A špatně.
Po přepsání mi ale zase přestal fungovat kontrolní součet. Důvodem bylo lajdácky napsané makro (možná ho asi ještě vyhodím):
#define SEND_WITH_CHECKSUM(X) { Serial.write( (X) ); tmpSum += (X); }
… jo, vyhodím. Prostě jsem byl dříve líný vypisovat jednotlivé části ve struktuře a updateovat tmpSum … a ty složené závorky tam nebyly, takže ve for-cyklu, to tu proměnnou aktualizovalo pouze jednou.
A nějaké výsledky? No zatím je to takové temné. Když se nic neděje, tak je návratová hodnota pro queryForce( číslo pinu ) 30000 nebo -30000. Pokud ale pohybuji byť jedním servem, tak se mění čísla u všech:
m:\git\fireant\force_test>force_test.py logs/fa131221_130511.log
ReplyLog logs/fa131221_130511.log
(8668, 820, 2587, 30000, -1253, -30000, -1464, -30000)
(39156, 820, 2587, 30000, -309, -30000, -1464, 2465)
(2764, 820, 770, -8540, -309, -11147, 94, -15895)
(33120, 820, 770, -8469, -309, -11036, 93, 10878)
(62240, 820, 770, -8503, -309, -11061, 93, 6627)
(30788, 820, 770, -8512, -307, -10971, 93, -9356)
(57476, 820, 770, -8480, -309, -11078, 93, -2126)
(24608, 820, 770, -8640, -309, -11007, 53, 1558)
(51440, 820, 771, -8497, -309, -10944, 14, 878)
(19980, 820, 770, -9693, -307, -11002, 5, 574)
(47964, 820, 770, -9012, -309, -11010, 0, 307)
(13856, 820, 770, -8835, -309, -11032, 0, 112)
(43004, 820, 770, -8633, -309, -11138, 0, 58)
(10160, 820, 770, -8521, -309, -11194, 0, 25)
(37192, 820, 770, -8439, -309, -11073, 0, 1)
(5500, 820, 770, -8403, -307, -11104, 0, 7)
(32176, 820, 770, -8400, -307, -11127, 0, -2)
…
Vysvětlivka k výpisu — čas, napětí baterky (8.2V), pozice serva1, síla serva1, pozice serva2, síla serva2, pozice serva3, síla serva3. Příkaz byl nechat servo1 a servo2 být a posunout servo3 do polohy 0.
P.S. to makro jsem dal pryč. Jinak zdrojový kód k těmto pokusům najdete na githubu v adresáři force_test.
P.P.S.S. „Rolničky”

23. prosinec 2013 — MIDI

Asi bych svoji bývalou profesorku na klavír moc nepotěšil, kdybych jí řekl, že teď elektronické piáno používám na testování chodících robotů … po pravdě ani mne by to dříve nenapadlo, ale ono se to samo nabízí. Vedle testování správné polohy, jde testovat „sílu úderu” a celkové časování. A není to jen slyšet, je to i možné vidět v číslech. Jak? Pomocí MIDI.
MIDI je zkratka za Musical Instrument Digital Interface. Je to cesta, jak si předávat informace mezi elektronickými nástroji. „Shodou okolností” (tenkrát to byl jeden z mých požadavků, aby to piáno MIDI mělo a mohlo se spojit s Atari ST 1040 ) MIDI výstup mám a cca před půl rokem jsem si koupil i MIDI-USB převodník. Původní motivace byla zkusit dodělat nějaký hudební doprovod k němým filmům z AD Drone 2, ale znáte to. Snad jednou.
HW tedy je. Co SW? Zeptal jsem se Google na „Python MIDI” a mezi spoustou odkazů byl i náš oblíbený pygame rovnou s MIDI příkladem:
pygame piáno
pygame piáno
Příklad nabízí tři možnosti:
  • výstup na MIDI zařízení
  • logování vstupu z MIDI zařízení
  • výpis MIDI zařízení
Další téma ke studiu tedy je dekódování, co přesně:
<Event(34-Unknown {'status': 144, 'vice_id': 1, 'timestamp': 13878, 'data1': 52,
 'data3': 0, 'data2': 0})>
<Event(34-Unknown {'status': 144, 'vice_id': 1, 'timestamp': 14148, 'data1': 55,
 'data3': 0, 'data2': 39})>
<Event(34-Unknown {'status': 144, 'vice_id': 1, 'timestamp': 14477, 'data1': 55,
 'data3': 0, 'data2': 0})>
<Event(34-Unknown {'status': 144, 'vice_id': 1, 'timestamp': 14552, 'data1': 53,
 'data3': 0, 'data2': 50})>
<Event(34-Unknown {'status': 144, 'vice_id': 1, 'timestamp': 15153, 'data1': 53,
 'data3': 0, 'data2': 0})>
znamená .

8. leden 2014 — Nevěř holka chlapci nevěř

… na micros() časy neměř, uint16_t ti přeteče, robot ti uteče bude tasku konec, uint16_t ti přeteče, robot ti uteče bude tasku konec.
Během offline, robot-free dovolené jsem si jen tak bloumal, jak to vychází s časováním. Serva běží na 50Hz, kdy v 20ms „oknech” robot posílá zhruba 1.5ms pulzy (viz řízení serva), tj. nemá smysl rychleji posílat příkazy ani se ptát na polohu/sílu. Na druhou stranu komunikaci jsem měl na 9600 baud, jeden start bit a jeden stop bit, tj. za sekundu pošle max 960 bajtů a za 20ms zhruba 19 bajtů. Časy při přehrávání logu vypadaly takto:
(11220, 818, 946, -98, -286, 592, -228, -7)
(42852, 818, 944, -98, -286, 286, -228, 1)
(6364, 818, 944, -96, -286, 193, -228, 0)
(37776, 818, 944, -92, -286, 145, -228, 0)
První číslo je v microsekundách a na první pohled vše vypadalo OK, tj. přetečení po 65ms (dvoubajtový int, tj. 65535), perioda zhruba 30ms (42-11 nebo 37-6). Pěkné, není-liž pravda? Jak naznačilo „střevo” v úvodním odstavečku — chyba lávky. V realitě je to jinak. Nějak mi to nedošlo. Jen struktura RobotStatus má 19 bajtů a RobotCmd 12 15 bajtů a jelikož zatím nevysílám a nepřijímám současně tak už ani toto by se za 30ms nemohlo stihnout.
Funkce micros() vrací long int a nikomu nevadilo, když jsem ho rval do uint16_t. Když jsem zvýšil komunikační rychlost 4x na 38400, tak chvílemi začal čas jít pozpátku. Divné co? (pak že se nedá otočit směr času … stačí jen změnit vzorkování) Jasnější to asi bude z obrázku, kdy jsem přešel na milisekundy a v grafu jsou rozdíly časů:
Prostě celá smyčka trvá pro 4x rychlejší komunikaci zhruba 62ms a při přetečení u 65ms si snad důsledek už umíte představit. T, d, dm, dam. Huston, máme problém. Pokud pro vyřízení stavů a příkazů pro 3 serva potřebuji skoro trojnásobek cyklu serva, co potom pro 25 serv?!
Ještě poznámka z MIDI světa — přidal jsem logování jak FireAnt mačká klaviaturu, viz midi.py. Generuje to celkem čitelné výstupy:
[ [ [144, 45, 36, 0], 14315] ]
[ [ [144, 45, 0, 0], 15555] ]
[ [ [144, 45, 46, 0], 16664] ]
[ [ [144, 45, 0, 0], 17937] ]
[ [ [144, 45, 43, 0], 19093] ]
[ [ [144, 45, 0, 0], 21647] ]
[ [ [144, 96, 58, 0], 46968] ]
kde poslední číslo je časová známka (snad generovaná piánem), 144 je stav, 45 číslo klávesy (čísla > 90 používám na ukončení logování) nenulové číslo (36, 46, 43) rychlost úderu (?) nebo 0 nota vypnuta.

9. leden 2014 — Dvě oka upletla a tři vypárala

… pokud vám to nic neříká, tak tak to dělala kněžna Bětka v Rumcajsovi. Prostě rychlost komunikace jsem změnil zpět na 9600 a pak i zakomentoval volání queryForce(). Proč? Abych potvrdil podezření, které jsem při čtení zdrojáků Orion knihovny nabyl: queryForce() je pomalé.
Výsledky:
  • 9600 s queryForce() — 96ms, logs/fa140108_195547.log
  • 9600 bez queryForce() — 64ms, logs/fa140108_195739.log
  • 38400 bez queryForce() — 32ms, logs/fa140108_195936.log (ale místy až 46ms)
  • 38400 s queryForce() … starší měření cca 63ms
Závěr? queryForce() si opravdu vezme 10ms+ na každé servo. Pro 20 serv bych se dostal na 200ms a update na 5Hz a to už není dobré. Důvodem je čekání při SPI komunikaci, které je sice v mikrosekundách, ale delay=5000 je opravdu hodně. Navíc se čeká 2x: po odeslání dotazu a v cyklu, před voláním cmdNOP a čekáním na platný výsledek. Pro queryForce() je 10ms tedy dolní odhad. Když SPI komunikace selže (checksum nebo timeout), tak se vše nekonečně opakuje:
unsigned char ReadPacketB(unsigned char cmd,unsigned delay=1000){
		unsigned int incrc;
		do{
			WritePacket(cmd,++ readindex);
			delayMicroseconds(delay);
			for(int i=0;i<20;i ++){
				incrc=WritePacket(cmdNOP);
				delayMicroseconds(delay);
				if(inpacketcrcincrc && inpacket[0]readindex){
					break;
				}
			}
		}while(inpacketcrc!=incrc || inpacket[0]!=readindex);

		return inpacket[1];
	}
Předpokádám, že pro delay=5000 je důvod a servo deska musí teprve dál komunikovat se samotným servem a stav zjistit … cestu s experimentálním snižováním této hodnoty tedy zatím neplánuji.
A co komunikace přes USB převodník? Nejprve oprava, že to není 19+12 bajtů, ale 19+15 bajtů (zapomněl jsem na start bajt, délku a kontrolní součet), tj. celkově 34 bajtů. Pro 9600 je spodní odhad 35ms, pro 38400 pak 9ms. Rozdíl tedy zhruba 16ms. V reálu to vypadá spíše na něco přes 32ms, takže předpokládám nějaké „paušální” zdržení spíše na PC straně. Data budu brzy posílat delší a pak bych to znova porovnal.
Co dál? Kurt a Nathan doporučují místo queryForce použít trigger (spouštěč?), kdy při překročení zadané hodnoty servo samo zastaví. Skoro bych tipoval, že tedy existuje další (tajný?) příkaz pro Orion digitální servo, kdy tento trigger se už přednastaví přímo na servu a není tedy nutná žádná další komunikace.

10. leden 2014 — Ubuntu

Dnes malá odbočka aneb jak rozchodit komunikaci mravenec — linux/Ubuntu. Důvod? Druhý „soutěžící v paralelním slalomu” používá Ubuntu a má zatím nějaké problémy …
Vlastně to bylo snazší (ťuk, ťuk, ťuk … ono se ještě určitě něco pokazí) než ve Windows, ale to především z důvodu, že jsem tušil, kde bude zádrhel. A byl. Zase VID/PID USB zařízení:
$ dmesg | tail
[ 1092.032093] usb 2-2: new full-speed USB device number 2 using uhci_hcd
[ 1092.235131] usb 2-2: New USB device found, idVendor=0403, idProduct=a559
[ 1092.235140] usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 1092.235147] usb 2-2: Product: Communications Port
[ 1092.235152] usb 2-2: Manufacturer: Basic Micro
[ 1092.235158] usb 2-2: SerialNumber: BMVNT4DB
I na linuxu je tedy třeba nějak říci, že ten VID=0403 a PID=a559 odpovídá standardnímu FTDI serial driveru. Asi nejlepší (funkční) nápovědu jsem našel na Basic Micro foru:
  • vytvořit soubor /etc/udev/rules.d/99-usbftdi.rules s obsahem
# load basicMicro usb2Serial
ATTRS{idVendor}"0403", ATTRS{idProduct}"a559", RUN+="/sbin/modprobe -q ftdi_sio product=0xa559
vendor=0x0403"
(člověk musí mít rootovská práva)
  • restartovat udev:
sudo restart udev
sudo udevadm trigger
Pak už se objeví vytoužený /dev/ttyUSB0.
Instalace „Arduino IDE” proběhla bez problémů — zase jen detail, že aby člověk mohl používat USB port, tak uživatel musí být ve skupině dialout (a je třeba vystoupit a nastoupit). Pak znova upravený příklad na pípání a hurá, jde to programovat i mravenec pobrukuje .
p.s. původně jsem postupoval podle Arduino Tutoriálu, takže některým problémum jsem se možná rovnou vyhnul (konkrétně konflikt s brltty)

13. leden 2014 — zapojeno 18 serv

Zítra je den D a ještě stále nechodím. Rozhodl jsem se jít cestou Record & Replay s tím, že jsem nejprve upravil kód aby respektoval executeAt parametr a pak přidával serva.
Zatímco přechod ze tří serv na devět vyžadoval drobné změny, přechod na 18 serv už byl triviální. To zní jako vítězství, ale … když jsem po record pustil replay, tak vždy levá přední noha šla do nesmyslné polohy (jiné, než nahrávané). Důvod? Ani kabeláž, ani porouchané servo, ani chyba v kódu … chyba byla v nějakém prehistorickém zápisu do registrů servo-desky. Matně si vybavuji, že mi to kdysi zlobilo už při „hraní na piáno” a „vyřešil” jsem to tak, že jsem začal používat jinou nohu. Ve zkratce řešení bylo zavolat v kódu Orion.resetRegs() a servoMin se změnilo na -2000, servoMax na 2000 a AOffset na 0. Teď se to chová správně, tj. co nahraji, to i přehraji … je čas jít spát.

15. leden 2014 — druhý FireAnt

Včera proběhlo první „pracovní setkání mravenců”. Přestože to jsou příbuzný
2x FireAnt
2x FireAnt
(stejná stavebnice), rozhodně to nejsou klony nebo jednovaječná dvojčata. Pominu-li vliv prostředí na vývoj jedince, pražská mutace měla jednu nohu obráceně (sám jsem si toho nevšiml, ale vlastně to je jen „kosmetický detail” nemající vliv na „funkci rostlináře” ), rozdíly byly i základních dílech. Mám na mysli především jiné mozky: můj mravenec má v sobě ATmega328 s deskou „Arduino Duemilanove” a ten druhý nevím jaký má čip (deska byla pěkně zadrátovaná v těle), ale deska to je typ „Uno”!
Další rozdíl byl v USB VID/PID. Když jsem to chtěl řešit a koukal do dmeg, tak jsem tam myslím zahlédl PID=6000 (?), ale nejsem si 100% jist. Proč jsem tomu nevěnoval větší pozornost? Protože to bylo standardní FTDI IDčko, na Ubuntu notebooku byl vidět /dev/ttyUSB0 a tato část rovnou fungovala.
Novinkou bylo Playstation2 rozhraní a třída BMPS2. Až když jsme to konečně prokopali jsem pochopil, že je to další převodník, který se pro Arduino desku tváří jako sériový port. Ne úplně zanedbatelný čas padl na chybu v zapojení — přijímač je třeba zapojit na Arduino pin 6, nebo v kódu změnit číslo na této řádce:
BMPS2 ps2x(6,100);	//Use Arduino Pin 6 with 100ms maximum refresh rate
V půl desáté večer už Francouzko-kanadský FireAnt s oficiálním firmware naběhl a přes PS2 šla spustit kalibrační procedura. Je třeba se všemi klouby hýbat do extrémů a definovat mechanické limity. Při této „rozcvičce” ale povolil spoj u konektoru baterky a stejně už bylo dost hodin … nic, pokračování zítra, resp. dneska.
Z věcí, které se nám zatím nepodařilo rozchodit, mne asi nejvíce vadí komunikace z Pythonu přes /dev/ttyUSB0. Přestože pyserial, python i git byly nainstalované, zatím se to nějak bránilo logování pozic serv a zpětnému přehrávání … TODO.
p.s. sešli jsme se na ČZU, kde asi budeme dnes pokračovat s Husky:
Robot Husky
Robot Husky
… a spíše jen z plezíru jsem vzlétl i s Isabele, což je klon Heidi jen s modrou „čapkou” (a bydlí na ČZU).

16. leden 2014 — doubleplusungood

Nefunguje to! To = oficiální firmware na chození s řízením přes PS2 :-(. Došlo i na telefonický hovor přes Atlantik … no prostě je to třeba málem celé rozebrat a zkoušet kousek po kousku.
O předvčerejší chybě v zapojení PS2 přijímače jsem psal a teď už i chápu jak k tomu asi došlo. Robot má 25 serv (18 nohy, 5 čelisti, 2 ocas), ale „servo shield” dokáže řídit maximálně 24. Trik je v tom, že z druhé desky (Arduina) je vyvedeno osm pinů a i ty mohou být použity pro řízení serva. Pokud vám někdo tedy řekne, „zapojte PS2 přijímač na pin 6”, tak je třeba zároveň zdůraznit, že se jedná o Arduino-pin 6.
Věřím, že tedy prapůvodně byl přijímač zapojen na pin 6 servo shieldu a ostatní konektory „pěkně vycházely” (ve finále tam má být jeden volný slot, ale číslo 2 a ne 6). Podobná chyba byla v zapojení serva na pin 16. Na toto přijít s dodávanou kalibrační rutinou a jen poslouchat pípání robota jako zpětnou vazbu snad fakt není ani možné.
OK, to byla první část. Pak jsem odkomentoval define na DEBUG (ano, ve zdrojácích oficiálního firmware), trošku znervózněl při pohledu na řádku:
Serial.begin(625000);
jestli to není „trošku moc” (Nathan mi pak po telefonu vysvětlil, že to je maximální rychlost, kterou to stejně nepojede … že to znamená „cpi tam data jak nejrychleji můžeš”) … stejně jsem to pak změnil na 9600, ale to je jedno. Do kódu jsem přidal skoro za každou řádku výpis na seriák, takže výstup pak vypadal třeba takto:
""" .START! xwaking upwaking done.a>>>>>>>>>>>>>>
..START! xwaking upwaking done.a>>>>>>>>
….START! xwaking upwaking done.a>>>>>>>>>>b
…START! xwaking upwaking done.ab
………..START! xwaking upwaking done.abcd
"""
No, tak trochu boj s větrnými mlýny. Část „a>>>...b” je z cyklu 50x opakuj update serv na ocase a jak vidíte, tak program se kousnul vždy po různém počtu opakovaní. Cyklus jsem zkracoval i úplně vypustil, ale stejně se to po chvíli kouslo a program zamrzl a občas se resetoval. Občas vůbec nenaběhl. Prostě prima.
Nathan zmínil ať ještě raději zkusím vývojové studio Arduino 1.0.1 (co má také na webu), ale dopadlo to stejně jako v mém Arduino 1.0.5. Podezření je na přerušení, tj. že kód na řízení Tail serv s tím nemá nic společného (také jsem ho celý zakomentoval, takže to potvrzuji).
A jak to dopadlo, přesněji jaký je stav teď? Sylvio ráno vyrazil na desetihodinou cestu autem zpět do Francie a druhého mravence mi tady nechal. Takže mám teď dva. Někdo by to interpretoval jako dobrý výsledek, ale já moc nevím … rozhodně je teď o něco více času ověřit to servo po servu a veškerou činnost logovat po seriáku.
p.s. pokud vám dnešní název nic neříká, tak viz Newspeak z 1984

20. leden 2014 — Joséphine pod drobnohledem

Joséphine jsem nazval druhého robota — Sylvio mu říká WeedAnt. Za mne to odpovídá dalšímu písmenku v abecedě po Heidi a Isabele („sestra Heidi” na ČZU). Jméno je z knížky „Ostružinové víno” od Joanne Harrisové, kterou momentálně čtu. Potřeboval jsem se od robotů nějak odreagovat a tak jsem s nimi tento víkend nedělal vůbec nic. Mám-li ještě jednou použít zmíněnou knížku, tak bych citoval Jay někde na straně 184: „Garden work clears the mind”. Krásně to sedělo/fungovalo .
Dnes ráno jsem do Joséphine nahrál týden starý kód na ovládání 18ti serv a ohackoval ho, aby místo queryForce() posílal queryAOffset(), pak flashnul na posílání queryServoMin() a konečně do třetice flashnul aby poslal queryServoMax(). Podle logu to byla práce celkově na necelé tři minuty. A už mám minimálně jedno podezření, co je špatně …
Výsledky pro min, offset, max:
(1675, 810, -458, -692, 1935,  -46, 359, -490, 427, -526, 1857,   206, …
(2296, 810, -458,   26, 1935, -892, 359, -425, 427,  -40, 1857, -1160, …
(1674, 810, -458,  972, 1935, 1954, 359, 1054, 427,  541, 1857,  1961, …
Je to zase čas (ze tří různých logů), napětí baterky, pozice serva 1, hackovaná hodnota serva 1, pozice serva2, … ale když o tom přemýšlím, tak je to možná správně. Kdyby kurňa ty funkce někdo zdokumentoval :-(. Co se mi ještě před chvílí nelíbilo byla poslední vypsaná hodnota (206, -1160, 1961). Nějak stále předpokládám, že pozice serv jsou absolutní, ale možná ne?! Pokud jsou absolutní, tak je to určitě špatně, protože středová poloha by měla být mezi min a max, není-liž pravda? Podle toho, jak Nathan říkal, že na pořadí nezáleží bych soudil, že tomu i tak musí být … ale nevěřím jim. Vyžádané zdrojáky na Sevo Shield stále neposlal, tak jdu asi dělat znova triviální testy s jedním servem na prvním FireAntovi.

21. leden 2014 — BASIC je základ!

Nedělám si srandu . Včera se mnou už lomcoval vztek a sršel jsem síru (ještě ji trošku cítím), sepisoval jsem si koncept „Jsem vážně nespokojený s Vaším produktem ...”, když Nathan odpověděl a poslal zdrojové kódy k Servo Sheiledu. K mému velkému překvapení je to naprogramované v BASICu! Ale asi proč ne. Používal jsem ho naposledy na ZX Spectrum a to už nějaký pátek je. Kód je celkem čitelný, jen zatím netuším co je to zpětné lomítko:
hservo [val1&0x1F\-30000+258]
Tak už WeedAnt chodí? Nechodí a „opakovanou kalibrací nakalibrovat nejde”!!! Trošku jsem se nechal o půnoci unést (viz Orion fórum). Ve zkratce, zkalibrovat FireAnt s existujícím firmware jde pouze poprvé a nesmíte prohodit pořadí kroků kalibrace. Nejprve extrémy min a max a teprve pak středový offset. Po pravdě si myslím, že i to nebude správně ani tehdy (viz níže), ale dokud to nerozchodím, tak si nejsem 100% jist.
O co jde? Surová (raw) vs. zpracovaná data. Sevo se řídí délkou pulzů a to není něco, co by jste chtěli v pěkném API mít. Orion Robotics tedy používají desetiny stupně. V jaké je servo poloze se dozvíte pomocí funkce queryFBAngle(). Tento úhel je již zpracovaný (!) — bere v úvahu offset (nastavitelný pomocí setAOffset() a zjistitelný pomocí queryAOffset()).
Dále zde máme limity, koncové dorazy, pro které se noha již dotýká konstrukce. Ty lze nastavit pomocí funkcí setServoMin() a setServoMax(). Zatímco offset je taková obezlička, aby se vám lépe počítalo (asi), tak tyto limity by na ofsetu měly být nezávislé. Souhlasíte? Jsou.
A teď zpět ke kalibrační proceduře. Pro kalibraci středu rozložíte robota do „stabilizované polohy”, prostě ho rozplácnete, srovnáte natažené nohy, aby se celou plochou dotýkaly podložky. Offsety se nejprve vynulují a až zmáčknete tlačítko, tak se uloží hodnota přečtená pomocí queryFBAngle() jako nový offset. OK?
Pro kalibraci limitů se nastaví proměnné min=3000 a max=-3000, tj. doplňkových 300 stupňů, a průběžně se berou hodnoty z queryFBAngle() a upravují min a max. Po stisku tlačítka se zase všechny uloží.
Je to srozumitelné? Nějaký problém? Ano, hned tři. Pokud máte čistou desku z továrny, tak defaultně jsou registry prázdné a offset je nula. Pokud tedy nejprve kalibrujete limity, tak máte šanci (ve skutečnosti nemáte, ale to později). Pokud ale nejprve zkusíte offsety (to byl náš případ a podle telefonického hovoru s podporou by to i mělo být jedno v jakém pořadí kalibraci děláte), jste na věky ztraceni. Min/max se pak totiž už nesbírá z absolutních čísel, ale z relativních vůči offsetu. Jediná cesta je nějak si resetovat registry Servo Shield desky (je na to funkce, viz jeden starší příspěvek).
A ty další dva problémy? Upravený úhel je nejen posunutý, ale může mít i opačné znaménko (v případě, že nastavíte opačný směr pomocí setServoDir(), což firmware FireAntu používá). Tímto způsobem ale pak kalibrujete opačné limity, které typicky nejsou symetrické.
Do třetice lze i nastavit, kolik tiků časovače je vlastně v realitě jeden stupeň (funkce setServoDegree()) a tato hodnota má vliv snad na všechno. V Servo Sheildu je původní hodnota 178, kalibrace mravence tam nastavuje 176 … to už je relativně drobná odchylka.
Ještě jednu prima chybu na závěr (viz diff). V Assembly Guide se píše: The robot has to be wired based on the default configuration. This configuration can be changed. However it is not recommended. Je to 25 čísel, a tak jsem si vůbec nevšiml, že tato sekce je demo kódu 2x. Navíc piny pro serva na druhé noze byly identické. Zatracený #ifdef CUSTOMPINS). Za mne je to příklad „zbytečného znečtelnění kódu”:
//#define CUSTOMPINS
…
//Servo pin numbers
  #ifdef CUSTOMPINS
#define LFC 21
#define LFF 22
#define LFT 23
#define LMC 20
#define LMF 19
#define LMT 18
#define LRC 17
#define LRF 16
#define LRT 0
#define RFC 13
#define RFF 14
#define RFT 15
#define RMC 12
#define RMF 11
#define RMT 10
#define RRC 9
#define RRF 8
#define RRT 1
#define HeadPitchPin 3
#define HeadRollPin 7
#define HeadYawPin 6
#define PincerLPin 5
#define PincerRPin 4
  #else
#define LFC 23
#define LFF 22
#define LFT 21
#define LMC 20
#define LMF 19
#define LMT 18
#define LRC 17
#define LRF 16
#define LRT 0
#define RFC 15
#define RFF 14
#define RFT 13
#define RMC 12
#define RMF 11
#define RMT 10
#define RRC 9
#define RRF 8
#define RRT 1
#define HeadRollPin 7
#define HeadYawPin 6
#define HeadPitchPin 5
#define PincerLPin 4
#define PincerRPin 3
  #endif

23. leden 2014 — Malé pozorování

Je to divné. Zatím tomu nerozumím. Včera jsem ještě chtěl psát příspěvek „0 1 2 3 SMRT!”, hezky jako v Blesku, ale ráno jsem se to pokusil zopakovat a nepovedlo se mi to. Co jsem teď možná dělal jinak je zapínání — nejprve jsem zapnul robota a pak teprve ho připojoval přes USB k notebooku. Na začátku to vždy pípne, tak jsem si myslel, že se resetuje deska, ale možná jenom jedna z nich??
A co to dělalo předešlé noci (resp. dva dny zpátky)? Nasbíral jsem pro oba roboty polohu středového offsetu a pak místo přehrávání jí celou poslal do robota. Pozice tam stihl poslat 4x (?) a pak už se to kouslo a nic. Smrt.
Změnil jsem kód na
…
  cmdOffset = offset[2::2] # výřez ze stavového pole
  cmdStop = [STOP_SERVO]*NUM_SERVOS
  for selectedServo in xrange(NUM_SERVOS):
    for i in xrange(10):
      print i,
      status = readRobotStatus( com )
      cmd = cmdStop
      cmd[selectedServo] = cmdOffset[selectedServo]
      writeRobotCmd( com, cmd=cmd )
    writeRobotCmd( com, cmd=[STOP_SERVO]*NUM_SERVOS )
    print "END"
Je v tom začátečnická chyba, kdy cmd = cmdStop předá pouze referenci na pole a nechtěně měním původní cmdStop (správně to má být kopie pole pomocí cmd = cmdStop[:]). Výsledkem tedy bylo to, že všechna dosud vybraná serva (selectedServo) zůstala aktivní. Tento kód vždy po chvíli vedl k resetu desky.
Opravená verze, kdy opravdu pouze jedno servo bylo aktivní, se také chovala zajímavě. Každé sudé servo způsobilo po třech vnitřních cyklech chybu kontrolního součtu vysílaného paketu … ale jelo to dál a prošlo to všechna serva.
Zase je tam asi spíš více problémů, ale jeden z nich je „špatné závorkování”. Prostě writeRobotCmd je tam v každém cyklu o jeden více! Nevím, proč by to mělo vadit, ale vadí. Přidáním readRobotStatus() před vypnutí serv se rozhodně „něco” zlepšilo … asi to dává smysl. Zatímco se Arduino snaží realizovat předposlední příkaz, tak poslední příkaz se ztrácí přetékáním Arduino bufferu pro sériovou linku.
Ještě jedno pozorování. To vypnutí serv dělá nějakou neplechu (špatné pozice po následném zapnutí serv), takže ve výsledném kódu jsem plošné vypínání dal úplně na konec programu … ještě tedy ono možná vadí vypnutí všech serv a ne jenom jednoho (???). TODO.
Teď je na čase zopakovat stejný tělocvik s Joséphine …

24. leden 2014 — Self-reset

Tak Joséphine tělocvik nevydržela. Při protahování sedmnáctého kloubu jí to přestalo bavit a resetovala se. To by i vysvětlovalo, proč při ovládání všech serv najednou moc nevydrží. Pokud pohybuji jenom s jedním servem a ostatní vypínám (kód), tak vše funguje a je i dobře vidět, že zapojení všech serv už je správné. Problémy nastanou, když to upravím tak, aby použitá serva zůstala zapnutá.
Čekám na dokončení nabíjení druhé baterky, která je dost nešťastně přidělaná v těle robota (a nedá se snadno vyndat). V plánu mám přidat dotaz queryForce(), který bude sice pomalý, ale mohla by to být taková automatická diagnóza, jestli nějaké servo není problémové. Stejně tak bych v druhém pokusu zkusil vypnout dotazy na polohu, jestli by řízení „normálního” serva nebylo stabilnější.
Trvá to nějak dlouho a musím do práce … tak snad večer …

28. leden 2014 — Uno, Due, …

Říkal jsem si, že bych měl mravence nějak jednoznačně rozlišovat a vzpomněl jsem si při tom na jeden starý vtip o dvou policajtech:
Dvojice policistů dostane na obchůzky dva koně. ,,Jak si poznáme, koho je který?'' ,,Víš co? Já tomu jednomu uříznu ocas a ten bude můj.'' Když ale druhý den přijdou do práce, tak mají oba koně zkrácené ocasy. ,,Víš co? Tak já jednomu uříznu ucho a ten pak bude můj.'' Další den, ale zase oba koně mají uřízlé ucho. ,,Hele co kdybych mu zkusil vypíchnout oko?'' Ale i další den jsou oba koně na jedno oko slepé. ,,Víš co? Co kdyby ty jsi si vzal toho bílého a já toho černého?''
Vtip byl možná ještě morbidnější, ale zapamatoval jsem si ho, protože to byl první (a možná i poslední) vtip, který se mi úspěšně podařil podat v angličtině . No nic, co to má společného s mravencema? Nemám v plánu jim trhat nožičky. Proč je nerozlišovat podle čísla, kdy jeden má řídící desku Uno a druhý Duemilanove .
Jinak je to dost otrava. Přešel jsem na test ověření funkcí setServoMin, setServoMax, setServoDir a setAOffset. A už první pokus přinesl zvláštní poznatky. Nedělám tam nic jiného, než že ve smyčce ověřuji stav baterky a nastavuji polohu jednoho serva. A co se stalo? To jedno servo to nastavilo správně, ale během pár sekund se nastavilo ještě jiné servo! Toto byl FireAntDuo.
Večer jsem to zkusil ještě na FireAntUno. Než se začalo něco podivného dít, tak uplynula delší doba, ale i jemu se po chvíli pohnula pravá prostřední noha nebo levé čelisti. Trošku to podlomilo moji důvěru v implementovanou SPI komunikaci a Orion knihovnu. To by snad měl rozdýchat nebo ne? Uznávám, nebyl tam skoro žádný čas na nádech, ale tak si ho měl zajistit sám?? Možná si ještě zkusím spočítat, kolik těch cyklů se stihne za sekundu …
Když jsem přidal delay(10), tak tyto anomality zmizely, resp. neměl jsem už dost trpělivosti na ně čekat, a mohl jsem přejít k původnímu testu.
Vypadalo to celkem rozumně. Min/max/offset jsou nejspíš absolutní hodnoty pozic serva a je jedno v jakém pořadí se nastaví směr serva setServoDir a offset. I min/max „zařezávaly” požadovaný úhel, že se servo nepohnulo dále. Max je silnější, takže když jsem zkusil nedefinovaný max=-200 a min=200, tak se servo pohnulo do polohy -200.
Konec pohádky. Když jsem omylem nastavil max=-2000 a min=2000, bylo to po pokusu s prohozením min a max, tak se nestalo nic. Když jsem pro správný interval -2000 až 2000 nastavil offset 100 a polohu 1000, tak jednou to šlo do záporného extrému, jednou do kladného a pak to následně nedělalo nic! Napadá mne, že programováním přes USB se asi resetuje pouze Arudino deska a Servo Shield je v nějakém divném stavu. Nebo občas nefungují nastavovací funkce v setup(). Nebo je tam ještě nějaký divný prvek v registrech, který si s tím dělá co chce … dnes ráno mne napadl „force trigger”, který to zabije??
Trošku únavné. Vlastně jsem nezmínil víkendovou motivaci — byl jsem bez robotů bos a tak jsem si četl zdrojáky FireAnt firmware ovládaného přes PS2. Vedle chození všemi směry, otáčení, regulování rychlosti a výšky chůze, by měl mít předprogramovaných deset typů chůze, různé vrtění a protahování … prostě jsem to chtěl vidět v reálném světě . Přepojil jsem PS2 přijímač na Duo (ten se sám od sebe neresetuje), zkusil nakalibrovat a pak zkusil chůzi. Nějaký naznak tam byl, ale nohy byly po jedné kalibraci pod robotem, po druhé hodně natažené a je to celkem agresor a jde z něj strach. Tak postupně 1, 2, …

29. leden 2014 — Gottwaldův koan

Nemyslím nějakého slavného programátora nebo zen-budhistu, ale osobu z dob, kdy se „bojovalo za mír” a skončili jsme ve slepé uličce, protože „zpátky ni krok”. Myslím jedno z hesel … Důvěřuj, ale prověřuj!
Prostě k nastavování parametrů jsem přidal i následné ověření, že daná hodnota byla opravdu nastavena. A kdyby to náhodou nesedělo (velmi nepravděpodobné), tak pípej (viz diff).
… a pípalo to zběsile :-(. Přidal jsem ještě výstup na konzoli a problém je v nastavení offsetu, kdy po setAOffset(100) vracel queryAOffset() nulu. Jak už po delším zápasení ztrácím smysl pro realitu, tak jsem to i napsal na Orion fórum a teprve teď vidím, že tam mám prohozené proměnné. Žádná záhada. „Měl byste se nad sebou soudruhu zamyslet a nestřílet hned na všechny strany...”

30. leden 2014 — Neckerova krychle aneb myšlenkový zlom

Znáte Neckerovu krychli? Pokud ne, tak zkuste např. tento odkaz. Prostě mozek si zafixuje jednu z variant a je hodně těžké přepnout na druhou. A stejný problém jsem měl i já. Prostě setServoMin/setServoMax jsem bral jako fyzické limity nezávislé na čemkoliv, ale ve skutečnosti to jsou „logické” limity a pouze ořezávají vstupní hodnotu pro setAngle(). Teprve pak přichází na scénu offset a směr serva.
Co z toho vyplývá? Především při kalibraci je zásadní nejprve provést nastavení středů (offset) a teprve pak rozsah (min/max). Nastavení směrů pokud možno fixované (jak je v oficiálním firmware). Pokud to uděláte obráceně, tak nastavené limity posunete úplně jinam po změně offsetu.
Nahrál jsem tedy do FireAnta znova původní firmware, ale tentokrát pouze kalibroval rozsah (středy jsem měl už od minule a ty tedy vlastně byly správně a na rozsahu nezávislé). Ovládání přes PS2 je mizerné, ale těší mne, že i ostatní mají problém. Jak to vypadá v reálu se můžete podívat na dost úděsném videu. A ještě jeden dost zásadní detail — aby byl mravenec v nějakém použitelném stavu, musíte ho postavit pomocí opakovaného mačkání kombinace: D-Pad Up + L1.

31. leden 2014 — FireAntUno už běhá!

Je to jak s karetními triky. Když je jednou prokouknete, už nikdy nepochopíte, „jak jste mohli být tak slepí?!” . Takže nejprve díky Ondrovi z práce za rozlousknutí a za RTFM (ošklivá zkratka o čtení manuálu, tady data sheetu). Skoro mám pocit, že u FireAntDuo jsem to na začátku zkoumal, ale u jedničky už jsem to neověřil. A přitom je to tak prosté …
Zajímá vás, proč se FireAntUno stále dokola resetoval? Nepomohla by ani Pavlem doporučená Kubáčova magická dioda. Důvodem byly čtyři špatně nastavené jumpery na Servo Shield desce (na obrázku je zakroužkováno, jak to má být správně — je to staré foto z Due(milanove)). Lze pomocí nich nastavit, zda napájení má být VS nebo VCC, tedy zda přímo z baterky nebo přes regulátor Arduino desky. A na Uno to šlo přes desku. T d dam dam … už to funguje. Viz důkaz.
A co dál? To ovládání přes PS2 je stále mizerné, nepomáhá aní Kurtova oprava (ještě jsem mu to nenapsal). Jelikož Sylvio chce s mravencem natočit krátký film, tak pro to je ovládání celkem kritické. Možná bych přešel na posílání příkazů z PC po USB. Ještě nevím. Každopádně první milník je konečně dosažen.

2. únor 2014 — execGait()

Dnes mám spadeno na tuto funkci:
void OrionClass::execGait(
     int BodyYaw,int BodyRoll,int BodyPitch,
     int BodyRotOffsetX,int BodyRotOffsetY,int BodyRotOffsetZ,
     int BodyOffsetX,int BodyOffsetY,int BodyOffsetZ,
     int Xdist,int Ydist,int Zdist,int Rdist,
     int XLegAdj, int ZLegAdj,
     int Rate,
     boolean EnableForce)
Na můj vkus má trošku moc parametrů, ale zase dělá „úplně všechno” co se týká gait. Toto anglické slovo jsem neznal a znamená (způsob) chůze , držení těla při chůzi. Pokud tím mravence nakrmíte, tak chodí deseti ruznými typy chůze (RG6, RG12, QR9, TRI4, TRI6, TRI8, TRIO12, TRIO18, WAVE12, WAVE18) s tím, že tělo může mít různě vysoko, posunuté do strany nebo dopředu, nakloněné, zvedat nohy hodně nebo málo … a asi ještě spoustu dalších věcí.
Zároveň to snad bude i odpověď na dotaz fandorama přispěvovatele Josefa: Máš v úmyslu do budoucna využívat dodaný firmware, nebo naprogramovat vlastní algoritmus chůze? Původně jsem si chtěl každé servo řídit zvlášť, od každého mít zpětnou vazbu o poloze a síle. Postupem času ale narážím na úzká hrdla a tak možná nejprve zkusím co přímo nabízí Orion knihovna: execGait.
Zdrojový kód pro test chůze je zde, ale zatím tomu moc nerozumím. Používá se TRI4, což předpokládám je vždy trojice nohou statická a trojice se pohybuje. Nevím proč, ale stále mi FireAnt(Duo) zatáčí vpravo. Teď výhoda dvou robotů, … flashuji FireAntUno … tak žádná magie. Uno chodí rovně, takže je to pravděpodobně problém kalibrace.
Jinak do „startovní polohy” (tlačítko A používám na start a tlačítko B na stop, takže mne netrápí zákmity), doslova skočí, takže tím poděsil nejen mne, ale i náš pes okamžitě zdrhnul .
Středy jsem teď na Duo znova překalibroval, ale žádná změna. Že by to zase bylo nějak provázané s min/max? Dnes už na to ale nemám moc náladu …

5. únor 2014 — PlayStation2 protokol

Dokumentace trošku zaostává za pokusy … tentokrát bližší zkoumání PS2. Ovládání mravence nefunguje tak jak bych si představoval a jedno z podezření padá na nespolehlivý příjem příkazů z dálkového ovládání. Původně jsem si myslel, že třetí kabel u přijímače v troj-pinovém servo konektoru je pouze výstup (z pohledu Arduina vstup), ale není tomu tak. Je to vstupně/výstupní seriák a už u tohoto faktu mne trošku zamrazí :-(. Chtěl jsem přepnout vysílání na „stream”, ale nevím jak a asi to ani nejde. Z jedné pseudo dokumentace vyplývá, že je třeba neustále posílat příkazy, na které dostanete odpověď se stavem tlačítek a páček.
Tak to je jeden HW potenciální problém. SW lze zkompilovat s DEBUG a vypisuje na konzoli případné problémy (přidal jsem si tam i výpis, „případného” úspěšného příjmu). Vypadalo to asi takto:
Bad packet FF FF 0 0 0 0 0 0 0 0 0 FF 0 FF 0 0 0 0 0 0 0 0 30 36
Bad packet FF FF 0 0 0 0 0 0 0 0 0 FF 0 FF 0 0 0 0 0 0 0 0 10 36
Data OK
Data OK
Bad packet FF FF 0 0 0 0 0 0 0 0 0 FF 0 FF 0 0 0 0 0 0 0 0 35 32
Data OK
Bad packet FF FF 0 0 0 0 0 0 0 0 0 FF 0 FF 0 0 0 0 0 0 0 0 35 32
Takže se mi to nezdá a něco tam opravdu je špatně!
Chvíli jsem si nahrával výpisy a udělal malou „statistiku”:
count:
     24	Bad packet FF FF 0 0 0 0 0 0 0 0 0 FF 0 FF 0 0 0 0 0 0 0 0 10 36
     85	Bad packet FF FF 0 0 0 0 0 0 0 0 0 FF 0 FF 0 0 0 0 0 0 0 0 30 36
      5	Bad packet FF FF 0 0 0 0 0 0 0 0 0 FF 0 FF 0 0 0 0 0 0 0 0 35 12
     88	Bad packet FF FF 0 0 0 0 0 0 0 0 0 FF 0 FF 0 0 0 0 0 0 0 0 35 32
      1	Bad packet FF FF 0 0 0 0 0 0 0 0 7F 36 0 FF 0 0 0 0 0 0 0 0 15 CC
      1	Bad packet FF FF 0 0 0 0 0 0 0 0 7F 38 0 FF 0 0 0 0 0 0 0 0 46 A3
      2	Bad packet FF FF 0 0 0 0 0 0 0 0 7F 7F 0 FF 0 0 0 0 0 0 0 0 21 CF
      1	Bad packet FF FF 0 0 0 0 0 0 0 0 7F 80 0 FF 0 0 0 0 0 0 0 0 80 C4
      2	Bad packet FF FF 0 0 0 0 0 0 0 0 7F FF 0 FF 0 0 0 0 0 0 0 0 80 65
      1	Bad packet FF FF 0 0 0 0 0 0 0 0 7F FF 0 FF 0 0 0 0 0 0 0 0 A0 65
      1	Bad packet FF FF 0 0 0 0 0 0 0 0 80 7F 0 FF 0 0 0 0 0 0 0 0 16 3C
      2	Bad packet FF FF 0 0 0 0 0 0 0 0 80 80 0 FF 0 0 0 0 0 0 0 0 A7 36
      1	Bad packet FF FF 0 0 0 0 0 0 0 0 80 AB 0 FF 0 0 0 0 0 0 0 0 CF 38
V prvních čtyřech případech má být kontrolní součet 35 36, takže všechny chyby jsou nuly v místech, kde mají být jedničky. Ale ne obráceně. Netuším, zda je to jenom náhoda nebo z počítání kontrolního součtu to je přece jasné?? V plánu mám test bez dalšího kódu pro serva, test s jiným PS2 ovladačem a logování po delší dobu.

7. únor 2014 — test_ps2

Dal jsem teď na github kód testování PlayStation2. Vlastně nedělá skoro nic, jenom dokola čte z PS2. Magie se skrývá v upravené knihovně BMPS2X, kterou kompiluji v DEBUG módu a výpis úspěšných a špatných paketů jsem zkrátil do jednoho bajtu. Dokud nezapnu ovladač, tak je vše OK. Pak začnou chodit špatné pakety, ale systém v tom zatím nevidím — vy ano?
Nepříjemné pozorování je, že chybových paketů je poměrně hodně. Skoro bych si troufl říci, že 50%. Navíc data sbírá poměrně pomalu:
BMPS2 ps2x(6,100);
tj. na PINu 6 poslouchá a čeká 100ms, tedy 10Hz update. Zkusil jsem to snížit na 10 a vůbec se nepodařilo navázat spojení. Posunul jsem to na defaultních 30 a dostal jsem následující obrázek:
Možná je to jenom klika, ale nikde nevidím dvě Béčka po sobě? Často je každý druhý paket špatně, ale stále to znamená rychlejší a spolehlivější komunikaci než při 100ms. Zkusím to obalit a nahradit jedno čtení dvěma. Nebo ještě chvíli experimentovat s tím časem …

8. únor 2014 — Travel Light

Včera už mi došla trpělivost a dálkový ovladač jsem hodil do koše. Skutečnost, že to pro 30ms vycházelo dobře minimálně každý druhý příjem, byla náhoda. Ještě jsem si chvíli hrál s původním kódem mravence a čtení nahradil troj-čtením s čekáním, jestli se to alespoň jednou nechytne, ale nijak viditelně to nepomáhalo. Takže konec a zpět k „verzi 0”.
Extrémisti mají na toto pravidlo: Travel Light, v překladu „cestuj nalehko”. Jinými slovy: „vše, co nutně nepotřebujete, hoďte přes palubu.” Tak už to lítá … žádné dálkové ovladače, žádný Orion.executeGait, žádné kalibrace, žádné setServoMin/setServoMax, žádný setServoDir/setServoDegree. „Proletáři všech zemí, vyližte ...” však víte … to se mi ulevilo . Předpokládám, že se vracím cca 2 měsíce zpět, ale už vím o trošku více a budu si jednoduchosti zase náležitě vážit.
Co teď robot dělá? V zásadě je to kód na ovládání serv přes USB, kdy jako stav vracím aktuální polohu serva a příkaz je požadovaná poloha serva. Nic víc a nic míň. Složitost přesouvám na PC do Pythonu. Kód na chození rovně najdete zde. Při kopírování kódu s použitím Kosinové věty bych si zase nafackoval:
ta,tb,tc = triangleAngles( b, c, d-a ) # TODO z-coordinate
… se skoro divím, že to na to piáno hrálo … když oprava je tak „hrozně složitá”:
ta,tb,tc = triangleAngles( b, c, math.hypot( d-a, z ) )
… ale možná jsem teď jenom „hrozně chytrej” a zanesl jsem tím jinou chybu (viz triangle.py).
Styl chození je ten nejjednodušší, kdy každou chvíli jsou na zemi právě 3 nohy. Úhly pro jednotlivá serva počítám z požadované relativní souřadnice (x,y,z) vůči prvnímu kloubu na těle robota. Přidal jsem tam ještě lineární interpolace mezi starým a novým příkazem a tam končím. A po X měsících jsem „neustálým přešlapováním na místě” konečně vybil baterku …

9. únor 2014 — První zničené servo

Když jsem včera zkoušel ver0, tak jsem slyšel nějaké nepříjemné zvuky. Dnes jsem mravenci „prohmatával klouby” a opravdu minimálně jedno servo je zničené :-(. Je to prostřední servo u prostřední nohy, tj. při 3+3 chůzi je na tuto nohu největší váha, ale že by to vytrhalo zuby?!

20. únor 2014 — Obezita

Obezita není dobrá na klouby. A platí to i pro mravence. Přestože Nathan mi přislíbil poslat náhradní převody (na webu mají krásnou (dost americkou) větu: All Orion Robotics servos come with a no questions asked 2 year warranty. Send us your servo and we will repair or replace it free of charge.) tak mám vážné obavy, že se celý scénář rychle zopakuje.
Kolik FireAnt váží?
Většinu váhy jsou serva, Weighs 2.1oz, česky Unce (1 unce [oz] = 28,3495 g), což i zhruba potvrzuje měření:
Dále je třeba zmínit, že číslo u HV220 digitálního serva znamená 220 oz/in, což je 6.226kg/254 milimetru (viz Palec) a zhruba 2.4kg na 1cm.
A teď páky — noha je běžně 22cm od středu robota, prostřední servo pak 13cm. Při „šťastném” rozdělení váhy 3kg na tři nohy je to 1kg, při nešťastném 1.5kg a více. Na první pohled tedy skoro desetinásobné přetížení specifikace serva?! To nemůže dobře dopadnout!
Je dost pravděpodobné, že mám ve výpočtech/odhadech nějakou zásadní chybu. Hlavní fyzik z bývalého Short Circuits týmu mi na toto téma napsal: „Myslim, ze ty tvoje uvahy jsou principialne dobre. Jen mi prijde, ze zapominas, ze ty sily, co vznikaji jednak musi kompenzovat vahu robota (to uvazujes), ale pak jeste (a na to mozna zapominas) zrychleni robota. A to je hur predpovidatelny, protoze muze byt do vsech smeru...”
Tak nevím — bude to dynamicky ještě horší nebo naopak lepší a vysvětluje se tím, že to občas vůbec funguje? Komentáře vítány .

21. únor 2014 — Robotici sobě!

Tamtamy fungují!
Na pracovním večírku mi kolega říká: „Četl jsem, že už jsi zničil servo?!” … a trošku to znělo jako „slyšel jsem, že jsi Pražákovi naboural sloupek” (Vesničko má středisková) … ale informační kanály fungují! A co víc pod-skupinka se hned vrhla na počítání rozložení sil na mravencově noze . V mezičase přišel mail od Martina Lockera. Poučný. Skoro se stydím. Zase špatné asociace … měl jsem pocit, že Hitec serva měla podobný kód a vycházelo to nějak okolo 3kg/1cm, ale …
,,Ahoj Martine, díval jsem se na tvůj rozbor obezity FireAnta. Trošku bych to poopravil (předpokládám, že tvůj omyl vznikl používáním zcela nesmyslné jednotky "krouticího momentu" - správně má být N.m - resp. v nejhorším kg.cm !!!): 220oz.in odpovídá tedy:
220 x 28,3495 g = 6,237 kg
1 (in) palec = 2,54 cm
220 oz.in = 6,237 x 2,54 = 15,842 kg.cm
(tvůj výpočet 2,4 kg.cm by byl horší než nejlevnější servo, ty mají cca 3kg.cm)
a tedy na rameně 22cm je maximální zatížení 0,72kg.
Jinak dynamické zatížení ti může odlehčit, ale ve většině případů ti naopak přitíží. Při běžné rychlosti pohybu to asi nebude nijak zásadní (předpokládám, že se tam nebudou vyskytovat zrychlení srovnatelná s tíhovým zrychlením g = 9,8 m.s-2). Přesto to není žádný zázrak: pokud předpokládáš maximální statické zatížení 1,5kg, tak je servo dvojnásobně přetížené.''
Tak veřejné díky . Teď to dává smysl.

6. březen 2014 — Náhradní převodovky

Možná se, stejně jako Sylvio, ptáte, co nového s mravencem? Odpověď vás asi zklame — nic. Naplno se věnuji Isabelle a Air Race, kam se letos přihlásilo 17. týmů. FireAnt tedy stojí na druhé koleji …
Můj „momentální mentální blok” je asi spojen se skutečností, že servo, se zpětnou vazbou a detekci sil, se může samo rozbít. To odporuje třetímu robotickému zákonu — „Robot se musí chránit před poškozením, kromě případů, kdy je to v rozporu s prvním nebo druhým zákonem.” A to Servo Shield nedělá. A jsem přesvědčený, že by na to měl schopnosti a defaultně by měl být v nějakém „self-protective” módu.
Prostě výmluvy, výmluvy, … . Stále mám podezření, že vedle přetížení serv si zuby vylámal při počátečním zákmitu. V plánu mám zase přejít na jedno servo, navíc ovládaného přímo pomocí časovače Arduina, a ověřit, že s tím servo nemá nic společného a že je to všechno jenom chyba Servo Shieldu. Stejně jako jsou nesmyslné informace o poloze po startu, tak servo může být asi dost zmatené??
Jinak včera dorazil balík s náhradními ozubenými kolečky od Nathana:
Murphyho zákony fungují dokonale — ráno jsem psal Nathanovi, jesli vůbec něco poslal a v poledne mi to už leželo na stole . Není mi moc jasné, proč mi poslal i náhradní (a hned několik) horní kryty … evidentně Nathan ví něco více, na co já musím teprve přijít …

13. březen 2014 — Výměna ozubeného kolečka

Včera jsem si od Heidi s Isabelle dal na chvíli pohov (verze 0 konečně funguje ) a relaxoval jsem s FireAntem. Výměna ozubených koleček (vyměnil jsem rovnou raději obě) byla až překvapivě snadná. Základní trik je vytáhnout cca 5mm osičky kolmo nahoru a je to. Otázka pár sekund a není třeba žádné násilí! K čemu náhradní kryty ale stále nevím — jedině mne napadá, že pokud by se osička vylomila, tak usazení v tom krytu není dost spolehlivé … hmm. Možná jsem ho opravdu měl rovnou vyměnit. Teď je opravované servo na ocase a tam snad taková zátěž nebude.

2. duben 2014 — Resuscitace

S létáním jsme skončili, tak zase zpátky na zem. Udělal jsem ráno pár rehabilitačních cvičení s mravencem na bedně a šlo to. Především jsem schopen 100% zopakovat smrtelné záškuby pokud ho mezi jednotlivými pokusy zcela nevypnu. Ještě jsem nezkoušel vyndat a zandat jenom USB kabel, ale to počká do zítra.
Je to hrozný, jak se člověk po měsíci nevyzná ve vlastním kódu — asi přijde na řadu „jarní řez” a vše co není bezpodmínečně nutné půjde pryč. Ale znám se, takže to bude spousta přemáhání se . Alespoň, že je tam to README.md a vím, že mám používat ver0.
Při kalibrování vyměněných serv jsem si uvědomil, že to je vlastně taková lékařská preventivní prohlídka. Není vůbec jasné, zda aktuální stav (představte si N-tici celých čísel) je dobrý či špatný, ale podle lékařských záznamů lze poznat, jak moc se změnil. A pokud je to výrazně jiné, tak je něco hodně špatně. Takže teď každý výcvik začne kalibračním testem. Já mu dám sebedestrukci!

8. duben 2014 — nový cíl: Robotem Rovně

Včera prošel fandorama projekt na Robotem Rovně 2014, takže mám teď definovaný krásný mezicíl s deadline 17. května 2014 … ujít autonomně co nejdál to rovně půjde . Zrevidoval jsem kód na chození s tím, že jsem opisoval co to šlo z Orion.execGait() a původního firmware pro FireAnt. A vůbec jsem se nestyděl. Ani trošku.
Ono to totiž spíše připomínalo „reverse engineering” i když jsem měl k dispozici zdrojové kódy. Je to tak strašně univerzální až je to téměř nepoužitelné a celkem nečitelné … nebo prostě už neumím číst komplikovaněji formulované programy.
Pár (možná zásadních) pozorování:
  • všech šest nohou si drží stejný úhel s odstupem 0.125m od kloubu na těle (ověřeno přes math.hypot(1083,625) je 1250.4055342167997)
  • střídá se poloha, kdy jsou všechny nohy na zemi s polohou přesunu trojice nohou
  • dopředný pohyb je symetrický (nohy na zemi se posouvají dozadu zatímco nohy ve vzduchu jdou dopředu)
  • přední a zadní noha je vytočena o 30 stupňů (math.degrees(math.atan2(625,1083)) je 29.98927208927858)
Věřte nevěřte, vypadá to o řád lépe. Prokládám to vypnutím celého robota před každým pokusem a pak už ani ty ošklivé záškuby nenastávají. Celkem mi dost pomohlo staré video, kde je vidět, že ty nohy nejsou v řadě:
Co dál? Přemýšlím, zda v rámci robotického úterka na CZU neudělat nějaký test chůze po dlažbě. Asi jo — test first. Na soutěž Robotem Rovně bych totiž chtěl vyzkoušet „ohmatání si dlažby” a srovnáváním se podle mezer. K tomu bude potřeba ještě pochopit tento řádek:
enableIKForce(LegIndex,1,1);	//enable force detect and clear force flags
v kombinaci s tímto IFem:
if(!Orion.queryIKForceTrig(LegIndex,1))
				//lower leg
Pak si naivně představuji, že se nohy přizpůsobí terénu.
Co jsem zatím moc nepochopil (a tedy zatím nekopíroval) je podivná interpolace mezi dvěma pozicemi:
GaitPosX[LegIndex]+=(Xdist-GaitPosX[LegIndex])/(totalsteps-step);
Podobných řádků najdete v Orion.cpp mnoho. step = (legstep*Rate)+SubStep a totalsteps = UpSteps*Rate, takže je to jasné? V zásadě to vypadá, že step jde od nuly do totalsteps-1, tj. v X-ové se posune o ??? Je-li totalsteps třeba 10, GaitPosX[LegIndex] nula a Xdist jedna. Pak budu mít řadu 0.0, 0.1, 0.1+(1-0.1)/9=0.2, 0.2+(1-0.2)/8=0.3 …
konec záhady hlavolamu. Alespoň chápete, co jsem měl na mysli tím „zpětným inženýrstvím”. Takže já to interpoluji stejně akorát bych to psal jinak, např.
GaitPosX[LegIndex] += Xdist/totalsteps;
Ale možná je tam magie se zaokrouhlováním (to mne ale na PC v Pythonu až tak netrápí, zatím). Vlastně to nedělám stejně — já interpoluji pozici kloubu a ne souřadnice. Teď mi to přijde jedno, ale to uvidím časem …

9. duben 2014 — první outdoor test

Včera jsem vzal mravence poprvé na procházku. A nebylo to tak špatné. Pro přihlížející hrozná nuda, ale vem je ďas . Prodloužil jsem chůzi na 10 metrů a po pokusu v mechu zvedl úroveň zdvihu nohou. Jinak jsem to pouštěl stále do kolečka. Chvíli po dlažbě, chvíli po trávě, jednou do kopce podruhé z kopce …
Dobře pozorovatelná a opakovatelná chyba byla (asi) v komunikaci. Jak když na srnu posvítíte dálkovýma … mravenec chvíli ztuhl a po pár sekundách (?) se zase pohnul dál. Toto se stalo skoro pokaždé v 10m testu, občas i dvakrát.
Druhé pozorování bylo, že homologaci v Písku by nedal. Celkem opakovaně ušel 12 dlaždic rovně a 3 vlevo, tj. cca 7m (dlaždice mají 50x50cm). Toto může klidně být posunutým těžištěm — přeci jenom baterka je tam jen tak položená a kabeláž je právě na levé straně.
Baterka se celkem držela. Vidím 12 logů z nich 8 je kompletních, začínal na 8.14V a končil na 7.42V, plus mínus. 60m by tedy na jedno nabití ušel, snad i násobně více.
Tak problémy s časem jsou v logu viditelné:
…
TIME	13733	146
TIME	13879	1461
TIME	15340	152
…
TIME	12103	143
TIME	12246	573
TIME	12819	148
…
Toto jsou absolutní milisekundové tiky a rozdíl po sobě jdoucích čísel. První zásek je tedy skoro 1.5s a druhý půl sekundy. Zvláštní. Na straně Pythonu žádný timeout a obnovení komunikace není, na straně Arduina je blokované čtení. V případě problému se tedy ani jedna strana nesnaží situaci vyřešit … tak kde se to kousne? Že by moje oblíbené SPI a komunikace se Servo Shield deskou? Jiný viník mne zatím nenapadá.
p.s. koukám teď ještě na průběh chůze u kloubů levé přední nohy:
Sloupce ABC jsou aktuální pozice a DEF jsou pak příkazy. To, že je stav opožděný za příkazy, je očekávané — výpis jsem přidal do funkce update(), která čte stav a posílá nové příkazy. O něco horší je to s množstvím měření. V kódu mám ale opravdu def setLegsXYZ( self, legXYZ, num=2 ):, tj. každý přechod rozfázuji pouze na dva (jeden mezikrok).
Zatím mi nejdivnější přijde soupec F. Není symetrický, protože se jedná o levou přední nohu, která je trošku (30 stupňů) vystrčená dopředu. Nahoru dolu je jasné, ale když je na zemi (hodnoty okolo -600), tak ten zlom se mi nelíbí. Že by to byl ten důvod proč interpolovat v XYZ a nikoliv jednotlivé klouby?

10. duben 2014 — triangle.Unsolvable

Tak jsem to nějak splácal dohromady … brrr. Divný souřadnicový systém noh, offsety, otočení znamének a do toho vylítne výjimka triangle.Unsolvable
Jsou to věci, které člověk podvědomě dávno ví a zná, ale dokud se znova nespálí, tak zapomene, že kamna jsou občas žhavá. Prostě lineární interpolaci mezi dvěma pozicemi v XYZ prostoru občas nedokážete udělat, protože rameno/noha by muselo projít nedosažitelnou oblastí. V mém případě to byl samozřejmě bug, kdy jsem od úhlů zapomněl odečíst offsety a změnit některým znaménka, ale je to spíše varování, že dříve funkce setLegsXYZ() byla schopná interpolovat odkudkoliv kamkoliv a teď už ne.
Původně jsem chtěl prezentovat nový graf a jak je to na něm jasné, že teď už je to opravené (jenom křivky příkazů, přehrávám staré logy s vypnutým identity assertem) a ono to zas tak moc vidět není … ostatně posuďte sami:

15. duben 2014 — Bluetooth

Dnes ráno jsem se konečně rozhoupal a zapojil (přesněji přilepil) Bluetooth modul k Arduino desce FireAnta. Jedná se o starší verzi JY-MCU Bluetooth Wireless Serial Port Module for Arduino, kterou mám zapůjčenou od kolegy z práce. Čtyři piny: zem, napájení, RX, TX … co by mohlo být jednoduššího?
Nejprve jsem zapojil pouze napájení. Na modulu není žádná indikace, ale na notebooku se objevilo nové zařízení H-C-2010-06-01. Klasicky to chtělo PIN, ale naštěstí fungoval jeden ze tří, které jsem kdy v životě na Bluetooth zařízeních potkal: 0000, 1111 a 1234. Připojilo se to a vytvořil se COM10. Tato část šla až moc podezřele hladce …
Bez velkého přemýšlení jsem zapojil zbývající piny na Arduino porty 8 a 9 s tím, že to zkusím a případně v kódu následně prohodím … to nebyl dobrý nápad :-(. Nejen že to nefungovalo, ale když teď nad tím trošku přemýšlím, tak jsem mohl obě strany snadno odpálit (a BT modul možná odpálil?). HW rozhodně není moje silná stránka. Pokusný kód je na githubu, ale zatím to nefunguje.
A k čemu to má celé být? Chci mravence ovládat z Android telefonu a nejsnazším řešením se zdá být právě modrozub. Asi bych si měl pořádně přečíst zdroj, ze kterého čerpám.

16. duben 2014 — Bluetooth revised

„Pěkný obrázek, polovina příkladu”, alespoň tak to říkala moje profesorka matematiky (Jahelková) na GWP … a měla pravdu . Původní obrázek jsem našel na DealExtreme.com:
Je z něj pěkně vidět zapojení pinu RX, TX, kde je PIO11, pro přechod na posílání AT příkazu (dokumentace je např. zde) … tak uvidíme. Druhý pokus.
Vedle správného zapojení PINu se chystám změnit rychlost komunikace. Nějak mi nedošlo, že na modulu není žádná autodetekce a musím tedy použít co je tam právě nastavené. Ondra, kterému modul patří, říkal, že zkoušel maximální rychlosti, takže by to mělo být spíše někde okolo 57600. A nebo přepnout do AT modu a zeptat se na 38400.
BMSerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false);
Tj. jestli koukám správně na zapojení, tak BMSerial bluetooth(8,9); bylo v pořádku. No ale nefunguje to. Čas na snídani …
… tak to vidím na test v práci. Modul je na 3.3V, ale podle dokumentace je modul možné napájet 5V a i UART piny by měly 5V zvládnout. Nikoliv však Logic HIGH level input voltage all other IO pins, který je 3.35V. Pavel S. mne v mailu uklidňoval, že prohozenim RX/TX bych modul odpálit neměl, tak uvidíme. Čeká vás minimálně ještě jedno pokračování .

Křemíkové nebe

A je hotovo. Ptal jsem se ještě Ondry na „permission to kill”, ale nemyslel jsem to moc vážně. No nic, modul je mrtvý a já nepoučitelný. Hlavně mi nikdo nic už raději nepůjčujte …
BT modul je na 3.3V a ta dokumentace, co jsem zmiňoval dříve je k nějakému úplně jinému modulu. V práci mi Ondra potvrdil, že modul stále funguje a že ta záhadná rychlost je 38400baud. I zkusil test, že to běží na 5V, i když to už bylo mimo specifikaci … not good idea.
No zapojil jsem to blbě. Vlastně hůř už to snad ani nešlo. Nejprve modul nešlo detekovat, tak jsem uzemnil PIN 34. Podařilo se mi znova získat COM10 (Pavle, potvrzuji, že je tam zrada se dvěma COMy … COM11 byl k dispozici stále ale byl k ničemu a šlo ho otevřít i když se zařízení tvářilo jako odpojené). Napájení 5V je na krajním trojpinu s jumperem, ALE na všech ostatních trojpinech je v tomto místě signál. A uprostřed je neregulovaných 8V. Sigh. Malá rána a smrad spálené elektroniky …
Tak dobrou noc.
p.s. na 90% jsem ten BT modul odpálil prvním úspěšně poslaným bajtem a časová souslednost tomu odpovídala. Dokud se nesnažil na výstupní pin psát tak se statečně držel, ale když měl mít na výstupu 0V, tak baterka byla příliš silný soupeř :-(

17. duben 2014 — Zádušní mše

V rámci zádušní mše za BT H-C-2010-06-01 jsem na uklidněnou dodal mravencovi trošku inteligence (když už já ji nemám). Celkem pěkné cvičení s generátorama. Do první polohy se už nevrhá slepě, ale v závislosti na aktuální pozici nohou to protažení chvíli trvá … ale stejně jsem myšlenkama trošku jinde a přemýšlím, jak tu smutnou novinu Ondrovi dneska řeknu. Asi ať si přečte novinky na robotika.cz.

18. duben 2014 — Basic Micro Studio

Původně jsem chtěl psát o něčem úplně jiném, ale nová vlna poznání trumfla polemiku na téma volně dostupných informací. Jen ochutnávka na následujících dvou fotografiích:
Jak vypadá ten vyšší trumf? Konečně jsem pochopil, proč ve dříve zmiňovaných zdrojácích k Servo Shieldu (psaných v BASICu) nemůžu najít velikosti pulzů pro zjišťování aktuální pozice a síly serva. Ono to tam totiž není! A kde to tedy sakra je? Vše je to zakopané ještě o další vrstvu hlouběji v knihovnách pro Basic Micro Studio.
RTFM … tak jsem si kousek z manual.pdf přečetl a na straně 123 jsem narazil na hservo [pin\pos\spd, ..., pinN\posN\spdN] HSERVO uses a back ground hardware system to control one or several servos at a time.. Řeší to i záhadu zpětných lomítek, prostě se tak kóduje N-tice. Zajímavá byla i další informace: Notes 1 Analog servos may need to be deactivated. To accomplish this set its position to –24000 on the BAP 24 and BAP 28 modules and to -30000 on the BAP 40 module and ARC32 dev board. Takže teď i vám je jasný „příkaz”
hservo [val1&0x1F\-30000+258]
… no tedy úplně jasné to není. Proč těch +258? V každém případě je to PIN daný proměnnou val1 a pozice je -30000+258.
A jak se to tam celé dostane? Odpověď naleznete na Orion fóru: 6) At top of ide, you will see some Drop down lists. In the first one choose: BasicATOMPro, in the 2nd one choose: "BAP Orion" and in the third one choose the Com port associated with the DaVinci. Prostě je to další speciální Orion knihovna.
V binárce: c:\Program Files (x86)\BasicMicro\Basic Micro Studio\bin\872v3we_18432.bin si moc nepočtu, i když pro případné hackování vidím c:\users\acidtech\desktop\basicmicro source\atomprofirmware\872v3we_18432\872v3we.asm a G našel jediný relevantní odkaz … takže zase Nathan, ale před osmi lety … no nic.
p.s. tak už jsem snad u jádra pudla resp. na dně, ze kterého se budu moci odrazit . Pokud v Basic Mircro Studio odšrktnete v Tools/Preferences/Basic/Delete Temporary Files, tak vám zůstane 223kB orion.ASM … a tam už to musí být. Ideální čtení na Velikonoce A on nějaký „Hello World!” zas tak veliký nebude …

22. duben 2014 — FTDI Latency Timer

S tím assemblerem to tak slavné nebylo :-(. V zásadě se klíčová slova převedou na kódy a ASM mezikrok vyřeší odkazy na proměnné a velikosti skoků. To zajímavé je v LIB souboru a ten snadno čitelný není.
Chci zkusit ještě jednu variantu: naprogramovat H8 Servo Shield v BASICu a komunikovat přímo s ním. První pokus ve mne nevzbudil příliš důvěry — mám takový XP tik, že nejprve mačkám build/test ještě než vůbec něco naprogramuji — no spadlo to:
Můj první program basic.bas zatím nefunguje, ale to se snad podá. Největší obavy mám z toho, že si tímto pokusem uzavřu přístup dalšímu programování, ale asi nemám na vybranou. Snad to nebude jako s BT, kdy první úspěch znamenal konec. Servo Shield a Arduino sdílejí stejný USB-serial převodník, tak jsem napsal ještě nop.ino pro Arduino, který vůbec nic nedělá a je tedy krásně bezkonfliktní
Před mým prvním BASIC programem jsem zkoušel ještě původní firmware. Šlo to, ale strašně dlouho to trvalo (454s … skoro jak z dob ZX Spectra a kateťáku). Důvodem je defaultní nastavení „zpoždění” (Latency Timer) u USB FTDI driveru. Zenta o tom psal na fóru, ale už jsem to pozapomněl. Konečně něco, co se může hodit i jinde … Device Manager > USB Serial Port (COM8) > Port Settings > Advanced … > Latency Timer (msec) … změnit z původních 16 na 1. Pak naprogramování Orion knihovny trvalo necelou minutu .

23. duben 2014 — BASIC Hello World!

Dnes ráno mne to programování v BASICu chvíli celkem i bavilo . Ukázkový „Hello World!” z manuálu mi nejprve zadřel terminál a vypisoval nesmysly, ale přidáním 10ms pauzy už jsem dostal to co chci:
main
	serout s_out, i9600, ["Hello Word!",13]
	pause 10
	goto main
Je pěkné, že Basic Micro Studio má rovnou integrované terminály a tak stačí kliknout na TAB a člověk vidí aktuální výstupy. Potěšil i DEC, což je „příkaz” pro konverzi čísla na textový desítkový zápis:
ADCSR = 0x30	;start scanning AD conversion
serout s_out, i9600, [DEC ADDRA,13]
… tento příklad posílá stav baterky.
Co se mi zatím nepodařilo rozchodit jsou nezdokumentované funkce „HSERVOFEEDBACK', ,,hservofbpos” a „hservofbpwr”. Domnívám se, že tou první celou mašinérii zapnu a pomocí dalších dvou funkcí pak můžu číst polohu serva a aktuální sílu. Když je dám obě do kódu, tak to řve na undefined reference, ale přitom Orion.prj žádnou specialitu s extra knihovnou nemá?! (resp. jí zatím nevidím)

24. duben 2014 — Pomoz si sám …

To byla zase úžasná hodinka s kompilátorem … přistupoval jsem k tomu matematicky, půlením intervalu. Když Orion kód funguje a můj malý kód nefunguje, přesněji nejde zlinkovat, tak někde na půli cesty musí být ta magická instrukce/parametr/define/čert ví co. Nakopíroval jsem všechny zdrojáky do jednoho a to zkompilovat šlo (32kB). Pak jsem odmazával a odmazával, rušil závislosti a stále to zkompilovat šlo (16kB, 13kB, 12kB, 6kB). A pak to přišlo . Po smazání relativně malého kousku kódu se objevila hláška:
C:\Program Files (x86)\BasicMicro\Basic Micro Studio\bin\ld.exe : Unsupported .stab relocation
c:\md\git\fireant\basicv0\basicv0.o(.text+0x568): undefined reference to `HSERVOFBPWR'
C:\Program Files (x86)\BasicMicro\Basic Micro Studio\bin\ld.exe : Unsupported .stab relocation
c:\md\git\fireant\basicv0\basicv0.o(.text+0x56e): undefined reference to `HSERVOFBPWR_OFFSET'
V programu se musí vyskytovat příkaz hservo[cokoliv\cokoliv] … a pak
tmp var word
HSERVOFEEDBACK
tmp = hservofbpwr( 21 )
zkompilovat jde. Průzračné, není-liž pravda?! … F … někdy mám pocit, že je ten život na podobné nesmysly příliš krátký.
… tak ještě malé ranní pokračování. Když se hservo v programu vyskytuje, tak to stačí k úspěšnému linkování, ale stejně to nefunguje . Je to třeba ještě zavolat (pro detaily viz github). Servo 21 tedy slepě posílám do polohy 0, což je naštěstí celkem rozumná poloha. A výstupy mne zprvu zmátly, ale vás určitě ne
LogIt: logs/fa140424_062022.log
24768 SERVO 11
24768 SERVO 9
24768 SERVO 8
24768 SERVO 7
24768 SERVO 14
24768 SERVO 7
24768 SERVO 8
24768 SERVO 65506
24768 SERVO 65345
24768 SERVO 65227
24768 SERVO 65224
24768 SERVO 65348
…
Ano, správně, je to 16bit se znaménkem, tj. místo word stačí použít sword, není-liž pravda?
LogIt: logs/fa140424_062341.log
24768 SERVO 4294967219
24768 SERVO 4294967217
24768 SERVO 4294967184
24768 SERVO 4294967186
24768 SERVO 4294967177
24768 SERVO 4294967179
24768 SERVO 4294967185
24768 SERVO 4294967180
…
WTF by řekli amíci … sword bude mít tedy spíše něco společného s mečem (fráze „dostat se do křížku” by možná v této situaci byla také vystižná) … tak už tak nadšený s DEC výpisu nejsem. Ona i ta tabulka typů v manuálu je nějaká divná:
Byte 8 0 to 255
SByte 8 -128 to +127
Word 16 0 to 65,535
SWord 32 -32,768 to +32,767
Long 32 0 to 4,294,967,295
SLong 32 -2,147,483,647 to +2,147,483,648
…. buď je to překlep nebo Word je opravdu 16bit a SWord 32bit. Nic, kašlu na ně. Stejně to budu chtít posílat binárně a pak se teprve uvidí.
Jdu teď zkusit pozici -30000, která by měla servo zastavit … ale asi už jste získali nějakou představu, jak moc tomu důvěřuji …
Jo, pěkné! Když to bylo ještě v původní pozici 0, kdy se to bránilo, tak to nic nedělalo a bránilo se to dál. Když to vypnu a zapnu, tak servo polohu nemění a data jsou:
LogIt: logs/fa140424_065105.log
24768 SERVO 35536
24768 SERVO 35536
24768 SERVO 35536
24768 SERVO 35536
… volně si tedy pozici 35536 interpretuji jako neznámá pozice, servo vypnuté. Je tedy čas na magickou -30000+258 opsanou z execute.bas v Orion projektu?? Tak trošku se bojím, aby mi to neuseklo ruku … přeci jenom je to predátor.
funguje to … no nic … no comment. Prostě 258 není kompenzace délky vykonávání rutiny přerušení. Tak ještě force feedback, ale to až po snídani …
p.s. čtení hservofbpwr něco dělá. Zkopíroval jsem i servohandler, ale obratem ho musel zase vyhodit … trošku podle očekávání to rozbije komunikaci po sériové lince:
m:\git\fireant\ver0>fireant.py Due walk
LogIt: logs/fa140424_074407.log
1440 : 1548 SERVO 5&077 FORCE 50351
1700 : 1548 SERVO 52077 FORCE 50348
1940 : 1548 SERVO 52073 FORCE 50350
2180 : 1548 S♣RVO 52074 FORCE 50348
2420 : 1548`SERVO 52076 FORCE 50349
2660 : 1548 SERVO 52077 FORCE 50350
2900 : 1548 SERVO 52075 FO$CE 50354
3140 : 1548 SERVO 52077 FORCE 50346
3380 : 1548 SERVO 5207f FORCE 50348
3620 : 1548 SERVO 52075 FORCE 50351
f860 : 1548 SERVO m2071 FORCE 50354
…

25. duben 2014 — Pseudo-pomocníci

Dnes ráno bych zase plakal . Původně měl být tento příspěvek o časovačích na H8, ale třeba na to ještě dojde. Sigh. Jsem fakt tak naivní? (případně si doplňte ošklivější synonyma). Ten BASIC, pěkný jazyc, hlavu mu urazic. Má pěknou funkci HSEROUT:
Syntax
hserout {uart,}[{modifiers}data1,…,{modifiers}dataN]
V BASICu jsou (asi nenadávám teď na všechny, ale jenom na tuto micro edici) jsou proměnné typované (pochybně, alias meč/sword z minula), ale jsou … musí být, nemáte na vybranou. Jinak to nejde zkompilovat. No problem.
Pak máte „super univerzální” funkci na posílání viz výše … pošle vám úplně všechno na světě … k tomu modifiers udělá z čísel případně různé textové reprezentace (desítkovou, šestnáctkovou, binární, …). Tak co by jste čekali, že tato funkce pošle, když jí předáte 16ti bitovou proměnnou (Word)?Já bych čekal, že , že je 16ti bitová a tak pošle dva bajty. Čert vem indiány … ale možná v tom je zakopaná ta válečná sekyra. Zkrátím to. Pošle jeden bajt.
Proč tak vyšiluji kvůli takové blbosti? … prostě mi toto zjištění „chvíli” trvalo a hledal jsem chybu úplně jinde, jako přetékání času (ale ve skutečnosti to byla časo-baterka), jak for-cyklus v BASICu zvládá for i=0 to 0 (teď si myslím, že zvládá a jednou to projde) a pod … No nic, měl bych to ještě dorazit, jestli je to alespoň pravda. Tady je případně původní nefunkční kód.
Pavel S. (fandorama přispěvovatel) mi ráno psal povzbudivý mail a že by původní řídící software vyhodil a napsal vlastní. Asi k tomuto závěru také brzy dojdu. Po Heidi se mi stýská, ale přeci to nevzdám? Zbývá 30-25+17 dní …
p.s. bylo by pěkné, kdyby z tohoto fňukání a mlácení kolem sebe vzniklo něco užitečného, pozitivního … jako příklad mne napadá Feynman a jeho revize učebnic pro střední (nebo základní?) školy

29. duben 2014 — Šicí stroj

„Wow, to byl fofr!” Verze 1 konečně běhá. Nakonec jsem se rozhodl používat stejné interní API jako má Orion knihovna, tj. desetiny stupňů pro určování polohy serv. Také přeindexování pozic serv na jednotlivých pinech jsem dal do nejhlubších funkcí readStatus() a writeCmd(), takže zbytek kódu funguje jako dříve včetně kalibrace .
Abych byl úplně přesný, tak stejně (naštěstí) nefunguje . Je to zhruba 10x rychlejší a navíc sbírá info jak o poloze serv tak o aplikované síle. To ale i znamená, že FireAnt i 10x rychleji šel! Měl bych spíše říci běžel, protože místo třech pohybu za sekundu (update byl okolo 150ms a jedna interpolace) jich teď možná udělal třicet. První asociace byla šicí stroj, od toho název dnešního příspěvku.
Všechno jsem 10x zpomalil, případně 10x zjemnil interpolaci a teď už ušel po podlaze první metr (ten sprint byl „na robotickém špalku”). V plánu mám ještě do posílaných zpráv přidat index příkazu (něco podobného jako je v AR Drone API). Přešel jsem totiž na stream, který spíše připomíná CAN na Eduru — mravenec posílá svůj stav i když se ho nikdo neptá. Myslel jsem, že jednou za sekundu, ale soudě podle zmiňovaného diffu vidím u TIMEOUT hodnotu 100 (ms). Opravím. Problém byl totiž v navazování komunikace. Na rozdíl od Arduino desky, kde to bylo bez problémů, to tady chvíli trvá, než se rozjede cyklus „pošli stav, přijmi příkazy”. Po timeoutu tedy pošle chybovou hlášku ERROR timeout (moc jsem se s tím nepáral — nemám ani LEDky ani bzučák) a aktuální stav.
S tou desetinásobnou rychlostí to zatím stále jenom odhaduji. Možná bych měl podrobněji zmínit ty H8 časovače. Mimochodem dokumentace k H8/3687 je přímo součástí Basic Micro Studio, takže fakt nechápu, proč si někdo dal práci s odstraňováním potisku čipu na Servo Shield desce :-(. Tento čip má tři časovače: Timer B1, Timer V a Timer Z. První dva jsou 8mi bitové poslední 16ti bitový. Problém v kombinaci s BASICem je, že netušíte, které používá „systém”. Timer V byl vypnutý, ale dovoluje pouze 128 prescaling a s 8mi bity je moc rychlý. Timer Z je pak pravděpodobně používán na řízení serv včetně zpětné vazby. Zbývá tedy pouze Timer B1, který má dokonce 2048 a 8192 prescaler, ale už je zapnutý. Použil jsem ho — čtu jenom čítač TCB1.

1. květen 2014 — BASIC Force

Možná to nebude s tou sílou tak marné, jak jsem si ještě před hodinou myslel. Ostatně posuďte sami:
Na grafu vidíte průběhy pozic a sil pro přední nohy, prostřední kloub. Důležité pozorování je, že jak směry serv, tak měřená síla jsou znaménkové a symetricky obrácené. To jestli se mravenec s něčím pere a „neměl by tak tlačit na pilu” záleží tedy na znaménku! A jak je mým špatným zvykem, koukal jsem na ten nezajímavý extrém. Na grafu zelená nad 4000 znamená přetížení … snad .
Upravil jsem trošku kód pro Servo Shield i PC, aby bylo zřejmé jak moc jednočip zaostává s realizací příkazů (viz diff), opravil dekódování síly se znaménkem a teď se chystám (se psem na procházku, ale to sem nepatří) vyzkoušet ty forceIKTrigger, tj. když prostřední kloub překročí daný limit, tak se nebude snažit danou nohu dávat níž. Konečně snad tedy také chápu, proč odlišuje forceTrigger a forceIKTrigger … zastavit totiž jenom jedno servo je nedostatečné.

… jenom připomínka, co má vlastně ohnivý mravenec dělat. Slug Killer. Ten pohled mne na zahradě moc nepotěšil — tak alespoň kompenzační pohled na on-line napojené skalničky.

5. květen 2014 — rrv0.bas

Dneska jsem vypotil opravdu pěkný kus kódu … fujtajbl. Ale doba je zlá a RR nepočká. Už necelých 14 dní. A nemít funkční verzi 0 mne opravdu hodně znervózňovalo, tak jsem to tam zadrátoval natvrdo. Do Pythonu jsem přidal výpis:
print "\tgosub execute", cmd2
a výstup rovnou použil jako BASIC program. Jelikož nevím, jak v BASICu předávat pole, tak jsem to raději rozepsal. Všech 24 serv. No jak říkám, fuj!
A proč ta hysterie? Bluetooth moduly ještě nedorazily a navíc BASIC kód mi stále timeoutuje. Teď mám podezření, že se mu ztrácí některé bajty a jelikož čeká určitý počet, tak nastane timeout. Zároveň si myslím, že nějakou chvíli trvá než vstupní buffer přes HSERIN je dosupný i kódu v BASICu a jak ho zpřístupní, tak už je pozdě. To je zatím jen teorie.
Jeden pozitivní závěr je, že alespoň tuším, jak rychle běží čas (časovač TCB1). Nechal jsem mravence pár minut běžet naprázdno a 269.662s na PC odpovídalo 656.654s na H8 … tj. jeden tik netrvá 1ms, ale 0.41066ms. A to už je poměrně blízko času pro 20MHz oscilátor a 8192 prescaler (8192/20000000. = 0.0004096).
Dnes snad zkusím udělat pár kroku s RaspberryPi a pak bych hard-coded verzi nemusel použít.
p.s. když jsem do kódu chtěl původně přidat i postavení se na nohy, tak už se to do H8 nevešlo:
C:\Program Files (x86)\BasicMicro\Basic Micro Studio\bin\ld.exe : region text is full
   (m:\git\fireant\robotem-rovne\rrv0.bin section .text)
Až mne tedy uvidíte, jak startuji s mravencem ve vzduchu a pak ho teprve pokládám, tak vám bude jasné s jakým programem běží …

6. květen 2014 — status (11 dní do konce)

Je to bída. Zkoušel jsem včera „Hello World!” v assembleru, rozchodit spojení FireAnt-RaspberryPi … o oboje špatně. Ale dokumentovat se mají i neúspěchy, tak to hackování je v gitu.

RaspberryPI

První kroky šly relativně dobře. Malinu mám zapůjčenou (už zase?! to se mne nebojí?!! ) včetně instalační SD karty. Napájení přes micro-USB dobíječku, video kabel jsem musel dokoupit přes vodu v GESu (HDMI-DVI) a pak rovnou zapojil do monitoru, USBčková myš a klávesnice. Vybral jsem si první doporučený Raspbian a už si nevybavuji žádné problémy/další detaily z pátku, kdy jsem to instaloval. Ethernet stačil také jenom zapojit … skoro bych řekl, že tato fáze lepší ani být nemohla .
Git už byl předinstalovaný a stejně tak SSHčko, takže z přepínání monitoru a klávesnice jsem rychle přešel na další otevřený terminál ve spoustě jiných oken. Stejně tak Python byl přeinstalovaný, takže dostat tam nejnovější zdrojáky a githubu byla otázka pár sekund.
První zádrhel:
pi@raspberrypi ~/git/fireant/ver1 $ python fireant.py
Traceback (most recent call last):
  File "fireant.py", line 8, in <module>
    import serial
ImportError: No module named serial
Ale nápovědu člověk rychle najde např. zde, tj. stačilo doplnit:
sudo apt-get install python-serial
Když už jsem byl v tom instalování, tak jsem tam rovnou dal i OpenCV, jak mi poradil Jakub:
sudo apt-get install python-opencv
Chtělo to extra sudo apt-get update, ale jinak OK. Jen ta verze je taková divná — cv2.__version__ vypisuje '$Rev: 4557 $'. No nic, časem uvidíme.
Pak jsem připojil mravence přes USB a inspiroval se vlastními poznámkami k Ubuntu
pi@raspberrypi ~/git/fireant/ver1 $ lsusb
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 006: ID 0403:a559 Future Technology Devices International, Ltd
Bus 001 Device 005: ID 0603:00f2 Novatek Microelectronics Corp.
Toto bylo OK, stejně tak
pi@raspberrypi ~/git/fireant/ver1 $ dmesg | tail
[   21.735417] smsc95xx 1-1.1:1.0 eth0: hardware isn't capable of remote wakeup
[   23.388347] smsc95xx 1-1.1:1.0 eth0: link up, 100Mbps, full-duplex, lpa 0x45E1
[   27.175692] Adding 102396k swap on /var/swap.  Priority:-1 extents:1 across:102396k SSFS
[ 1280.515285] usb 1-1.2: USB disconnect, device number 4
[ 1323.765045] usb 1-1.2: new full-speed USB device number 6 using dwc_otg
[ 1323.893246] usb 1-1.2: New USB device found, idVendor=0403, idProduct=a559
[ 1323.893287] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 1323.893306] usb 1-1.2: Product: Communications Port
[ 1323.893324] usb 1-1.2: Manufacturer: Basic Micro
[ 1323.893341] usb 1-1.2: SerialNumber: BMVNT4DB
Pak jsem přidal zmiňovaný soubor /etc/udev/rules.d/99-usbftdi.rules. Nešlo mi restartovat pomocí:
pi@raspberrypi ~/git/fireant/ver1 $ sudo restart udev
sudo: restart: command not found
ale fungoval podobně znějící
pi@raspberrypi ~/git/fireant/ver1 $ sudo /etc/init.d/udev restart
[ ok ] Stopping the hotplug events dispatcher: udevd.
[ ok ] Starting the hotplug events dispatcher: udevd.
… tak možná ta pravidla jsou v Debianu a Ubutu jinak?? Zkusil jsem ještě reboot a zatím nic.

Assembler

Říkal jsem si, že napsat ten bufferovaný příjem a vysílání nebude takový problém, ale zatím je. Civět do těch pár řádek kódu je celkem otrava. Zkoušel jsem jak BASIC verzi, tak skoro čistou ASM verzi (vše kompiluji v tom Basic Mirco Studio) … ale to se snad podá.
Jako inspiraci používám SPI komunikaci z původních Orion zdrojáků. Přečetl jsem si něco o registrech (jak er0 je 32bit ale přístupný i jako e0 a r0 16bit nebo dokonce r0l a r0h 8bit … … jenom si nejsem jist, jestli všechny kombinace jsou u všech příkazů povolené). Když jsem toto pochopil, tak mi přišlo, že má Nathan chybu v obsluze přerušení … ale třeba z ostatního kódu ví, že e1 je vždy 0 a nikde se nepoužívá?? A nebo to vždy adresuje 16bit prostor, takže je to jedno …
No nic, jedna zrada byl PMR1 registr, kde se nastavuje TXD výstupní pin. Kde je ale problém teď moc netuším. Sigh.

Šroubky

Ještě jednu „vtipnou” poznámku — povolují se šroubky. Skoro jako u starých Merkurových robotů, kde je bylo nutné před každým kolem všechny dotáhnout. Pár jsem jich tedy už asi poztrácel v trávě a možná je to i vysvětlení, proč levá zadní noha trošku pokulhávala …
Robotům zdar!

12. květen 2014 — 2D pohyb (5 dní do konce)

Soutěž „Robotem rovně” je sice o tom jet/jít/letět rovně, ale k tomu je potřeba, přestože to možná na první pohled není zřejmé, i umět trošku zatáčet. V lepším případě chybu rozpozná robot sám a vyrovná ji, v horším (což bude můj případ) robota 3x pustíte, upravíte konstanty a třeba mírným zatáčením dorazí dál.
Pohyb do strany byl ještě relativně triviální. Horší to bylo s otáčením, které jsem trošku odflákl — všechny nohy totiž otáčím o stejný úhel, ale měl bych to dělat podle jejich absolutní pozice. Střed otáčení není tedy úplně dobře definovaný … ale možná pro tu korekci 0.3 stupně, co teď používám, je to jedno.
Řízení robota přes kabel mi stále selhává (timeout). Přidal jsem do reportů i číslo bajtu, na kterém to selhává (viz diff) a kupodivu je to zatím vždy první bajt (hlavička) a nikoliv nějaký chybějící bajt uprostřed paketu. Co je ještě divnější, že se mi pakety neztrácí, „jenom” jsou občas (i v řádu sekundy!) opožděné. Nathan si myslí, že je to mým USB portem a možná má pravdu. Dnes ráno mi došlo, že je asi trošku jiná situace, když mám notebook v napájení než když s ním chodím venku s mravencem a běží z baterky. Na krabici teď „ušel” 10 metrů bez timeoutu.
Mám teď vybitou baterku, tak pokus hned nezopakuji (jo jo, jsou věci, které nechávám na poslední chvíli … dnes koupím druhou … ano měl jsem to udělat dávno!).
Na 90% budu „soutěžit” s rrv0.bas, který před tím vygeneruji v Pythonu s „korekcema šitýma na míru Písku”. Sigh. Za toto asi pivo od Pavla nevyhraji .
A co jinak? V pátek dorazily Bluetooth moduly:
Je na nich celkem přesvědčivé 3.3V, tak se mi to hned na těch 5V připojovat nechce. Teoreticky je to stále stejný modul, jen obalen převodníkem a LEDkama … nevím. Ještě mne trošku odrazuje skutečnost, že když to zkoušel kolega v práci, tak přes Bluetooth se připojil, ale žádná rozumná data nepřenesl (zatím doufám, že to bylo jen chybnou komunikační rychlostí).
Baterka je dobita a Bluetooth zapojen … kdybych si minule napsal, jaký že to mělo PIN … 1234 a opsal jsem to zase z toho původního článku a navíc je tam i rychlost 9600. Jen ten čas už mi teď pomalu chybí …
p.s. tak další 10m test na krabici selhal … jenom ten timeout tam probliknul :-( … CRLF … výpis opraven.
p.p.s.s. test se starým notebookem prošel (jak 10m na krabici, tak 10m chození po chodbě) — zatím žádný timeout. Pokud se to potvrdí i venku, tak dlužím Nathanovi omluvu …

13. květen 2014 — Puzzle (4 dny do konce)

Je to taková skládačka a je to se mnou divný: když něco nefunguje, tak je to „očekávané chování” a když to funguje, tak je to „podezřelé” … při zpětném pohledu se mi tento posun moc nelíbí. Ve zkratce nový Bluetooth modul funguje . Zapojil jsem ho tentokrát správně (ano, 3x jsem to raději kontroloval — zase tolik munice na ohňostroje nemám), změnil komunikační rychlost na 9600 a už to kopíruje znaky z COM8 na COM12 a obráceně. Potvrzuji, co mi dříve psal Pavel S. — vznikl COM12 a COM13 s tím, že pro přímou komunikaci funguje jen ten první. Druhý je asi pro nějaké nastavování, ale to v této fázi zkoumat neplánuji.
Proč „puzzle”? Mám teď kousky skládačky, jenom mi úplně nepasují a nevím, jak je spojit. Servo shield lze ovládat přes USB/sériový port, ale nevím jak s_in a s_out nahradit, aby používal (v BASICu) RXD_2 a TXD_2. S čísly pinů to nesedí. To vidím v generovaném assembleru, že s_in je ve kódované jako 0x20, což by odpovídalo pinu P32, ale na H8/3687 je to ve skutečnosti P21 nebo nožička číslo 45 … no jsem zvědav na rozuzlení. Nathan zatím mlčí a na fóru též.
Je tedy čas na malou pauzu a „context switch” do přípravy Heidi/Isabelle (včera Jakub poslal „větrné logy” a ještě jsem je neprošel … nějak moc robotů …

15. květen 2014 — SW drát (2 dny do konce)

Mravenec už chodí přes Bluetooth! Tedy pomalinku (9600bps), trošku se u toho klepe, ale chodí.
V čem byly problémy? No skoro škoda slov a čas odejít do důchodu . První byl s HSERIN piny … ono to totiž nejsou piny, ale číslo UARTu. Tj. stačí tam dát 1 pro první HW UART a 2 pro druhý HW UART. V detailu to ale až tak zřejmé není. Důležité je, zda zavoláte sethserial1 nebo sethserial2 (nastavuje rychlost komunikace, počet bitů, paritu a pod). Když totiž zavoláte jenom sethserial1, tak pro jakékoliv číslo budete používat první port, včetně dvojky. Nevím, zda podobná situace platí i pro setserial2, ale asi jo. Co mi teď funguje je nastavení obou a použití 2 jako první parametr u HSERIN.
Druhý problém byla oblíbená zvířátka MOSI a MISO (viz programování jednočipu). Že to je Master, In, Slave, Out vím, ale při volání BMSerial jsem to otočil.
Do třetice to byl pull-up na vstupním pinu Bluetooth modulu. Asi by mi to nedošlo, ale pozorování divně blikající zelenou LEDku, kde jsem odpovídající pin zapomněl přepnout na výstupní, trošku pomohlo . A je to i ve zdrojácích BMSerial, který mi předtím fungoval:
pinMode(tx, OUTPUT);
if (!_inverse_logic)
  	digitalWrite(tx, HIGH);
pinMode(rx, INPUT);
if (!_inverse_logic)
    digitalWrite(rx, HIGH);  // pullup for normal logic!
… teď koukám, že bych asi měl otočit i výstup na TXD. Nevím. Jak je to teď to funguje.
Co by to chtělo dál? Změnit rychlost AT příkazy na 38400, naprogramovat mobil, aby si společně pokecali a pak už to jenom několik dní zkoušet … ha ha ha.
p.s. pokud se ptáte, co že to byl ten SW drát, tak jsem z Arduina udělal propojovací desku — prostě místo drátků jsou tam IFy, a na základě přečtené hodnoty se zapne druhý výstup … viz wire.ino

16. květen 2014 — Vylepšený SW drát (1 den do konce)

Dnes ráno jsem zkoušel přepnout Bluetooth modul na vyšší rychlost, ale zatím neúspěšně. Udělal jsem si k tomu přímé zapojení, které by tolerovalo všechny rychlosti. Pak jsem na chvíli propojil KEY a 5V a přepnul se do AT režimu. Chvilku jsem si hrál s CR LF v putty (nevěděl jsem, jak poslat LF … tak příště Ctrl+J), ale pak se dočetl It’s different from HC-04 and HC-06 (They don’t need terminator)., tj. na AT to po chvilce odpoví OK. Ale to je všechno :-(. Verzi, adresu nebo rychlost UARTu jsem z něj nevyrazil.
Ještě tam psali: When PIN34 keeps high level, all commands can be used. Otherwise, only some of them can be used. Ale asi by jim ublížilo říci, které AT příkazy fungují a které ne. Je tedy možné, že to zapojení bylo nedokonalé (což asi bylo, protože to neskočilo na rychlost 38400). Zkusím to ještě v práci s pomocí HW oddělení …
Ještě poznámka k drátování — v gitu je teď verze, která kombinuje USB s Bluetooth. Je mi jasné, že si koleduji, ale … nepřijde vám ideální mít možnost mravence připojit buď po kabelu nebo bezdrátově aniž by bylo nutné ho znova flashovat??

19. květen 2014 — FireAnt na RORO14

Znáte ten pocit, kdy si myslíte, že extra den nebo dokonce jenom hodina by stačila k dodělání soutěžní verze? Zkusili jste to pak dodělat ještě po soutěži, jestli jste si jenom „nelhali do kapsy”? Podobné myšlenky jsem měl i já s mravencem a modro-zubem …
Jak jsem psal, tak mravenec už chodil připojený přes Bluetooth na rychlosti 9600 (i Sylvio ho tak viděl chodit, za což jsem byl rád). Ale nedařilo se mi změnit rychlost na vyšší. AT+UART? nic nedělal :-(. Už jste si pomalu zvykly na různé obskurnosti, tak tady je další: „je naprosto zásadní, jaký firmware v Bluetooth modulu máte!”. Hardware je stále stejný (ten základní BT modul), ale HC-03, HC-04, HC-05 a HC-06 používají různé piny a různé AT příkazy! Já mám firmware HC-06 a tam je pro nastavení rychlosti příkaz AT+BAUD6. Ne, nebudu se rozčilovat.
Na toto zase přišel Ondra a tak jsme překonfigurovali modul na 38400, ale tím to přestalo fungovat úplně. Ten SW drát nebyl úplně dobrý nápad. Vyhodil jsem blikání LEDkama, zakázal přerušení a stále se mi ztrácela půlka bajtů po kabelu a přímé propojení se Servo Shieldem nefungovalo vůbec.
Ještě bych zmínil, že ani nevím jak se dostat zpět na funkčních 9600. Key pin slouží k přerušení spojení s masterem. Na původních 9600 jste automaticky přešly do AT příkazů, pokud nebyl vytvořen pár. Teď už se tam dostat neumím.
Co ten SW drát? Ondra říkal, že je dobré pokud na pulz padnou alespoň 3 vzorky. Pro rychlost 38400 bps, to je 384000 změn (10 bitů = start bit, 8bitů, stop bit) a 3x to jsme na 1MHz. A to už ten Atmel moc věcí udělat nestihne.
Ještě bych zmínil vyhraný boj Ondry, když připojil modul k jeho RS232 převodníku. Nefungovalo to a musel si odpájet jednu ochrannou diodu … prostě je do modul pro Arduino a jinde můžete mít problém.
K RORO14 se teď už asi nedostanu, tak alespoň malá upoutávka, kdy jsem nestačil s dronou včas odstartovat (stahovala staré video):
p.s. na 9600 to lze vrátit příkazem AT+BAUD4, který ještě na původní rychlosti odpoví OK9600

20. květen 2014 — Hrátky s Assemblerem

Zkouším v tom „extra dni navíc” rozchodit mravence a zatím mi to podle očekávání moc nejde. Pro inspiraci používám Inline Assembler Cookbook a data sheet ATmega32. Dobrá zpráva je, že už se zase umím přepnout do AT příkazů — je nutné na notebooku vypnout Bluetooth, aby se nemohly párovat, a pak se k modulu připojit na dané rychlosti. Zkoušel jsem tedy 19200, což bylo o něco lepší, ale nikoliv ideální.
Tak tady je první pokus:
// PD0 = RXD … PIND=0x09, PORTD=0x0B
// PD1 = TXD
// PB3 = MOSI … PINB=0x03, PORTB=0x05
// PB4 = MISO
// PB0 = 8 BT_RXD
// PB1 = 9 BT_TXD

// Bluetooth <-> Servo Shield
void loop()
{
  asm volatile (
    "cli"  "\n\t" // disable interrupts
   "1:" " sbis 0x3,0"   "\n\t"
    "cbi 0x5,3"    "\n\t"
    "sbic 0x3,0"   "\n\t"
    "sbi 0x5,3"    "\n\t"

    "sbis 0x3,4"   "\n\t"  // 1/2/3
    "cbi 0x5,1"    "\n\t"  // 2
    "sbic 0x3,4"   "\n\t"
    "sbi 0x5,1"    "\n\t" // 2
    "rjmp 1b" "\n\t" // 2
    ::);
}
Funkce setup() je stále stejná a tu najdete v gitu. cli vypíná přerušení, sbis (Skip if Bit in I/O Register is Set) přeskakuje když je vstupní bit nastavený a sbic (Skip if Bit in I/O Register Cleared) naopak když je nulový, sbi nastav bit, cbi vynuluj bit a konečně rjmp je relativní skok.
Trošku zrada je to se čtením portů, kdy je nutné číst PINB, ale zapisovat do PORTB, ale to je ve všech jazycích, takže zas tak velké překvapení to není.
Je to tedy hotové? No není. Ty dvojky jsou časy kolik to trvá a pokud chceme na 16MHz mít tři vzorky pro komunikační rychlost 38400, tak máme jenom 16 tiků. Nevím, jak se to přesně u sbis a sbic počítá (jedno číslo je když je podmínka splněna, ale co je to třetí nevím … možná v závislosti na typu portu) — pokud počítám správně tak 18?
Do kódu jsem přidal while smyčku, aby přesněji detekovala změnu na portu (tj. využívám faktu, že jak MISO/MOSI, tak BT_RXD/B_TXD jsou na stejném portu).
"2:"
    "in r0, 0x3"   "\n\t" // 1
    "eor r0, r1"   "\n\t" // 1
    "breq 2b"      "\n\t" // 1/2
celý diff … no na první pohled to moc nepomohlo. Je pěkně vidět, že bitové operace jsou dvojnásob dražší a my navíc potřebujeme sledovat dva piny a nastavovat dva piny. Konečně 1 se přenese s jiným zpožděním než 0.
Jak to paralelizovat? Čtu bit 0 a 4 a zapisuji je do 3 a 1. Pokud budu mít bitové masky, tak 0 -> 0, 1 -> 16, 8 -> 2 a 9 -> 18. Tomu říkám kvíz Celkem by mne zajímalo, jaká vás napadají řešení … něco jako když sedí holka s klukem v parku na lavičce a kluk se po chvíli zeptá „myslíš na to na co myslím já?”. Dívka odpoví „Ano, a kolik ti to vyšlo?” (starý vtip o matfyzácích)
Sigh, tak je to zase prohra. Zkusil jsem verzi přímo se čtením a zapisováním portu a dostal nejprve Error: register number above 15 required, takže jsem r0 a r1 posunul na r20 a r21, ale je tam asi ještě nějaká bota. Nefunguje to.
p.s. matfyzáckou úlohu jsem chtěl řešit přes +24 a prohazování nybble (instrukce swap), ale přes ty bity v registrech mi to přišlo čitelnější a zhruba stejně rychlé … ale stále nefunkční.

21. květen 2014 — CBI vs. CBR

  • CBI — Clear Bit in I/O Register
  • CBR — Clear Bit(s) in Register
Táááák a teď v všichni koukejte jak umím plavat/programovat v assembleru!!!!!! (Mach a Šebestová/Školní výlet). Včera jsem nečekal a rovnou volal o pomoc … MartinaL. Obratem mi odpověděl, ... tak jsem na to kouknul a na 99% procent je tam obvyklá chyba. Instrukce cbr, sbr nepracuje s číslem bitu, ale s bitovou maskou (můžeš nastavit, resp. nulovat více bitů zároveň).
Proč proboha? Vždyť kdybych to takto chtěl udělat tak už na to mám instrukce ANDI a ORI, tj. bitový AND/OR s konstantou, která také trvá jeden tik. Je fakt, že to Bit(s) mi přišlo divné, když jsem to poprvé četl, ale nevěnoval jsem tomu dostatečnou pozornost. Chyba! Ale ne moje .
Troufale bych si dovolil tvrdit, že je špatně navržená instrukční sada, přesněji název je zavádějící a navíc celá instrukce redundantní. Jako argument bych použil citaci je tam obvyklá chyba, tj. když tuto chybu dělají často i ostatní, tak je to designově špatně. Před lety mi kolega z práce „vnutil” knížku The Design of Everyday Things - Don Norman (nevím, jestli toto naskenované PDFko bude stále k dispozici) … je to starší knížka a je o každodenních věcech jako jsou kliky u dveří a pod. Norman popisuje základní psychologické přístupy a např. vysvětluje, co bylo skutečnou příčinou výbuchu atomové elektrárny v USA … a podle mne CBI/CBR do této kategorie patří.
Mile mne potěšilo, že během včerejška přišel ještě další mail od VlastimilD: tak mě napadlo "vzít to přes STATUS", taková vzpomínka, že to nějak šlo, a ono asi ano - zkuste instrukce BST a BLD. Jinak SBR nebere číslo bitu, ale masku, je to vlastně alias pro ORI.
Martinovi i Vlastimilovi díky. Úpravy už jste mohli vidět v gitu: oprava CBR a použití T bitu.
Myslíte, že mne teď mravenec poslouchá? Komunikuje, ale se spousty timeouts a tak je neustále „v křeči”. Takže jenom rychlostí smyčky to asi nebylo. Ale už také vím, že ani extra den přípravy do soutěže by k „inteligentní chůzi” nepomohl.
MartinL navíc psal, že tam mám chybu ve výpočtu: A tedy pro rychlost 38400bd (bitů za sekundu) to dává více než 46 vzorků na bit (16e6 / 9 / 38400 = 46,3 což je více než dostatečné). Ty tvoje hodnoty se mi nezdají (nevím jak jsi na ně přišel). … a má samozřejmě pravdu. 38400 je přenosová rychlost v bitech a nikoliv v bajtech tj. žádné násobení 10 … bylo by naopak třeba dělit deseti, kdyby člověk chtěl vědět, kolik se přenese bajtů za sekundu.
Tak že by to bylo tou ochrannou diodou, co s ní Ondra zápasil v práci?

23. květen 2014 — The Ant End

Když jsem se před mnoha lety bavil s jedním amíkem, jak je to tam u nich hrozné, že se na kole nedá nikam jet, protože jsou všechny cesty slepé (dead end), tak se divil, jaké mrtvé mravence mám na mysli (dead ants) . Je pomalu na čase tento blog skončit. Pokud se vám bude stýskat, tak můžete podpořit blog/článek o Field Robot Event 2014, kde se s mravencem budu snažit o nějakou autonomous show … slimáky jsem si převedl na žluté golfové míčky (budou použité v Task3) a až jednou FireAnta nasadím ve skleníku, tak si tam nejspíše udělám kontrastní „zónu smrti”, kde budou slimáci snadno rozpoznatelní.
autorem snímků z RORO14 je Zdeněk Kakáč

Poděkování

Nejprve děkuji čtyřem fandorama přispěvovatelům: Josef S., Pavel S., Dušan K. a Robert F.
Dále bych chtěl poděkovat aktivním čtenářům, kteří mne opravovali a pomohli mi z různých depresí , tj. Martin L. a Vlastimil D.
Konečně velký dík mají moji HW kolegové z práce Ondra a Honza za ochotnou pomoc s nejrůznějšími problémy.