Kollisionsvermeidung – Reaktive Programmierung
Bei der Kollisionsvermeidung liest der Roboter kontinuierlich seine Abstandssensoren aus und reagiert sofort auf Hindernisse in seiner Umgebung. Wenn ein Hindernis zu nah kommt, unterbricht der Roboter seine Vorwärtsbewegung und ändert seine Richtung. Erst wenn der Weg wieder frei ist, setzt er seine Fahrt fort – so navigiert er autonom durch den Raum, ohne anzustoßen.
Der Roboter reagiert auf Umgebungsinformationen und passt sein Verhalten in Echtzeit an. Dies ist ein grundlegendes Konzept in der autonomen Navigation und Robotik.
Die Abstandssensoren verstehen
Der Arduino Alvik verfügt über 5 Infrarot-Abstandssensoren, die kontinuierlich die Entfernung zu Objekten messen:
- distance_l – Links außen
- distance_cl – Mitte-Links
- distance_c – Zentral/Mitte
- distance_cr – Mitte-Rechts
- distance_r – Rechts außen
Die Sensoren sind so angeordnet, dass der Roboter ein breites Sichtfeld hat. Der mittlere Sensor erkennt Hindernisse direkt voraus, während die seitlichen Sensoren auch schräge Annäherungen erfassen.
Grundlegendes Code-Beispiel
Hier ist ein einfacher Kollisionsvermeidungs-Algorithmus:
from arduino_alvik import ArduinoAlvik
from time import sleep_ms
alvik = ArduinoAlvik()
alvik.begin()
# Konfigurierbare Parameter
distance = 15 # Mindestabstand in cm
degrees = 45.00 # Drehwinkel bei Hindernis
speed = 10.00 # Fahrgeschwindigkeit in cm/s
while True:
# Alle 5 Abstandssensoren auslesen
distance_l, distance_cl, distance_c, distance_r, distance_cr = alvik.get_distance()
# Debug-Ausgabe: Mittlerer Sensor
print(distance_c)
# Reaktion auf Hindernisse
if distance_c < distance:
alvik.rotate(degrees, 'deg')
elif distance_cl < distance:
alvik.rotate(degrees, 'deg')
elif distance_cr < distance:
alvik.rotate(degrees, 'deg')
elif distance_l < distance:
alvik.rotate(degrees, 'deg')
elif distance_r < distance:
alvik.rotate(degrees, 'deg')
else:
# Kein Hindernis: Vorwärts fahren
alvik.move(speed)
sleep_ms(100) # Kurze Pause vor der nächsten Messung
Code-Analyse: Wie funktioniert das?
1. Initialisierung
Der Code beginnt mit der Initialisierung des Roboters und der Definition von drei wichtigen Parametern:
distance = 15– Sicherheitsabstand (15 cm)degrees = 45.00– Drehwinkel beim Ausweichenspeed = 10.00– Fahrgeschwindigkeit
2. Hauptschleife
Die while True-Schleife läuft kontinuierlich und führt folgende Schritte aus:
- Sensoren auslesen mit
get_distance() - Entfernungen prüfen gegen den Schwellenwert
- Reaktion ausführen – entweder drehen oder geradeaus fahren
- Kurze Pause von 100ms vor der nächsten Messung
3. Prioritätenlogik
Die if-elif-else-Kette prüft die Sensoren in einer bestimmten Reihenfolge:
- Zuerst der mittlere Sensor (wichtigste Position)
- Dann die Mitte-Links/Rechts-Sensoren
- Zuletzt die äußeren Sensoren
Der mittlere Sensor hat Priorität, weil er Hindernisse direkt in Fahrtrichtung erkennt. Eine Kollision dort wäre am wahrscheinlichsten.
Verbesserter Algorithmus mit intelligenter Richtungswahl
Der Basis-Algorithmus dreht sich immer in dieselbe Richtung. Ein intelligenterer Ansatz wäre, die Drehrichtung basierend auf der Sensor-Position zu wählen:
from arduino_alvik import ArduinoAlvik
from time import sleep_ms
alvik = ArduinoAlvik()
alvik.begin()
distance = 15
speed = 10.00
while True:
# Sensoren auslesen
distance_l, distance_cl, distance_c, distance_r, distance_cr = alvik.get_distance()
# Hindernis erkannt?
if distance_c < distance:
# Zentral: Drehe nach rechts
print("Hindernis zentral - drehe rechts")
alvik.rotate(45, 'deg')
elif distance_cl < distance or distance_l < distance:
# Links: Drehe nach rechts
print("Hindernis links - drehe rechts")
alvik.rotate(45, 'deg')
elif distance_cr < distance or distance_r < distance:
# Rechts: Drehe nach links
print("Hindernis rechts - drehe links")
alvik.rotate(-45, 'deg') # Negativ = nach links
else:
# Weg frei: Vorwärts
alvik.move(speed)
sleep_ms(100)
Vorteile dieser Variante:
- ✅ Intelligentere Navigation: Dreht weg vom Hindernis
- ✅ Effizientere Wegfindung: Weniger unnötige Drehungen
- ✅ Bessere Debug-Ausgaben: Du siehst, welcher Sensor reagiert
- ✅ Einfachere Sensorgruppierung: Linke und rechte Sensoren zusammengefasst
Erweiterte Version: Adaptive Geschwindigkeit
Diese Version passt die Geschwindigkeit basierend auf der Entfernung zum nächsten Hindernis an:
from arduino_alvik import ArduinoAlvik
from time import sleep_ms
alvik = ArduinoAlvik()
alvik.begin()
min_distance = 10 # Kritische Entfernung
safe_distance = 25 # Sichere Entfernung
max_speed = 15.00 # Maximale Geschwindigkeit
min_speed = 5.00 # Minimale Geschwindigkeit
while True:
# Sensoren auslesen
distance_l, distance_cl, distance_c, distance_r, distance_cr = alvik.get_distance()
# Kleinste Entfernung finden
min_dist = min(distance_l, distance_cl, distance_c, distance_r, distance_cr)
# Kritisch nah: Drehen
if min_dist < min_distance:
print(f"Kritisch! Entfernung: {min_dist} cm")
# Intelligente Drehrichtung
if distance_l < min_distance or distance_cl < min_distance:
alvik.rotate(45, 'deg')
else:
alvik.rotate(-45, 'deg')
# Innerhalb sicherer Entfernung: Geschwindigkeit anpassen
elif min_dist < safe_distance:
# Je näher, desto langsamer
speed_factor = (min_dist - min_distance) / (safe_distance - min_distance)
current_speed = min_speed + (max_speed - min_speed) * speed_factor
print(f"Angepasste Geschwindigkeit: {current_speed:.2f} cm/s")
alvik.move(current_speed)
# Weg frei: Volle Geschwindigkeit
else:
print("Freie Fahrt!")
alvik.move(max_speed)
sleep_ms(100)
Funktionsweise der adaptiven Geschwindigkeit:
Die Geschwindigkeitsberechnung verwendet eine lineare Interpolation:
- Bei 10 cm (min_distance): Geschwindigkeit = 5 cm/s (min_speed)
- Bei 25 cm (safe_distance): Geschwindigkeit = 15 cm/s (max_speed)
- Dazwischen: Proportional zur Entfernung
speed_factor = (aktuell - minimum) / (sicher - minimum)geschwindigkeit = min_speed + (max_speed - min_speed) × speed_factor
Praxis-Beispiel: Labyrinth-Navigation
Für komplexere Umgebungen wie Labyrinthe kannst du eine "Wandfolge-Strategie" implementieren:
from arduino_alvik import ArduinoAlvik
from time import sleep_ms
alvik = ArduinoAlvik()
alvik.begin()
wall_distance = 12 # Idealer Abstand zur Wand
speed = 10.00
while True:
distance_l, distance_cl, distance_c, distance_r, distance_cr = alvik.get_distance()
# Hindernis direkt voraus?
if distance_c < 15:
print("Wand voraus - drehe rechts")
alvik.rotate(90, 'deg')
continue
# Folge der rechten Wand
if distance_r < wall_distance - 2:
# Zu nah an rechter Wand: Leicht nach links lenken
print("Zu nah an rechter Wand")
alvik.move(speed, 10.0)
elif distance_r > wall_distance + 2:
# Zu weit von rechter Wand: Leicht nach rechts lenken
print("Zu weit von rechter Wand")
alvik.move(speed, -10.0)
else:
# Perfekter Abstand: Geradeaus
alvik.move(speed)
sleep_ms(100)
Vergleich der Strategien
| Strategie | Vorteile | Anwendung |
|---|---|---|
| Basis-Vermeidung | Einfach, zuverlässig | Offene Räume, Hindernisparcours |
| Intelligente Richtungswahl | Effizientere Navigation | Räume mit mehreren Hindernissen |
| Adaptive Geschwindigkeit | Sanftere Bewegung, sicherer | Enge Räume, präzise Navigation |
| Wandfolge | Systematische Erkundung | Labyrinthe, strukturierte Umgebungen |
Optimierungstipps
1. Sensor-Kalibrierung
Teste die Sensor-Reichweite auf verschiedenen Oberflächen:
# Sensor-Test-Programm
from arduino_alvik import ArduinoAlvik
from time import sleep_ms
alvik = ArduinoAlvik()
alvik.begin()
while True:
d_l, d_cl, d_c, d_cr, d_r = alvik.get_distance()
print(f"L:{d_l:5.1f} | CL:{d_cl:5.1f} | C:{d_c:5.1f} | CR:{d_cr:5.1f} | R:{d_r:5.1f}")
sleep_ms(200)
2. Drehwinkel anpassen
- Kleine Winkel (15-30°): Für sanfte Kurskorrekturen
- Mittlere Winkel (45-60°): Standard-Ausweichen
- Große Winkel (90-180°): Für enge Räume oder Sackgassen
3. Update-Frequenz
Die sleep_ms(100)-Pause beeinflusst die Reaktionszeit:
- 50-100 ms: Schnelle Reaktion, höherer Stromverbrauch
- 100-200 ms: Guter Kompromiss (empfohlen)
- 200+ ms: Langsamere Reaktion, Gefahr von Kollisionen bei hoher Geschwindigkeit
Häufige Probleme und Lösungen
Problem: Roboter fährt im Kreis
Ursache: Alle Drehungen gehen in dieselbe Richtung
Lösung: Verwende die intelligente Richtungswahl (siehe oben)
Problem: Roboter bleibt stehen
Ursache: Sensoren erkennen "Geister-Hindernisse"
Lösung: Erhöhe den Schwellenwert oder füge eine Sensor-Validierung hinzu:
# Nur reagieren, wenn mehrere Messungen Hindernis zeigen
obstacle_counter = 0
if distance_c < 15:
obstacle_counter += 1
if obstacle_counter > 2: # Erst nach 3 Messungen reagieren
alvik.rotate(45, 'deg')
obstacle_counter = 0
else:
obstacle_counter = 0
Problem: Roboter kollidiert trotzdem
Ursache: Geschwindigkeit zu hoch für die Reaktionszeit
Lösung: Reduziere speed oder sleep_ms()
Erweiterungsideen
- 🎯 Zielverfolgung: Kombiniere Kollisionsvermeidung mit GPS/Kompass-Navigation
- 🗺️ Kartierung: Speichere erkannte Hindernisse in einer Karte
- 🔊 Akustische Signale: Töne bei Hindernissen (wie Einparkhilfe)
- 💡 LED-Feedback: Verschiedene Farben für verschiedene Sensor-Zustände
- 📊 Datenaufzeichnung: Logge Sensordaten für spätere Analyse
- 🤖 Schwarmverhalten: Mehrere Alviks koordiniert navigieren lassen
Zusammenfassung
Kollisionsvermeidung ist ein grundlegendes Konzept in der autonomen Robotik:
- Sensoren kontinuierlich auslesen für Echtzeit-Reaktion
- Schwellenwerte definieren für sichere Navigation
- Intelligente Entscheidungen treffen basierend auf Sensor-Daten
- Parameter anpassen für verschiedene Umgebungen
- Strategien kombinieren für robustes Verhalten
Experimentiere mit verschiedenen Parametern und Strategien. Baue einen Hindernisparcours und teste, welche Variante am besten funktioniert. Versuche, eine Kombination aus mehreren Strategien zu implementieren!
Challenge: Intelligente Kollisionsvermeidung
Programmiere einen autonomen Navigator!
🧠 Wissens-Check
1. Wie viele Abstandssensoren hat der Alvik?
2. Was macht der Roboter, wenn distance_c < 15 ist?
3. Warum ist sleep_ms(100) am Ende der Schleife wichtig?
💻 Programmier-Challenge
📝 Intelligente Richtungswahl
Programmiere den Alvik so, dass er bei Hindernissen intelligent entscheidet: Links- oder Rechtssensor erkennt Hindernis → drehe in die Gegenrichtung!
- Linkes Hindernis → drehe rechts (positive Grad)
- Rechtes Hindernis → drehe links (negative Grad)
- Mittleres Hindernis → drehe nach rechts
- LEDs zeigen Richtung an (rot links, grün rechts)
✅ Selbsttest: Das kann ich jetzt!
Hake ab, was du verstanden hast:
Punkte verstanden