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.
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).
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
.
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
.
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
.
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
.
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
.
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
.
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)
.Die Ausgabe des Programms auf dem Display des EV3 lautet:
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.
boolean | – | Taste ist gedrückt: |
isUp()
prüft, ob die Taste zum Zeitpunkt des Methodenaufrufs oben (nicht
gedrückt) ist.
boolean | – | Taste ist nicht gedrückt: |
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.
int | – | ID_UP: 1 |
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.
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.
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.
Die Ausgabe des Programms auf dem Display des EV3 lautet:
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.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.
vol | – | Lautstärke mit Wertebereich zwischen Null (Stumm) und 100 (max) |
getVolume()
liest analog zu setVolume
die aktuelle Lautstärke aus.
int | – | Aktuelle Lautstärke |
playTone(int freq, int duration)
spielt einen Ton mit einer bestimmten Frequenz für die angegebene
Dauer.
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.
file | – | Abzuspielende WAV-Datei |
int | – | Länge der Soundausgabe in Millisekunden |
Das Programm 10.3 zur Klasse Sound spielt Töne und Tonfolgen verschiedener Frequenzen ab.
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
.
float | – | Batteriespannung in Volt |
getVoltageMilliVolt()
Gibt die aktuelle Batteriespannung in Millivolt aus. Methode ist
static
.
int | – | Batteriespannung in Millivolt |
Das Programm 10.4 zur Klasse »Battery« gibt den Batteriestand am Display aus, bis die ENTER-Taste gedrückt wird.
Die Ausgabe des Programms auf dem Display des EV3 lautet:
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).
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.
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 | ca. 0,08 Nm |
Anfahrmoment | ca. 0,4 Nm | ca. 0,12 Nm |
Gewicht | 76g | 36g |
Auto-ID | ja, bei EV3-Software | ja, bei EV3-Software |
|
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.
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.
immediateReturn | – | Optionaler Parameter;
wenn immediateReturn |
rotate(int angle, boolean immediateReturn)
rotiert den Motor um den angegeben Winkel.
angle | – | Winkel in Grad |
immediateReturn | – | Optionaler Parameter;
wenn immediateReturn |
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.
limitAngle | – | Winkel in Grad |
immediateReturn | – | Optionaler Parameter;
Wenn immediateReturn |
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).
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.
boolean | – | Liefert |
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.
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.
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.
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.
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.
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.
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.
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.
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:
BaseSensor
SampleProvider
-Objekts
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.
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.
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.
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.
modeName | – | Name eines Modus als String |
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.
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.
int | – | Anzahl der Elemente |
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 |
|
»Farb-ID« | 0 | Color ID |
»Rotlicht« | 1 | Red |
»RGB« | 2 | RGB |
»Umgebungslicht« | 3 | Ambient |
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.
int | – |
|
getAmbientMode()
erstellt ein SampleProvider
-Objekt für den »Umgebungslicht«-Modus
und liefert dieses zurück.
SensorMode | – | Sample Provider für den »Umgebungslicht«-Modus |
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.
SensorMode | – | Sample Provider für den »Farb-ID«-Modus |
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.
SensorMode | – | Sample Provider für den »Rotlicht«-Modus |
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.
SensorMode | – | Sample Provider für den »RGB«-Modus |
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.
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.
SensorMode | – | Sample Provider für den »Touch«-Modus |
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.
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.
Modus | int mode |
|
»Distanz« | 0 | Distance |
»Passiv« | 1 | Listen |
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.
SampleProvider | – | Sample Provider für den »Distanz«-Modus |
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.
SampleProvider | – | Sample Provider für den »Passiv«-Modus |
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.
boolean | – | Liefert |
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.
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.
Modus | int mode |
|
»Distanz« | 0 | Distance |
»Suchen« | 1 | Seek |
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 |
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.
chan | – |
Übertragungskanal (0, 1, 2, oder 3) |
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.
SensorMode | – | Sample Provider für den »Distanz«-Modus |
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.
SensorMode | – | Sample Provider für den Signal-Modus |
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 |
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 |
|
»Winkel« | 0 | Angle |
»Winkelgeschwindigkeit« | 1 | Rate |
»Winkel und Winkelgeschwindigkeit« | 2 | Rate and Angle |
|
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).
SampleProvider | – | Sample Provider für den Winkel-Modus |
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.
SampleProvider | – | Sample Provider für den Modus »Winkelgeschwindigkeit« |
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.
SampleProvider | – | Sample Provider für den Modus »Winkel und Winkelgeschwindigkeit« |
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.
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.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.