TigerJython4Kids
HomeTurtlegrafikRobotikDatenbanken
ultrasonic

4. ULTRASCHALLSENSOR (DISTANZSENSOR)

 

 

DU LERNST HIER...

 

wie du mit einen Ultraschallsensor Distanzen messen und auswerten kannst.


 

WIE FUNKTIONIERT EIN ULTRASCHALLSENSOR?

 
Ein Ultraschallsensor hat einen Sender und einen Empfänger für die Ultraschallwellen. Bei einer Distanzmessung sendet er einen kurzen Ultraschallpuls und misst die Zeit, die dieser benötigt, um zum Objekt und wieder zurück zu laufen. Daraus kann er mit Hilfe der bekannten Schallgeschwindigkeit die Distanz ermitteln.  

Der Callibot-Sensor kann die Distanzen im Bereich von ca. 5 bis 200 cm messen und liefert die Werte in cm zurück. Wenn kein Objekt im Messbereich ist, gibt er den Wert 255 zurück.



 

MUSTERBEISPIELE

 


Beispiel 1: Ein Objekt erkennen

Der Roboter fährt vorwärts und misst alle 200 Millisekunden die Entfernung zum Objekt, der sich vor ihm befindet. Wenn die Entfernung kleiner als 20 cm ist, hält er an.

 

from callibot import *

forward()
repeat:
    d = getDistance()
    print(d)    
    if d < 20:
        stop()    
    delay(200)
► In Zwischenablage kopieren

Der Befehl getDistance() gibt die Distanz zum Objekt zurück. Der Sensorwert wird in einer Endlosschleife abgefragt und in der Variablen d gespeichert. delay(200) gibt die Messperiode an. Für die Überprüfung der Sensorwerte verwendest du die if-Struktur. Die eingerückte Anweisung stop() wird nur dann ausgeführt, wenn die Bedingung nach if erfüllt ist. Falls der Roboter via USB-Kable mit dem Computer verbunden ist, werden mit print(d) die Sensorwerte im Terminalfenster angezeigt.


Beispiel 2: Ein Regelungssystem für die Distanz
zum Objekt


Dein Programm soll dafür sorgen, dass der Roboter in einer bestimmten Distanz zu deiner Hand bleibt. Ist er zu nahe, soll er rückwärts, sonst vorwärts fahren.

Für die Auswertung der Sensorwerte verwendest du die if-else-Struktur. Falls die Bedingung nach if stimmt, wird die Anweisung nach if ausgeführt, sonst die Anweisung nach else.

 

 


from callibot import *

forward()
setSpeed(30)
repeat:
    d = getDistance()
    if d < 20:
        backward()
    else: 
        forward()    
    delay(100)
► In Zwischenablage kopieren


Beispiel 3: Objekt suchen
Ein Roboter mit einem Ultraschallsensor soll ein Objekt finden und danach zu ihm fahren und ihn umstossen. Der Roboter steht beim Start in einer beliebigen Richtung, d.h. er muss zuerst drehen, bis er den Gegenstand detektiert.

 

from callibot import *

def searchTarget():
   repeat:  
      right()
      delay(50)    
      dist = getDistance()
      if dist != 255:
         right()
         delay(500)
         break
 
setSpeed(20)
searchTarget()
setSpeed(50)
forward()
► In Zwischenablage kopieren

Den Suchvorgang definierst du in der Funktion searchTarget(). Der Roboter dreht jeweils um einen kleinen Winkel nach rechts und misst die Distanz. Falls er ein Objekt detektiert (der Sensor gibt nicht mehr den Wert 255 zurück), dreht er noch ein wenig weiter, damit er gegen Mitte des Objekts gerichtet ist. Mit break kannst du die repeat-Schleife abbrechen und damit den Suchvorgang beenden. Im Hauptprogramm wird die Funktion searchTarge() aufgerufen und der Roboter fährt nach dem erfolgreichen Suchvorgang zum Objekt. Du kannst das Programm noch optimieren, indem du den Roboter stopst, sobald er näher als 5 cm beim Gegenstand ist.


Eine moderne Industrieanlage ohne Sensoren ist heute kaum mehr denkbar. Auch in unserem Alltag umgeben uns Sensoren. Die modernen Autos verfügen über 50 - 100 verschiedene Sensoren: Abstandsensoren, Drehzahl- und Geschwindigkeitsensoren, Füllstansensor des Benzintanks, Temperatursensor usw.

Beim Einparkieren werden Distanzsensoren verwendet, die ähnlich funktionieren, wie diejenigen unseres kleinen Callibots.

 

 

 

 

MERKE DIR...

 

Die Anweisung getDistance() gibt den Wert des Ultraschalsensors zurück. Die Sensorwerte werden in einer repeat-Schleife periodisch gemessen, delay(100) bestimmt die Messperiode. Dieser Befehl ist wichtig, das sonst die Werte zu häufig abgefragt werden, was zur Überlastung des Mikroprozessors führen kann.

 

 

ZUM SELBST LÖSEN

 

 

1.

Das Regelungssystem im Beispiel 2 ist noch nicht optimal. Wenn du die Hand ganz wegnimmst, reagiert der Roboter oft verwirrt, da er entweder weit entfernte Gegenstände oder gar nichts detektiert. Optimiere das Programm so, dass der Roboter im Fall, dass die Distanz grösser als 50 cm ist, stehen bleibt.

 
if d < 20:
   ... 
elif d >= 20 and d < 50:
   ... 
else:
   ...    
  Dazu verwendest du die if-elif-else-Struktur, mit welcher du eine mehrfache Auswahl programmieren kannst.

2.

Ein Roboter mit einem Ultraschallsensor soll einen höherer Gegenstand (Säule aus Pappkarton, Kerze, Büchse...) finden, indem er am Ort langsam dreht und die Distanz misst. Falls er ein Objekt im Abstand kleiner als 40 cm detektiert, löst er für 4 Sekunden einen Alarm aus.


 
3.

Ein Roboter soll gleich wie im Beispiel 2 ein Objekt finden, indem er am Ort dreht und die Werte seines Ultraschalsensors auswertet. Wenn er ein Objekt entdeckt, fährt er hinzu und bleibt im Abstand von 10 cm vor dem Objekt stehen.

4.
Ein Roboter mit einem Ultraschallsensor versucht den Ausgang aus einem begrenzten Raum zu finden. Er dreht zuerst langsam am Ort und wenn er keine Wand detektiert, fährt er los.  

 

 

ZUSATZSTOFF: ULTRASCHALLSENSOR IM SIMULATIONSMODUS

 

Die Distanzmessung mit einem Ultraschallsensor lässt sich auch im Simulationsmodus ausführen. Dazu musst du die die Koordinaten des Objekts (target) im Grafik-Fenster angegeben.

Beispiel 4: Ultraschallsimulation (Objekt erkennen)
Der Roboter soll zum Hindernis fahren. Wenn die Distanz kleiner als 30 cm ist, fährt er eine kurze Strecke rückwärts und danach wieder vorwärts.

Für die Simulation verwendest als Hindernis einen horizontalen Balken, den du mit folgendem Context erzeugst:

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

In der ersten Zeile sind die Koordinaten der Eckpunkte des Objekts (ein Rechteck mit dem Mittelpunkt bei (0,0)). Im Grafikfenster wird das Objekt an der Position (250, 100) mit dem Bild bar0.gif dargestellt. Die Bilder sind in der TigerJython-Distribution enthalten (Bilderbibiothek).

from callibot import *

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

forward()
repeat:
    d = getDistance()
    if d < 30:
        backward()
        delay(2000)
    else: 
        forward()    
    delay(100)
► In Zwischenablage kopieren

Der Ultraschallsensor ist beim simulierten EV3 oben auf dem Brick und nicht vorne platziert. Deswegen fährt der Roboter etwas näher zum Balken hin.

Beispiel 5: Ultraschallsimulation (Objekt suchen)
Ein Roboter mit Ultraschallsensor dreht sich langsam am Ort. Wenn er einen Gegenstand detektiert, fährt er hinzu und hält kurz vor ihm an.
Du schreibst eine Funktion searchTarget(), die den Suchvorgang definiert: Der Roboter dreht in kleinen Schritten nach rechts und misst dabei die Distanz dist. Wenn er ein Objekt detektiert (dist != -1), dreht er ein wenig weiter und unterbricht den Suchvorgang mit break.

 

Danach fährt er mit Hilfe einer zweiten repeat-Schleife so lange vorwärts, bis die Distanz zum Objekt kleiner als 30 ist. Mit dem Befehl setBeamAreaColor() kannst du den Suchvorgang besser veranschaulichen.

from callibot import *

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

def searchTarget():
   repeat:  
      right()
      delay(50)    
      dist = getDistance()
      if dist != -1: 
         right()
         delay(600)
         break
 
setBeamAreaColor(Color.green) 
setSpeed(10)
searchTarget()
forward()

repeat:
   dist = getDistance()
   print(dist)
   if dist < 20:
      stop()
      break
► In Zwischenablage kopieren

Das Objekt ist mit den Koordinaten eines Sechsecks mit dem Mittelpunkt (0, 0) beschrieben und mit dem Bild redtarget.gif an der Position (400, 400) dargestellt wird.


 

MERKE DIR...

 

Auch den Ultraschalsensor kannst du simulieren. Dabei musst du das Hindernis mit den Koordinaten der Eckpunkte beschreiben. Wenn der simulierte Sensor kein Objekt detektiert, gibt er den Wert -1 zurück (der reale Roboter 255). Für den Realmodus musst du die Zeilen mit RobotContext deaktivieren.


 

ZUM SELBST LÖSEN

 
5.

Ein Roboter soll mit einem Ultraschallsensor soll drei hohe leichte Gegenstände nacheinander finden und umstossen. Er dreht langsam am Ort und wenn er ein Objekt detektiert, fährt er etwas schneller auf ihn los los bis er ihn zum Fall gebracht hat. Danach fährt er eine kurze Strecke zurück und sucht er das nächste Objekt.

Im Simulationsmodus verwendest du das folgende RobotContext:

 

 
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)
RobotContext.setStartDirection(250)

6.

Der Roboter soll eine rechteckige Fläche, die auf allen Seiten begrenzt ist, so abfahren, als ob er sie wie ein Rasenmäher mähen würde. Falls er mit seinem Ultraschalsensor eine Begrenzung detektiert, so dreht er 90 Grad, fährt eine kurze Strecke parallel zur Begrenzung, dreht nochmals um 90 Grad und fährt wieder vorwärts, bis er bei der gegenüberliegenden Begrenzung ankommt. Diese Bewegung wiederholt er, bis er das ganze Feld gemäht hat.

Im Simulationsmodus kannst du folgende Feld-Begrenzung verwenden

 

 
target = [[200, 10], [-200, 10], [-200, -10], [200, -10]]
RobotContext.useTarget("sprites/bar0.gif", target, 250, 20)
RobotContext.useTarget("sprites/bar0.gif", target, 250, 480)
RobotContext.setStartPosition(430, 480)

Die Aufgabe ist nicht so einfach, da der Roboter abwechslungsweise links und rechts drehen muss. Dies lässt sich mit folgendem Trick lösen: du definierst eine Funktion turn(n), die für gerade n eine Drehung links und für die ungeraden n eine Drehung nach rechts bewirkt. n musst du zu Beginn auf 0 setzen.

def turn(n):
if n % 2 == 0:
left()
else:
right()
delay(540))