2. díl - NXJ - základy API a první užitečný program

Java LEGO NXT NXJ - základy API a první užitečný program

V minulém dílu jsme si zprovoznili vývojové prostředí pro NXJ. Dnes si konečně uděláme něco užitečného. Pokud jste si procházeli NXJ firmware na NXT, asi jste si všimli absence nějaké utilitky na odečítaní hodnot z vestavěných rotačních senzorů v motorech a ostatních senzorů. Přesně tento nedostatek dnes částečně zaplníme. Zároveň nám to poskytne prostor k představení některých ze základních tříd, kterými NXJ API disponuje.

Užitečné třídy API

Nejdříve si pojďme představit třídy, se kterými budeme pracovat. Před tím ale ještě trochu terminologie. Budu používat termín “blokující metody” (nevím, jestli to můžu prostě přeložit z “blocking method”, takže mě klidně opravte). Znamená to, že se vlákno zastaví a čeká na její vykonání. Takovým příkladem může být třeba Button.waitForAnyPress().

Motor

Bezesporu jedna z nejpoužívanějších tříd a to ať už přímo, nebo nepřímo, poněvadž jen zřídkakdy bude výstupem programu jen obraz na displeji nebo zvuk. Nejdříve bychom si měli sdělit něco o hardwarové povaze motorů. Jak jsem již zmínil, mají vestavěné rotační senzory, které dokáží s přesností ±1° snímat fyzické natočení výstupu (oranžová část). Zároveň mají nastavitelnou rychlost, a sice ve stupních za sekundu. Maximální rychlost == 100 * napětí dodávané bateriemi, proto závisí na tom, zda používáte alkalické baterie (6*1,5V=9V => maximální rychlost= 900°/s), nebo nabíjecí (6*1,2V=7.2V, plně nabité i přes 8V => používejte rychlost cca 700°/s, 7.2V jsou už většinou baterie skoro vybité). Samotná třída Motor nic neumí, ale o to zajímavější jsou statické instance třídy NXTRegulatedMotor: A, B, a C. Jistě víte, že NXT nabízí výstupy pro 3 motory, které se právě těmito písmeny označují.

NXTRegulatedMotor

Tato třída reprezentuje motor připojený na daný port a k neužitečnějším metodám patří:

  • rotate(int angle) - otočí motor o daný počet stupňů relativně k současné pozici; blokující metoda
  • rotate(int angle, boolean immediateReturn) - stejná jako předchozí, ale pokud uvedete druhý parametr true, nebude metoda blokující
  • rotateTo(int angle) - otočí motor do absolutní pozice k nulovému bodu na nehybném tělu motoru. Blokující, disponuje stejným přetížením jako metoda rotate()
  • forward() - motor se začne točit dopředu, dokud ho jinou metodou nezastavíte
  • backward() - stejně jako předchozí, ale točí se pozpátku
  • stop() - jedna z metod, která zastaví forward() nebo backward(). Po zavolání si motory “zabrzdí” a nelze s nimi otáčet. Blokující, ale zastavení je prakticky okamžité (pokud nezastavujete setrvačník :D)
  • flt() - další metoda k zastavení, ale tentokrát se bude motor volně protáčet. Opět teoreticky blokující, ale nemá smysl se tím zabývat
  • setSpeed(int/float speed) - nastavuje rychlost v °/s
  • getTachoCount() - vrací celkovou relativní rotaci interního rotačního senzoru typu int ve stupních
  • resetTachoCount() - vynuluje interní rotační senzor. (Přesně tohle bude jádro našeho programu) Pozor: na konci se zavolá stop()

LCD

Jak již název napovídá, tato statická třída reprezentuje LCD na NXT. Displej disponuje rozlišením 100*64px a umí jen 2 barvy- černou a bílou (ona není bílá, ale budeme jí tak říkat), nic mezi tím, pokud jste nad tím přemýšleli. Ještě trochu terminologie - LCD znamená liquid crystal display, proto nepoužívejte spojení “LCD displej”, je to barbarské. Metody:

  • clear() - smaže veškerý obsah displeje
  • drawString(String str, int x, int y) - vykreslí str na určených souřadnicích. Nejedná se o souřadnice v pixelech, ale ve znacích. Na jednu z 8 řádek se vejde 16 znaků. Všechny znaky jsou stejně velké (6*8px). Příklad: LCD.drawStrin­g(“hi”,7,3) vykreslí “hi” přibližně uprostřed. Souřadnice pochopitelně začínají nulou.
  • drawInt(int i, int x, int y) - stejné jako předchozí metoda, jen umí kreslit pouze čísla.
  • setPixel(int x, int y, int color) - vykreslí jediný pixel na [x,y], kteréžto souřadnice jsou v pixelech. Barva může nabývat pouze hodnot 1, nebo 0 (1=černá, 0=bílá)
  • scroll() - posune poslední řádek vypsaný pomocí System.out úplně nahoru

Sound

Další statická třída určená jako výstup informací. Ačkoliv se jedná o relativně nepodstatnou část, zjistíte, že ji budete používat relativně často. Metody:

  • setVolume(int vol) - nastaví hlasitost reproduktoru na hodnotu 0-100. Pokud chcete pracovat se zvukem, nezapomeňte ji použít, protože výchozí hlasitost je téměř neslyšitelná.
  • metody pro pípání a podobně, nic, co by stálo za rozebrání

Button

Poslední třídou, kterou si dnes uvedeme, bude třída pro práci s tlačítky. Na NXT najdeme 4 tlačítka - ENTER, ESCAPE, LEFT, RIGHT, každé z nich je reprezentováno číselným id a zároveň instancí třídy Button. Jedinou užitečnou statickou metodou je:

  • waitForAnyPress() - s touto metodou jsme se už setkali, zastaví běh programu, dokud není stlačeno některé z tlačítek, které vrátí jako id typu int. Id je konstanta na Button, vypadá asi takto: Button.ID_ENTER.

Instanční metody jsou mnohem zajímavější, resp. užitečnější:

  • isUp() - vrací boolean, jestli je tlačítko stlačené
  • isDown() - asi nemá cenu popisovat

První užitečná utilitka

Založte si nový projekt (opravdu si ho založte, nepřepisujte “hello world”, později budeme pracovat s jednotlivými projekty, a proto se hodí mít více než jeden) “Motor measure” a přidejte hlavní třídu Main. Všimněte si, že používám anglický název, a protože je to velmi dobrý zvyk, měli byste s anglickým pojmenováváním začít (pokud to už ovšem neděláte). Tento styl budu používat během celého seriálu.

Každý návrh programu musí nutně začít otázkou: Co vlastně chci udělat? Naše současná odpověď by byl program, který bude odečítat rotaci motorů a bude nám je v reálném čase zobrazovat na displeji + bude umožňovat vynulování hodnot. Další otázka bude: Jak? Vzhledem k tomu, že se jedná o opravdu jednoduchý program, použijeme adekvátně jednoduché řešení - necháme běžet nekonečnou smyčku, která bude neustále přepisovat hodnoty na LCD na aktuální. Na začátku cyklu se navíc ujistíme, že není stlačené žádné tlačítko - pokud zjistíme, že ano, provedeme - v případě ENTERu vynulování, v případě ESCAPE ukončení programu. Vystačíme si s metodou main(String[] args)

public static void main(String[] args) throws Exception
{
    NXTRegulatedMotor[] motors = {Motor.A, Motor.B, Motor.C};
    // abychom nemuseli opisovat vše pro každý motor zvlášť, budeme je
    // procházet cyklem

    char[] names = {'A', 'B', 'C'};// písemné označení motorů na stejných
                                   // indexech jako v poli motors

    while (Button.ESCAPE.isUp())
    {
        LCD.clear();//smazat vše na displeji

        boolean reset = Button.ENTER.isDown();// chceme vynulovat motory?

        for (int i = 0; i < motors.length; i++)
        {
            NXTRegulatedMotor motor = motors[i];// motor se kterým pracujeme
            if (reset)
            {
                motor.resetTachoCount();// vynulovat
                motor.flt();// motory se po vynulování zastaví, takto se
                            // budou volně protáčet
            }

            LCD.drawString(names[i] + " " + motor.getTachoCount(), 0,
                    i);
            // v NXJ nefunguje String.format()
        }

        Thread.sleep(50);//uspat vlákno na 50ms
        //kdyby to tu nebylo, displej by podivně problikával
    }
}

Asi nic v kódu není nějaká záhada. Všimněte si, že si uložíme stav tlačítka ENTER na začátku cyklu místo toho, abychom přímo v kódu použili Button.ENTER.isDown(). Děláme to proto, že teoreticky se může stav tlačítka mezi jednotlivými cykly změnit, a takový problém určitě řešit nechceme. Další zajímavost je, že nemůžeme použít String.format(). Proč? Protože to nikdo neimplementoval. NXJ nevyužívá přímo knihovny Javy, ale vlastní. Program si nahrajte a vyzkoušejte. To je pro zatím vše, příště se budeme kódu věnovat zase o něco méně.


 

  Aktivity (3)

Č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 (2 hlasů) :
55555


 


Miniatura
Předchozí článek
Seznámení s NXJ pro LEGO NXT
Miniatura
Všechny články v sekci
LEGO NXT
Miniatura
Následující článek
NXJ - senzory a ladění

 

 

Komentáře

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.

Zatím nikdo nevložil komentář - buď první!