3. Lichtsensoren

Ein Licht Sensor ist mit einer roten Leuchtdiode (LED) und einer Fotodiode ausgestattet. Leuchtdiode beleuchtet die darunterliegende Fläche, die Fotodiode misst die Lichtintensität. Der Color-Sensor, der im EV3-Bausatz mitgeliefert wird, kann Farben erkennen und dient darüber hinaus als Lichtsensor, der Lichtstärke messen kann. Wird der Color Sensor in einem Programm als LightSensor bezeichnet, so kann er für die Helligkeitsmessung verwendet werden, gleich wie der NXT Light Sensor aus dem Bausatz des Vorgängermodells.

 
Light Sensor

Color Sensor

Die Funktion getValue() gibt den Sensorwert zurück. Die Werte liegen zwischen 0 und 1023 (je grösser der Wert, umso heller).

Es gibt zwei Möglichkeiten, die Sensorwerte zu erfassen:

Viele Anwendungen lassen sich mit beiden Verfahren lösen. Grundsätzlich ist Pollen immer anzuwenden, wenn man die Messwerte laufend benötigt (Steuern-Probleme). Bei Anwendungen, bei welchen der Roboter nur dann reagieren soll, wenn bestimmte Sensorwerte überschritten werden, ist das Event-Modell eleganter.

Für die Simulation wird im Grafikfenster mit RobotContext.useBackground() ein Hintergrundbild hinzugefügt. Die RobotContext-Anweisungen müssen in einem Python-Programm vor dem Erstellen des Roboter-Objekts stehen. Alle Hintergrundbilder, die in den Beispielen und Aufgaben verwendet werden, sind in der Bilderbibliothek in der TigerJython-Distribution enthalten.

Eigene Hintergundbilder (500 x 500 Pixel gross und im gif- oder png-Format) können Sie im beliebigen Ordner auf Ihrem Computer speichern. Im Programm müssen Sie den Pfadd der Bilddatei angeben.
Unter Windows z.B.
RobotContext.useBackground("c:/users/UrsMeier/desktop/bilder/mybackground.gif")
oder RobotContext.useBackground("d:/bilder/bild.gif") 

Unter MacOS z.B.
RobotContext.useBackground("/Users/UrsMeier/Desktop/Bilder/mybackground.gif")  

Unter Windows können die Bilder auch im Unterverzeichnis sprites des Unterverzeichnisses /bin des Installationsverzeichnisses gespeichert sein. Mit RobotContext.useBackground("sprites/mybackground.gif")
werden sie automatisch in Ihrem Programm integriert.

Beispiel 1: Roboter längst einer Hell-Dunkel-Kante steuern
Der Roboter misst mit seinem Lichtsensor die Helligkeit der Unterlage und wird mit den Methoden leftArc() bzw. rightArc() gesteuert. Wenn die Lichtsensorwerte kleiner als 500 sind, so befindet sich der Roboter auf einer dunklen Unterlage und muss seine Richtung mit einem Linksbogen korrigieren. Auf einer weissen Unterlage sind die Sensorwerte grösser als 500 und der Roboter fährt auf einem Rechtsbogen.

Die Roboterbewegung ist aber auch vom Bogenradius der Methoden leftArc() und rightArc() abhängig. Ist der Radius zu gross (z.B. 0.6), so erreicht der Roboter das Ziel nicht. Bei zu kleinem Radius (z.B. 0.05) reagiert der Roboter zu nervös. Bei noch kleinerem Radius (0.01) wird das System völlig unstabil.

 
Die Sensorwerte werden in einer endlosen while-Schleife abgefragt: while not robot.isEscapeHit(). Diese wird beendet, wenn der Escape-Button auf dem EV3 gedrückt wird, im direkten Modus auch durch Schliessen der Connectionbox, im Simulationsmodus durch Schliessen des Grafikfensters.

# Ro3a.py

from simrobot import *
#from ev3robot import *
#from nxtrobot import *

RobotContext.useBackground("sprites/border.gif")
RobotContext.setStartPosition(250, 490)
  
robot = LegoRobot()
gear = Gear()
robot.addPart(gear)
ls = LightSensor(SensorPort.S3)
robot.addPart(ls)
ls.activate(True)
gear.forward()

while not robot.isEscapeHit():
   v = ls.getValue()
   if v < 500:
      gear.leftArc(0.2)
   else:
      gear.rightArc(0.2)
   Tools.delay(100)     
robot.exit()
Programmcode markieren (Ctrl+C kopieren)

Erklärungen zum Programmcode:

 
ls = LightSensor(SensorPort.S3): erzeugt ein Lichtsensorobjekt
robot.addPart(ls): schliesst den Lichsensor am Roboter an
activate(True): aktiviert die LED (nur beim NXT notwendig, beim EV3 ist LED immer aktiviert und diese Zeile wird nicht ausgeführt)
ls.getValue(): gibt den Lichtwert des Sensors zurück
Tools.delay(100): damit das System beim Pollen durch ständige Abfrage nicht zu stark belastet ist, ist es besser nach jeder Abfrage eine kurze Pause einzuschalten
RobotContext.useBackground("sprites/border.gif"): Fügt das Hintergrundbild border.gif hinzu. Befehle im RobotContext werden im realen Modus nicht beachtet, das Programm kann daher ohne Änderung im Realen Modus ausgeführt werden
RobotContext.getStartPosition(250, 490): Im Simulationsmodus wird der Roboter an die Startposion im Grafikfenster versetzt

 

Beispiel 2: Mit einem Lichtsensor verschiedene Farben registrieren
Ein Roboter kann mit einem Lightsensor nicht nur schwarz-weisse Unterlagen unterscheiden, sondern auch Flächen mit verschiedenen Farben. Wählt man Farben, die unterschiedliche Helligkeiten haben, sind die vom Lightsensor gemessene Werte unterschiedlich. Der Roboter soll einer schwarzen Strasse, die zwischen einer blauen und gelben Fläche liegt, folgen.

Um das Problem zu lösen, müssen Sie wissen, welche Werte ein Lightsensor in einer gelben, blauen und schwarzen Fläche misst. Mit einem Testprogramm, welches die Werte mit print v ausschreibt, können Sie diese leicht herausfinden.

 

# LightTest.py

from ev3robot import *
#from nxtrobot import *

robot = LegoRobot()
gear = Gear()
robot.addPart(gear)
ls = LightSensor(SensorPort.S3)
robot.addPart(ls)
gear.forward()

while not robot.isEscapeHit():
    v = ls.getValue()
    print v
    Tools.delay(10)
robot.exit()
Programmcode markieren (Ctrl+C kopieren)

Das Testprogramm liefert im Realmodus für schwarz den Wert 60, blau den Wert 128 und für Gelb den Wert 800. Im Simulationsmodus sind die Werte etwas grösser. Im Programm wird ein einfacher Regelalgorithmus verwendet: Ist der Sensorwert kleiner als 100, so befindet sich das Fahrzeug auf der Strasse und kann geradeausfahren. Für Werte, die im gelben Gebiet und der Roboter muss eine Rechtskurve fahren, sieht er blau, muss er eine Linkskurve fahren.


# Ro3b.py

from simrobot import *
#from ev3robot import *
#from nxtrobot import *

RobotContext.setStartPosition(50, 490)
RobotContext.useBackground("sprites/roboroad.gif")

robot = LegoRobot()
gear = Gear()
robot.addPart(gear)
gear.setSpeed(30)
ls = LightSensor(SensorPort.S3)
robot.addPart(ls)
ls.activate(True)
gear.forward()

while not robot.isEscapeHit():
   v = ls.getValue()
   if v < 100:
      gear.forward()
   if v > 300 and v < 750:
      gear.leftArc(0.1)
   if v > 800:
      gear.rightArc(0.1)
   Tools.delay(100)         
robot.exit()
Programmcode markieren (Ctrl+C kopieren)

Erklärungen zum Programmcode:

leftArc(0.05): Der Bogenradius muss so eingestellt werden, dass der Roboter optimal links- bzw. recht gesteuert wird. Die realen Werte stimmen in der Regel mit den Werten bei der Simulation nicht ganz überein

 

Beispiel 3: Änderung der Sensorwerte mit Event-Modell erfassen

Der Roboter bewegt im weissen Feld, z. Bsp. auf einem weissen Tisch und darf nicht hinunterfallsen. Wenn über den Rand fährt und dunkel "sieht", fährt er ein kurzer Weg zurück, dreht um 90°nach links und fährt anschliessend wieder vorwärts.

Beim Verlassen der weissen Fläche wird ein Event ausgelöst und die Callbackmethode onDark() aufgerufen.

 

# Ro3c.py

from simrobot import *
#from ev3robot import *
#from nxtrobot import *

RobotContext.setStartPosition(250, 200)
RobotContext.setStartDirection(-90)
RobotContext.useBackground("sprites/circle.gif")
  
def onDark(port, level):
   gear.backward(1500)
   gear.left(550)
   gear.forward()

robot = LegoRobot()
gear = Gear()
robot.addPart(gear)
ls = LightSensor(SensorPort.S3,dark = onDark)
robot.addPart(ls)
ls.activate(True)
gear.forward()
while not robot.isEscapeHit():
   pass
robot.exit()
Programmcode markieren (Ctrl+C kopieren)

Erklärungen zum Programmcode:

onDark(port, level): die Callbackmethode braucht zwei Parameter: der Sensorport und ein Grenzwert, bei dem ein Event ausgelöst wird
ls = LightSensor(SensorPort.S3, dark = onDark): registriert die Callbackmethode, die aufgerufen wird, wenn der Roboter dunkel "sieht"

 

Beispiel 4: Roboter mit zwei Lichtsensoren steuern
Der Roboter soll dem dunklen Weg auf einer hellen Unterlage nachfahren. Mit zwei Lichtsensore kann der Roboter effizienter gesteuert werden. Falls sich ein Sensor ausserhalb der Spur befindet, wird die Fahrrichtung korrigiert. Wenn beide Sensoren Werte im dunklen Bereich zurückgeben, kann der Roboter geradeaus fahren. Sind beide Sensoren im hellen Bereich, fährt er zurück, bis er die Spur wieder findet.


# Ro3d.py

from simrobot import *
#from ev3robot import *

RobotContext.setStartPosition(250, 250)
RobotContext.setStartDirection(-90)
RobotContext.useBackground("sprites/track.gif")
  
robot = LegoRobot()
gear = Gear()
robot.addPart(gear)
lsR = LightSensor(SensorPort.S1)
robot.addPart(lsR)
lsL = LightSensor(SensorPort.S2)
robot.addPart(lsL)
#gear.setSpeed(20)
gear.forward()

while not robot.isEscapeHit():
    vR = lsR.getValue()
    vL = lsL.getValue()   
    if vR < 500 and vL < 500:
        gear.forward()
    if vR < 500 and vL > 500:   
        gear.rightArc(0.06)
    elif vR > 500 and vL < 500:
        gear.leftArc(0.06)
    elif vR > 500 and vL > 500:
        gear.backward()
    Tools.delay(100)                     
robot.exit()
Programmcode markieren (Ctrl+C kopieren)

 

Erklärungen zum Programmcode:

if vR < 500 and vL < 500: Beide Sensoren "sehen" dunkel
gear.setSpeed(20): Im Realen Modus muss die Geschwindigkeit je nach der Grösse der Bahn angepasst werden

 


Aufgaben:

1)

Ein Roboter mit einem Lichtsensor bewegt sich zwischen den zwei dunklen Streifen. Wenn er schwarz "sieht", dreht er um 180° und fährt wieder zurück. Für die Simulation können Sie das Hintergrundbild blacktapes.gif verwenden und dieses wie folgt als RobotContext einfügen:

RobotContext.setStartDirection(0)
RobotContext.useBackground("sprites/blacktapes.gif")

 

 

 

2)

Ein Roboter mit einem Lichtsensor soll quer über einige dunkle Streifen fahren. Bei jedem nächsten Streifen erhöht den Streifen-Zähler um 1. Die Anzahl der Streifen soll fortlaufend im Ausgabefenster angezeigt werden.
Für die Simulation können Sie das Hintergrundbild panels.gif verwenden und dieses wie folgt als RobotContext einfügen:

RobotContext.setStartPosition(0, 250)
RobotContext.setStartDirection(0)
RobotContext.useBackground("sprites/panels.gif")

 

 

3)

Der Roboter möglichst schnell und möglichst genau der schwarzen Kante nachfahren.

Für die Simulation können Sie das Hintergrundbild oval.gif benutzen

RobotContext.useBackground("sprites/oval.gif")
RobotContext.setStartPosition(150, 400)
 


4)

Der Roboter soll dem gelben Weg nachfahren. Auf dem schwarzen Streifen soll er jeweils eine kurze Zeit warten (eine Haltestelle) und dann weiter fahren. Verwende das Programm LightTest.py aus dem Beispiel 2, um die Farbwerte zu bestimmen.

Für die Simulation kannst du das Hintergrundbild bg_a4.gif verwenden.

RobotContext.useBackground("sprites/bg_a4.gif")
RobotContext.setStartPosition(100, 380)