This is an old revision of the document!
Lichtsensor und Line Follower
In diesem Abschnitt geht es um Regelungstechnik. Typische Probleme sind:
- im Haushalt: Temperatur von Heizung bzw. Kühlschrank bzw. Bügeleisen so regeln, dass die gewünschte Temperatur möglichst konstant bleibt.
- Tempomat beim Auto: Halte die Geschwindigkeit konstant (auch bei Steigungen, Wind etc.).
- Autopiloten in der Luftfahrt, Schiffahrt, Raumfahrt.
- Regelung des Abflusses eines Stausees, damit die gewünschte Strommenge erzeugt wird.
- Autonomes Fahren.
Der Roboter soll z. B. der äusseren schwarzen Linie auf der Plane folgen!
Aufgabe 1: Licht-Sensor kalibrieren
Erstelle per “Create a new project” ein neues Projekt und kopiere ans Ende des Programms main.py den folgenden Code.
Ersetze die Nullen wie in den Kommmentaren im Programm beschrieben.
# Bitte sicherstellen, dass dein Computer im tech-lab-Netz ist und nicht in Schule SG o.ä.. ############### # AUFGABE 1 # ############### ev3.speaker.say(text="Hello, I'll follow the line.") links = Motor(Port.A) rechts = Motor(Port.B) licht = ColorSensor(Port.S1) # Sind die Motoren und Sensoren richtig verkabelt? while True: r = licht.reflection() print(r) wait(100) # Wartezeit in Millisekunden # Ermittle mit Hilfe der obigen Schleife die Werte # für Weiss und Schwarz auf der Plane und trage sie # unten ansstelle der Nullen ein. schwarz = 0 weiss = 0 # Idealwert, wenn der Sensor mittig auf der Kante ist. idealwert = (schwarz + weiss) / 2
Aufgabe 2: Drivebase kennenlernen
Im bisher erstellten Programm: Lösche die while True-Schleife (oder kommentiere sie aus).
Dann kopiere den folgenden Code-Block ans Ende des Programms und lerne damit den drive-Befehl kennen.
############### # AUFGABE 2 # ############### fahrwerk = DriveBase(links, rechts, wheel_diameter=55.5, axle_track=125) # Raddurchmesser und Achsenabstand (in Millimeter) sind hier die beiden letzten Parameter. # Lerne den "drive"-Befehl kennen: # - erster Parameter: Robotergeschwindigkeit in mm/s # - zweiter Parameter: Rotationsgeschwindigkeit des Roboters in Grad/s # Die entsprechende Bewegung wird solange ausgeführt, bis ein anderer Befehl oder ein Stopp-Befehl kommt. Mit anderen Worten wechselt der Roboter zwischen verschiedenen Zuständen. # Ersetze die Fragezeichen durch (motorschonende) Werte deiner Wahl. # Erster Parameter z. B. 100 (oder auch -100), zweiter 0 oder +20 oder -20. # # Spiele dann etwas mit den Parametern. # fahrwerk.drive(??, ??) wait(??) # Wartezeit in Millisekunden fahrwerk.drive(??, ??) wait(??) fahrwerk.drive(??, ??) wait(??) ev3.speaker.say(text="Now I stop.") fahrwerk.stop() # # Mögliche Fragen: # (1) Überlege zuerst theoretisch: Wie lange muss der Roboter mit einer gegebenen Geschwindigkeit geradeaus fahren, um genau einen Meter zurückzulegen? Passe danach die Parameter (Raddurchmesser, Spurbreite) so an, dass die Praxix möglichst gut mit der Theorie übereinstimmt. # (2) Welche Parameter sorgen dafür, dass der Roboter in 10 Sekunden einen Viertelkreis mit Radius 50 cm abfährt? # (3) Schaffst du es, den Roboter auf einem Linienzug (aus Klebeband am Boden) fahren zu lassen?
Genaueres über die “Drivebase” steht hier: https://pybricks.com/ev3-micropython/robotics.html
Dort wird z. B. auch erklärt (Abschnitt “Measuring and validating the robot dimensions”), dass man zuerst den Raddurchmesser (wheel_diameter) und dann die Spurweite (axle_track) anpassen sollte. Auch wird dort erklärt, wie man den aktuellen Zustand des Roboters erhält (per state()).
Aufgabe 2b (neu)
Lass den Roboter geradeaus fahren, bis er auf eine weisse Linie trifft. Dort soll er stoppen und irgendetwas sagen, dann Programmende.
Aufgabe 3: Einfacher Line Follower
Idee: Der Helligkeitssensor des Roboters soll sich immer genau über der Kante der schwarzen Linie befinden: Lass dazu den Roboter nach links bzw. rechts abbiegen, wenn der Grauwert zu klein bzw. zu gross ist.
Im bisher erstellten Programm: Lösche die letzten acht Zeilen mit den drive-Befehlen (oder kommentiere sie aus).
Dann übersetze den folgenden Pseudo-Code nach Python und schreibe dies ans Ende deines Programms.
############### # AUFGABE 3 # ############### Vereinbare ein Variable namens "geschwindigkeit" und setze sie auf 50. Wiederhole unendich oft: Berechne die Abweichung der aktuellen "Reflektionsdaten" vom Idealwert (dieser ist in einer Variblen gespeichert). Wenn die Abweichung < 0 ist: ändere den Zustand des Roboters auf "Linkskurve-Fahren" sonst, wenn die Abweichung > 0 ist: ändere den Zustand des Roboters auf "Rechtskurve-Fahren" sonst: ändere den Zustand des Roboters auf "Geradeaus-Fahren"
Statt zwischen $<0$ und $>0$ und $=0$ zu unterscheiden, ist es vielleicht besser, den Roboter nicht nur bei verschwindender Abweichung vorwärts fahren zu lassen, sondern auch dann, wenn die Abweichung zwischen -3 und 3 liegt (dann zittert er vermutlich weniger). Du könntest dazu eine Variable “Schwellwert” verwenden.
Aufgabe 4: Proportionaler Line Follower
Im bisher erstellten Programm: Ersetze den Inhalt der while True-Schleife durch die folgenden Zeilen.
Die Idee ist, dass die Drehgeschwindigkeit proportional (= linear mit $y$-Achsenabschnitt 0) mit der Abweichung steigt, d. h. je grösser die Abweichung, desto grösser die Drehgeschwindigkeit.
############### # AUFGABE 4 # ############### abweichung = licht.reflection() - idealwert # Ersetze ''??'' durch Ausprobieren durch eine geeignete Zahl (zwischen 0 und 2)! fahrwerk.drive(geschwindigkeit, ?? * abweichung)
Aufgabe 5: PID Line Follower
Modifiziere das bisher erstellten Programm wie folgt; Ziel ist danach, die drei Konstanten gut zu wählen.
Idee dahinter: Die Abbiegedrehgeschwindigkeit soll nicht nur proportional zur Abweichung sein, sondern auch die Summe aller bisherigen Abweichungen berücksichtigen und auch die aktuelle Änderung. Dies nennt sich PID-Steuerung (wegen P=proportional, I=Integral (in etwa die Summe) und D=Differential).
Füge vor der while True-Schleife die folgende Definition von Konstanten ein:
############### # AUFGABE 5 # ############### # Finde durch Ausprobieren (= Testfahrten) gute Werte für die gleich folgenden Konstanten! # Dabei am besten erst die letzten beiden Konstanten auf Null setzen und den ersten Wert ''proportional_faktor''gut wählen. # Dann den zweiten Wert gut wählen. # Dann den dritten. proportional_faktor = ?? # zwischen 0 und 2 integral_faktor = ?? # kleiner als 0.1 differential_faktor = ?? # zwischen 0 und 4 letzte_abweichung = 0 integral = 0 zaehler = 0
Ersetze den Inhalt der while True-Schleife durch die folgenden Zeilen und finde dann gute Werte für die obigen Konstanten.
abweichung = licht.reflection() - idealwert zaehler = zaehler + 1 proportional_fix = proportional_faktor * abweichung integral = integral + abweichung integral_fix = integral_faktor * integral veraenderung = abweichung - letzte_abweichung differential_fix = differential_faktor * veraenderung letzte_abweichung = abweichung if zaehler % 250 == 0: print(10 * '-' + str(zaehler) + 10 * '-') print('proportional_fix=' + str(proportional_fix)) print('integral_fix=' + str(integral_fix)) print('differential_fix=' + str(differential_fix)) fahrwerk.drive(geschwindigkeit, proportional_fix + integral_fix + differential_fix) wait(5)
In diesem Abschnitt ging es um Regelungstechnik, siehe etwa
Für nächstes Mal: Aktuelle Werte von abweichung, integral, veraenderung graphisch ausgeben!
</hidden>