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ę!