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.

🤖 Reaktive Programmierung:
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:

💡 Sensor-Layout:
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:

2. Hauptschleife

Die while True-Schleife läuft kontinuierlich und führt folgende Schritte aus:

  1. Sensoren auslesen mit get_distance()
  2. Entfernungen prüfen gegen den Schwellenwert
  3. Reaktion ausführen – entweder drehen oder geradeaus fahren
  4. 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:

  1. Zuerst der mittlere Sensor (wichtigste Position)
  2. Dann die Mitte-Links/Rechts-Sensoren
  3. Zuletzt die äußeren Sensoren
Warum diese Reihenfolge?
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:

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:

💡 Formel:
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

3. Update-Frequenz

Die sleep_ms(100)-Pause beeinflusst die Reaktionszeit:

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

Zusammenfassung

Kollisionsvermeidung ist ein grundlegendes Konzept in der autonomen Robotik:

  1. Sensoren kontinuierlich auslesen für Echtzeit-Reaktion
  2. Schwellenwerte definieren für sichere Navigation
  3. Intelligente Entscheidungen treffen basierend auf Sensor-Daten
  4. Parameter anpassen für verschiedene Umgebungen
  5. Strategien kombinieren für robustes Verhalten
💡 Nächste Schritte:
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!

💡 Anforderungen:
  • 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:

0/4

Punkte verstanden