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:
- Stránky výrobce: http://www.orionrobotics.com/FireAnt-Hexapod-Robot_p_248.html
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 …
… omlouvám se za mizernou fotku z
telefonu. LEGO Kobra se umí plazit a i vás uštknout .
LEGO Kobra |
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
jiného (třeba vánoční úklid).
FireAnt a Piano |
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 |
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ý
(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”!
2x FireAnt |
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:
… 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).
Robot Husky |
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 ví, ž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.