Zum Inhalt springen
BetaEN
Lektion 5 von 8Robotik mit LEGO SPIKE

Robotik mit LEGO SPIKE · Lektion 5 · 25 Minuten

Tasten und Gyrosensor

Das lernst du

  • Auf einen Tastendruck am Hub warten
  • Mit dem Gyrosensor die Drehrichtung messen
  • Den kürzesten Drehwinkel mit Modulo berechnen

Der Code in dieser Lektion stammt aus dem Buch „Python für Roboter“, Kapitel 2.3, und läuft hier unverändert im Simulator. Zum Buch bei Amazon ↗

Der Hub hört zu

Der SPIKE-Hub hat Tasten, und dein Programm kann darauf reagieren. Die mittlere Taste ist normalerweise die Stopp-Taste. Damit dein Code sie selbst benutzen darf, legt man die Stopp-Funktion auf eine Tastenkombination:

from pybricks.hubs import PrimeHub
from pybricks.parameters import Button, Color
from pybricks.tools import wait

hub = PrimeHub()
# Die Center-Taste ist normalerweise die STOPP-Taste fuer das ganze Programm.
# Wir geben sie hier frei, damit wir sie im Code selbst abfragen koennen -
# zum Stoppen dient ab jetzt Center- UND Bluetooth-Taste gleichzeitig.
hub.system.set_stop_button((Button.CENTER, Button.BLUETOOTH))

print("Druecke die mittlere Taste, um zu starten ...")

# Solange die mittlere Taste NICHT gedrueckt ist, warten wir
while Button.CENTER not in hub.buttons.pressed():
    wait(50)   # kurze Pause, damit die Schleife den Prozessor nicht blockiert

hub.light.on(Color.GREEN)
print("Los geht's!")

Drück auf Ausführen und dann auf die mittlere Taste am virtuellen Hub rechts.

Der Gyrosensor

Im Hub steckt ein Gyrosensor. Er merkt, wie weit sich der Roboter gedreht hat. hub.imu.heading() liefert den Winkel in Grad:

from pybricks.hubs import PrimeHub
from pybricks.tools import wait

hub = PrimeHub()

# Drehwinkel auf 0 zuruecksetzen - er zaehlt danach immer weiter (auch ueber 360 hinaus)
hub.imu.reset_heading(0)

for _ in range(10):
    winkel = hub.imu.heading()   # aktueller Drehwinkel in Grad
    print(f"Aktueller Winkel: {winkel} Grad")
    wait(500)

Der Roboter steht hier still, deshalb bleibt der Winkel bei 0. Im nächsten Beispiel dreht er sich – und dann wird es spannend.

Der Gyro kennt keine 360 Grad

Der Winkel zählt immer weiter: Nach anderthalb Drehungen steht dort 540, nicht 180. Mit dem Modulo-Operator % rechnest du den kürzesten Weg zurück aus:

from pybricks.hubs import PrimeHub
from pybricks.pupdevices import Motor
from pybricks.parameters import Port, Direction
from pybricks.robotics import DriveBase

hub = PrimeHub()
linker_motor = Motor(Port.A, positive_direction=Direction.COUNTERCLOCKWISE)
rechter_motor = Motor(Port.B, positive_direction=Direction.CLOCKWISE)
antrieb = DriveBase(linker_motor, rechter_motor, wheel_diameter=56, axle_track=114)

def kuerzester_drehwinkel(aktuell, ziel):
    differenz = (ziel - aktuell) % 360
    if differenz > 180:
        differenz = differenz - 360
    return differenz

hub.imu.reset_heading(0)          # Startrichtung = 0 Grad

antrieb.turn(400)                 # der Roboter dreht sich mehr als eine ganze Runde
# ... hier wuerde dein Programm etwas anderes tun ...

# Zurueck zur Startrichtung - auf dem kuerzesten Weg:
zurueck = kuerzester_drehwinkel(hub.imu.heading(), 0)
antrieb.turn(zurueck)

(ziel - aktuell) % 360 liefert immer einen Wert zwischen 0 und 359. Ist er größer als 180, ist es kürzer, andersherum zu drehen – deshalb ziehen wir 360 ab.

Merke: Vergleiche Winkel nie mit ==. Der Gyro liefert oft Kommazahlen und trifft einen Wert fast nie genau. Prüfe lieber einen Bereich, z. B. abs(differenz) < 2.

Deine Aufgabe

Jetzt bist du dran

Der Roboter dreht sich mit antrieb.turn(250) weg. Bring ihn danach auf dem kürzesten Weg zurück in die Startrichtung. Benutze dafür hub.imu.heading() und eine Funktion kuerzester_drehwinkel(aktuell, ziel). Tipp: Von 250 Grad zurück auf 0 ist es kürzer, noch 110 Grad weiterzudrehen, als 250 Grad zurück.

from pybricks.hubs import PrimeHub
from pybricks.pupdevices import Motor
from pybricks.parameters import Port, Direction
from pybricks.robotics import DriveBase

hub = PrimeHub()
linker_motor = Motor(Port.A, positive_direction=Direction.COUNTERCLOCKWISE)
rechter_motor = Motor(Port.B, positive_direction=Direction.CLOCKWISE)
antrieb = DriveBase(linker_motor, rechter_motor, wheel_diameter=56, axle_track=114)

def kuerzester_drehwinkel(aktuell, ziel):
    # berechne den kürzesten Winkel (zwischen -180 und 180)
    return 0

hub.imu.reset_heading(0)
antrieb.turn(250)

# zurück in die Startrichtung:

Ohne Hinweise gelöst gibt es einen ⭐ auf deiner Fortschrittsseite.

Lösung anzeigen

Versuch es erst selbst – aus Fehlern lernt man am meisten. Hier ist eine mögliche Lösung:

from pybricks.hubs import PrimeHub
from pybricks.pupdevices import Motor
from pybricks.parameters import Port, Direction
from pybricks.robotics import DriveBase

hub = PrimeHub()
linker_motor = Motor(Port.A, positive_direction=Direction.COUNTERCLOCKWISE)
rechter_motor = Motor(Port.B, positive_direction=Direction.CLOCKWISE)
antrieb = DriveBase(linker_motor, rechter_motor, wheel_diameter=56, axle_track=114)

def kuerzester_drehwinkel(aktuell, ziel):
    differenz = (ziel - aktuell) % 360
    if differenz > 180:
        differenz = differenz - 360
    return differenz

hub.imu.reset_heading(0)
antrieb.turn(250)

# zurück in die Startrichtung:
zurueck = kuerzester_drehwinkel(hub.imu.heading(), 0)
antrieb.turn(zurueck)