# CUNO – Admin-Dokumentation Stand: 2026-05-21 --- ## 1. Hardware & Betriebssystem | Eigenschaft | Wert | |---|---| | Hardware | Raspberry Pi 4 Model B Rev 1.4 | | Betriebssystem | Debian GNU/Linux 13 (Trixie) | | Kernel | 6.12.75+rpt-rpi-v8 (64-bit ARM) | | Python | 3.13.5 | | Docker | 26.1.5 | --- ## 2. Raspberry Pi – Zugangsdaten | Eigenschaft | Wert | |---|---| | Hostname | `ExoMyCuno` | | Benutzer | `pi` | | Passwort | `Sonneberg` | | LAN-IP | `192.168.1.83` | | WLAN-IP | `192.168.1.9` | **SSH-Zugang:** ``` ssh pi@192.168.1.9 ``` --- ## 3. WLAN-Logik Der Rover wählt automatisch das beste verfügbare Netzwerk. Ein Hintergrunddienst (`exomy-wifi-fallback`) prüft alle 20 Sekunden die Verbindung und schaltet bei Bedarf um. ### Prioritätenreihenfolge | Priorität | SSID | Typ | Wann aktiv | |---|---|---|---| | 1 (höchste) | `eskimue.de` | Heimnetz | wenn im Heimnetz | | 2 | `4pi` | Mobiler Hotspot | wenn unterwegs mit Handy | | 3 (Fallback) | `CUNO` | Eigener AP des Rovers | wenn kein bekanntes WLAN erreichbar | ### Netzwerk-Passwörter | SSID | Passwort | |---|---| | `4pi` | `st89Saf6H86n` | | `CUNO` (Rover-AP) | `astr0cun042` | ### Verhalten im Detail - Ist `eskimue.de` erreichbar → Verbindung wird hergestellt und gehalten. - Ist `eskimue.de` nicht erreichbar, aber `4pi` sichtbar → Verbindung mit `4pi`. - Ist keines der beiden Netze erreichbar → Rover öffnet den eigenen WLAN-Hotspot **CUNO**. - Sobald ein besser priorisiertes Netz wieder verfügbar wird, schaltet der Dienst automatisch zurück. ### Eigener Access Point (CUNO) Wenn der Rover als AP läuft, ist er unter einer festen IP erreichbar: | Eigenschaft | Wert | |---|---| | SSID | `CUNO` | | Passwort | `astr0cun042` | | IP des Rovers | `192.168.50.1` | | Sicherheit | WPA2-PSK | Browser-Adresse im AP-Modus: `http://192.168.50.1:8000/` --- ## 4. Offene Ports und Dienste Alle Dienste laufen auf dem **Host** (Raspberry Pi), nicht im Docker-Container. | Port | Dienst | Beschreibung | |---|---|---| | `8000` | Web-GUI | Haupt-Steuerseite und Admin-Seite (Python HTTP-Server im Container) | | `8081` | Kamerastream (Quelle) | Rohstream direkt von der Kamera, kein Delay. Nur intern genutzt. | | `8082` | Admin-API | REST-API für Systemsteuerung (Neustart, Status, Delay). Kein Browser-Frontend. | | `8083` | Video-Delay-Proxy | Kamerastream **mit** eingestellter Verzögerung. Wird von der Web-GUI gezeigt. | | `9090` | ROSBridge WebSocket | Verbindung zwischen Browser und ROS im Container. | ### Kamera-Signalkette ``` Kamera (Hardware) ↓ libcamera_mjpeg_server → Port 8081 (Rohstream, kein Delay) ↓ video_delay_proxy → Port 8083 (mit Delay, 0–10 s einstellbar) ↓ Web-GUI (Browser) ``` Bei Delay = 0 s wird das Bild sofort weitergegeben (kein echtes Buffern). --- ## 5. Webseiten ### 4.1 Steuerung – `http://:8000/` Die Haupt-Steuerseite des Rovers. **Inhalt:** - Kamerabild (live, mit Delay wenn eingestellt) - Virtueller Joystick (Maussteuerung) - Modus-Anzeige (Ackermann / Punkt-Drehen / Crabbing) - Systemstatus-Panel (rechts): Verbindung, CPU, RAM, Temp, WLAN, Uptime, Speicher **Besonderheiten:** - Physischer Controller und Web-Joystick können gleichzeitig betrieben werden. - Wenn die Web-GUI aktiv gesteuert hat, wird der physische Controller für 2 Sekunden ignoriert (Prioritätslogik). - Moduswechsel vom physischen Controller werden in der Web-GUI sofort angezeigt. - Die Joystick-Spiegelanzeige zeigt, welche Eingaben der physische Controller gerade sendet. --- ### 4.2 Admin-Seite – `http://:8000/admin.html` Systemverwaltung des Rovers. Die Seite ist passwortgeschützt — bei jedem Aufruf wird das Passwort abgefragt. | Eigenschaft | Wert | |---|---| | Passwort | `cuno` | **Bereiche:** #### Aktionen | Schaltfläche | Funktion | |---|---| | GPS-Kaltstart | Sendet einen Kaltstart-Befehl an den GlobalSat BU-353N5 und startet danach den GPS-Knoten neu | | GPS neu starten | Startet nur den GPS-Knoten im laufenden ExoMy-Container neu | | Kameradienst neu starten | Startet `exomy-camera-stream.service` neu | | ExoMy-Container neu starten | Startet Docker-Container `exomy_autostart` neu (ROS, Motoren, Joystick) | | Raspberry Pi neu starten | Fährt den Pi neu hoch | | Raspberry Pi herunterfahren | Fährt den Pi aus | #### Dienststatus Zeigt den Live-Status von Kamera, Admin-API und ExoMy-Container. #### Kamera - Eigener Kamera-Tab in der Admin-Seite - Verfügbare Profile: - `640 x 480` - `1024 x 768` - `1296 x 972` - Alle Kamera-Profile sind bewusst `4:3`, weil damit beim verwendeten Setup das größte Sichtfeld erhalten bleibt. - Ein Profilwechsel speichert die Auswahl dauerhaft und startet den Kameradienst automatisch neu. #### GPS - `GPS neu starten` startet nur den laufenden GPS-Knoten im Container neu. - `GPS-Kaltstart` sendet einen Kaltstart-Befehl an den GlobalSat `BU-353N5` und startet danach den GPS-Knoten neu. - Ein Kaltstart löscht die bisherigen Hilfsdaten des Empfängers; der nächste Fix dauert deshalb meist deutlich länger. #### Motorentest Link zur separaten Motortest-Seite (siehe 4.3). #### Latenz-Simulation Dropdown 0–10 Sekunden. Verzögert **gleichzeitig**: - Steuerbefehle (sowohl Web-GUI als auch physischer Controller) - Kamerabild So lässt sich realitätsnahe Steuerung mit erhöhter Signallaufzeit simulieren (z. B. Mond-Delay ≈ 1 s hin + 1 s zurück → 2 s einstellen). #### Systemstatus | Anzeige | Quelle | |---|---| | WLAN-Status | nmcli | | WLAN-Signal | nmcli (`AP.SIGNAL`) | | IP-Adressen | wlan0 | | CPU-Temperatur | `/sys/class/thermal/thermal_zone0/temp` | | Unterspannung | `vcgencmd get_throttled` | | Uptime | `/proc/uptime` | | Freier Speicherplatz | Root-Partition | --- ### 4.3 Motortest – `http://:8000/admin-motor-test.html` Separate Testseite zum Kalibrieren und Prüfen einzelner Räder. **Wichtig:** Der ExoMy-Container muss für den Motortest **gestoppt** sein (Schaltfläche auf der Seite). Nach dem Test kann er wieder gestartet werden. **Funktionen:** - Lenkung links / rechts je Rad testen - Vorwärts / Rückwärts je Rad testen - Servo-Mittenwerte (Lenkung) einstellen und speichern - Antriebsneutralwert einstellen und speichern --- ## 7. Controller-Belegung (Logitech F710) Der Controller muss im **D-Modus** (Schalter auf der Rückseite) betrieben werden. | Taste / Achse | Funktion | |---|---| | **Linker Stick** | Fahren und Lenken | | **A** | Ackermann-Modus (normales Kurvenfahren) | | **X** | Punkt-Drehen (Rover dreht auf der Stelle) | | **Y** | Crabbing (seitliche Fahrt, alle Räder gleich eingeschlagen) | | **B** | (nicht belegt) | | **START** | Motoren ein- / ausschalten (Toggle) | | **SELECT** | (nicht belegt) | ### Fahrmodi im Detail **Ackermann** (Standard): Normales Kurvenfahren wie ein Auto. Die Vorder- und Hinterräder lenken gegenläufig für einen engen Wendekreis. **Punkt-Drehen:** Der Rover dreht sich auf der Stelle. Alle Räder stehen schräg, der Antrieb dreht links und rechts gegeneinander. **Crabbing:** Alle Räder werden auf den gleichen Winkel eingeschlagen. Der Rover fährt seitlich (wie eine Krabbe). Lenkrichtung folgt dem X-Achsen-Ausschlag des Sticks. --- ## 6. Docker-Container ### Container `exomy_autostart` | Eigenschaft | Wert | |---|---| | Image | `exomy:latest` (lokal gebaut, basiert auf `ros:melodic`) | | ROS-Version | ROS 1 Melodic (Ubuntu 18.04-Basis im Container) | | Startet automatisch | ja (`--restart=always`) | | Ports (Host → Container) | `8000→8000` (Web-GUI), `8080→8080` (alt, nicht aktiv genutzt), `9090→9090` (ROSBridge) | ### ROS-Knoten im Container | Knoten | Funktion | |---|---| | `/delay_node` | Puffert `/joy` → `/joy_delayed` mit einstellbarer Verzögerung (0–10 s) | | `/f710_joy_node` | Liest den Logitech F710 Controller und publiziert auf `/joy` | | `/joystick_parser_node` | Übersetzt Joystick-Eingaben in Rover-Befehle (`/rover_command`) | | `/robot_node` | Berechnet Rad-Winkel und -Geschwindigkeiten aus dem Rover-Befehl | | `/motors` | Schreibt PWM-Werte auf den Servo-Controller (I²C) | | `/rosbridge_websocket` | WebSocket-Brücke zwischen Browser und ROS (Port 9090) | | `/rosapi_node` | Erlaubt dem Browser, ROS-Parameter zu lesen/schreiben | ### ROS-Signalfluss ``` Controller (USB) ↓ /f710_joy_node → /joy ↓ /delay_node → /joy_delayed ↓ Web-GUI (Browser) → /joy /joystick_parser_node (frame_id="webgui") ↓ /rover_command ↓ /robot_node ↓ /motor_commands ↓ /motors (PWM → Servos) ``` ### Nützliche Container-Befehle ```bash # Container neu starten docker restart exomy_autostart # Shell im Container öffnen docker exec -it exomy_autostart bash # ROS-Knoten anzeigen docker exec exomy_autostart bash -c 'source /opt/ros/melodic/setup.bash && rosnode list' # Alle ROS-Topics anzeigen docker exec exomy_autostart bash -c 'source /opt/ros/melodic/setup.bash && rostopic list' # Delay-Parameter im ROS lesen/setzen docker exec exomy_autostart bash -c 'source /opt/ros/melodic/setup.bash && rosparam get /delay_seconds' docker exec exomy_autostart bash -c 'source /opt/ros/melodic/setup.bash && rosparam set /delay_seconds 2.0' # Alten Image-Schrott aufräumen (dangling images) docker image prune -f ``` --- ## 8. Systemdienste (Übersicht) Alle laufen auf dem Raspberry Pi als systemd-Dienste: | Dienst | Beschreibung | Startet automatisch | |---|---|---| | `exomy-camera-stream` | MJPEG-Kamerastream auf Port 8081 | ja | | `exomy-video-delay` | Delay-Proxy auf Port 8083 | ja | | `exomy-admin-api` | REST-API auf Port 8082 | ja | | `exomy-wifi-fallback` | WLAN-Priorisierung und AP-Fallback | ja | Der **Docker-Container** `exomy_autostart` enthält ROS und startet ebenfalls automatisch (via `docker run --restart=always` oder manuell). ### Nützliche SSH-Befehle ```bash # Dienststatus prüfen systemctl status exomy-camera-stream systemctl status exomy-video-delay systemctl status exomy-admin-api # Dienst neu starten sudo systemctl restart exomy-camera-stream # Container-Status docker ps # Container-Logs docker logs exomy_autostart # ROS-Topic live anzeigen (im Container) docker exec exomy_autostart bash -c \ 'source /opt/ros/melodic/setup.bash && rostopic echo /rover_command' # Aktuellen Delay prüfen cat /tmp/exomy_delay.txt ``` --- ## 9. Latenz-Simulation – technischer Hintergrund Die Verzögerung wirkt auf zwei Ebenen gleichzeitig: 1. **Steuerbefehle** (ROS-Ebene): Der `delay_node` puffert alle Joystick-Nachrichten vom Topic `/joy` und gibt sie verzögert auf `/joy_delayed` aus. Der Joystick-Parser liest nur `/joy_delayed`. 2. **Kamerabild** (Host-Ebene): Der `video_delay_proxy` puffert JPEG-Frames aus Port 8081 mit Timestamps. Beim Abruf wird der Frame geliefert, der zum Zeitpunkt `jetzt − Delay` aufgezeichnet wurde. Der eingestellte Wert wird in `/tmp/exomy_delay.txt` gespeichert und von beiden Komponenten gleichzeitig gelesen. Änderungen über die Admin-Seite wirken sofort. --- ## 10. Bekannte Eigenheiten - **Crabbing**: Funktioniert softwareseitig, mechanische Einstellung der Einzelräder ist noch nicht abgeschlossen. - **Containerstart**: Niemals `sudo docker run ...` nutzen – das falsche Home-Verzeichnis wird gemountet. - **Browser-Cache**: Nach GUI-Updates ggf. Shift+F5 (Hard Reload) im Browser nötig. - **Port 8081 direkt**: Erreichbar für Debug-Zwecke, zeigt immer das Live-Bild ohne Delay.