3. díl - NXJ - senzory a ladění

Java LEGO NXT NXJ - senzory a ladění

V minulém dílu jsme se seznámili se základy API a předvedli si jeho užití na názorném příkladu. Tentokrát se budeme věnovat něčemu zajímavějšímu - naučíme se číst data z různých typů senzorů. Protože u programů, které využívají telemetrii (senzory), může relativně snadno dojít k výjimce, ukážeme si, jak se s nimi vypořádat.

Senzory

Na NXT najdeme na spodní straně celkem 4 porty pro senzory označené čísly 1-4. Do jakéhokoliv portu je možné připojit jakýkoliv typ, musíte ovšem NXJ sdělit, o jaký senzor se jedná. Pokud byste měli obavy, zda umí pracovat NXJ se senzorem, který jste si přikoupili navíc (třeba gyroskop), odpověď zní, že pravděpodobně ano. Práci s takovým hardwarem tento seriál nepokrývá, proto vás musím odkázat na oficiální článek.

Popíšeme si práci s těmi základními - tlačítkem, světelným, zvukovým a ultrazvukovým. Každý z nich je reprezentován jednou ze tříd API, a způsob vytváření instancí je vždy stejný - uvedu příklad na tlačítku připojenému k portu 1.

TouchSensor ts=new TouchSensor(SensorPort.S1);

Tlačítko

Bezesporu nejjednodušší typ - nabývá pouze 2 stavů, je reprezentováno třídou TouchSensor a disponuje jedinou metodou- isPressed(), která vrací boolean.

Světelný

Pozor, nepleťte si ho s barevným. Tento senzor funguje na jednoduchém principu - obsahuje červenou LEDku a samotný snímač odraženého (vlastně jakéhokoliv) světla. To, jestli má LED svítit, lze určit metodou setFloodlight(boolean onoff). Z toho také vyplývá, že umí číst i intenzitu okolního světla bez přisvětlení. Ke čtení hodnot slouží pár metod:

  • getLightValue() - vrací intenzitu světla typu int- 0=úplná tma, 100=extrémní světlo
  • getNormailsedLightValue() - přesnější předchozí metoda- vrací 0-1023

Zvukový

Osobně jsem pro něj snad nikdy nenašel reálné využití, protože jediná věc, kde se na něj dá spolehnout je aktivace něčeho zvukem - jakýmkoliv zvukem. Disponuje dvěma módy dB a dBA - ačkoliv se může stát, že bude v obou módech vracet stejnou hodnotu, rozdíl je v tom, že dBA (adjusted) “slyší” pouze zvuky, které slyší člověk. Metody má pouze 2:

  • setDBA(boolean dba) - přepínání mezi módy (true=dBA mód)
  • readValue() - vrátí 0-100 podle intenzity zvuku

Ultrazvukový

Jeden z nejzajímavějších senzorů - dokáže určit vzdálenost objektu až na ~1,7m s přesností ± 3cm. Jak to funguje? Samotný princip je relativně jednoduchý - funguje stejně jako echolokace, kterou požívá netopýr - vyšlou se zvukové vlny s frekvencí vyšší, než dokáže člověk vnímat, ty se odrazí (pokud mají od čeho), vrátí se zpět k vysílači a z doby, jak dlouho jim to trval návrat lze spočítat přibližnou vzdálenost objektu. Velké a hladké objekty odráží nejlépe, zatímco menší objekty, zvlášť pokud jsou pokryté jemnou látkou, jsou složité na detekci - na tu látku opravdu pozor, pokud byste vhodným typem pokryli zeď, nemuselo by ji NXT vůbec detekovat.

Protože detekce probíhá pomocí zvuku, který se může různě odrážet, není doporučeníhodné používat více ultrazvukových senzorů v 1 místnosti. Senzor pracuje opět ve dvou módech (vlastně ve 4, ale to je nad rámec tohoto tutoriálu) - ping a průběžný. Průběžný je výchozí, přičemž neustále vysílá vlny a kdykoliv se můžete zeptat na vzdálenost. Druhý normálně nic nedělá, pouze na zavolání ping() vyšle sérii signálů a až 8 z nich zachytí.

  • getDistance() - vzdálenost v cm typu int, pokud nic nezachytí, vrací 255 (průběžný mód). Blokující metoda. V ping módu vrátí vzdálenost prvního echa.
  • continuous() - přepnutí do průběžného módu
  • ping() - vyšle sérii vln, které zachytí. Zároveň zapne ping mód
  • getDistances(int[] distances) - jako parametr bere pole o délce 8, kam uloží výsledky (vzdálenosti) z posledního ping(). Pozn.: chvíli (~~70ms) trvá, než jsou data k dispozici od ping(), proto je blokující.
Vsuvka

Je na místě podotknout, že neuvádím vzorové zdrojové kódy, a mám k tomu 2 velice prosté důvody:

  1. Předpokládám, že umíte Javu - proto se nebudeme učit zobrazovat číslo na displeji.
  2. Kód pro různé typy robotů bude určitě vypadat jinak, takže cokoliv pokročilejšího by nemělo smysl.

Výjimky

Nebudeme chodit okolo horké kaše, výjimky jsou iritující a nelze se jim vyhnout. U NXJ jsou ještě o něco horší, protože způsob, jakým se zjišťuje, kde k ní došlo, je mírně řečeno nepohodlný. Než zabředneme do detailů, napište si krátký program, kde dozajista dojde k výjimce - nejjednodušší bude asi dělení nulou. Ani nemusíte vytvářet nový projekt, s klidem můžete nějak provizorně vložit náš kód do jednoho ze stávajících.

int exc=0/0;

Program nahrajte. Asi vás překvapí na první pohled nicneříkající výpis chyby na LCD. (vaše čísla se budou lišit):

Exception: 27
  at:   25:2
  at:   31:5

Než tlačítkem ESCAPE ukončíte program, zapište si hlášení. Před tím, než si povíme, co to vše znamená, by bylo na místě vysvětlit, proč tomu tak je. NXJ programy po spuštění získají prakticky absolutní moc nad NXT - včetně tlačítek (nelze “hezky” ukončit program) a USB, popř. Bluetooth komunikací (Eclipse neví vůbec nic, s NXT komunikuje jen při nahrávání). To má za následek, že neexistuje způsob, jak zobrazit chybu v lidsky čitelném formátu na tak malém displeji, který je jediný způsob, jak s programátorem komunikovat.

První číslo říká, o jakou výjimku jde, zbytek je “stack trace”. Abychom odkryli, co nám stack trace říká, budeme potřebovat otevřít příkazový řádek v umístění s .nxd zkompilovaným souborem programu. Najdete ho v kořenové složce projektu. (Podržte shift+stiskněte pravé tlačítko myši > zde otevřít příkazový řádek) Použijeme příkaz “nxjdebugtool”, a sice následovně:

nxjdebugtool -di <.nxd_soubor> -c -m 27 25 2

Všiměte si, že nepotřebujeme čísla 31:5 a místo nich používám čísla z vrchního řádku. Výstup bude přibližně:

The class number 27 refers to:
  java.lang.ArithmeticException (ArithmeticException.java)

The method number 25 refers to:
  Sensors.main([Ljava/lang/String;)V (Sensors.java)

PC 2 refers to:
  line 9 in Sensors.java

Moje výjimka byla vyhozena na řádku 9 v souboru Sensors.java v entry pointu- main(String() args) a jedná se o ArithmeticExcep­tion.

Existuje ještě několik způsobů, jak ladit programy, ale musíte se vzdát pohodlného rozhraní Eclipse včetně nahrávání, nicméně způsob, který jsme si uvedli je nejjednodušší v případě, kdy předpokládáte, že kód je v pořádku. V opačném případě byste měli zvážit použití některého z alternativních způsobů.

Opět jsme na konci dílu, a vzhledem k tomu, že umíte veškerý potřebný základ, zkoušejte si před přečtením příštího dílu dělat vlastní programy, protože v něm se přesuneme na počítač.


 

  Aktivity (1)

Článek pro vás napsal Petr Čech (czubehead)
Avatar
Autor se věnuje především desktopovým aplikacím v C#, okrajově Javě na Legu NXT.

Jak se ti líbí článek?
Celkem (3 hlasů) :
55555


 


Miniatura
Všechny články v sekci
LEGO NXT

 

 

Komentáře

Avatar
iqbigbang
Člen
Avatar
iqbigbang:

Kdy bude další díl?

Odpovědět 31. května 5:49
Say me, why not?
Avatar
Petr Čech (czubehead):

Pravděpodobně nebude.

Odpovědět 31. května 14:17
Why so serious? -Joker
Avatar
huty
Člen
Avatar
huty:

Ahoj, ten další díl by se mi hodil :) předpokládám, že přes pc projekt by se mohl robot ovládat na dálku. to bych rád uměl

Odpovědět 21. července 14:54
obecně je lepší používat více proměnných a dodržovat přehlednost, než psát co nejkratší kód a po měsíci zapomenout, j...
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 3 zpráv z 3.