Jython HomeDruckenJava-Online

Lichtsensoren


Der Pi2Go hat 4 fest eingebaute, nach oben gerichtete Lichtsensoren, die mit LS_FRONT_LEFT, LS_FRONT_RIGHT, LS_REAR_LEFT, LS_REAR_RIGHT oder mit den IDs 0, 1, 2, 3 bezeichnet werden. Die Lichtsensoren können die Helligkeit der Umgebung messen. Die Funktion getValue() gibt die Werte zwischen 0 und 1000 zurück. Je heller, umso grösser ist der Sensorwert.
 

Beispiel 1: Beim Lichtsignal anhalten
Der Roboter bewegt sich auf einer Kreisbahn mit einem Lichtsignal. Wenn er das Lichtsignal mit seinem vorderen rechten Lichtsensor registriert, hält er an, schaltet alle Leds ein und wartet 1500 Millisekunden. Danach werden die Leds ausgeschaltet und der Roboter fährt auf der Kreisbahn weiter.

Im Simulationsmodus wir die Lichtquelle mit einem grauen, halbtransparenten Kreis simuliert. Dieser wird im RobotContext mit useTorch() definiert und kann im Grafikfenster beliebig positioniert werden.

#LightSensor1.py

from raspisim import *
# from raspibrick import *

RobotContext.useTorch(1, 150, 250, 100)
RobotContext.setStartPosition(350, 250)

robot = Robot()
gear = Gear()
ls = LightSensor(LS_FRONT_RIGHT)
gear.leftArc(0.15)
isBright = False

while not robot.isEscapeHit():
    v = ls.getValue()
    print v
    if  v > 950 and not isBright:  
        isBright = True
        Led.setColorAll(255, 0, 0) 
        gear.stop()
        Tools.delay(1500) 
        Led.clearAll()       
        gear.leftArc(0.15)
    if v < 900 and isBright:
        isBright = False                          
robot.exit()
Programmcode markieren (Ctrl+C kopieren)
 
Ausführen mit Webstart
   

Erklärungen zum Programmcode:

v = ls.getValue(): Gibt den Sensorwert zurück. Die Sensorwerte werden mit Pollen abgefragt
if v > 950 and not isBright: Das Flag isBright ist zu Beginn False und wird gesetzt, wenn der Roboter in den hellen Bereich eintritt. Gleichzeitig werden im if-Block die Leds eingeschaltet und der Roboter während der Wartezeit angehalten. Nach der Wartezeit fährt der Roboter weiter, befindet sich aber immer noch im hellen Gebiet. Der Block wird aber nicht erneut ausgeführt, da isBright erst dann zurückgesetzt wird, wenn der Roboter aus dem hellen Gebiet herausgefahren ist
RobotContext.useTorch(1, 150, 250, 100): Definiert eine Lichtquelle mit der Leistung 1, an der Position(150, 250) und mit der Höhe 100 über der Grundfläche. Die Helligkeit nimmt mit dem Quadrat des Abstandes ab

 

Beispiel 2: Einer Lichtquelle folgen
Der Roboter soll einer Lichtquelle, z.B. einer Taschenlampe folgen. Wenn die linke Seite stärker beleuchtet ist als die rechte, fährt er links. Wird die rechte Seite mehr beleuchtet, so fährt er rechts, sonst fährt er geradeaus. Im Simulationsmodus kann die Lichtquelle im Grafikfenster mit der gedrückten Maustaste gezogen werden. Zieht man die Lichtquelle im Grafikfenster herum, folgt der Roboter dieser simulierten Taschenlampe.

 

Realmodus

 

Simulationsmodus.   Ausführen mit Webstart

# LightSensor2.py

from raspibrick import *

robot = Robot()
gear = Gear()
lsL = LightSensor(LS_FRONT_LEFT)
lsR = LightSensor(LS_FRONT_RIGHT)
gear.setSpeed(20)
gear.forward()
s = 0.08
while not isEscapeHit():
    vL = lsL.getValue()
    vR = lsR.getValue()
    print vL, vR
    d = (vL - vR) / (vL + vR)
    if d > -s and d < s:
        gear.forward()
    else:
        if d >= s:
            gear.leftArc(0.08)
        else:
            gear.rightArc(0.08)            
robot.exit()
 
# LightSensor2a.py

from raspisim import *

RobotContext.useTorch(1, 150, 250, 100)
  
robot = Robot()
gear = Gear()
lsL = LightSensor(LS_FRONT_LEFT)
lsR = LightSensor(LS_FRONT_RIGHT)
gear.setSpeed(25)
gear.forward()
s = 0.02
while not isEscapeHit():
    vL = lsL.getValue()
    vR = lsR.getValue()
    print vL, vR
    d = (vL - vR) / (vL + vR)
    if d > -s and d < s:
        gear.forward()
    else:
        if d >= s:
            gear.leftArc(0.05)
        else:
            gear.rightArc(0.05)
robot.exit()   
Programmcode markieren (Ctrl+C kopieren)
 
Programmcode markieren (Ctrl+C kopieren)

Erklärungen zum Programmcode:

vL = lsL.getValue(): Gibt den Lichtwert des linken vorderen Sensors zurück
d = (vL - vR) / (vL + vR) : Für die Nachführung ist die relative Differenz zuständig
if d > -s and d < s : Wenn die Differenz klein ist, fährt der Roboter vorwärts. Sonst muss er auf dem linken bzw. rechten Kreisbogen fahren

Anmerkung: Falls sich die Taschenlampe hinten dem Roboter befindet, funktioniert das Programm nicht. Bessere Lösung zeigt Beispiel 3.

Beispiel 3: Vier Lichtsensoren verwenden, um einer Lichtquelle folgen
Der Pi2Go verfügt über 4 Lichtsensoren. Wenn man auch die hinteren Sensoren verwendet, "merkt" der Roboter, wenn sich die Lichtquelle hinter ihm befindet. In diesem Fall muss er so lange am Ort drehen, bis die vorderen Lichtsensoren einen grösseren Wert liefern.


Realmodus

 

Simulationsmodus.     Ausführen mit Webstart

# Lightsensor3.py

from raspibrick import *
  
robot = Robot()
gear = Gear()
ls = [0] * 4
for i in range(4):
   ls[i] = LightSensor(i)
gear.setSpeed(20)
gear.forward()
s = 0.1
isTurning = False
v = [0] * 4
while not isEscapeHit():
    for i in range(4):
        v[i] = ls[i].getValue()
    d = (v[0] - v[1]) / (v[0] + v[1])
    if v[2] + v[3] > v[0] + v[1]:  
        if not isTurning:
            if v[2] > v[3]:
                gear.right()
            else:
                gear.left()
            isTurning = True
    else:
        isTurning = False
        if d > -s and d < s:
            gear.forward()
        else:
            if d >= s:
                gear.leftArc(0.1)
            else:
                gear.rightArc(0.1)
robot.exit()   
 
# Lightsensor3a.py

from raspisim import *

RobotContext.useTorch(1, 150, 250, 100)
  
robot = Robot()
gear = Gear()
ls = [0] * 4
for i in range(4):
   ls[i] = LightSensor(i)
gear.setSpeed(25)
gear.forward()
s = 0.02
isTurning = False
v = [0] * 4
while not isEscapeHit():
    for i in range(4):
        v[i] = ls[i].getValue()
    d = (v[0] - v[1]) / (v[0] + v[1])
    if v[2] + v[3] > v[0] + v[1]:  
        if not isTurning:
            if v[2] > v[3]:
                gear.right()
            else:
                gear.left()
            isTurning = True
    else:
        isTurning = False
        if d > -s and d < s:
            gear.forward()
        else:
            if d >= s:
                gear.leftArc(0.05)
            else:
                gear.rightArc(0.05)
robot.exit()   
Programmcode markieren (Ctrl+C kopieren)
 
Programmcode markieren (Ctrl+C kopieren)

 

Erklärungen zum Programmcode:

ls[i] = LightSensor(i): Die Lichtsensoren werden mit der ID 0, 1, 2 und 3 erzeugt
if v[2] + v[3] > v[0] + v[1]: : Wenn die Sensoren 3 und 4 den grössen Wert zurückgeben, befindet sich die Lichtquelle hinter dem Roboter. Der Roboter dreht danach am Ort gegen rechts

 

Beispiel 4: Im Tunnel Leds einschalten
Der Roboter fährt in einen Tunnel (z.B. Schuhschachtel). Wenn er mit Lichtsensoren die Dunkelheit erkennt, schaltet er die vorderen zwei LEDs wie Scheinwerfer mit weissem Licht und die zwei hinteren als rote Schlusslichter ein. Am Ende des Tunnels schaltet er die Leds wieder aus. Da beim Raspi die vorderen Lichtsensoren nahe bei den Leds angebracht sind, werden die Lichtsensorenwerte durch die Leds beeinflusst. Es ist deshalb notwendig die Helligkeit mit den hinteren Lichtsensoren zu prüfen und die roten Schlusslichter nur schwach leuchten lassen.

Im Simulationsmodus wird mit useTorch() eine Lichtquelle erzeugt und mit useShadow() ein Schatten geworfen. Der Lichtsensorwert im Schattenbereich ist 0.


Realmodus

 

Simulationsmodus.      Ausführen mit Webstart

# LightSensor4.py

from raspibrick import *

robot = Robot()
gear = Gear()
ls1 = LightSensor(LS_REAR_LEFT)
ls2 = LightSensor(LS_REAR_RIGHT)
ledFront = Led(LED_FRONT)
ledRear = Led(LED_REAR)
gear.setSpeed(20)
gear.forward()
isOn = False

while not isEscapeHit():
    v1 = ls1.getValue()
    v2 = ls2.getValue() 
    print v1, v2
  
    if (v1 < 500 or v2 < 500) and not isOn: 
        ledFront.setColor(255, 255, 255)
        ledRear.setColor(20, 0, 0)
        isOn = True
        Tools.delay(100) 
     
    if (v1 > 600 or v2 > 600) and isOn:
        Led.clearAll()       
        isOn = False 
        Tools.delay(100)                  
robot.exit()
 
# LightSensor4a.py

from raspisim import *

RobotContext.useTorch(1, 250, 220, 100)
RobotContext.useShadow(100, 150, 400, 350)
RobotContext.setStartPosition(50, 250)
RobotContext.setStartDirection(0)
  
robot = Robot()
gear = Gear()
gear.setSpeed(25)
ls1 = LightSensor(LS_REAR_LEFT)
ls2 = LightSensor(LS_REAR_RIGHT)
ledFront = Led(LED_FRONT)
ledRear = Led(LED_REAR)
gear.forward()
isOn = False

while not isEscapeHit():
    v1 = ls1.getValue()
    v2 = ls2.getValue() 
    print v1, v2
    if (v1 == 0 or v2 == 0) and not isOn: 
        ledFront.setColor(255, 255, 255)
        ledRear.setColor(255, 0, 0)
        isOn = True
    if (v1 > 0 or v2 > 0) and isOn:
        Led.clearAll()       
        isOn = False     
robot.exit()   
Programmcode markieren (Ctrl+C kopieren)
 
Programmcode markieren (Ctrl+C kopieren)

Erklärungen zum Programmcode:

isOn = False: Da die Lichtwerte mit Pollen ständig abgefragt werden, wird ein Flag isOn verwendet. Dadurch werden die Leds bei der Überschreitung der Helligkeitsschwelle nur einmal ein- bzw. ausgeschaltet.
ledRear.setColor(20, 0, 0) : Die hinteren Leds leuchten nur schwach, damit sie die Helligkeitsmessung der Lichtsensoren nicht beeinflussen
RobotContext.useTorch(1, 250, 220, 100): Erzeugt eine Lichtquelle
RobotContext.useShadow(100, 150, 400, 350): Erzeugt einen Schatten mit dem gegebenen linken oberen und rechten unteren Ecke
if (v1 == 0 or v2 == 0) and not isOn: Der simulierte Lichtsensor gibt den Wert 0 zurück, wenn sich der Roboter im Schatten befindet

 


Aufgaben Serie 8:

1)

Der Roboter mit einem Lichtsensor soll 5 Mal bei einer Lichtschranke durchfahren. Er bewegt sich auf einer Kreisbahn und zählt die Runden. Sobald er zum fünften Mal die Lichtschranke passiert, hält er an.

 

 

2)

Der Roboter soll mit seinem Lichtsensor seine Fahrbahn so regeln, dass er sich wie ein Satellit auf einer Kreisbahn immer im gleichen Abstand von einer Lichtquelle befindet. Löse die Aufgaben im Simulationsmodus.