TigerJython xx
für Gymnasien

4. Touchsensor


Ein Touchsensor reagiert auf die Berührung. Die Methode isPressed() gibt True zurück, wenn der Sensor berührt wurde. Die Sensorwerte können wie folgt erfasst werden:

 
  • Mit Pollen (Beispiele 1 und 2):
    In einer endlosen while-Schleife wird mit der Methode isPressed() der Sensorwert ständig abgefragt. isPressed() gibt True zurück, wenn der Sensort berührt wurde.
  • Mit Events (Beispiel 3):
    Wenn der Roboter mit dem Touchsensor einen Gegenstand berührt, wird ein Event ausgelöst. Dabei wird eine Callbackmethode aufgerufen, in welcher definiert wird, wie der Roboter reagieren soll.

Beispiel 1: Hinderniss registrieren und Richtung ändern
Ein Roboter mit einem Touchsensor fährt vorwärts, bis er ein Hindernis berührt. Dann fährt er eine kurze Strecke zurück, dreht um 90° nach links und fährt in der neuen Richtung weiter.

Der Sensorwert wird in einer endlosen while-Schleife abgefragt:


# Ro4a.py

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

RobotContext.useObstacle("sprites/field1.gif", 250, 250)  
robot = LegoRobot()
gear = Gear()
robot.addPart(gear)
ts = TouchSensor(SensorPort.S3)
robot.addPart(ts)
gear.forward()

while not robot.isEscapeHit(): 
    if ts.isPressed():
        gear.backward(1500)
        gear.left(550)
        gear.forward()
robot.exit()
Programmcode markieren (Ctrl+C kopieren)

 

Erklärungen zum Programmcode:

ts = TouchSensor(SensorPort.S3): erzeugt einen Touchsensor
robot.addPart(ts): schliesst den Touchsensor am Roboter an
if ts.isPressed(): der nachfolgende Programmcode wird ausgeführt, wenn der Sensor gedrückt wurde
RobotContext.useObstacle(): für die Simulation wird das Hintergrundbild field1.gif verwendet. Die weitere zwei Parameter sind Koordinaten des Mittelpunktes des Bildes. Hintergrundbilder für die Touchsensorsimulation müssen einen transparenten Hintergrund haben.

 

Beispiel 2: Kanalroboter
Ein Roboter mit zwei Touchsensoren soll den Weg im Kanal finden.

Mit zwei Touchsensoren kann ein Roboter effizienter gesteuert werden. Je nach dem, ob er ein Hinderniss mit dem linken oder mit dem rechten Sensor berührt, wird seine Richtung entsprechend geändert. Die Werte der beiden Sensoren werden mit Pollen in einer endlosen while-Schleife abgefragt.

 

# Ro4b.py

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

RobotContext.useObstacle("sprites/racetrack.gif", 250, 250)
RobotContext.setStartPosition(420, 460)

robot = LegoRobot()
gear = Gear()
robot.addPart(gear)
tsR = TouchSensor(SensorPort.S1)
robot.addPart(tsR)
tsL = TouchSensor(SensorPort.S2)
robot.addPart(tsL)
gear.forward()

while not robot.isEscapeHit():    
    if tsR.isPressed():
        gear.backward(250)
        gear.left(200)
        gear.forward() 
    elif tsL.isPressed():        
        gear.backward(250)
        gear.right(200)
        gear.forward()           
robot.exit()
Programmcode markieren (Ctrl+C kopieren)

Erklärungen zum Programmcode:

tsR = TouchSensor(SensorPort.S1): der rechte Touchsensor wird am Port S1 angeschlossen
tsL = TouchSensor(SensorPort.S2): der linke Touchsensor wird am Port S2 angeschlossen

 

Beispiel 3: Drücken des Touchsensor wird als Event aufgefasst
Ein Roboter bewegt sich in einem beschränkten Feld mit dem Ziel, den Ausgang zu finden. Wenn die Begränzung berührt, so fährt er eine kurze Strecke zurück, dreht um einen kleinen Winkel nach links und fährt anschliessend wieder vorwärts.

Die Programmiertechnik, um auf einen Touchevent zu reagieren, ist die Folgende: Man schreibt eine Callbackfunktion onPressed(), Hier definiert man, wie sich der Roboter beim Drücken des Touchsensor verhalten soll. Der Callback wird der mit dem benannten Parameter pressed beim Erzeugen des Touchsensors registriert.

 

# Ro4c.py

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

RobotContext.useObstacle("sprites/trap.gif", 250, 250);

def onPressed(port):
    gear.backward(800)
    gear.left(240)
    gear.forward()
  
robot = LegoRobot()
gear = Gear()
robot.addPart(gear)
ts = TouchSensor(SensorPort.S3, pressed = onPressed)
robot.addPart(ts)
gear.forward()
while not robot.isEscapeHit():
   pass
robot.exit()
Programmcode markieren (Ctrl+C kopieren)

Erklärungen zum Programmcode:

ts = TouchSensor(pressed = onPressed): mit dem Parameter pressed wird der Callback registriert
def onPressed(port): die Callbackmethode braucht nur einen Parameter: die Portnumme

 

Beispiel 4: Weg suchen
Roboter mit einem Touchsensor soll den Weg durch einen Kanal, der aus rechtwinklig liegenden Wegstücken besteht, finden. Er sucht den Weg nach folgender Strategie: Er fährt vorwärts, bis er mit dem Touchsensor eine Wand berührt. Dann fährt er eine kurze Strecke zurück, dreht um 90° nach links und fährt in der neuen Richtung weiter. Wenn der Weg nicht links, sondern rechts führt, so trifft er nach einer kurzen Zeit wieder an eine Wand. In diesem Fall muss er um 180° drehen, was einer Drehung nach rechts entspricht.

Die Zeit bis zum Anstoss kann mit einem Timer gemessen werden.

 

# Sim4d.py

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

RobotContext.useObstacle("sprites/bg.gif", 250, 250)  
RobotContext.setStartPosition(310, 470)

def onPressed(port):
   global startTime
   dt = time.clock() - startTime
   print dt
   gear.backward(900)
   if dt > 2: 
      gear.left(turnTime)      
   else:
      gear.left(2 * turnTime)  
   gear.forward()   
   startTime = time.clock()     
      
robot = LegoRobot()
gear = Gear()
gear.setSpeed(50)
robot.addPart(gear)
ts = TouchSensor(SensorPort.S3, pressed = onPressed)     
robot.addPart(ts)
gear.forward()
startTime = time.clock()
turnTime = 545        
Programmcode markieren (Ctrl+C kopieren)

Erklärungen zum Programmcode:

import time: importiert die Klasse time, welche die Methode zur Echtzei-Zeitmessung enthält
startTime = time.clock(): bei einer Wandberührung wird die Zeit als startTime gespechert
global startTime: damit man die Variable startTime in einer Funktion verändern kann, muss sie als global bezeichnet werden
dt = time.clock() - startTime: Zeit, die seit der letzten Wandberührung vergangen ist



Aufgaben: Serie 4

1)

Rasenmäher
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 auf eine Begrenzung trifft, so fährt er zuerst ein wenig zurück, dreht um 90 Grad, fährt eine kurze Strecke parallel zur Wand, dreht nochmals um 90 Grad und fährt wieder vorwärts.

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

RobotContext.useObstacle("sprites/field1.gif",250, 250)
RobotContext.setStartPosition(350, 350)

 

 

 

2)

Der Roboter soll sich auf einer rechteckigen Fläche, die auf allen Seiten begrenzt ist, wie ein Staubsaugerroboter bewegen. Er fährt vorwärts und weicht den Hindernissen aus, indem er beim Erkennen eines Objekts zuerst ein wenig zurück fährt, sich dreht um einen bestimmten Winkel dreht und dann wieder vorwärts fährt.

Für die Simulation kannst du das nebenstehende Hintergrundbild cleaner.png verwenden. Klicke mit der rechten Maustaste in das Bild und wähle "Grafik speichern unter". Speichere das Bild im Unterverzeichnis sprites des Verzeichnisses, in dem dein Programm gespeichert ist.

RobotContext.useObstacle("sprites/cleaner.gif",250, 250)  

 

 

cleaner,gif
3)

Kanalroboter
Ein Roboter mit zwei Touchsensoren soll das ganze Rohr durchfahren und wieder zum Ausgangsort zurückkehren. Für die Simulation kannst du das Hintergrundbild channel.gif verwenden.

RobotContext.useObstacle("sprites/channel.gif",250, 250)
RobotContext.setStartPosition(250, 250)
RobotContest.setStartDirection(0)

 

 

4)

Erstellen Sie selbst mit einem Grafikprogramm ein Hintergrundbild für einen Touchsensor-Parcours im Simulationsmodus. Das Bild darf höchstens 501x501 Pixel gross sein und hat einen transparenten Hintergrund.

Speichere das Bild im Unterverzeichnis sprites z.Bsp. unter dem Name myParcours.gif und geben verwende das Bild im RobotContext:

RobotContext.useObstacle("sprites/myparcours.gif",250, 250)