# Handover Mobile Base Station Dieses Repository ist eine vollständige Kopie eines fertigen Uni-Projekts zur Demonstration eines WLAN-Handover-Szenarios mit: - einem mobilen Fahrzeug/Roboter (AlphaBot2 + Raspberry Pi + ESP32), - mehreren ESP32-basierten Basisstationen, - einem Webinterface zur Live-Visualisierung von Verbindungsdaten und Kamerabildern. Das Projekt kombiniert Robotik, Embedded-Firmware, serielle Kommunikation, UDP-Weiterleitung und ein Web-Dashboard. ## Projektziel Ziel ist es, ein mobiles System zu bauen, das sich zwischen zwei WLAN-Basisstationen bewegt und dabei: - kontinuierlich Verbindungsdaten (RSSI, verbundene Basisstation, alternative Basisstation) überträgt, - bei besserem Signal automatisch einen Handover ausführt, - Kamerabilder vom Fahrzeug streamt, - alle Daten in einem Webinterface visualisiert. ## Repository-Struktur ```text HandoverMobileBaseStation/ ├── doc_vault/ # Hardware-Doku, Datenblätter, Pinout-Grafiken ├── esp_firmware/ # Arduino-ESP32-Firmware (MBS1, MBS2, Fahrzeug) │ ├── MBS1_stripped/ │ ├── MBS2_stripped/ │ └── car_stripped/ ├── robot/ # Raspberry Pi / AlphaBot2 Python-Skripte │ ├── AlphaBot2.py │ ├── TRSensors.py │ ├── line_follow.py │ ├── pid_line_follow1.py │ ├── IRremote.py │ ├── cam_stream.py │ └── ReadMe.md # Teil-Doku zum Robotik-Teil └── webinterface/ └── cotmw/ # Vue 3 + Vite Frontend + Node Serial-Bridge ├── src/ └── serial/ ``` ## Gesamtarchitektur (vereinfacht) ```text [Raspberry Pi am Roboter] ├─ Kamera -> cam_stream.py -> JSON (image) über USB-Serial (115200) └─ AlphaBot2 / IR / Line-Follow (lokal auf Pi) | v [ESP32 im Fahrzeug: car_stripped] - sendet Telemetrie + Kamera-JSON per UDP (Port 6666) - wechselt zwischen AP1/AP2 je nach RSSI | +---------+---------+ | | v v [MBS1 / AP1] [MBS2 / AP2] | | | (direkt) | (über MBS2_1 -> UART -> MBS2_2 -> AP1) +---------+---------+ | v [ESP32 MBS1 per USB an PC] | v [Node Serial Backend :6666] | v [Vue Webinterface (Vite)] ``` Hinweis zu `MBS2`: Im Code ist die zweite Basisstation in zwei Rollen aufgeteilt (`MBS2_1` und `MBS2_2`). Dafür werden in der vollständigen Kette typischerweise zwei ESP32 mit derselben Sketch-Datei (aber unterschiedlichen `#define`-Modi) verwendet. ## Komponenten im Detail ### 1) `esp_firmware/` (ESP32 / Arduino) ### `MBS1_stripped` (AP1 + UDP -> USB-Serial Bridge) Datei: `esp_firmware/MBS1_stripped/MBS1_stripped.ino` Funktion: - startet einen Access Point `ESP32-AP1`, - hört auf UDP Port `6666`, - schreibt empfangene UDP-Pakete auf `Serial` (USB, 115200 Baud), - dient als zentrale Einspeisung ins Webinterface (über den PC-USB-Port). Wichtige Parameter (im Code): - SSID: `ESP32-AP1` - Passwort: `PASS0000` - AP-IP: `192.168.178.1` - UDP-Port: `6666` - Baudrate: `115200` ### `MBS2_stripped` (zweite Basisstation / Relay, zwei Modi) Datei: `esp_firmware/MBS2_stripped/MBS2_stripped.ino` Die Sketch enthält zwei Rollen, die über `#define` ausgewählt werden: - `MBS2_1`: hostet `ESP32-AP2` (Access Point) - `MBS2_2`: verbindet sich als Client mit `ESP32-AP1` und tunnelt Daten weiter #### Modus `MBS2_1` (AP2) - startet Access Point `ESP32-AP2` - empfängt UDP-Pakete auf Port `6666` - schreibt empfangene Daten auf `Serial` und `Serial2` - kann damit Daten an eine zweite ESP32-Instanz weitergeben #### Modus `MBS2_2` (Relay zu AP1) - verbindet sich mit `ESP32-AP1` - liest Daten von `Serial2` - sendet diese Daten per UDP an AP1 (`192.168.178.1:6666`) #### UART-Verbindung in `MBS2_stripped` `Serial2` ist auf folgende Pins gelegt: - RX: GPIO `18` - TX: GPIO `17` Siehe auch `doc_vault/esp32s3_pico_uart1_rx_tx.png`. ### `car_stripped` (Fahrzeug-ESP / Handover-Client) Datei: `esp_firmware/car_stripped/car_stripped.ino` Funktion: - scannt verfügbare Netze (`ESP32-AP1`, `ESP32-AP2`) - verbindet sich initial mit der stärkeren Basisstation - sendet Statusdaten regelmäßig per UDP an das Gateway (`UDP_PORT 6666`) - nimmt Kameradaten/JSON von `Serial` entgegen und leitet sie per UDP weiter - führt automatischen Netzwechsel aus, wenn das andere Netz deutlich stärker ist Handover-Logik (aus Code): - Wechsel, wenn `otherRSSI` mindestens ca. `3 dBm` besser ist als aktuelles RSSI. Gesendete Statusdaten (JSON, newline-terminiert): ```json {"type":"text","IP":"192.168.178.x","Base Station":"ESP32-AP1","RSSI":"-56","Other Network":"ESP32-AP2","Other RSSI":"-68"} ``` Kameradaten (vom Raspberry Pi kommend) werden als JSON-Pakete weitergeleitet: ```json {"type":"image","data":""} ``` ### 2) `robot/` (Raspberry Pi + AlphaBot2) Dieser Teil läuft auf dem Raspberry Pi auf dem Fahrzeug/Roboter. ### `cam_stream.py` (Kamera -> ESP über Serial) Datei: `robot/cam_stream.py` Funktion: - liest Frames von einer Pi-Kamera (`Picamera2`), - konvertiert zu Graustufen, - komprimiert/verkürzt JPEGs so, dass Base64-Daten klein bleiben (im Code `MAX_B64 = 1200`), - sendet die Daten als JSON (`type=image`) über Serial an den Fahrzeug-ESP, - versucht bei Serial-Abbruch automatisch die Verbindung neu aufzubauen. Wichtige Details: - serielle Schnittstelle ist aktuell hartkodiert auf `/dev/ttyACM1` - Baudrate: `115200` - Ausgabeformat ist newline-terminiertes JSON (wichtig für den Parser im Backend) ### `line_follow.py` (regelbasierter Linienfolger) Datei: `robot/line_follow.py` Funktion: - automatische Sensor-Kalibrierung (`TRSensor`) - Erkennung schwarzer/weißer Linie - einfache Korrekturlogik für Spurhaltung - zusätzliche Erkennung stärkerer Kurven (90°-ähnliche Abbiegungen) ### `pid_line_follow1.py` (PID-Linienfolger) Datei: `robot/pid_line_follow1.py` Funktion: - PID-Regelung für glatteres Folgen der Linie - Suchroutine bei Linienverlust - konfigurierbare Parameter (`Kp`, `Ki`, `Kd`, Geschwindigkeit, Timeouts) ### `IRremote.py` (Fernsteuerung + Start/Stopp von PID-Line-Follow) Datei: `robot/IRremote.py` Funktion: - liest IR-Signale über GPIO - steuert den AlphaBot2 manuell (vor/zurück/links/rechts/stop) - passt PWM-Geschwindigkeit an - startet `pid_line_follow1.py` als separaten Prozess per Tastendruck - stoppt den PID-Line-Follow-Prozess erneut per Tastendruck Hinweis: - Die konkreten Tasten-Codes sind auf die verwendete Fernbedienung abgestimmt (NEC-artige IR-Codes im Skript). ### `AlphaBot2.py` und `TRSensors.py` Dateien: - `robot/AlphaBot2.py` - `robot/TRSensors.py` Funktion: - Hardware-Abstraktion für Motoransteuerung (PWM, Fahrtrichtung) - Ansteuerung und Kalibrierung des 5-Kanal-TR-Linienfolgesensors ### Vorhandene Teil-Doku Datei: `robot/ReadMe.md` Enthält zusätzliche Projektnotizen zu: - Kamera-Streaming - Line Follow (Entwicklungsideen) - Fernbedienungssteuerung - systemd/Daemon-Setup auf dem Raspberry Pi ### 3) `webinterface/cotmw/` (Vue 3 + Vite + Serial Backend) Das Webinterface besteht aus zwei Teilen: - einem Vue-Frontend (`webinterface/cotmw`) - einem Node/Express-Backend für den Zugriff auf lokale Serial-Ports (`webinterface/cotmw/serial`) ### Frontend (Vue 3 + Vite) Wichtige Dateien: - `webinterface/cotmw/src/App.vue` - `webinterface/cotmw/src/components/*` - `webinterface/cotmw/vite.config.js` Funktionen im UI: - HUD mit Live-Werten: - IP - aktuelle Basisstation - RSSI - alternative Basisstation + RSSI - Polling-Zähler - Kamera-Widget (drag & drop) - RSSI-Plot (aktuelle vs. alternative Basisstation) - Topologie/Locations-Visualisierung (inkl. Handover-Animation) - optionale Weiterleitung der Daten an externes System (`External.vue`) #### Verstecktes Serial-Menü Der Serial-Connector ist absichtlich versteckt und wird per Tastenkombination eingeblendet: - `Ctrl + B` (Windows/Linux) - `Cmd + B` (macOS) Danach kann im UI: - ein lokaler Serial-Port ausgewählt werden - die Verbindung mit `115200` Baud aufgebaut werden - der eingehende Datenstrom eingesehen werden Das Frontend pollt anschließend standardmäßig alle `200 ms` den Backend-Endpunkt `/api/serial-utils/latest`. ### Backend (Node + Express + serialport) Wichtige Dateien: - `webinterface/cotmw/serial/server.js` - `webinterface/cotmw/serial/serial.js` - `webinterface/cotmw/serial/routes/serialUtils.js` Funktion: - listet lokale Serial-Ports - verbindet sich mit ausgewähltem Port - liest eingehende Zeilen (newline-basiert) - speichert das zuletzt empfangene `text`-Paket und `image`-Paket - stellt diese Daten per HTTP-API fürs Frontend bereit API-Endpunkte (Port `6666`): - `GET /api/serial-utils/serialports` - `POST /api/serial-utils/connect` mit Body `{ "path": "/dev/tty..." }` - `GET /api/serial-utils/latest` #### Vite Proxy In `webinterface/cotmw/vite.config.js` ist im Dev-Server ein Proxy konfiguriert: - `/api` -> `http://localhost:6666` Dadurch kann das Frontend lokal ohne CORS-Probleme auf das Serial-Backend zugreifen. ## Hardware-Übersicht (praktisch) Je nach Aufbau werden typischerweise benötigt: - 1x AlphaBot2 (oder kompatibles Chassis mit Motorsteuerung) - 1x Raspberry Pi (z. B. Pi 4) auf dem Fahrzeug - 1x Pi-Kamera (Picamera2-kompatibel) - 1x TR-Linienfolgesensor (5-Kanal) - 1x IR-Empfänger + passende Fernbedienung - 1x ESP32 auf dem Fahrzeug (`car_stripped`) - 1x ESP32 für `MBS1_stripped` - 2x ESP32 für `MBS2_stripped` (einmal `MBS2_1`, einmal `MBS2_2`) bei vollem AP2-Relay-Aufbau - 1x PC/Laptop für Webinterface + Node-Backend ## Software-Voraussetzungen ### PC / Laptop (Webinterface + Serial Backend) - Node.js (empfohlen: aktuelle LTS-Version) - npm - Zugriff auf den USB-Serial-Port des MBS1-ESP32 (Linux: ggf. Gruppe `dialout`) ### Raspberry Pi (Robot / Kamera) - Raspberry Pi OS - Python 3 - `Picamera2` / `libcamera` - `RPi.GPIO` - `pyserial` - `Pillow` - optional/je nach Skript-Imports: `Flask`, `opencv-python` In `robot/cam_stream.py` sind bereits Beispiel-Schritte für die Kamera-Umgebung notiert (APT + venv). ### ESP32-Entwicklung - Arduino IDE mit ESP32-Boardpaket oder PlatformIO - passende Board-Konfiguration für die verwendeten ESP32-Module ## Setup und Inbetriebnahme ### A) ESP32-Firmware flashen 1. `MBS1_stripped.ino` auf den ESP für AP1 flashen. 1. `MBS2_stripped.ino` einmal mit `#define MBS2_1` auf den AP2-ESP flashen. 1. `MBS2_stripped.ino` einmal mit `#define MBS2_2` auf den Relay-ESP flashen. 1. `car_stripped.ino` auf den Fahrzeug-ESP flashen. Hinweise: - SSIDs/Passwort sind im Code hartkodiert (`ESP32-AP1`, `ESP32-AP2`, `PASS0000`). - UDP-Port ist durchgehend `6666`. - Baudrate ist durchgehend `115200`. ### B) Verkabelung / Verbindungen herstellen Mindestens notwendig: - Fahrzeug-ESP per USB/Serial mit Raspberry Pi verbinden (für Kamera-/JSON-Übergabe) - MBS1-ESP per USB/Serial mit PC/Laptop verbinden (für Webinterface-Datenquelle) Für den vollen AP2-Relay-Aufbau zusätzlich: - `MBS2_1` und `MBS2_2` per UART (`Serial2`) verbinden (Pins siehe Firmware / `doc_vault`) ### C) Serial-Backend starten (PC) ```bash cd webinterface/cotmw/serial npm install node server.js ``` Das Backend läuft anschließend auf `http://localhost:6666`. ### D) Frontend starten (PC) ```bash cd webinterface/cotmw npm install npm run dev ``` Danach im Browser die von Vite ausgegebene URL öffnen (typisch `http://localhost:5173`). ### E) Serial-Port im Webinterface verbinden 1. Webinterface öffnen. 1. `Ctrl + B` / `Cmd + B` drücken (Serial-Menü einblenden). 1. Den USB-Port des MBS1-ESP32 auswählen. 1. `Connect (Baud: 115200)` klicken. Wenn Daten ankommen, sollten Telemetrie und Kamerabild im Dashboard erscheinen. ### F) Robotik-/Kamera-Skripte auf dem Raspberry Pi starten Beispiele: ### Kamerastream zum Fahrzeug-ESP ```bash cd robot python3 cam_stream.py ``` ### IR-Fernsteuerung + PID-Line-Follow-Start/Stopp ```bash cd robot python3 IRremote.py ``` ### Direkter Start des PID-Line-Followers ```bash cd robot python3 pid_line_follow1.py ``` ### Direkter Start des regelbasierten Line-Followers ```bash cd robot python3 line_follow.py ``` ## Kommunikationsformate und Schnittstellen ### Serial (Pi -> Fahrzeug-ESP) Format: - newline-terminiertes JSON - `115200` Baud Beispiel: ```json {"type":"image","data":""}\n ``` ### UDP (Fahrzeug-ESP -> Basisstationen) - Port: `6666` - Payload: JSON-Strings (Text-Status und Kamera-Frames) ### HTTP (Web-Frontend -> Serial-Backend) Basis-API (über Vite-Proxy als `/api/...`): - `/api/serial-utils/serialports` - `/api/serial-utils/connect` - `/api/serial-utils/latest` ### Optional: Externe Datenweiterleitung (im Webinterface) Komponente: `webinterface/cotmw/src/components/External.vue` Funktion: - sendet Änderungen von `rssi`, `other_rssi` und `image` an einen externen HTTP-Endpunkt - Ziel-URL: `http://:/api/send` - Authentifizierung via Header `x-api-key` Standardwerte im UI: - IP: `138.68.114.176` - Port: `3000` ## Bekannte Einschränkungen / technische Schulden - Viele Parameter sind hartkodiert (SSID, Passwort, Ports, Serial-Pfade, IPs). - `cam_stream.py` verwendet fest `/dev/ttyACM1`. - Es gibt keine zentrale `.env`-Konfiguration. - Das Serial-Backend hält nur das zuletzt empfangene `text`- und `image`-Paket im Speicher. - Fehlerbehandlung und Logging sind für Demo/Prototyping ausgelegt, nicht für Produktion. - Das Vue-Frontend enthält bewusst versteckte UI-Elemente (Serial-Menü per Shortcut). - Die `webinterface/cotmw/package.json`-Scripts sind eher Frontend-orientiert; der Serial-Server wird separat gestartet. ## Troubleshooting ### Keine Daten im Webinterface - Prüfen, ob `webinterface/cotmw/serial/server.js` läuft (Port `6666`). - Prüfen, ob im Browser das Serial-Menü geöffnet und ein Port verbunden wurde (`Ctrl/Cmd + B`). - Prüfen, ob der richtige USB-Port des MBS1-ESP32 gewählt wurde. - Prüfen, ob Baudrate `115200` verwendet wird. - Prüfen, ob tatsächlich newline-terminierte JSON-Pakete gesendet werden. ### Kamera erscheint nicht / instabil - Kamerazugriff auf dem Raspberry Pi prüfen (`libcamera`, `Picamera2`). - Serielle Verbindung zum Fahrzeug-ESP prüfen (`/dev/ttyACM1` in `robot/cam_stream.py` anpassen). - Paketgröße kann kritisch sein: `MAX_B64` in `cam_stream.py` beeinflusst Bildqualität und Übertragbarkeit. ### ESP verbindet sich nicht mit Basisstationen - SSID/Passwort im ESP-Code prüfen (`ESP32-AP1`, `ESP32-AP2`, `PASS0000`). - Sicherstellen, dass beide Access Points gestartet sind. - Versorgungsspannung und Antennen/Position prüfen (RSSI). ### Rechteprobleme bei Serial/GPIO (Linux) - Benutzer in passende Gruppen aufnehmen (z. B. `dialout`, ggf. GPIO-spezifisch je Setup). - Skripte testweise mit ausreichenden Rechten starten. ## Hinweise zur Weiterentwicklung Sinnvolle nächste Schritte für eine robustere Version: - zentrale Konfiguration (`.env` / Config-Dateien) für SSIDs, Ports, Serial-Geräte - strukturiertere Paketprotokolle (Sequenznummern, Timestamps, Checks) - besserer Image-Transport (Chunking statt einzelner kurzer Base64-Payloads) - Telemetrie-Logging / Replay im Backend - sauberer Start per `docker-compose` (Web + Serial-API, sofern Host-Serial durchgereicht) - automatische Geräteerkennung und Health-Checks ## Zusatzmaterial im Repository `doc_vault/` enthält u. a.: - `esp32s3_pico_1_datasheet.pdf` - `esp32s3_pico_uart1_rx_tx.png` - weitere Projektdokumente (`doc_esp.odt`)