Robottiohjelmoinnin harjoitustyö : leJOS+NXT
Yleistä NXT:n ohjelmoinnista leJOSilla
Jonkinlaisen yleiskuvan ominaisuuksista saa lukemalla ja hakemalla RELEASENOTES-tiedostosta. Darby Thompson on kirjoittanut pitkän listan rajoituksista tai bugeista, joista moni lienee jo korjattu, mutta listasta voi silti olla hyötyä mahdollisissa ongelmissa. Sivulla ei täsmennetä mitä versiota on käytetty, päiväyksestä päätellen 0.8 tai uudempaa. Paljon tuoreempi SVN-versiokin on saatavilla, jos tietää mitä tekee.
Robottiohjelman runko on täysin samanlainen kuin tavallisen Java-pääohjelman runko:
public class RobotTest { public static void main (String[] args) { // koodia } } |
Kun koodi on kirjoitettu, pääohjelma käännetään, kytketään NXT päälle ja siihen kaapeli (tai suoritetaan Bluetooth-paritus) ja lähetetään ohjelma:
nxjc RobotTest.java nxj RobotTest |
Tämän onnistumisen jälkeen (palikka päästää nousevan melodian) ohjelma on valittavissa suoritukseen palikan Files-valikosta. Lisäksi komennolle nxj voidaan antaa parametri -r, jolloin ohjelma käynnistetään heti kun se on siirretty NXT:lle, mikä on usein kätevää ainakin testauksen ajan. Oletuksena nxj yrittää ensin lähettää ohjelman USB-yhteydellä ja sen jälkeen Bluetoothilla ensimmäiseen löytämäänsä NXT:hen.
Ohjelmassa voi käyttää suurinta osaa tutuista Javan toiminnoista, kuitenkin pienin rajoituksin johtuen laitteen pienehköstä muistista.
Tiedostojärjestelmä
NXT:n muistiin voi tallettaa ja siitä lukea tiedostoja, mutta tiedostotaulun koko on rajallinen (512 tavua), joten tiedostojen määrää rajoittaa tiedostonimien pituus. Ohjelman tiedostonimi voi päätteineen (.nxj) olla korkeintaan 20 merkkiä pitkä, joten luokan nimelle raja on 16.
- Mitä lyhyempiä tiedostojen nimet ovat, sitä enemmän tiedostoja on mahdollista tallettaa.
Laitteen tiedostoja voi hallita graafisesti nxjbrowse-ohjelmalla.
Ohjelman pysäyttäminen
NXT:n voi sammuttaa painamalla yhtä aikaa etupuolen Enter- ja Escape-nappeja (oranssi & tummanharmaa). Joskus hyvin harvoin laite saattaa jäädä niin jumiin, ettei tämä toimi, jolloin on irrotettava paristo.
Nämä ovat kuitenkin likaisia
tapoja päättää ohjelma, ja moottorit saattavat jatkaa liikettään jonkin aikaa, kenties väärillä arvoilla. Turvallisempi tapa on laatia ohjelma niin, että sen voi päättää siististi jollain painalluksella.
"Hello world" -esimerkki
import lejos.nxt.*;
public class HelloWorld { |
Keskusyksikön toiminnot
Speksejä (Wikipedia)
- 32-bit AT91SAM7S256 (ARM7TDMI) main microprocessor @ 48 MHz (256 KB flash memory, 64 KB RAM)
- 8-bit ATmega48 microcontroller @ 4 MHz (4 KB flash memory, 512 Bytes RAM)
- CSR BlueCore 4 Bluetooth controller @ 26 MHz (8 MBit external flash memory, 47 KB RAM)
- 100×64 pixel LCD matrix display
- A single USB 1.1 port full speed (12 Mbit/s)
- Bluetooth (Class II) wireless connectivity
- 4 input ports, 6-wire cable digital platform (One port includes a IEC 61158 Fieldbus Type 4/EN 50 170 (P-NET) compliant expansion port for future use)
- 3 output ports, 6-wire cable digital platform
- Digital Wire Interface, allowing for third-party development of external devices
Näyttö
NXT:n yksivärinen LCD-näyttö on resoluutioltaan 100x64 pikseliä. LeJOSissa on toimintoja tekstin ja muuttujien tulostamiseen, pikselien piirtämiseen ja grafiikkapuskurien käsittelyyn. Näitä harvemmin tarvitsee tekstin tulostusta enempää, mutta joskus voi haluta näyttöön vaikka kuvaajan näkyviin.
Grafiikan piirtoon on myös kehittyneempiä toimintoja (viivat, suorakulmiot, jne.) luokassa javax.microedition.lcdui.Graphics.
Näytön tyhjentäminen |
LCD.clear(); |
Tekstin tulostus | // konsolitulostus ohjautuu näytölle System.out.println("Hei mualima."); // tulosta teksti kohtaan (11,4) // (huom. merkkikoordinaatit, ei pikseli-) LCD.drawString("Moi", 11, 4); |
Grafiikka | // piirrä yksi musta pikseli (40,25) LCD.setPixel(1, 40, 25); // talleta ruudun sisältö puskuriin byte[] buffer = LCD.getDisplay(); // muuta puskuria . . . // aseta uusi sisältö LCD.setDisplay(buffer); // Kopioi sprite muistista ruudulle kohtaan 15,15 byte[] face = {0x24,0x00,0x18,0x00,0x81,0xff}; LCD.bitBlt(face, 8, 5, 0, 0, 15, 15, 8, 5, ROP_COPY); |
Ruudunpäivitys | // automaattinen päivitys pois LCD.setAutoRefresh(0); . . . // ruudun sisältö ei muutu ennen refresh-kutsua. // Tästä on hyötyä grafiikan piirtämisessä sulavasti LCD.refresh(); |
Napit
Nappeja on keskusyksikössä neljä.
Painallusten lukeminen (karkea tapa) | while(!Button.ESCAPE.isPressed()) { if(Button.ENTER.isPressed()) return "Enter painettu"; if(Button.LEFT.isPressed()) return "Vasen painettu"; if(Button.RIGHT.isPressed()) return "Oikea painettu"; } return "Escape painettu"; |
Painalluksen odotus | Button.ENTER.waitForPressAndRelease(); |
Tiedostot
LeJOSissa on yksinkertainen tiedostojärjestelmä, joka mahdollistaa tiedostojen lukemisen ja kirjoittamisen, esimerkiksi robotin havaintojen tallentamista varten kun bluetooth-yhteyttä ei ole käytettävissä.
Äänen tuottaminen
Palikassa on kaiutin ja se kykenee toistamaan 8kHz taajuista monoääntä. Ääniä voi soittaa joko suoraan taajuusgeneraattorilla tai toistaa 8-bit PWM WAV-näytteitä. Äänitiedostot pitää lähettää palikalle ja lukea ohjelmassa tiedostosta. Koska ääni on pakkaamatonta, ei muistiin mahdu kovin montaa sekuntia.
Sekunnin kestävä 3500Hz:n ääni | Sound.playTone(3500, 1000); |
Systeemiäänien soittaminen | // ääniä 0-4 (ks. API) Sound.systemSound(true, 3); // erilaisia pörinöitä Sound.beep(); Sound.buzz(); Sound.beepSequence(); Sound.beepSequenceUp(); |
"Instrumentit" (ks. API) |
// "ksylofoni", 2000Hz, 0.3s Sound.playNote(Sound.XYLOPHONE, 2000, 300); // "piano", 1500Hz, 0.5s Sound.playNote(Sound.PIANO, 1500, 500); |
Näytteen soittaminen
Ääninäytteen pitää olla muodoltaan 8kHz, 8-bit, mono-WAV. (katso lejos_nxj/projects/samples/SoundSample/SoundSample.java) Äänitiedoston voi muuttaa sopivaksi seuraavasti sox-ohjelmalla (linux):
|
File hihat = new File("hihat.wav"); // palauttaa näytteen pituuden millisekunteina Sound.playSample(hihat); |