Files
HandoverMobileBaseStation/README.md
T
2026-02-22 23:30:15 +01:00

536 lines
15 KiB
Markdown

# 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":"<base64-jpeg>"}
```
### 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":"<base64-jpeg>"}\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://<ip>:<port>/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`)