TigerJython xx
für Gymnasien

6. Ultraschallsensor


Der Ultraschallsensor bestimmt die Distanz zu einem Objekt durch die Laufzeit, die ein kurzer Ultraschall-Puls benötigt, um vom Sensor zum Objekt und wieder zurück zu laufen. Der Ultraschallsensor des EV3- bzw. NXT-Roboters kann die Distanzen im Bereich 5 cm bis ca. 80 cm messen. Die Funktion getDistance() gibt die Entfernung in cm zurück. Die Sensorwerte können mit Pollen oder mit Eventmodell erfasst werden.  


Beispiel 1: Distanz messen und reagieren
Der Roboter fährt vorwärts und misst die Entfernung zum Objekt, welches vor ihm liegt. Wenn die Entfernung kleiner als 30 ist, fährt er eine kurze Strecke rückwärts. Danach fährt er wieder vorwärts bis seine Distanz zum Objekt kleiner als 30 ist usw.

Für die Erfassung eines Objekts durch den simulierten Sensor wird nicht Bild des Objekts, sondern Koordinaten seiner Eckpunkte verwendet. Für die Berechnung der Entfernung wird die Fläche des Objekts in Dreiecksmaschen (mesh) zerlegt. In diesem Beispiel wird für die Simulation ein horizontaler Balken bar0.gif mit der Breite 400 und Höhe 20 Pixel verwendet. Legt man den Mittelpunkt des Balkens in das Zentrum des Grafikfensters, haben seine Eckpunkten die Koordinaten (200, 10), (-200, 10), (-200, -10), (200, -10). Die Position des Balkens im Grafikfenster wird im RobotContext festgelegt

 

# Ro6a.py 

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

mesh_hbar = [[200, 10], [-200, 10], [-200, -10], [200, -10]]
RobotContext.useTarget("sprites/bar0.gif", mesh_hbar, 250, 100)

robot = LegoRobot()
gear = Gear()
robot.addPart(gear)
us = UltrasonicSensor(SensorPort.S1)
robot.addPart(us)
gear.setSpeed(25)
gear.forward()
   
while not robot.isEscapeHit():
    distance = us.getDistance()
    print distance
    if distance < 30:
        gear.backward(3000)
        gear.forward()
        
Programmcode markieren (Ctrl+C kopieren, Ctr+ v einfügen)
 



Erklärungen zum Programmcode:

us = UltrasonicSensor(SensorPort.S1): Erzeugt ein Ultraschallsensor-Objekt
us.getDistance(): Gibt die Distanz zum Gegenstand zurück. Falls kein Gegenstand detektiert wird, wird -1.
mesh_hbar = [[200, 10], [-200, 10], [-200, -10], [200, -10]]: Koordinaten der Eckpunkte des horizontalen Balkens, Mittelpunkt im Zentum
RobotContext.useTarget("sprites/bar0.gif", mesh_hbar, 250, 100): legt die Position des Balken fest. Der Mittelpunkt hat die Koordinaten (250, 100)

 

Beispiel 2: Mehrere Hindernisse registrieren und ausweichen
Der Roboter fährt vorwärts und misst die Entfernung zum Objekt, welches vor ihm liegt. Wenn die Entfernung kleiner als 40 ist, dreht er um 90° nach links und fährt in der neuen Richtung weiter bis das nächste Objekt im Weg ist.

Um die Situation zu simulieren, werden zwei horizontale und zwei vertikale Balken verwendet. Diese werden wie im Beispiel 1 durch die Koodinaten der Eckpunke und ihre Position im Grafikfenster festgelegt. Zusätzlich kann mit setBeamerAreaColor() und setProximityCircleColor() veranschaulicht werden, wie die Distanzmessung des Ultraschallsensors im Simulationsmodus erfolgt.

# Ro6b.py

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

mesh_hbar = [[200, 10], [-200, 10], [-200, -10], [200, -10]]
mesh_vbar = [[10, 200], [-10, 200], [-10, -200], [10, -200]]
RobotContext.useTarget("sprites/bar0.gif", mesh_hbar, 250, 100)
RobotContext.useTarget("sprites/bar0.gif", mesh_hbar, 250, 400)
RobotContext.useTarget("sprites/bar1.gif", mesh_vbar, 100, 250)
RobotContext.useTarget("sprites/bar1.gif", mesh_vbar, 400, 250)

robot = LegoRobot()
gear = Gear()
robot.addPart(gear)
us = UltrasonicSensor(SensorPort.S1)
robot.addPart(us)
us.setBeamAreaColor(Color.green)
us.setProximityCircleColor(Color.lightGray)
gear.setSpeed(25)
gear.forward()
   
while not robot.isEscapeHit():
    distance = us.getDistance()
    print distance
    if distance < 40:
        gear.backward(2000)
        gear.left(1070)
        gear.forward()
Programmcode markieren (Ctrl+C kopieren)
 


Erklärungen zum Programmcode:

setBeamAreaColor(Color.green) : veranschaulicht den Sichtwinkel des Sensors
setProximityCircleColor(Color.lightGray): Die Entfernung wird mit einem Kreis dargestellt

 

Beispiel 3: Einen Gegenstand finden und hinfahren
Der Roboter dreht sich wie eine Radarantene am Ort und sucht nach einem Gegenstand (Target). Falls er ein Objekt entdeckt, soll er hinfahren. Sobald die Distanz zum Gegenstand kleiner ist als 20 ist, soll er anhalten. Da wir laufend Messwerte benötigen, ist es sinnvoll die Werte mit Pollen zu erfassen. Die Werte werden laufend angezeigt. Das Programm kann im Real- und Simulationsmodus ausgeführt werden, wobei im Realmodus die Zeilen mit mesh, RobotContext, BeamerArea und ProximtyCircle nicht beachtet werden (können auch weggelassen werden).

Im Simulationsmodus entspricht das sichtbare Target der Bilddatei redtarget.gif. Der simulierte Sensor erfasst das Target mit Hilfe von Randpunkten der Bildfigur, die man im Programm als mesh angeben muss. Die Koordinaten werden vom Mittelpunkt des Grafikfensters der Figur berechnet. Das rote Sechseck in unserem Beispiel hat den Durchmesser 100. Die Eckpunkte haben daher die Koordinaten [50, 0] , [25, 43], [-25, 43], [-50, 0], [-25, -43], [25, -43].

Die Position des Targets im Grafikfenster wird im RobotContext angegeben (hier (400, 400)).

Der Sensor dreht sich nach rechts. Falls er ein Target entdeckt, speichert er den Winkel, dreht dann weiter, bis er das Target nicht mehr siegt und speichert wieder den Winkel. Er dreht anschliessend unm die Hälfte der Differenz der beiden Winkel zurück und fährt zum Target hin.

 



 


# Ro6c.py

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

mesh = [[50, 0], [25, 43], [-25, 43], [-50, 0],[-25, -43], [25, -43]] 
RobotContext.useTarget("sprites/redtarget.gif", mesh, 400, 400)

def searchTarget():
   global left, right
   found = False
   step = 0
   while not robot.isEscapeHit():  
      gear.right(50)
      step = step + 1
      dist = us.getDistance()
      if dist != -1:
         if not found:
            found = True
            left = step
      else:
         if found:   
            right = step
            break

robot = LegoRobot()
gear = Gear()
robot.addPart(gear)
us = UltrasonicSensor(SensorPort.S1)
robot.addPart(us)
us.setBeamAreaColor(Color.green)  
us.setProximityCircleColor(Color.lightGray)
gear.setSpeed(10)
searchTarget()
gear.left((right - left) * 25)
gear.forward()

while not robot.isEscapeHit() and gear.isMoving(): 
   dist = us.getDistance()
   print "Distance = " + str(dist)
   if dist < 40:
      gear.stop()
robot.exit()
Programmcode markieren (Ctrl+C kopieren)

Erklärungen zum Programmcode:

mesh = [[50, 0], [25, 43], [-25, 43], [-50, 0],[-25, -43], [25, -43]]: Koordinaten der Eckpunkte des roten 6-Ecks

RobotContext.useTarget("sprites/redtarget.gif", mesh, 400, 400): letze zwei Parameter geben die Position des Tagets im Grafikfenster an

def searchTarget() der Suchvorgang wird in einer funktion definiert
if dist != -1: falls kein Objekt in Sicht ist, wird im Simulationsmodus die Distanz -1 zurückgegeben.
Achtung: Der reale Roboter gibt den Wert 255 zurück, falls keine Objekt in der Nähe ist.
gear.left((right - left) * 25): Damit der Roboter direkt auf das Target fährt, wird zuerst der linke und der rechter Rand registriert, dann dreht der Roboter um den halben Winkel zurück (1 step = 50 Millisekunden). Auf hier gibts es ein leichter Unterschied zwischen den Werten im realen und Simulierten Modus.

 


Aufgaben: Serie 6

1)

Roboter mit einem Ultraschallsensor soll deinen Handbewegungen folgen, indem er ständig die Distanz 20 cm halten versucht. Wenn er eine Distanz grösser als 20 cm misst, fährt er vorwärts, bei einer Distanz kleiner als 20 cm fährt er zurück. Im Remote-Modus kannst du den Befehl print verwenden, um die Distanz anzuzeigen.

 

2)

Ein Roboter soll mit seinem Ultraschallsensor soll 3 höhere Gegenstände (Kerzen, Büchsen...) finden, auf sie losfahren und umstossen.

Im Simulationsmodus kann man squaretarget.gif verwenden, um die Gegenstände darzustellen. Für den RobotContext kannst du folgende Vorlage verwenden.

mesh = [[-30, -30], [-30, 30], [30, -30], [30, 30]]
RobotContext.useTarget("sprites/squaretarget.gif", mesh, 350, 250)
RobotContext.useTarget("sprites/squaretarget.gif", mesh, 100, 150)
RobotContext.useTarget("sprites/squaretarget.gif" ,mesh, 200, 450)
RobotContext.setStartPosition(40, 450) 

3)

Nur Realmodus
Roboter mit einem Ultraschallsensor bewegt sich auf einer Fläche (z.B. Tisch) und misst den abstand zu der Unterlage. Falls er an der Tischkante ankommt, stürzt er nicht ab, sondern fährt ein kurze Strecke zurück, dreht 90° links oder rechts und bewegt sich weiter vorwärts.