10  Klassen- und Methodenübersicht

Dieses Kapitel gibt eine Übersicht über die für die Programmierung des EV3 wichtigsten Klassen und Methoden. Für jede Klasse wird zunächst eine Übersicht über das repräsentierte Objekt gegeben, danach folgt eine Beschreibung der Klassenmethoden, abschließend wird die Verwendung der Klasse an einem Beispiel verdeutlicht.

pict
Der Abschnitt über die leJOS-Klassen und leJOS-Methoden basiert auf dem von leJOS konzipierten Wiki, welches unter http://sourceforge.net/p/lejos/wiki/Home/ eingesehen werden kann.1

10.1  Display

Das Display ist, neben dem Sound und der Hintergrundbeleuchtung der Tasten, die Hauptausgabemöglichkeit des EV3. Auf dem Display können sowohl Textnachrichten als auch Messwerte oder Sensorwerte ausgegeben werden. Dabei handelt es sich um ein schwarz/weiß-LC-Display mit einer Auflösung von 178 x 128 Pixel. Ein Zeichen ist 16px hoch und 10px breit. Somit können in einer Zeile 17 Zeichen untergebracht werden. Durch die Zeichenhöhe ergibt sich, dass maximal acht Zeilen auf dem Display zur Verfügung stehen, beginnend bei Zeile null bis Zeile sieben. Der Ursprung des Koordinatensystems befindet sich, wie in Java üblich, am oberen linken Displayrand (siehe Abbildung 10.1).

pict

Abbildung 10.1.: LCD-Dimensionen des EV3

Die für das Display verwendete Klasse heisst »LCD« und befindet sich im Package »lejos.hardware.lcd« (zum Einbinden in Eclipse: import lejos.hardware.lcd.LCD). Es folgt eine Übersicht über die wichtigsten Methoden zur Verwendung des Displays.

drawString(String str, int x, int y, boolean inverted)
gibt einen String auf dem Display in Spalte x und Zeile y aus. Mit inverted kann der Text farblich invertiert (weiße Schrift auf schwarzem Hintergrund) ausgegeben werden. Die Methode ist static.

Parameter
str  – 

Der anzuzeigende String

x  – 

X-Koordinate

y   – 

Y-Koordinate

inverted – 

Optionaler Parameter zur farblichen Invertierung des Strings.


drawInt(int i, int x, int y)
gibt eine Ganzzahl i auf dem Display in Spalte x und Zeile y aus. Methode ist static.

Parameter
i – 

Die anzuzeigende Ganzzahl

x  – 

X-Koordinate

y   – 

Y-Koordinate

 


drawChar(char c, int x, int y)
gibt einen einzelnen Buchstaben auf dem Display in Spalte x und Zeile y aus. Methode ist static.

Parameter
c – 

Der anzuzeigende Buchstabe

x  – 

X-Koordinate

y   – 

Y-Koordinate

 


clear()
löscht die Gesamte Anzeige auf dem Bildschirm. Methode ist static.


clear(int y)
löscht die Anzeige in Zeile y. Methode ist static.

Parameter
y – 

Zu löschende Zeile


clear(int x, int y, int n)
löscht n Zeichen, beginnend in Spalte x und Zeile y. Methode ist static.

Parameter
x – 

X-Koordinate

y   – 

Y-Koordinate

n  – 

Anzahl zu löschender Zeichen

 


scroll()
lässt den gesamten Bildschirminhalt um eine Zeile nach oben wandern. Methode ist static.

pict
Der Modifier static bedeutet, dass es sich hier um sogenannte Klassenmethoden handelt, die verwendet werden können, ohne vorher ein Objekt der Klasse erzeugen zu müssen. Der Aufruf erfolgt an der gewünschten Stelle mittels LCD.Methodenname(Parameter).
Das Programm 10.1 zur Klasse LCD zeigt den Text »Die Loesung aller moeglichen Probleme lautet: 42«. Dabei wird jedes Wort in einer eigenen Zeile dargestellt. In acht Schritten wird der Text zeilenweise nach oben verschoben, wodurch die oberste Zeile immer aus dem Display verschwindet. Zwischen den Schritten wird der Thread für 1000ms, also für eine Sekunde, angehalten.

Programm 10.1: LCD-Test
 
1import lejos.hardware.lcd.LCD; 
2/∗∗ 
3 This class displays a text on the EV3Display. 
4 After being printed, the text is scrolled upwards out of the screen. 
5/ 
6public class LCDTest { 
7    public static void main(String[] args) throws Exception { 
8        /Print text line per line/ 
9        LCD.drawString("The", 0, 0); 
10        LCD.drawString("answer", 0, 1); 
11        LCD.drawString("to", 0, 2); 
12        LCD.drawString("all", 0, 3); 
13        LCD.drawString("questions", 0, 4); 
14        LCD.drawString("is: ", 0, 5); 
15        /Print Number 42/ 
16        LCD.drawInt(42, 0, 6); 
17        /Scroll seven times/ 
18        for (int i = 0; i < 7; i++) { 
19            Thread.sleep(1000); 
20            LCD.scroll(); 
21        } 
22    } 
23}

Die Ausgabe des Programms auf dem Display des EV3 lautet:

pict

Abbildung 10.2.: Ausgabe des LCD-Test-Programms

10.2  Bedienelemente – EV3 Tasten

Der EV3-Baustein verfügt über sechs Tasten, die direkt unter dem Display platziert sind. Die Tasten sind entsprechend ihrer Ausrichtung benannt, also LEFT, RIGHT, DOWN, UP, ENTER und ESCAPE. Ihre Belegung wurde in Abschnitt 9.3 genauer beschrieben. Die Methoden zur Ansteuerung der Tasten befinden sich in der Klasse »Button« aus dem Package »lejos.hardware« (zum Einbinden in Eclipse: import lejos.hardware.Button). Sie werden mit Button.NAME.Methodenname() angesprochen, wobei der NAME entweder LEFT, RIGHT, DOWN, UP, ENTER oder ESCAPE sein kann. Es folgt eine Übersicht über die wichtigsten Methoden zur Programmierung mit den EV3-Tasten:

isDown()
prüft, ob die Taste zum Zeitpunkt des Methodenaufrufs gedrückt ist.

Rückgabewert
boolean – 

Taste ist gedrückt: true; Taste ist nicht gedrückt: false


isUp()
prüft, ob die Taste zum Zeitpunkt des Methodenaufrufs oben (nicht gedrückt) ist.

Rückgabewert
boolean – 

Taste ist nicht gedrückt: true; Taste ist gedrückt: false


waitForPress()
wartet darauf, dass die mittels NAME angegebene Taste gedrückt wird und fährt unmittelbar mit der Programmausführung fort.


waitForPressAndRelease()
wartet darauf, dass die mittels NAME angegebene Taste gedrückt und wieder losgelassen wird. Es wird erst nach dem Loslassen mit der Programmausführung fortgefahren


getID()
gibt die Ganzzahl-ID der mittels NAME angegebenen Taste zurück.

Rückgabewert
int – 

ID_UP: 1
ID_ENTER: 2
ID_DOWN: 4
ID_RIGHT: 8
ID_LEFT: 16
ID_ESCAPE: 32


waitForAnyEvent()
wartet darauf, dass eine beliebige Taste gedrückt oder losgelassen wird. Die Methode gibt die ID der Taste zurück. Sie wird nur mittels Button.Methodenname() aufgerufen, da sie sich nicht auf eine bestimmte Taste bezieht.

Rückgabewert
int – 

BUTTON_ID


waitForAnyPress()
wartet darauf, dass eine beliebige Taste gedrückt wird und gibt die ID der Taste zurück, die gedrückt wurde. Die Methode wird ebenfalls nur mittels Button.Methodenname() aufgerufen, da sie sich nicht auf eine bestimmte Taste bezieht.

Rückgabewert
int – 

BUTTON_ID

In folgendem Programm 10.2 wird in einer while-Schleife auf das Drücken einer Taste gewartet und geprüft welche Taste gedrückt wurde, um dies daraufhin auf dem Display anzuzeigen. Dafür wird die ID der Taste in einer Integer-Variable zwischengespeichert. Beim Drücken der ESCAPE-Taste wird die while-Schleife und damit auch das gesamte Programm beendet.


Programm 10.2: Button-Test
 
1import lejos.hardware.Button; 
2import lejos.hardware.lcd.LCD; 
3 
4/∗∗ 
5 This class waits for a Button to be pressed and then displays its name. Program exits after ESCAPE is pressed. 
6/ 
7public class ButtonTester { 
8 
9    public static void main(String[] args) { 
10        int buttonId = 0; 
11 
12        while (buttonId != Button.ID_ESCAPE) { 
13            buttonId = Button.waitForAnyPress(); 
14 
15            if (buttonId == Button.ID_LEFT) { 
16                LCD.clear(); 
17                LCD.drawString("LEFT pressed", 0, 0); 
18            } 
19            else if (buttonId == Button.ID_RIGHT) { 
20                LCD.clear(); 
21                LCD.drawString("RIGHT pressed", 0, 0); 
22            } 
23            else if (buttonId == Button.ID_ENTER) { 
24                LCD.clear(); 
25                LCD.drawString("ENTER pressed", 0, 0); 
26            } 
27            else if (buttonId == Button.ID_UP) { 
28                LCD.clear(); 
29                LCD.drawString("UP pressed", 0, 0); 
30            } 
31            else if (buttonId == Button.ID_DOWN) { 
32                LCD.clear(); 
33                LCD.drawString("DOWN pressed", 0, 0); 
34            } 
35        } 
36    } 
37}

Die Ausgabe des Programms auf dem Display des EV3 lautet:

pict

Abbildung 10.3.: Ausgabe des Button-Test-Programms (nach Drücken der ENTER-Taste)

pict
Wie wir in den if-Abfragen in Programm 10.2 sehen, kann auf die ID einer Taste direkt in der Klasse »Button« mittels Button.ID_BUTTONNAME zugegriffen werden. Sie muss also nicht jedes Mal mittels Button.BUTTONNAME.getId() ermittelt werden.

10.3  Lautsprecher

Der EV3 verfügt über einen internen Monolautsprecher, mit dem einzelne Töne und Tonfolgen oder auch WAV-Dateien abzuspielen. Über das Firmware-Menü kann er zudem stumm geschaltet werden. Das beinhaltet Tastentöne und die Wiedergabe von Sounddateien in Programmen. Zur Verwendung des Lautsprechers stellt leJOS die Klasse »Sound« aus dem Package »lejos.hardware« zur Verfügung (zum Einbinden in Eclipse: import lejos.hardware.Sound). Diese liefert u.a. folgende static-Methoden zur Ansteuerung des Lautsprechers:

beep()
spielt einen einzelnen Ton ab.


twoBeeps()
spielt einen doppelten Ton ab.


beepSequence()
spielt eine Tonfolge absteigender Höhe ab.


beepSequenceUp()
spielt eine Tonfolge aufsteigender Höhe ab.


buzz()
spielt ein tiefes Summen ab.


setVolume(int vol)
Stellt die Lautstärke auf den angegebenen Wert.

Parameter
vol – 

Lautstärke mit Wertebereich zwischen Null (Stumm) und 100 (max)


getVolume()
liest analog zu setVolume die aktuelle Lautstärke aus.

Rückgabewert
int – 

Aktuelle Lautstärke

 


playTone(int freq, int duration)
spielt einen Ton mit einer bestimmten Frequenz für die angegebene Dauer.

Parameter
freq  – 

Frequenz in Hertz

duration – 

Dauer des Tons in Millisekunden


playSample(java.io.File file)
spielt die übergebene Sounddatei ab und gibt die Länge der Soundausgabe zurück. Bei einem Fehler wird ein negativer Wert zurückgegeben.

Parameter
file – 

Abzuspielende WAV-Datei

Rückgabewert
int – 

Länge der Soundausgabe in Millisekunden

Das Programm 10.3 zur Klasse Sound spielt Töne und Tonfolgen verschiedener Frequenzen ab.


Programm 10.3: Sound-Test
 
1import lejos.hardware.Sound; 
2 
3/∗∗ 
4 This class makes the EV3 play a series of sounds. 
5/ 
6public class SoundTester { 
7    public static void main(String[] args) throws Exception { 
8        int pause = 100; 
9 
10        Sound.beep(); 
11        Thread.sleep(pause); 
12        Sound.beepSequenceUp(); 
13        Thread.sleep(pause); 
14        for (int i = 1; i < 6; i++) { 
15            Sound.playTone(i*440,500); 
16        } 
17        for (i = 5; i >= 1; i--) { 
18            Sound.playTone(i*440,500); 
19        } 
20        Thread.sleep(pause); 
21        Sound.beepSequence(); 
22        Thread.sleep(pause); 
23        Sound.beep(); 
24    } 
25}

10.4  Batterie

Da der EV3 ein mobiles Endgerät ist, wird dieser durch Akkus oder Batterien betrieben. Um einen möglichst fehlerfreien Betrieb zu gewährleisten, sollte vor kritischen Situationen der Ladezustand der Spannungsversorgung geprüft werden. Ferner ist die Batteriestärke wichtig, um die maximale Motorleistung zu erreichen. Informationen über die eingesetzten Akkus oder Batterien bietet die Klasse »Battery« aus dem Package »lejos.hardware« (einzubinden mittels: import lejos.hardware.battery). Folgende Methoden können zum Auslesen der Batteriespannung genutzt werden:

getVoltage()
gibt die aktuelle Batteriespannung in Volt aus. Methode ist static.

Rückgabewert
float – 

Batteriespannung in Volt

 


getVoltageMilliVolt()
Gibt die aktuelle Batteriespannung in Millivolt aus. Methode ist static.

Rückgabewert
int – 

Batteriespannung in Millivolt

 

Das Programm 10.4 zur Klasse »Battery« gibt den Batteriestand am Display aus, bis die ENTER-Taste gedrückt wird.


Programm 10.4: Battery-Test
 
1import lejos.hardware.Battery; 
2import lejos.hardware.Button; 
3import lejos.hardware.lcd.LCD; 
4/∗∗ 
5 This class displays the current battery voltage. 
6/ 
7public class BatteryTester { 
8    public static void main(String[] args) { 
9        LCD.drawString("Battery:", 0, 0); 
10        LCD.drawString(Battery.getVoltage() +" Volt",0,1); 
11        LCD.drawString(Battery.getVoltageMilliVolt() +" mVolt",0,2); 
12        Button.ENTER.waitForPress(); 
13    } 
14}

Die Ausgabe des Programms auf dem Display des EV3 lautet:

pict

Abbildung 10.4.: Ausgabe des Battery-Test-Programms

10.5  Motoren

Für den EV3 sind zwei Arten von Motoren verfügbar: der Servomotor (siehe Abbildung 10.5 rechts) und der Servomotor medium (siehe Abbildung 10.5 links).

pict

Abbildung 10.5.: Die Servomotoren des EV3 [14]

10.5.1  Großer Servomotor

Der große Servomotor besitzt einen eingebauten Rotationssensor mit einer Genauigkeit von einem Grad. Durch ihn können Messwerte bezüglich des Rotationswinkels erfasst werden. Weiterhin ist es durch einen eingebauten Regelkreis möglich, den Motor mit einer bestimmten Drehgeschwindigkeit laufen zu lassen. So kann die Geschwindigkeit zum Beispiel auf einer Steigung oder unter Last konstant gehalten werden.

10.5.2  Servomotor medium

Der Servomotor medium ist dazu gedacht, in Konstruktionen mit geringerem verfügbaren Platz eingesetzt zu werden sowie bei Anwendungen, die geringere Last und höhere Drehzahlen erfordern. So können kürzere Reaktionszeiten und eine platzsparende Konstruktion erreicht werden. Der Servomotor medium verfügt ebenfalls über einen Rotationssensor und über eine Genauigkeit von einem Grad.

In der nachfolgenden Tabelle 10.1 sind noch einmal die Spezifikationen der beiden Motoren aufgelistet:

Servomotor

Servomotor medium

Messgenauigkeit

1 Grad

1 Grad

Drehgeschwindigkeit

160 bis 170 U/min

240 bis 250 U/min

Nennmoment

ca. 0,2 Nm
 Antriebsmoment)

ca. 0,08 Nm
 Antriebsmoment)

Anfahrmoment

ca. 0,4 Nm
(maximales, kurzfristig erreichbares Drehmoment)

ca. 0,12 Nm
(maximales, kurzfristig erreichbares Drehmoment)

Gewicht

76g

36g

Auto-ID

ja, bei EV3-Software

ja, bei EV3-Software

Tabelle 10.1.: Spezifikationen der beiden EV3-Motoren

10.5.3  Motor-Klasse

In leJOS gibt es zwei Arten von Motoren: die »regulated« und die »unregulated« Motoren.

Die bekannten Motoren des EV3 und auch des NXT gehören zu den »regulated« Motoren. Das heißt, dass die Motoren mittels des Rotationssensors ihre Geschwindigkeit überprüfen und so angewiesen werden können, einen bestimmten Rotationswinkel anzusteuern und eine bestimmte Geschwindigkeit zu fahren. Die Geschwindigkeit hängt bei den Motoren von der Spannung der Batterien ab: Als Faustregel können die Motoren ca. 100 Grad pro Sekunden je Volt erreichen. Mit normalen Alkaline Batterien kann die Geschwindigkeit daher bis zu 900 Grad/Sekunde sein. Bei dem wiederaufladbaren Lithium-Akkupack liegt die Geschwindigkeit bei etwa 740 Grad/Sekunde.

Zu den »unregulated« Motoren gehören beispielsweise die Motoren des alten RCX-Systems und einige Motoren von Zusatzanbietern, wie die Servomotoren von HiTechnic oder Tetrix. Diese besitzen keinen Rotationssensor und können daher nur durch Vorgabe der Power und der Richtungsangabe (vorwärts oder rückwärts) gesteuert werden.

Die Motoren werden über die jeweilige Motor-Klasse und die darin enthaltenen Methoden angesprochen. Die Klasse für den großen Servomotor heißt »EV3 LargeRegulatedMotor«, die Klasse für den Servomotor medium heißt »EV3MediumRegulatedMotor«. Beide Klassen erben von der Klasse »BaseRegulatedMotor«, befinden sich im Package »lejos.hardware.motor« und werden wie gewohnt in Eclipse eingebunden. Beim Erzeugen eines Motorobjekts muss dem Konstruktor der Motorport, an den der Motor angeschlossen ist, als Parameter übergeben werden (also konkret: MotorPort.X, wobei X dann A, B , C, oder D sein kann). Die folgende Übersicht beschreibt die wichtigsten Methoden zur Ansteuerung der Servomotoren.

setSpeed(float speed)
setzt die Motorgeschwindigkeit in Grad/Sekunde.

Parameter
speed – 

Geschwindigkeit in Grad/Sekunde


forward()
lässt den Motor vorwärts fahren bis stop() aufgerufen wird.


backward()
lässt den Motor rückwärts fahren bis stop() aufgerufen wird.


stop(boolean immediateReturn)
veranlasst einen sofortigen Stopp und hält den Motor auf Position (lock). Beendet zum Beispiel forward()- Funktionen.

Parameter
immediateReturn – 

Optionaler Parameter; wenn immediateReturn true ist, wird sofort mit der Programmausführung fortgefahren, der Motor stoppt von alleine und es wird nicht gewartet bis er vollständig angehalten hat


rotate(int angle, boolean immediateReturn)
rotiert den Motor um den angegeben Winkel.

Parameter
angle  – 

Winkel in Grad

immediateReturn – 

Optionaler Parameter; wenn immediateReturn true ist, wird sofort mit der Programmausführung fortgefahren, der Motor stoppt von alleine und es wird nicht gewartet bis er vollständig angehalten hat


rotateTo(int limitAngle, boolean immediateReturn)
rotiert den Motor auf den angegebenen Winkel relativ zum Nullpunkt des Tachos. Dieser entspricht entweder der Motorposition zum Programmstart oder Position, an der zuletzt resetTachoCount() aufgerufen wurde.

Parameter
limitAngle  – 

Winkel in Grad

immediateReturn – 

Optionaler Parameter; Wenn immediateReturn true ist, wird sofort mit der Programmausführung fortgefahren, der Motor beendet die Rotation im Hintergrund


resetTachoCount()
setzt den Nullpunkt des Tachos auf die aktuelle Motorposition.


getTachoCount()
gibt den Tachowert (gedrehte Grad relativ zum Nullpunkt) zurück. Der Tacho verhält sich dabei ähnlich wie der Kilometerzähler eines Autos, mit dem Unterschied, dass Bewegungen in negativer Rotationsrichtung ebenfalls berücksichtigt werden (also vom Tachowert abgezogen werden).

Rückgabewert
int – 

Motorposition in Grad


flt()
setzt den Motor in den float-Modus. Dadurch stoppt der Motor ohne »lock« und die Motorposition wird nicht länger überwacht. Der Motor ist danach frei drehbar.


isMoving()
prüft, ob der Motor gerade in Bewegung ist.

Rückgabewert
boolean – 

Liefert true falls der Motor eine Bewegung ausführt

Analog dazu können die NXT-Servomotoren mittels NXTRegulatedMotor angesprochen werden. Die vier Motorports am EV3 werden mit MotorPort.A, MotorPort.B, MotorPort.C und MotorPort.D angesprochen. Die Klasse »MotorPort« befindet sich im Package »lejos.hardware.port« und muss zur Verwendung in Eclipse eingebunden werden.

pict
Bei manchen Aufgaben kann es zweckdienlich sein, einen Motor im »unregulated«-Modus zu nutzen. Dafür kann die Klasse »NXTMotor« aus dem Package » lejos.hardware.motor« verwendet werden. Die Methoden zu dieser Klasse werden in der leJOS-API unter http://www.lejos.org/ev3/docs/ beschrieben.

Im folgenden Programm 10.5 werden die grundsätzlichen Funktionen der Motoren gezeigt. Wie in der nebenstehenden Abbildung soll der Roboter ein Stück vorwärts fahren, dann eine leichte Linkskurve beschreiben und schließlich ein Stück zurücksetzen. Die Methode forward() startet die Motoren, die dann drehen, bis sie explizit von der Methode stop() gestoppt werden. Zusätzlich kann die Geschwindigkeit der Motoren eingestellt werden, die dann bis zur nächsten Änderung gültig ist.

Um dieses Beispielprogramm mit einem eigenen Roboter nachzuvollziehen, wird empfohlen das Roberta-Modell (kurz: Roberta) zu verwenden, da dieses auch im weiteren Verlauf des Buches in diversen Beispielen zum Einsatz kommt (siehe Abbildung 10.6). Die Roberta kann komplett mit einem LEGO MINDSTORMS Education -Set aufgebaut werden. Die Bauanleitung befindet sich im Roberta-Portal unter http://roberta-home.de/de/node/528 und kann dort angesehen sowie heruntergeladen werden.

Falls kein Education-Set zur Verfügung steht: Die Bauanleitung für den sogenannten »5 Minute Bot« ist unter https://shslab.wikispaces.com/5+Minute+Bot+for+EV3 zu finden. Dieser stellt einen einfachen und schnell aufzubauenden Roboter dar, der ebenfalls von zwei Motoren angetrieben wird.

pict

Abbildung 10.6.: Das Roberta-Modell (kurz: Roberta)


Programm 10.5: Motor-Test
 
1import lejos.hardware.motor.EV3LargeRegulatedMotor; 
2import lejos.hardware.port.MotorPort; 
3/∗∗ 
4 This class makes a Robot with two motors move along a certain path. 
5/ 
6public class MotorTester { 
7    public static void main(String[] args) throws Exception { 
8        EV3LargeRegulatedMotor motorL = new EV3LargeRegulatedMotor(MotorPort.A); 
9        EV3LargeRegulatedMotor motorR = new EV3LargeRegulatedMotor(MotorPort.B); 
10        //set speed to 360 deg/s 
11        motorR.setSpeed(360); 
12        motorL.setSpeed(360); 
13        //forward for 1 seconds 
14        motorR.forward(); 
15        motorL.forward(); 
16        Thread.sleep(1000); 
17        motorR.stop(true); 
18        motorL.stop(true); 
19        //reduce speed for left motor 
20        motorL.setSpeed(250); 
21        motorR.forward(); 
22        motorL.forward(); 
23        Thread.sleep(3000); 
24        //Forward movement is finished 
25        motorR.stop(true); 
26        motorL.stop(true); 
27        //set both motors to 360 deg/s again 
28        motorR.setSpeed(360); 
29        motorL.setSpeed(360); 
30        //go backwards for 3 seconds 
31        motorR.backward(); 
32        motorL.backward(); 
33        Thread.sleep(3000); 
34    } 
35}

10.6  Sensoren

Die Sensoren des EV3 sind die Schnittstelle, mit der ein Roboter Informationen über seine Umwelt sammeln kann. Im EV3 Spielwaren-Set sind drei Sensoren enthalten: Ein Farbsensor, ein Infrarotsensor mit zugehöriger Infrarot-Fernbedienung und ein Berührungssensor.

pict

pict
pict
pict
Abbildung 10.7.: Die Sensoren des EV3 Spielwaren-Sets [14]

Im Education-Set sind dagegen fünf Sensoren enthalten: Der Infrarotsensor mit Fernbedienung wird durch einen Ultraschallsensor ersetzt. Zudem enthält das Education-Set einen Gyrosensor und zwei Berührungssensoren.

pict

Abbildung 10.8.: Die Sensoren des EV3 Education-Sets [14]

Im Folgenden wird zunächst darauf eingegangen, wie die Sensoren allgemein in leJOS behandelt werden. Daraufhin folgt zu jedem Sensor ein eigener Unterabschnitt, in dem die spezifischen Sensormethoden erklärt werden und ein Programmbeispiel zur Verwendung des Sensor angeführt wird.

10.6.1  Namensgebung

Um es ProgrammiererInnen einfacher zu machen, die richtige Klasse für den jeweiligen Sensor zu finden, wurden die Klassennamen nach dem Prinzip [Hersteller bzw. Mindstorms-Modell][Sensortyp] vergeben. Die Sensoren für den EV3 heißen also alle »EV3SensorXYZ«. Demnach heißt der Farbsensor für den EV3 »EV3 ColorSensor«, der des NXT »NXTColorSensor« und der Farbsensor der Firma HiTechnic wird als »HiTechnicColorSensor« bezeichnet. Falls es mehrere Versionen eines Sensors gibt, wird noch ein dritter Teil an den Namen zur Bezeichnung der Version nach dem Schema [Hersteller bzw. Mindstorms-Modell][Sensortyp][V#] angehängt. Gäbe es also beispielsweise eine neue Version des Farbsensors für den EV3, würde diese »EV3ColorSensorV2« heißen.

10.6.2  Ports

Die Sensoren werden über die Sensorports mit dem Brick verbunden. Generell kann mit dem Interface SensorPort über die Einträge S1 bis S4 einer der vier Sensorports angesprochen werden. Der Port, an den der Sensor angeschlossen ist, muss bei der Erstellung eines Sensorobjekts im Konstruktor als Parameter übergeben werden. Konkret also: SensorPort.SX, wobei X dann 1, 2, 3 oder 4 sein kann.

10.6.3  Samples

Die einzelnen Messungen, welche die Sensoren durchführen, werden in leJOS als »Samples« bezeichnet. Ein einzelnes »Sample« besteht aus einem oder mehreren Werten, die im selben Moment aufgenommen wurden. Dazu zählen beispielsweise die gemessene Entfernung eines Ultraschallsensors (ein Messwert) oder die Rot-, Grün-, und Blauanteile einer Messung des Farbsensors (drei Messwerte). Auch wenn der Sensor je Zeitpunkt nur einen Messwert speichert, wird dennoch ein Array genutzt um das »Sample« zu speichern.

10.6.4  Sensormodi

Wie auch nachfolgend in den einzelnen Sektionen zu den Sensoren beschrieben, besitzen einige Sensoren verschiedene Modi, in denen sie betrieben werden können. Der Farbsensor beispielsweise kann im »Farb-ID«-Modus verschiedene Farben erkennen und im Modus »Umgebungslicht« die Lichtintensität messen. leJOS stellt in der aktuellen Version 0.9.0 zwei Möglichkeiten zur Verfügung um die Modi der Sensoren zu nutzen und Messwerte mit ihnen aufzunehmen:

1.
Die Verwendung der Methoden der Klasse BaseSensor
2.
Die Verwendung eines SampleProvider-Objekts

10.6.5  BaseSensor

Jedem LEGO-Sensorobjekt stehen die Methoden der Klasse BaseSensor durch Vererbung zur Verfügung. Mit ihrer Hilfe kann man einen Sensor in einen gewünschten Modus versetzen und Messdaten erfassen. Diese Vorgehensweise ist sehr intuitiv, da die Samples direkt vom Sensorobjekt kommen und nicht erst den Umweg über einen sogenannten Sample Provider machen (siehe nächsten Unterabschnitt). Aus diesem Grund ist dies die bevorzugte Vorgehensweise, die auch in den Beispielprogrammen dieses Buches verwendet wird, um Messdaten aufzunehmen.

Die Methoden werden direkt vom Sensorobjekt aufgerufen und im Folgenden genauer erklärt:

fetchSample(float[] sample, int offset)
speichert die Messdaten des Sensors in das Array sample, in das durch den Index offset definierte Feld.

Parameter
sample – 

Array zum abspeichern der Messdaten

offset  – 

Index, an dem das erste Messdatum im Array abgespeichert werden soll


sampleSize()
gibt die Anzahl der Elemente je Sample zurück. Diese Zahl ist für jeden Modus unterschiedlich.

Rückgabewert
int – 

Anzahl der Elemente


setCurrentMode(int mode)
versetzt den Sensor in den der Ganzzahl mode entsprechenden Modus. Die zu den Modi gehörenden Ganzzahlen können der Beschreibung der einzelnen Sensoren in diesem Kapitel entnommen werden.

Parameter
mode – 

Einem Modus entsprechende Ganzzahl


setCurrentMode(String modeName)
versetzt den Sensor in den durch den String modeName angegebenen Modus. Die möglichen Modusnamen können der Beschreibung der einzelnen Sensoren in diesem Kapitel entnommen werden.

Parameter
modeName – 

Name eines Modus als String

10.6.6  SampleProvider

Eine weitere Möglichkeit um Messwerte zu erfassen verwendet die zuvor schon erwähnten SampleProvider. Möchte man einen Sensor in einem bestimmten Modus nutzen, muss mit Hilfe des Sensorobjekts ein Objekt vom Typ SampleProvider erzeugt werden, welches den Modus repräsentiert. Dieser SampleProvider kann dann mittels fetchSample() Messdaten erfassen. So kann ein Sensor auch verschiedene Modi innerhalb eines Programms benutzen, ohne dass er manuell dafür konfiguriert werden muss. Zur Erfassung von Messdaten mit Hilfe eines SampleProviders stehen also folgende Methoden zur Verfügung:

fetchSample(float[] sample, int offset)
speichert die Messdaten des Sensors in das Array sample, in das durch den Index offset definierte Feld.

Parameter
sample – 

Array zum abspeichern der Messdaten.

offset  – 

Index, an dem das erste Messdatum im Array abgespeichert werden soll.


sampleSize()
gibt die Anzahl der Elemente je Sample zurück. Diese Anzahl ist für jeden Modus konstant.

Rückgabewert
int – 

Anzahl der Elemente

pict
Bei manchen Sensoren benötigt der Wechsel zwischen zwei Modi eine gewisse Zeit zur internen (Um-)Konfiguration des Sensors. Dies sollte beim Programmieren unbedingt beachtet werden, wenn häufig zwischen den Modi gewechselt wird.

10.6.7  Farbsensor

Der Farbsensor des EV3 ist ein digitaler Sensor, der vier verschiedene Modi unterstützt. Zum einen kann der Sensor im »Farb-ID«-Modus Farben erkennen, zum anderen in den beiden Modi »Rotlicht« und »Umgebungslicht« die Lichtintensität messen. Darüberhinaus wird im »RGB«-Modus die Intensität der drei Grundfarben Rot, Grün und Blau gemessen. Der Sensor heisst in leJOS »EV3ColorSensor« und befindet sich im Package »lejos.hardware.sensor«.

Der Farbsensor erkennt im »Farb-ID«-Modus die sieben Farben Rot, Gelb, Grün, Blau, Braun, Schwarz und Weiß sowie »keine Farbe«.

Für den Modus »Rotlicht« ist der Farbsensor mit einem Rotlicht ausgestattet, welches die zu messende Fläche anstrahlt. Das dadurch reflektierte Licht beurteilt der Sensor dann auf einer Skala von 0 (sehr dunkel) bis 1 (sehr hell).

Dieselbe Skala wird für den Modus »Umgebungslicht« genutzt, bei dem das ins Sensorfenster eindringende Umgebungslicht gemessen wird.

Im »RGB«-Modus strahlt der Sensor rotes, grünes und blaues Licht ab und misst die jeweiligen Farbanteile des reflektierten Lichts wiederum auf eben genannter Skala. Um die höchstmögliche Genauigkeit bei der Messung zu erzielen, sollte der Sensor im rechten Winkel zu dem zu messenden Objekt und möglichst nah an dessen Oberfläche positioniert werden.

Folgende Tabelle 10.2 gibt Übersicht über die Modi des Farbsensors. Die angegebenen Parameter mode und modeName können mit den Methoden der Klasse BaseSensor verwendet werden um den Sensor in den gewünschten Modus zu versetzen.

Modus int mode

String modeName

»Farb-ID« 0

Color ID

»Rotlicht« 1

Red

»RGB« 2

RGB

»Umgebungslicht« 3

Ambient

Tabelle 10.2.: Modi des Farbsensors

leJOS stellt zur Verwendung des Farbsensors folgende Methoden zur Verfügung:

getColorID()
gibt einen Integer-Wert zurück, der einer Farbe entspricht. Diese Methode kann unabhänging vom momentan verwendeten Modus des Sensors verwendet werden.

Rückgabewert
int – 
-1:Color.NONE
0 : Color.RED
1:Color.GREEN
2 : Color.BLUE
3:Color.YELLOW
6 : Color.WHITE
7:Color.BLACK
13 : Color.BROWN


getAmbientMode()
erstellt ein SampleProvider-Objekt für den »Umgebungslicht«-Modus und liefert dieses zurück.

Rückgabewert
SensorMode – 

Sample Provider für den »Umgebungslicht«-Modus

Sample
sample[0] – 

Stärke des auf den Sensor fallenden Lichts mit Fließkommawerten zwischen 0 und 1


getColorIDMode()
erstellt ein SampleProvider-Objekt für den »Farb-ID«-Modus und liefert dieses zurück.

Rückgabewert
SensorMode – 

Sample Provider für den »Farb-ID«-Modus

Sample
sample[0] – 

Fließkommazahl mit Ganzzahlwerten zwischen -1 und 13, die einer Farbe entsprechen (Siehe Tabelle unter getColorID ())


getRedMode()
erstellt ein SampleProvider-Objekt für den »Rotlicht«-Modus und liefert dieses zurück. Dabei wird Objekt mit rotem Licht bestrahlt und die Stärke des reflektierten Lichts gemessen.

Rückgabewert
SensorMode – 

Sample Provider für den »Rotlicht«-Modus

Sample
sample[0] – 

Stärke des reflektierten Lichts mit Fließkommawerten zwischen 0 und 1


getRGBMode()
erstellt ein SampleProvider-Objekt für den »RGB«-Modus, der RGB-Werte zurückgibt und liefert dieses zurück. Dabei wird das Objekt mit rotem, grünem und blauem Licht bestrahlt und die Stärke des reflektierten Lichts gemessen.

Rückgabewert
SensorMode – 

Sample Provider für den »RGB«-Modus

Sample
sample[0] – 

Rotanteil als Fließkommazahl, mit Werten zwischen 0 und 1

sample[1]  – 

Grünanteil als Fließkommazahl, mit Werten zwischen 0 und 1

sample[2]  – 

Blauanteil als Fließkommazahl, mit Werten zwischen 0 und 1

In folgendem Programm 10.6 wird eine Farbsonde, bestehend aus einem EV3 und dem Farbsensor am Sensorport S1, programmiert. Beim Drücken der ENTER-Taste sollen die gemessenen Farbwerte des Sensors für Rot, Grün und Blau auf dem Display ausgegeben werden. Der Farbsensor wird also im RGB-Modus betrieben. Beim Drücken einer beliebigen anderen Taste wird das Programm beendet. Dafür wird die Klasse »ColorProbe« erstellt. Sie enthält eine Variable für den Farbsensor und eine weitere für das Sample. Der Sensor wird im Konstruktor in den »RGB«-Modus versetzt. Des weiteren enthält die Klasse eine Methode, die für das Auslesen der Farbwerte und die Ausgabe auf dem Display zuständig ist. Diese wird aus der main-Methode aufgerufen.


Programm 10.6: Beispielprogramm zum EV3ColorSensor
 
1import lejos.hardware.Button; 
2import lejos.hardware.lcd.LCD; 
3import lejos.hardware.port.SensorPort; 
4import lejos.hardware.sensor.EV3ColorSensor; 
5import lejos.robotics.SampleProvider; 
6/∗∗ 
7 This class describes a color probe. 
8 It fetches a RGBsample after ENTER is pressed. 
9/ 
10public class ColorProbe { 
11 
12    private EV3ColorSensor colorSensor = new EV3ColorSensor(SensorPort.S1); 
13    private float[] sample 
14    /∗∗ 
15     Constructor for setting sensormode to "RGB" 
16    / 
17    ColorProbe() { 
18        colorSensor.setCurrentMode("RGB"); 
19        sample = new float[colorSensor.sampleSize()]; 
20    } 
21    /∗∗ 
22     Method for getting a sample and printing the RGBvalues 
23    / 
24    private void getAndPrintData() { 
25        LCD.drawString("ENTER for sample", 0, 0); 
26        while (Button.waitForAnyPress() == Button.ID_ENTER) { 
27            colorSensor.fetchSample(sample, 0); 
28            LCD.drawString("Red: " + sample[0], 0, 1); 
29            LCD.drawString("Green: " + sample[1], 0, 2); 
30            LCD.drawString("Blue: " + sample[2], 0, 3); 
31        } 
32    } 
33 
34    public static void main(String[] args) { 
35        ColorProbe ourProbe = new ColorProbe(); 
36        ourProbe.getAndPrintData(); 
37    } 
38}

10.6.8  Berührungssensor

Der Berührungssensor ist der einfachste der vier mitgelieferten Sensoren. Während alle drei anderen Sensoren einen quantitativen Wert zurückgeben, kann der Tastsensor nur erfassen, ob er gedrückt ist oder nicht. Die Klasse, die den Berührungssensor beschreibt heisst »EV3TouchSensor« und befindet sich ebenfalls im Package »lejos.hardware.sensor«. Da es nur einen Modus (»Touch«) gibt, muss der Sensor theoretisch nach Instanziierung nicht erst in diesen Modus versetzt werden um Samples aufzunehmen. Es wird allerdings empfohlen immer einen Modus explizit anzugeben, da es sonst bei der Initialisierung des Sensors zu Fehlern kommen kann.

Falls gewünscht erhält man den entsprechenden SampleProvider mittels:

getTouchMode()
liefert ein SampleProvider-Objekt für den »Touch«-Modus.

Rückgabewert
SensorMode – 

Sample Provider für den »Touch«-Modus

Sample
sample[0] – 

Fließkommazahl, die den Zustand des Touchsensor zum Zeitpunkt der Messung darstellt: 1.0 falls der Sensor gedrückt war, 0.0 wenn nicht

In folgendem Programm 10.7 wird die Farbsonde aus Programm 10.6 um einen Touchsensor am Sensorport S2 erweitert. Es soll nun jedes Mal, wenn der Touchsensor gedrückt wird, eine Farbmessung durchgeführt und die Farbanteile auf dem Display ausgegeben werden. Damit das Programm durch Drücken der ENTER-Taste beendet wird, sind entsprechende Abfragen in der while- und do- Schleife eingefügt worden.


Programm 10.7: Beispielprogramm zum EV3TouchSensor
 
1import lejos.hardware.Button; 
2import lejos.hardware.lcd.LCD; 
3import lejos.hardware.port.SensorPort; 
4import lejos.hardware.sensor.EV3ColorSensor; 
5import lejos.hardware.sensor.EV3TouchSensor; 
6 
7/∗∗ 
8 This class implements a color probe, that is triggered by a EV3TouchSensor 
9/ 
10public class ColorProbeTouch { 
11 
12    EV3ColorSensor colorSensor = new EV3ColorSensor(SensorPort.S1); 
13    EV3TouchSensor touchSensor = new EV3TouchSensor(SensorPort.S2); 
14    private float[] colorSample; 
15    private float[] touchSample; 
16    /∗∗ 
17     Constructor for getting RGBMode Sample Provider 
18    / 
19    ColorProbeTouch() { 
20        colorSensor.setCurrentMode("RGB"); 
21        touchSensor.setCurrentMode("Touch"); 
22        colorSample = new float[colorSensor.sampleSize()]; 
23        touchSample = new float[touchSensor.sampleSize()]; 
24    } 
25    /∗∗ 
26     Method for getting a sample and printing the colorvalues 
27    / 
28    public void getAndPrintData() { 
29        while (Button.ENTER.isUp()) { 
30            LCD.drawString("Touch for sample",0,0); 
31            do { 
32                touchSensor.fetchSample(touchSample,0); 
33            } while ((touchSample[0] == 0.0) && Button.ENTER.isUp()); 
34            touchSample[0] = 0.0F; 
35            colorSensor.fetchSample(colorSample, 0); 
36            LCD.drawString("Red: " + colorSample[0], 0, 1); 
37            LCD.drawString("Green: " + colorSample[1], 0, 2); 
38            LCD.drawString("Blue: " + colorSample[2], 0, 3); 
39        } 
40    } 
41 
42    public static void main(String[] args) { 
43        ColorProbeTouch ourProbe = new ColorProbeTouch(); 
44        ourProbe.getAndPrintData(); 
45    } 
46}

10.6.9  Ultraschallsensor

Der Ultraschallsensor kann die Distanz zu einem Objekt erkennen. Er misst die Distanz eines Objektes von 3cm bis 250cm mit einer Genauigkeit von +/- 1 cm. Bei leJOS wird allerdings die Einheit Meter verwendet, ein Sample liegt also auf einer Skala zwischen 0,03 und 2,50.

Um die Entfernung zu messen, dient der »Distanz«-Modus, dessen Aktivität durch ein dauerhaft leuchtendes rotes Licht signalisiert wird. In diesem Modus sendet der Ultraschallsensor hochfrequente Schallwellen aus. Die Zeit, welche die Schallwellen benötigen, um von einem Objekt reflektiert und wieder zum Sensor zurückzukommen, wird gemessen und in eine Distanz umgerechnet.

pict
Da die Messung nur bei einer direkten Reflexion der Schallwellen zuverlässig möglich ist, kann es vorkommen, dass strukturierte oder abgerundete Oberflächen und zu kleine Objekte nicht oder nur schwer erkannt werden.
Der Sensor unterstützt neben dem gerade beschriebenen Modus »Distanz« noch den »Passiv«-Modus. In diesem Modus kann er andere aktive Ultraschallsensoren erkennen, die sich in der Nähe befinden. Damit keine eigenen Schallwellen fälschlicherweise für einen anderen aktiven Sensor gehalten werden, sendet der Ultraschallsensor im »Passiv«-Modus keine eigenen Schallwellen aus. Erkennbar ist dieser Modus am blinkenden roten Licht.

Modus int mode

String modeName

»Distanz« 0

Distance

»Passiv« 1

Listen

Tabelle 10.3.: Modi des Ultraschallsensors

Zur Verwendung des Ultraschallsensors stellt leJOS die im Folgenden beschriebenen Methoden zur Verfügung:

disable()
schaltet den Sensor sowie die Status-LED aus.


enable()
schaltet den Sensor sowie die Status-LED nach einem Aufruf von disable() wieder ein.


getDistanceMode()
erstellt ein SampleProvider-Objekt für den »Distanz«-Modus und liefert dieses zurück.

Rückgabewert
SampleProvider – 

Sample Provider für den »Distanz«-Modus

Sample
sample[0] – 

Entfernung als Fließkommazahl in Metern mit Werten von 0,03 bis 2,5


getListenMode()
erstellt ein SampleProvider-Objekt für den »Passiv«-Modus und liefert dieses zurück.

Rückgabewert
SampleProvider – 

Sample Provider für den »Passiv«-Modus

Sample
sample[0] – 

Fließkommazahl: 1.0 falls eine Ultraschallquelle detektiert wird, 0.0 sonst


isEnabled()
gibt zurück, ob der Sensor angeschaltet ist oder nicht.

Rückgabewert
boolean – 

Liefert true bei eingeschaltetem Sensor, false bei ausgeschaltetem Sensor

Zur Veranschaulichung der Verwendung des EV3-Ultraschallsensors wird in folgendem Programm 10.8 eine Roberta darauf programmiert, in Abständen von 250ms eine Entfernungsmessung durchzuführen. Die resultierenden Entfernungen werden in Frequenzen umgerechnet, die dann ebenfalls für 250ms als Ton abgespielt werden. Durch Veränderung der Entfernung zu einem Objekt, zum Beispiel der Hand oder einer Wand, kann der Programmierer – jetzt als Dirigent – dem Roboter Anweisungen zum »musizieren« geben.


Programm 10.8: Beispielprogramm zum EV3UltrasonicSensor
 
1import lejos.hardware.Button; 
2import lejos.hardware.Sound; 
3import lejos.hardware.lcd.LCD; 
4import lejos.hardware.port.SensorPort; 
5import lejos.hardware.sensor.EV3UltrasonicSensor; 
6import lejos.utility.Delay; 
7 
8public class UltrasonicRoberta { 
9 
10    private EV3UltrasonicSensor uSensor = new EV3UltrasonicSensor(SensorPort.S4); 
11    private float[] sample; 
12    /∗∗ 
13     Constructor for setting sensormode to "Distance" 
14    / 
15    UltrasonicRoberta() { 
16        uSensor.setCurrentMode("Distance"); 
17        sample = new float[uSensor.sampleSize()] 
18    } 
19    /∗∗ 
20     This method plays 250ms long tones with different frequencies. 
21     The frequencies depend on measured distances from the ultrasonic sensor in distancemode. 
22    / 
23    private void sing() { 
24        int frequency; 
25 
26        while (Button.ENTER.isUp()) { 
27            uSensor.fetchSample(sample, 0); 
28            frequency = (int) (sample[0] * 2000); 
29            LCD.drawString(""+frequency, 0, 0); 
30            Sound.playTone(frequency, 250); 
31            Delay.msDelay(250); 
32            LCD.clear(); 
33        } 
34    } 
35 
36    public static void main(String[] args) { 
37        UltrasonicRoberta roberta = new UltrasonicRoberta(); 
38        roberta.sing(); 
39    } 
40}

10.6.10  Infrarotsensor

Der digitale Infrarotsensor ist in der Lage, Infrarotlicht, das von Festkörperobjekten reflektiert wird, zu erkennen und so grob die Entfernung zu diesen abzuschätzen. Ausserdem kann er die Infrarotsignale der Fernbedienung wahrnehmen. leJOS stellt die Klasse »EV3IRSensor« aus dem Package » lejos.hardware.sensor« zur Verwendung des Infrarotsensors zur Verfügung.

Der Infrarotsensor kann in zwei verschiedenen Modi betrieben werden. Der sogenannte »Distanz«-Modus dient der Entfernungsmessung zwischen dem Sensor und einem Objekt. Die von dem Objekt reflektierten Lichtwellen werden gemessen und ein Distanz-Wert auf einer Skala von 0 (sehr nah) bis 100 (sehr entfernt) zurückgegeben (es wird also keine genaue Maßeinheit verwendet). Die maximale Entfernung, die der Sensor erkennen kann, liegt bei circa 70cm zwischen Sensor und Objekt. Dies kann je nach Größe, Form und Oberfläche des Objekts allerdings stark abweichen.

Der »Suchen«-Modus dient der Ortung eines Signals der Infrarot-Fernbedienung des EV3. Die maximale Distanz, die zwischen Sensor und Fernbedienung liegen darf, damit der Sensor noch Signale erkennen kann, liegt bei circa 200 cm (in Blickrichtung des Sensors). Der Sensor kann die ungefähre Richtung und Distanz eines empfangenen Signals schätzen und teilt dieses in die zwei Skalen von 0 (sehr nah) und 100 (sehr entfernt) für die Distanz und von -25 (linke Seite) bis 25 (rechte Seite) für die Richtung ein. Ein aufgenommenes Sample enthält somit acht Werte, zwei für jeden der vier Kanäle: Einen für die Entfernung und einen für die Richtung aus der das Signal kommt.

pict
Eine 0 bei der Richtung bedeutet also, dass sich die Quelle des Signals frontal vor dem Sensor befindet.

Modus int mode

String modeName

»Distanz« 0

Distance

»Suchen« 1

Seek

Tabelle 10.4.: Modi des Infrarotsensor

Die Fernbedienung kann Infrarotsignale auf vier verschiedenen Kanälen (engl. channel) senden, damit keine Störungen beim gleichzeitigen Fernsteuern mehrerer Roboter auftreten. Welcher Kanal benutzt werden soll, kann über den roten Schieberegler eingestellt werden. Wird die große, graue Taste der Fernbedienung betätigt, schaltet sie in den sogenannten Beacon- oder Signal-Modus (angezeigt durch dauerhaftes Leuchten der Status-LED). Die Fernbedienung sendet dann kontinuierlich Infrarot-Signale, die vom Sensor im »Suchen«-Modus geortet werden können.

Um beispielsweise einen Roboter fernzusteuern, können mit der Fernbedienung verschiedene Signale (die dem Druck einer Taste oder der Kombination von Tasten entsprechen) an den EV3 gesendet werden. Mit Hilfe der im Folgenden beschriebenen Methode getRemoteCommand, können diese Befehle erkannt und dann auf beliebige Weise darauf reagiert werden. Die vom Sensor erkennbaren Kombinationen sind in Tabelle 10.5 aufgeführt:

Befehl als Integer Gedrückte Taste(n)
0 Keine Taste (Signal-Modus ist deaktiviert)
1 Taste 1 (oben-links)
2 Taste 2 (unten-links)
3 Taste 3 (oben-rechts)
4 Taste 4 (unten-rechts)
5 Taste 1 und Taste 3
6 Taste 1 und Taste 4
7 Taste 2 und Taste 3
8 Taste 2 und Taste 4
9 Große Beacon-Taste (Signal-Modus ist aktiviert)
10 Taste 1 und Taste 2
11 Taste 3 und Taste 4
Tabelle 10.5.: Kommandos der IR-Fernbedienung

Es folgt eine Übersicht der wichtigsten Methoden aus leJOS zur Verwendung des EV3-Infrarotsensors.

getRemoteCommand(int chan)
gibt den aktuell über den Kanal chan empfangenen Befehl als eine der oben beschriebenen Integer-Zahlen zurück.

Parameter
chan – 

Übertragungskanal (0, 1, 2, oder 3)

Rückgabewert
int – 

Taste bzw. Tastenkombination als Ganzzahl codiert. Siehe Tabelle 10.5


getDistanceMode()
erstellt ein SampleProvider-Objekt für den »Distanz«-Modus und liefert dieses zurück.

Rückgabewert
SensorMode – 

Sample Provider für den »Distanz«-Modus

Sample
sample[0] – 

Entfernung als Fließkommazahl ganzzahligen Werten von 1.0 bis 100.0 (keine genaue Maßeinheit vorhanden)


getSeekMode()
Erstellt ein SampleProvider-Objekt für den »Suchen«-Modus und liefert dieses zurück. Rückgabewert ist die ungefähre Richtung und Distanz zu einem oder mehreren Infrarotsendern.

Rückgabewert
SensorMode – 

Sample Provider für den Signal-Modus

Sample
sample[0] – 

Entfernung des auf Kanal 1 empfangenen Signals mit werten zwischen 0.0 und 100.0

sample[1]  – 

Richtung des auf Kanal 1 empfangenen Signals mit werten zwischen -25.0 (ganz links) und 25.0 (ganz rechts)

sample[2]  – 

Entfernung für Kanal 2

sample[3]  – 

Richtung für Kanal 2

sample[4]  – 

Entfernung für Kanal 3

sample[5]  – 

Richtung für Kanal 3

sample[6]  – 

Entfernung für Kanal 4

sample[7]  – 

Richtung für Kanal 4

 
pict
Ein Beispiel zum Infrarotsensor kann im Roberta-Portal zu diesem Band unter www.roberta-home.de/javaband-ev3 gefunden werden.

10.6.11  Gyrosensor

Der Gyrosensor, von LEGO auch Kreiselsensor genannt, ist ein weiterer digitaler Sensor und erkennt Drehbewegungen um seine eigene vertikale Achse mit einer Frequenz von 1 kHz. Dabei kann entweder die Drehrate in Grad pro Sekunde (maximal 440 Grad/Sekunde), oder der Gesamtdrehwinkel in Grad mit einer Genauigkeit von +/- 3 Grad gemessen werden. leJOS stellt zur Verwendung des Gyrosensors die Klasse »EV3GyroSensor« aus dem Package »lejos.hardware.sensor« zur Verfügung.

Modus

int mode

String modeName

»Winkel«

0

Angle

»Winkelgeschwindigkeit«

1

Rate

»Winkel und Winkelgeschwindigkeit«

2

Rate and Angle

Tabelle 10.6.: Modi des Gyrosensors

Es folgt eine Beschreibung der wichtigsten Methoden dieser Klasse:

getAngleMode()
liefert einen Sample Provider für den »Winkel«-Modus. In diesem Modus misst der Sensor den Winkel in Bezug auf seine Ausgangsposition. Ein positiver Winkel bedeutet dabei eine Orientierung nach links und ein negativer Winkel eine Orientierung nach rechts (gemessen in Grad).

Rückgabewert
SampleProvider – 

Sample Provider für den Winkel-Modus

Sample
sample[0] – 

Winkel in Bezug auf die Ausgangsposition des Sensors


getRateMode()
liefert einen Sample Provider für den Modus »Winkelgeschwindigkeit«. Hier wird die Geschwindigkeit der Drehung in Grad pro Sekunde gemessen. Ein positiver Wert bedeutet eine Drehung im Uhrzeigersinn, ein negativer Wert gegen den Uhrzeigersinn.

Rückgabewert
SampleProvider – 

Sample Provider für den Modus »Winkelgeschwindigkeit«

Sample
sample[0] – 

Winkelgeschwindigkeit in Grad/Sekunde


getAngleAndRateMode()
liefert einen Sample Provider für den Modus »Winkel und Winkelgeschwindigkeit«. Hier wird die Geschwindigkeit der Drehung und der aktuelle Winkel in Bezug auf die Ausgangsposition gemessen.

Rückgabewert
SampleProvider – 

Sample Provider für den Modus »Winkel und Winkelgeschwindigkeit«

Sample
sample[0] – 

Winkelgeschwindigkeit in Grad/Sekunde

sample[1]  – 

Winkel in Bezug auf die Ausgangsposition des Sensors


In folgendem Programm 10.9 wird zur Veranschaulichung der Benutzung des Gyrosensors wieder das Roberta-Robotermodell verwendet. Diese wird um einen Gyrosensor am Sensorport S3 erweitert. Der Sensor muss so angebracht werden, dass er parallel zur Oberfläche, auf der sich der Roboter bewegen soll, ausgerichtet ist. Die Roberta soll ein Quadrat abfahren indem sie sich für zwei Sekunden geradeaus bewegt, sich anschließend mit Hilfe des Gyrosensors um 90 Grad dreht und diesen Vorgang noch drei Mal wiederholt. Der Gyrosensor ist hier insofern praktisch, da es sonst schwierig ist mit den bisher kennengelernten Methoden eine bestimmte Drehung mit einem zweimotorigen (differential angetriebenen) Roboter durchzuführen. Auf Grund von Messungenauigkeiten wird das Quadrat auch mit dem Gyrosensor nicht ganz genau abgefahren. Ein wenig Feintuning ist also am Winkel (ANGLE) nötig. Besser ist eine solche Aufgabe mit der im Kapitel 11 vorgestellten »DifferentialPilot«-Klasse zu lösen.

pict
Der Sensor wird in der aktuellen leJOS-Version 0.9.0 bei der ersten Benutzung der fetchSample-Methode initialisiert. Dabei muss er absolut ruhig gehalten werden, damit er die richtige Ausgangsposition ermitteln kann. Aus diesem Grund wird die Methode schon im Konstruktor des Beispiels einmal aufgerufen und danach eine Sekunde gewartet. Auch wenn ein Programm den Sensor-Modus wechselt, führt der Sensor intern einen Reset durch, bei dem dieser ebenfalls regungslos sein muss, um anschließend keine falschen Werte zu liefern.

Programm 10.9: Beispielprogramm zum EV3GyroSensor
 
1import lejos.hardware.motor.EV3LargeRegulatedMotor; 
2import lejos.hardware.port.MotorPort; 
3import lejos.hardware.port.SensorPort; 
4import lejos.hardware.sensor.EV3GyroSensor; 
5import lejos.utility.Delay; 
6/∗∗ 
7  This class describes a Robertarobot, that uses a gyrosensor to move along a squared path. 
8 / 
9public class GyRoberta { 
10 
11    private EV3LargeRegulatedMotor engineR = new EV3LargeRegulatedMotor(MotorPort.B); 
12    private EV3LargeRegulatedMotor engineL = new EV3LargeRegulatedMotor(MotorPort.C); 
13    private EV3GyroSensor gyroSensor = new EV3GyroSensor(SensorPort.S3); 
14 
15    private float[] sample; 
16 
17    GyRoberta() { 
18        gyroSensor.setCurrentMode("Angle"); 
19        sample = new float[gyroSensor.sampleSize()]; 
20        gyroSensor.fetchSample(sample, 0); 
21        Delay.msDelay(1000); 
22    } 
23 
24    private void driveSquare() { 
25        engineR.setSpeed(250); 
26        engineL.setSpeed(250); 
27        final int ANGLE = 90; 
28 
29        for (int i = 1; i <= 4; i++) { 
30            engineR.forward(); 
31            engineL.forward(); 
32            Delay.msDelay(2000); 
33            engineR.stop(true); 
34             do { 
35                gyroSensor.fetchSample(sample, 0); 
36            } while (sample[0] > (-ANGLE * i)); 
37            engineL.stop(true); 
38        } 
39    } 
40 
41    public static void main(String[] args) { 
42        GyRoberta roberta = new GyRoberta(); 
43        roberta.driveSquare(); 
44    } 
45}

1 An dieser Stelle sei auch auf die leJOS-API verwiesen, welche unter http://www.lejos.org/ev3/docs/ eingesehen werden kann und eine vollständige Beschreibung aller leJOS-Klassen darstellt.