public void

Transkrypt

public void
Podstawy programowania w leJOS
Krzysztof Szarzyński – [email protected]
Andrzej Wójtowicz – [email protected]


Wirtualna maszyna Java dla NXT
Obsługuje:
◦
◦
◦
◦
◦
◦

typy podstawowe (float, long, and String),
tablice (również wielowymiarowe),
obiektowość,
obsługa wątków,
Rekursje, synchronizacje, wyjątki
większość:
 java.lang,
 java.util,
 java.io classes.
Posiada dobrze udokumentowane API


Powstał w oparciu o TinyVM
Nazwa:
◦ Nawiązuje do Java Operating System (JOS)
◦ Dodano „le” od LEGO
◦ Nazwa jest podobna do legOS – innego firmwareu
do Mindstorms
◦ Zamieniono „g” na „J” (od Java)
◦ Wymowa (z hiszpańskiego):
 Lehos
 co tłumaczy się na „daleko”.

leJOS był na ISS!
[citation needed]
Piszemy nasz program w pliku NaszProgram

◦

◦

◦

◦

◦
◦
Na przykład w Notepad++
Kompilujemy plik NaszProgram.java
nxjc NaszProgram.java
Linkujemy plik NaszProgram.class
nxjlink -v NaszProgram -o NaszProgram.nxj
Wysyłamy plik *.nxj do kostki
nxjupload NaszProgram.nxj
Uruchamiamy nasz program na kostce
Patrzymy czy działa…
Lub nie 
public class HelloWorld
{
}

Tworzymy plik tekstowy HelloWorld.java
◦ Nazwa pliku musi być taka sama jak nazwa naszego
programu (głównej jego klasy)



Tworzymy klasę HelloWorld
To jest główny obiekt naszego programu.
W nim umieszczamy nasze funkcje i
odwołania do innych obiektów.
public class HelloWorld
{
public static void main(String[] args) {
}
}


Wskazujemy miejsce, gdzie nasz program ma
zacząć działać.
W praktyce od tego zaczyna się każdy
program.
◦ Zmienia się jedynie jego nazwa (nazwa klasy
głównej)
public class HelloWorld
{
public static void main(String[] args) {
System.out.println("Hello World");
}
}

Aby w Javie wyświetlić coś na domyślnym
wyświetlaczu (np. w komputerze Monitor, a w NXT
wyświetlacz LCD) używa się:
◦ System.out.println(„Jakiś tekst");

Jednak nie zobaczymy takiego napisu na ekranie!
◦ Program zakończy się po wykonaniu wszystkich instrukcji w
funkcji main()
import lejos.nxt.*;
public class HelloWorld
{
public static void main(String[] args) {
System.out.println("Hello World");
Button.waitForPress();
}
}

leJOS potrafi oczekiwać na wciskanie
przycisków na kostce.
◦ Używa się do tego klasy Button
◦ Jednak Button nie należy do standardu Javy
◦ Musimy, więc zaimportować z leJOSa narzędzia
(klasy) do obsługi NXT
import lejos.nxt.*;
public class HelloWorld
{
public static void main(String[] args) {
System.out.println("Hello World");
Button.waitForPress();
}
}

Plik HelloWorld.java kompilujemy
◦ nxjc HelloWorld.java
◦ Otrzymujemy plik HelloWorld.class

Łączymy pliki *.class
◦ nxjlink -v HelloWorld -o HelloWorld.nxj
◦ Dostajemy plik HelloWorld.nxj

Wysyłamy plik HelloWorld.nxj do kostki
◦ nxjupload HelloWorld.nxj



Program wykonywany jest po kolej - „linia po
linii”.
Czasami chcemy dokonać zmian w jego
zachowaniu w zależności od jakiś
parametrów.
Służą temu m.in. instrukcje sterujące:
◦
◦
◦
◦
if (…) { }
if (…) { } else { }
while(…) { }
do { } while(…)
if (1>0) {
System.out.println(„1 is greater than 0”);
}
if (true == false) {
//I don't want to live on this planet anymore
}
else {
System.out.println(„True is not false!”);
}
if (Motor.A.isMoving()) {
Motor.A.stop(); // Stop the Motor
}
else {
Motor.A.forward(); // Start the Motor
}
while (true) {
// infinite loop!
}
int i = 0;
do {
i++;
} while (i<10);
int i = 0;
do {
i = Motor.A.getTachoCount();
} while (i<1000);
Motor.A.backward();
while (i>0) {
i--;
}

leJOS udostępnia obiekty odpowiadające
motorom podpiętym do portów:
◦ Motor.A
◦ Motor.B
◦ Motor.C


Każdym z takich motorów można sterować
wywołując odpowiednie funkcję (metody).
Należy pamiętać, że włączony motor będzie
działać tak długo, aż nie zostanie
zatrzymany, albo nie skończy się program.



Podstawowe sterowanie silnikami:
◦
◦
◦
◦
Motor.A.forward();
Motor.A.backward();
Motor.A.stop();
Motor.A.changeDirection();
◦
◦
◦
◦
Motor.A.setSpeed( szybkosc );
Motor.A.flt();
Motor.A.getTachoCount();
Motor.A.resetTachoCount();
Obsługa liczników i mocy:
I wiele innych
◦ (por. dokumentacja leJOSa)

Tekst na ekran można wydrukować na dwa
sposoby:
◦ System.out.println(„Ala ma kota!”);
 Drukuje napis na dole ekranu, przesuwa wszystko o
jeden rząd w górę
◦ Używając statycznej klasy LCD
 LCD.drawString(String tekst, x, y);
 LCD.drawInt(int i, int x, int y);
 LCD.clear();



Button służy do obsługi przycisków.
Button.waitForPress();
Klaiwsze:
◦
◦
◦
◦

Button.ENTER
Button.ESCAPE
Button.RIGHT
Button.LEFT
Każdy w/w klawisz posiada metody:
◦ isPressed();
◦ waitForPress();
◦ waitForPressAndRelease();


Umożliwia odtwarzanie prostych dźwięków
jak i bardziej skomplikowanych melodii
wgranych w specjalnym formacie na kostkę.
Podstawowe metody to:
◦ Sound.playTone(int freq, int len);
◦ Sound.systemSound(boolean queued, int code),





code
code
code
code
code
=
=
=
=
=
0
1
2
3
4
–
–
–
–
–
krótki pisk
podwójny pisk
arpeggio odpadające
arpeggio rosnące
długi, niski buczący dźwięk


Często chcemy, żeby nasz robot robił dwie
rzeczy jednocześnie – niezależnie od siebie.
Na przykład:
◦ Poruszał się
◦ Wyświetlał tekst na ekran


Takie zadania często rozdziela się na wątki,
czyli „równocześnie” wykonywane kawałki
programu.
Takie zadanie spełnia klasa Thread w Javie.

Możemy tworzyć nasze wątki poprzez
rozszerzenie klasy Thread.
class MyThread extends Thread {
@Override
public void run() {
// Do something!
}
}




Tworzymy obiekt klasy MyThread.
Uruchamiamy wątek za pomocą metody start().
Taki wątek pracuje w trybie użytkownika.
Program kończy się, gdy zakończą się wszystkie
wątki użytkownika.
MyThread thr = new MyThread();
thr.start();

Jeżeli chcemy, aby wątek pracował w tle to
możemy go uruchomić jako demon.
◦ setDaemon(true);


Musimy to zrobić przed uruchomieniem wątku.
Wątek zostanei zakończony, gdy wszystkie wątki
użytkownika zostaną zakończone.
MyThread thr = new MyThread();
thr.setDaemon(true);
thr.start();

Aby wcześniej zakończyć wątek użyjemy flag
◦ Zmienne boolean (true/false) i pętla while;

Kiedy zdecydujemy się zakończyć wątek
podniesiemy/opuścimy flagę.
class MyThread extends Thread {
public boolean doIt = true;
@Override
public void run() {
while(doIt) {
// Do something!
}
}
}


Ponieważ zmienna doIt jest publiczna
możemy w każdej chwili dostać się do niej z
zewnątrz.
Zmieniamy ją na false
◦ Doprowadza to do zmiany zachowania naszego
wątku
MyThread thr = new MyThread();
thr.setDaemon(true);
thr.start();
// Do something!
thr.doIt = false;



Usypianie wątków powoduje zatrzymanie ich pracy na chwilę
Wykorzystuję się metodę sleep(int)
Jest to metoda statyczna więc można jej też użyć „poza” wątkiem
class MyThread extends Thread {
public boolean doIt = true;
@Override
public void run() {
this.sleep(5000); // Sleep for 5 seonds
}
}
Thread.sleep(1000); // Pauses the program for 1 second



Kiedy program dokona czegoś
nieoczekiwanego rzuca wyjątek – Exception
Taki wyjątek należy, albo przechwycić i
obsłużyć, albo „wyrzucić” dalej.
Są różne rodzaje wyjątków, np.:
◦ InterruptedException
◦ IllegalThreadStateException

Jednak wszystkie dziedziczą po klasie
Exception.


Jeżeli w naszym programie wykorzystujemy kawałek
ryzykownego kodu (na przykład Thread.sleep()), to w
przypadku wystąpienia wyjątku możemy przekazać
odpowiedzialność wyżej.
Dopisujemy do definicji naszej metody klauzule:
throws Exception:
import lejos.nxt.*;
public class HelloWorld
{
public static void main(String[] args) throws Exception {
System.out.println("Hello World");
Thread.sleep(5000);
}
}

Możemy też obsłużyć wyjątek.
import lejos.nxt.*;
public class HelloWorld
{
public static void main(String[] args) {
System.out.println("Hello World");
try {
Thread.sleep(5000);
}
catch (Exception e) {
System.out.println(„Something went wrong!”);
}
}
}

W dokumentacji
◦ throws InterruptedException

W trakcie kompilacji
◦ Kompilator wyświetla komunikat:
◦ unreported exception
java.lang.InterruptedException;
must be caught or declared to be thrown
◦ „Śmiało” można wyrzucać wyjątki ponad główną
klasę!