Tage der Naturwissenschaften, Johannes-Keppler-Gymnasium, 2025
Prof. Dr. Sebastian Zug
Technische Universität Bergakademie Freiberg
Die interaktive Ansicht dieses Kurses ist unter folgendem Link verfügbar. Der Quellcode der Materialien ist unter https://github.com/LiaPlayground/Alvik_Controler zu finden.
Wer bin ich und was macht man so an der TUBAF?
Wer sind Sie? Was erwarten Sie vom heutigen Tutorial?
Ziele des Kurses:
- Sie verstehen das Grundlegende Prinzip der Regelungstechnik
- Lernen die Vielfalt der Nutzungsmöglichkeiten von Python kennen.
Dazu werden wir uns gemeinsam in folgendes Problem einarbeiten:
Der Roboter folgt der Hand: Ein Arduino Alvik Roboter soll immer in einem festen Abstand (z.B. 20 cm) zu Ihrer Hand bleiben, wenn Sie diese vor den Roboter halten.
Aufgabe: Welchen Anwendungsfall sehen Sie darin? Wo könnte so etwas nützlich sein?
Die Programmierung kann in C++ (Arduino IDE) oder MicroPython erfolgen. Es gibt auch grafische programmierbare Umgebungen wie mBlock.
Unsere Aufgabe integriert alle Komponenten eines klassischen Regelkreises:
Sollwert ┌─────────────┐ ┌──────────────┐ ┌─────────────┐
─────>│ Fehler │─────>│ Regler │─────>│ Stellglied │
│ │ │ Software │ │ Motoren │
└─────────────┘ └──────────────┘ └──────┬──────┘
^ │
│ v
│ ┌─────────────┐
│ "$Regelkreis$" │ Strecke │
│ │ Roboter&Hand│
│ └──────┬──────┘
│ ┌──────────────┐ │
└──────────────│ Messglied │<────────────┘
│Distanz-Sensor│
└──────────────┘ .
{{0-1}}
Aufgabe: Nehmen wir an, wir wollen einen Regelkreis aufbauen, so dass ein autonomes Automobile immer in der Mitte der Straße bleibt. Wie würden wir das umsetzen?
{{1-2}}
Was brauchen wir für unser "Der Roboter folgt der Hand"-Projekt?
Komponente Beschreibung Aufgabe 1. Messglied ToF-Sensor misst aktuelle Distanz zur Hand Messung ins Programm einbauen 2. Sollwert / Fehler Gewünschter Abstand zur Hand (z.B. 20 cm) Definieren und Berechnung umsetzen 3. Stellglied Motoren, die den Roboter bewegen im Programm ansteuern 4. Regler Software, die den Fehler verarbeitet Entwerfen und implementieren Danach testen wir unsere Regelung und optimieren die Parameter mit der Strecke - also unserem Roboter auf dem Tisch.
{{0-1}}
ToF-Sensoren messen die Entfernung durch Laufzeitmessung von Lichtsignalen:
- Sensor sendet einen kurzen Lichtimpuls aus
- Licht wird vom Objekt reflektiert
- Sensor misst die Zeit bis zum Empfang
- Distanz = (Lichtgeschwindigkeit × Zeit) / 2
Vorteile:
- ✅ Präzise Messung (±3%)
- ✅ Funktioniert bei verschiedenen Materialien
- ✅ Messbereich: 5-200 cm
- ✅ Schnelle Messung (bis 50 Hz)
{{1-2}}
from arduino_alvik import ArduinoAlvik
import time
# Alvik initialisieren
alvik = ArduinoAlvik()
alvik.begin()
print("Bereit. Tippe 'OK' (check) auf das Touch-Panel, um die Messung zu starten...")
# --- Programmstart per OK-Touch ---
while not alvik.get_touch_ok():
time.sleep(0.05)
# --- Hauptloop ---
running = True
while running:
# --- Abbruch per CANCEL-Touch ---
if alvik.get_touch_cancel():
print("Messung manuell gestoppt (CANCEL).")
running = False
break
# Distanzwerte holen
distance = alvik.get_distance(unit='cm')
print(distance[0], distance[1], distance[2], distance[3], distance[4])
time.sleep(0.1)
# --- Aufräumen ---
alvik.stop()
print("Roboter gestoppt.")Aufgabe: Erklären Sie den Code, was passiert in der Hauptschleife?
Aufgabe: Was müssen wir abändern, damit wir überprüfen können, ob der mittlere Sensor (Index 2) einen Abstand von größer oder kleiner 10 cm misst?
Wir entwerfen gemeinsam einen Code!
Der Alvik-Roboter hat zwei Motoren, deren Geschwindigkeit wir separat steuern können.
Aufgabe: Welche Bewegungen erwarten Sie bei folgenden Funktionsaufrufen?
| Funktion | Beschreibung |
|---|---|
alvik.set_wheels_speed(10, 10) |
Vorwärtsbewegung mit mittlerer Geschwindigkeit |
alvik.set_wheels_speed(0, 0) |
|
alvik.set_wheels_speed(-10, -10) |
|
alvik.set_wheels_speed(10, -10) |
Wie sieht ein Programm für die Ansteuerung der Motoren dann konkret aus?
from arduino_alvik import ArduinoAlvik
import time
# Alvik initialisieren
alvik = ArduinoAlvik()
alvik.begin()
print("Bereit. Tippe 'OK' (check) auf das Touch-Panel, um den Motortest zu starten...")
# --- Programmstart per OK-Touch ---
while not alvik.get_touch_ok():
time.sleep(0.05)
# --- Motoren ansteuern ---
alvik.set_wheels_speed(10, 10)
# --- Hauptloop ---
running = True
while running:
# --- Abbruch per CANCEL-Touch ---
if alvik.get_touch_cancel():
print("Messung manuell gestoppt (CANCEL).")
running = False
break
time.sleep(0.1)
# --- Aufräumen ---
alvik.stop()
print("Roboter gestoppt.")Aufgabe: Die Geschwindigkeit soll langsam erhöht werden. Wie würden Sie das umsetzen?
Wir wollen, dass der Roboter immer einen konstanten Abstand zu Ihrer Hand hält:
- Hand kommt näher → Roboter fährt rückwärts
- Hand entfernt sich → Roboter fährt vorwärts
- Hand bleibt auf Zielabstand → Roboter steht still
Die einfachste Form der Regelung ist der P-Regler:
Dabei ist:
-
$u(t)$ = Stellgröße (Motorgeschwindigkeit) -
$K_p$ = Proportionalfaktor (Verstärkung) -
$e(t)$ = Regelfehler = Sollwert - Istwert
from arduino_alvik import ArduinoAlvik
import time
# Alvik initialisieren
alvik = ArduinoAlvik()
alvik.begin()
print("Bereit. Tippe 'OK' (check) auf das Touch-Panel, um die Messung zu starten...")
# --- Programmstart per OK-Touch ---
while not alvik.get_touch_ok():
time.sleep(0.05)
# --- Hauptloop ---
start = time.ticks_ms()
running = True
while running:
# --- Abbruch per CANCEL-Touch ---
if alvik.get_touch_cancel():
print("Messung manuell gestoppt (CANCEL).")
running = False
break
# Distanzwerte holen
distance = alvik.get_distance(unit='cm')
center_distance = distance[2]
# Regelfehler berechnen (10 cm Zielabstand)
error = (center_distance - 10)
# Stellgröße berechnen (P-Regler)
speed = 100 * error
# Zeitmessung für Datenaufzeichnung
elapsed = time.ticks_diff(time.ticks_ms(), start)
print(elapsed, center_distance, error, speed)
# Motoren ansteuern
alvik.set_wheels_speed(speed, speed)
time.sleep(0.05)
# --- Aufräumen ---
alvik.stop()
print("Roboter gestoppt.")Beobachtung: Wie verhält sich der Roboter? Sind Sie zufrieden mit der Regelung?
Der Parameter
| Verhalten | Vor-/Nachteile | |
|---|---|---|
| Klein (z.B. 10) | Langsame, sanfte Annäherung | ✅ Stabil, ❌ Langsam |
| Mittel (z.B. 30) | Moderate Reaktion | ✅ Guter Kompromiss |
| Groß (z.B. 100) | Schnelle, aggressive Reaktion | ✅ Schnell, ❌ Überschwingen |
Ursachen:
- Überschießen: Roboter reagiert zu stark → fährt über Ziel hinaus
- Gegenreaktion: Regler erkennt negativen Fehler → fährt in Gegenrichtung
- Oszillation: System schwingt um den Sollwert
Ein gut eingestellter Regler sollte:
- ✅ Keine Dauerschwingung zeigen
- ✅ Schnell den Sollwert erreichen
- ✅ Minimal überschwingen (< 10%)
- ✅ Stabil bei Störungen bleiben
Wie können wir diesen Wert sinnvoll festlegen? Wir brauchen eine systematische Methode
Unsere Daten sind zeilenweise gespeichert worden. Beim bloßen draufschauen, ist es schwer, das Verhalten des Reglers zu beurteilen.
time distance error speed
0 13.4 3.400001 340.0001
54 13.5 3.5 350.0
110 13.3 3.3 330.0
165 13.2 3.2 320.0
219 13.2 3.2 320.0
274 13.3 3.3 330.0
331 13.0 3.0 300.0
Diagramme helfen uns:
- 📈 Das Systemverhalten zu verstehen
- 🔍 Probleme zu erkennen
- ⚙️ Parameter optimal einzustellen
Sie können natürlich die Daten auch in Excel oder Google Sheets importieren und dort Diagramme erstellen. Aber ... Python ist hier viel mächtiger und flexibler!
Visualisierung ist ein wichtiger Anwendungsfall von Python. Bibliotheken dafür sind Pandas (Datenstrukturierung) und Matplotlib (Plots).
Pandas macht es uns sehr einfach csv-Dateien zu laden: Dazu brauchen wir nur wenige Zeilen Code.
Im Unterschied zum bisherigen Programmcode, der auf dem Arduino Alvik lief, wird dieser Code lokal ausgeführt. Damit das hier funktioniert haben wir eine browserbasierte Variante für Sie vorbereitet. Klicken Sie auf den Button unter dem Codefenster.
time distance error speed
0 13.4 3.400001 340.0001
54 13.5 3.5 350.0
110 13.3 3.3 330.0
165 13.2 3.2 320.0
219 13.2 3.2 320.0
274 13.3 3.3 330.0
331 13.0 3.0 300.0
386 12.8 2.8 280.0
442 12.2 2.2 220.0
498 11.6 1.6 160.0
554 11.2 1.2 120.0
609 10.6 0.6000004 60.00004
664 10.6 0.6000004 60.00004
719 9.5 -0.5 -50.0
775 8.8 -1.2 -120.0
828 8.5 -1.5 -150.0
884 7.7 -2.3 -230.0
940 7.8 -2.2 -220.0
import pandas as pd
df = pd.read_csv('data.csv', header = 0, sep=" ")
print(df)@LIA.eval(["data.csv", "main.py"], none, python3 main.py)
Schauen wir uns zunächst einen Schwingenden Regler (Kp = 100) an. Hinweis: Das Hindernis stand bei dieser Messung still!
import pandas as pd
import matplotlib.pyplot as plt
import pandas as pd
url = "https://raw.githubusercontent.com/LiaPlayground/Alvik_Controler/refs/heads/main/data/critical.csv"
df = pd.read_csv(url, header = 0, sep=" ")
plt.plot(df["time"], df["distance"])
plt.axhline(y=10, color='r', linestyle='--')
plt.savefig('foo.png')@LIA.eval(["main.py"], none, python3 main.py)
Was fehlt Ihnen am Diagramm?
import pandas as pd
import matplotlib.pyplot as plt
import pandas as pd
url = "https://raw.githubusercontent.com/LiaPlayground/Alvik_Controler/refs/heads/main/data/optimal.csv"
df = pd.read_csv(url, header = 0, sep=" ")
plt.plot(df["time"], df["distance"], label='Gemessene Distanz')
plt.axhline(y=10, color='r', linestyle='--', label='Sollwert (10 cm)')
plt.xlabel("Zeit (s)")
plt.ylabel("Distanz (cm)")
plt.legend()
plt.savefig('foo.png')@LIA.eval(["main.py"], none, python3 main.py)
Wie können wir die Geschwindigkeiten im Diagramm darstellen, um das Regelverhalten besser zu verstehen?
Dieser Kurs zeigt die Bandbreite von Python:
- 🔧 Hardware-Programmierung (MicroPython auf ESP32)
- 📊 Datenanalyse (Pandas, NumPy)
- 📈 Visualisierung (Matplotlib)
- 🤖 Robotik (Echtzeit-Regelung)
Wir kennen die grundlegenden Konzepte der Regelungstechnik:
- Messglied
- Sollwert und Regelfehler
- Stellglied
- Regler (P-Regler)
Vielen Dank für Ihr Interesse und viel Erfolg bei Ihren eigenen Projekten!
Frage 1: Was misst ein ToF-Sensor?
[( )] Temperatur [(X)] Distanz durch Laufzeitmessung [( )] Helligkeit [( )] Geschwindigkeit
Frage 2: Was passiert, wenn Kp zu groß gewählt wird?
[( )] Der Roboter wird langsamer [(X)] Das System beginnt zu schwingen [( )] Der Sensor funktioniert nicht mehr [( )] Nichts
Frage 3: Was ist der Regelfehler?
[( )] Die Motorgeschwindigkeit [(X)] Die Differenz zwischen Sollwert und Istwert [( )] Die Sensormessgenauigkeit [( )] Die Rechenzeit
Frage 4: Welche Python-Bibliothek nutzen wir zur Visualisierung?
[( )] NumPy [(X)] Matplotlib [( )] TensorFlow [( )] Flask
Frage 5: Was ist ein gutes Zeichen für einen stabilen Regler?
[(X)] Der Fehler konvergiert gegen Null ohne Dauerschwingung [( )] Der Roboter fährt sehr schnell [( )] Die Motoren sind immer an [( )] Der Sensor zeigt immer denselben Wert
Um das Regelverhalten besser zu verstehen, schauen wir uns sowohl die Distanz als auch die Stellgröße (Geschwindigkeit) an:
import pandas as pd
import matplotlib.pyplot as plt
url = "https://raw.githubusercontent.com/LiaPlayground/Alvik_Controler/refs/heads/main/data/optimal.csv"
df = pd.read_csv(url, header=0, sep=" ")
# Zwei Subplots untereinander
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8))
# Oberes Diagramm: Distanz
ax1.plot(df["time"], df["distance"], 'b-', linewidth=2, label='Gemessene Distanz')
ax1.axhline(y=10, color='r', linestyle='--', linewidth=2, label='Sollwert (10 cm)')
ax1.set_ylabel('Distanz [cm]', fontsize=12)
ax1.set_title('Distanzverlauf bei optimierter Regelung', fontsize=14, fontweight='bold')
ax1.legend()
ax1.grid(True, alpha=0.3)
# Unteres Diagramm: Geschwindigkeit
ax2.plot(df["time"], df["speed"], 'orange', linewidth=2, label='Motorgeschwindigkeit')
ax2.axhline(y=0, color='k', linestyle='-', linewidth=0.5)
ax2.fill_between(df["time"], df["speed"], alpha=0.3, color='orange')
ax2.set_xlabel('Zeit [ms]', fontsize=12)
ax2.set_ylabel('Geschwindigkeit', fontsize=12)
ax2.set_title('Stellgröße (Motorgeschwindigkeit)', fontsize=14, fontweight='bold')
ax2.legend()
ax2.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('foo.png')@LIA.eval(["main.py"], none, python3 main.py)
Beobachtung:
- Im oberen Diagramm sehen Sie, wie sich die Distanz dem Sollwert annähert
- Im unteren Diagramm erkennen Sie, wie die Motorgeschwindigkeit entsprechend angepasst wird
- Anfangs ist die Geschwindigkeit hoch (großer Fehler), dann nimmt sie ab, wenn der Sollwert erreicht wird





