lehrkraefte:snr:informatik:glf22:robotik:line-follower

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
lehrkraefte:snr:informatik:glf22:robotik:line-follower [2024/06/12 21:00] – [Aufgabe 2: Drivebase kennenlernen] Olaf Schnürerlehrkraefte:snr:informatik:glf22:robotik:line-follower [2025/01/23 10:27] (current) – [Aufgabe 2: Drivebase kennenlernen] Olaf Schnürer
Line 1: Line 1:
 +~~NOTOC~~
 +
 +====== Lichtsensor und Line Follower ======
 +
 +<WRAP center round info>
 +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. 
 +</WRAP>
 +
 +Der Roboter soll z. B. der äusseren schwarzen Linie auf der Plane folgen!
 +===== Aufgabe 1: Licht-Sensor kalibrieren =====
 +
 +<WRAP center round todo>
 +Erstelle per "Create a new project" ein neues Projekt (das geht mit dem Button "LEGO@ MINDSTORMS@ EV3 MicroPython" am linken Rand in Visual Studio Code) und gib ihm einen sinnvollen Namen, etwa "Line_follower"
 +
 +Kopiere ans Ende des Programms ''main.py'' den folgenden Code.
 +
 +Ersetze die Nullen wie in den Kommmentaren im Programm beschrieben.
 +
 +<code python>
 +# 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
 +</code>
 +</WRAP>
 +
 +===== Aufgabe 2: Drivebase kennenlernen =====
 +
 +<WRAP center round todo>
 +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.
 +
 +<code python>
 +###############
 +#  AUFGABE 2  #
 +###############
 +
 +fahrwerk = DriveBase(links, rechts, wheel_diameter=55.5, axle_track=125)
 +# Raddurchmesser und Achsenabstand/Spurbreite (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 Praxis 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? 
 +</code>
 +<!-- 
 +# (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()'').
 +</WRAP>
 +
 +===== Aufgabe 2b (neu) =====
 +
 +<WRAP center round todo 60%>
 +Lass den Roboter geradeaus fahren, bis er auf eine weisse Linie trifft. Dort soll er stoppen und irgendetwas sagen, dann Programmende.
 +</WRAP>
 +
 +
 +
 +===== Aufgabe 3: Einfacher Line Follower =====
 +
 +<WRAP center round todo>
 +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.
 +
 +<code python>
 +
 +###############
 +#  AUFGABE 3  #
 +###############
 +
 +Vereinbare ein Variable namens "geschwindigkeit" und setze sie auf 50.
 +
 +Wiederhole unendlich oft:
 +    Berechne die Abweichung der aktuellen "Reflektionsdaten" vom Idealwert (dieser ist in einer Variablen 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"
 +    warte ein bisschen, etwa 10  Millisekunden
 +</code>
 +
 +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.
 +
 +<hidden Lösungshilfen><code python>
 +
 +geschwindigkeit = 50
 +
 +while True:
 +    ...
 +    if ...: 
 +        ...
 +    elif ...: 
 +        ...
 +    else:
 +        ...
 +</code>
 +</hidden>
 +</WRAP>
 +
 +===== Aufgabe 4: Proportionaler Line Follower =====
 +
 +<WRAP center round todo>
 +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.
 +<code python>
 +
 +    ###############
 +    #  AUFGABE 4  #
 +    ###############
 +    abweichung = licht.reflection() - idealwert
 +    # Ersetze ''??'' durch Ausprobieren durch eine geeignete Zahl (zwischen 0 und 2)!
 +    fahrwerk.drive(geschwindigkeit, ?? * abweichung)
 +</code>
 +</WRAP>
 +
 +===== Aufgabe 5: PID Line Follower =====
 +
 +<WRAP center round todo>
 +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:
 +
 +<code python>
 +###############
 +#  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
 +</code>
 +
 +Ersetze den Inhalt der ''while True''-Schleife durch die folgenden Zeilen und finde dann gute Werte für die obigen Konstanten.
 +
 +<code python>
 +    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)
 +</code>
 +
 +<hidden Bei mir klappten die folgenden Werte (auf der äusseren Rennstrecke der Plane) gut:>
 +<code python>
 +proportional_faktor = 1
 +integral_faktor = 0.01
 +differential_faktor = 1
 +</code>
 +</hidden>
 +</WRAP>
 +
 +<WRAP center round info>
 +In diesem Abschnitt ging es um Regelungstechnik, siehe etwa 
 +  * https://de.wikipedia.org/wiki/Regler
 +  * https://en.wikipedia.org/wiki/PID_controller
 +
 +Für nächstes Mal: Aktuelle Werte von ''abweichung'', ''integral'', ''veraenderung'' graphisch ausgeben!
 +</WRAP>
 +
 +<hidden Mögliche Lösung><code python>
 +
 +###############
 +#  AUFGABE 3  #
 +###############
 +
 +geschwindigkeit = 50
 +
 +while True:
 +    abweichung = licht.reflection() - idealwert
 +    if abweichung < 0: 
 +        fahrwerk.drive(geschwindigkeit, -20)
 +    elif abweichung > 0: 
 +        fahrwerk.drive(geschwindigkeit, 20)
 +    else:
 +        fahrwerk.drive(geschwindigkeit, 0)
 +</code>
 +</hidden>
 +
 +