TASIOMIND.DEV — OPERATIONAL▸▸▸FULL STACK DEVELOPER @ GWQ SERVICEPLUS AG▸▸▸FOUNDER — K8SGPT.AI▸▸▸OPEN SOURCE: ACTIVE▸▸▸DISTRIBUTED SYSTEMS / KUBERNETES / AI▸▸▸RUST + GO + PYTHON▸▸▸FIELD TESTED / STATUS — NOMINAL▸▸▸LOCATION: EUROPE/BERLIN▸▸▸TASIOMIND.DEV — OPERATIONAL▸▸▸FULL STACK DEVELOPER @ GWQ SERVICEPLUS AG▸▸▸FOUNDER — K8SGPT.AI▸▸▸OPEN SOURCE: ACTIVE▸▸▸DISTRIBUTED SYSTEMS / KUBERNETES / AI▸▸▸RUST + GO + PYTHON▸▸▸FIELD TESTED / STATUS — NOMINAL▸▸▸LOCATION: EUROPE/BERLIN▸▸▸
MicromouseMaze SolvingPD-RegelungC++Mikrocontroller

Micromouse – Autonomer Labyrinth-Roboter

Entwicklung eines autonomen Roboters zur Labyrinth-Navigation, basierend auf Sensorsteuerung, PD-Regelung und Maze-Solving-Algorithmen in C++.

Aland Baban · April 2023 · 5 min read
[ click to zoom ]
01 / 05

Micromouse ist ein Robotik-Wettbewerb, bei dem kleine autonome Roboter ein 16×16-Zellen-Labyrinth durchqueren müssen. Ziel ist es, den schnellsten Weg vom Startpunkt zum Zentrum des Labyrinths zu finden. Dieses Projekt umfasst den gesamten Entwicklungsprozess von der Hardware-nahen Programmierung bis zur Implementierung von Navigationsalgorithmen.

Systemanforderungen

Ein erfolgreicher Micromouse-Roboter muss mehrere Kernfähigkeiten beherrschen:

  • Umgebungserfassung: Erkennung von Wänden mittels Infrarot-Sensoren zur Orientierung.
  • Odometrie: Präzise Positionsbestimmung innerhalb des Labyrinths ohne externe Hilfsmittel wie GPS.
  • Kartenerstellung (Mapping): Aufbau einer internen Repräsentation des Labyrinths während der Erkundungsphase.
  • Pfadfindung: Berechnung des optimalen Pfades zum Ziel basierend auf der erstellten Karte.
  • Motorregelung: Effiziente und präzise Steuerung der Antriebsmotoren für schnelle und stabile Bewegungen.

Software-Implementierung

Die gesamte Software wurde in C++ für einen Mikrocontroller entwickelt. Die Implementierung umfasste die Ansteuerung der Hardwarekomponenten sowie die Realisierung der übergeordneten Steuerungslogik.

Sensoranbindung und ADC-Konfiguration

Die Infrarot-Sensoren zur Wand- und Abstandserkennung wurden über einen Analog-Digital-Wandler (ADC) ausgelesen. Die Initialisierung und der Lesevorgang wurden wie folgt implementiert:

code
void adc_init() {
    // ADC initialisieren: Referenzspannung setzen, ADC aktivieren, Prescaler konfigurieren
    ADMUX  = (1 << REFS0);
    ADCSRA = (1 << ADEN) | (1 << ADPS1) | (1 << ADPS0);
}

uint16_t read_adc(uint8_t channel) {
    // Kanal auswählen, Konvertierung starten und auf Abschluss warten
    ADMUX = (ADMUX & 0xF0) | (channel & 0x0F);
    ADCSRA |= (1 << ADSC);
    while (ADCSRA & (1 << ADSC));
    return ADC;
}

Motorsteuerung mittels PWM

Die beiden DC-Motoren wurden über Pulsweitenmodulation (PWM) angesteuert, um eine präzise Geschwindigkeitskontrolle zu ermöglichen.

code
void pwm_init() {
    // PWM-Pins als Ausgänge definieren und Timer für Fast-PWM-Modus konfigurieren
    DDRD |= (1 << PD6) | (1 << PD5);
    TCCR0A = (1 << COM0A1) | (1 << COM0B1) | (1 << WGM01) | (1 << WGM00);
    TCCR0B = (1 << CS01);
}

void set_motor_speed(uint8_t left, uint8_t right) {
    // Geschwindigkeiten für den linken und rechten Motor setzen
    OCR0A = left;
    OCR0B = right;
}

PD-Regelung zur Spurhaltung

Um eine stabile Geradeausfahrt zu gewährleisten und Abweichungen durch ungleiche Motorleistung oder Untergrundbeschaffenheit zu korrigieren, wurde ein Proportional-Differential (PD)-Regler implementiert. Der Regler minimiert den Fehler zwischen den linken und rechten Wandsensoren.

code
int16_t pd_controller(int16_t error) {
    static int16_t prev_error = 0;
    const int16_t Kp = 8; // Proportionalanteil
    const int16_t Kd = 4; // Differentialanteil

    int16_t derivative = error - prev_error;
    prev_error = error;

    return (Kp * error) + (Kd * derivative);
}

Labyrinth-Lösungsalgorithmus: Right-Wall-Follower

Als initiale Navigationsstrategie wurde ein einfacher, aber effektiver "Right-Wall-Follower"-Algorithmus verwendet. Der Roboter hält konstant einen bestimmten Abstand zur rechten Wand und folgt so dem Labyrinthverlauf.

code
void follow_right_wall() {
    uint16_t front_sensor = read_adc(0);
    uint16_t right_sensor = read_adc(1);

    if (right_sensor > 200) { // Wand rechts erkannt
        if (front_sensor > 200) { // Wand vorne erkannt
            turn_left();
        } else {
            drive_forward();
        }
    } else { // Keine Wand rechts
        turn_right();
    }
}

Bewegungsprimitiven

Grundlegende Bewegungsfunktionen wie Geradeausfahrt und Drehungen wurden implementiert. Für präzisere Manöver wären Encoder zur Distanzmessung und ein Gyroskop zur Rotationskontrolle erforderlich.

code
void drive_forward() {
    set_motor_speed(200, 200);
}

void turn_left() {
    set_motor_speed(100, 200);
    _delay_ms(300); // Zeitbasierte Drehung
}

void turn_right() {
    set_motor_speed(200, 100);
    _delay_ms(300); // Zeitbasierte Drehung
}

Hauptschleife (Main Loop)

Die Hauptschleife des Programms orchestriert die kontinuierliche Ausführung der Navigationslogik.

code
int main(void) {
    adc_init();
    pwm_init();

    while (1) {
        follow_right_wall();
    }
}

Ergebnis und Wettbewerbserfolg

Trotz der einfachen Navigationsstrategie erwies sich der Roboter als sehr robust und schnell. Im Rahmen eines Hochschulwettbewerbs konnte er sich gegen Konkurrenzmodelle durchsetzen und erreichte die schnellste Zeit, ohne Kollisionen oder Navigationsfehler.

Zukünftige Erweiterungen

Für eine weitere Optimierung sind folgende Verbesserungen geplant:

  • Flood-Fill-Algorithmus: Für eine intelligentere Kartenerstellung und die Berechnung des absolut kürzesten Pfades.
  • Gyroskop-Integration: Zur präzisen Steuerung von Drehungen.
  • Rad-Encoder: Für eine exakte Distanzmessung anstelle von zeitbasierten Verzögerungen.
  • OLED-Display: Zur Anzeige von Debugging-Informationen und Systemstatus.
  • Drahtlose Kommunikation: Bluetooth oder UART für Echtzeit-Logging und -Analyse.

Fazit

Das Micromouse-Projekt ist eine herausfordernde, aber äußerst lehrreiche Disziplin der Robotik. Es erfordert ein tiefes Verständnis für Embedded-Systeme, Regelungstechnik und Algorithmen. Die erfolgreiche Entwicklung und der Wettbewerbserfolg demonstrieren die Effektivität eines methodischen Ansatzes bei der Lösung komplexer mechatronischer Probleme.