Files
ExoMy_Cuno/README.md
T
2026-05-28 14:52:28 +02:00

6.9 KiB

ExoMy CUNO — Software

CUNO steht für Celestian Unified Navigation and Observation.

ExoMy Mars-Rover auf Basis eines Raspberry Pi mit ROS1 Melodic, betrieben vollständig in einem Docker-Container.


Die Software liegt in diesem Repository direkt an der Wurzel. Nicht zur Software gehörende CAD-, Datenblatt- und Anleitungsbestände wurden bewusst entfernt.

Zugang zum Raspberry Pi

Modell Raspberry Pi 4 Model B Rev 1.4
Hostname cuno
Benutzer pi
SSH-Passwort Sonneberg
LAN-IP (eskimue.de) 192.168.1.83
WLAN-IP (eskimue.de) 192.168.1.9
WLAN-IP (4pi, SSH) 10.42.44.150
Fallback-AP SSID CUNO, IP 192.168.50.1, Passwort astr0cun042
# im WLAN "eskimue.de"
ssh pi@192.168.1.9

# im WLAN "4pi"
ssh pi@10.42.44.150

Architektur

Web-GUI (Port 8000)
    │ WebSocket (Port 9090)
    ▼
rosbridge_websocket ──► /joy ──► joystick_parser_node ──► /rover_command
                                                                │
f710_joy_node ──────────────────────────────────────────────────┘
(Logitech F710, /dev/input/js0)

/rover_command ──► robot_node ──► /motor_commands ──► motor_node ──► PCA9685 PWM ──► Motoren

Software auf dem Pi: /home/pi/ExoMy_Software/
ROS-Workspace im Container: /root/exomy_ws/src/exomy/


Systemd-Services auf dem Pi

Service Beschreibung
exomy-admin-api.service Admin-API (exomy_admin_api.py)
exomy-camera-stream.service MJPEG Kamera-Stream
exomy-wifi-bootstrap.service Wählt beim Start 4pi oder eskimue.de, sonst eigener Access Point

WLAN-Startlogik

Beim Booten sucht der Rover genau einmal nach den bekannten WLANs 4pi und eskimue.de.

  • Wenn 4pi sichtbar ist, verbindet er sich mit 4pi.
  • Sonst, wenn eskimue.de sichtbar ist, verbindet er sich mit eskimue.de.
  • Wenn keines von beiden sichtbar ist, spannt er den eigenen Access Point CUNO auf.

Nach dieser Entscheidung bleibt die gewählte Verbindung bestehen. Es gibt kein späteres Nachscannen und kein automatisches Umschalten auf ein anderes WLAN oder auf den Access Point. Erst nach einem Neustart wird erneut gesucht.

# Status prüfen
systemctl status exomy-admin-api.service

Docker-Container

Der Container exomy_autostart (Image: exomy) startet automatisch beim Booten.

# Status
docker ps

# Logs
docker logs exomy_autostart --tail=50

# Shell im Container
docker exec -it exomy_autostart bash

ROS-Nodes im Container

Node Beschreibung
f710_joy_node.py Liest Logitech F710 von /dev/input/js0, publiziert auf /joy mit 20 Hz — auch wenn der Joystick in Ruhe liegt
joystick_parser_node.py Konvertiert /joy → /rover_command; priorisiert Web-GUI über physischen Controller
gps_node.py Liest den GPS-Empfänger, publiziert Fix- und Diagnosedaten und kann über die Admin-Seite gezielt neu gestartet oder per Kaltstart zur Neuinitialisierung gezwungen werden
robot_node.py Berechnet Lenkwinkel und Geschwindigkeiten aus /rover_command
motor_node.py Setzt PWM-Werte über PCA9685; Watchdog stoppt Motoren nach 5 s ohne Befehl
rosbridge_websocket WebSocket-Bridge für die Web-GUI (Port 9090)
rosapi_node ROS-API für die Web-GUI

Admin-Funktionen

  • Admin-Seite: http://<IP>:8000/admin.html
  • Kamera-Tab nur mit 4:3-Profilen:
    • 640 x 480
    • 1024 x 768
    • 1296 x 972
  • Systemstatus mit zusätzlicher WLAN-Signalstärke in Prozent
  • GPS-Aktionen:
    • GPS neu starten
    • GPS-Kaltstart für den GlobalSat BU-353N5

Ports

Port Verwendung
8000 Web-GUI
9090 ROSBridge WebSocket
8082 Admin-API

Deploy-Workflow

Dateien lokal bearbeiten, dann auf den Pi und in den laufenden Container übertragen:

# Datei auf den Pi kopieren
scp src/meine_datei.py pi@192.168.1.9:/home/pi/ExoMy_Software/src/

# In den Container kopieren
ssh pi@192.168.1.9 "docker cp /home/pi/ExoMy_Software/src/meine_datei.py exomy_autostart:/root/exomy_ws/src/exomy/src/"

# Container neu starten
ssh pi@192.168.1.9 "docker restart exomy_autostart"

Im WLAN 4pi dieselben Befehle jeweils mit 10.42.44.150 statt 192.168.1.9 verwenden.

GUI-Dateien:

scp gui/index.html pi@192.168.1.9:/home/pi/ExoMy_Software/gui/
ssh pi@192.168.1.9 "docker cp /home/pi/ExoMy_Software/gui/index.html exomy_autostart:/root/exomy_ws/src/exomy/gui/"
# Kein Neustart nötig — Browser-Reload genügt

Bekannte Probleme & Fixes

Web-GUI: Ruckartige Bewegung bei angeschlossenem Controller

Problem: Der f710_joy_node sendet permanent mit 20 Hz auf /joy, auch wenn der Logitech F710 in Ruhe liegt (Nullwerte). Wenn die Web-GUI gleichzeitig steuert, wechseln sich Fahr- und Stopp-Befehle im 50-ms-Takt ab — der Rover bewegt sich ruckartig.

Fix: joystick_parser_node.py ignoriert Nachrichten des physischen Controllers für 2 Sekunden, sobald eine Web-GUI-Nachricht eintrifft (erkennbar an frame_id == "webgui"). Danach übernimmt der physische Controller automatisch wieder.

SyntaxError in rover.py (Point-Turn-Modus)

Problem: Überzählige schließende Klammer in rover.py Zeile 157 ließ robot_node.py beim Start abstürzen — der Rover war nicht steuerbar.

# Falsch:
math.atan((self.wheel_rx + self.wheel_fx) / self.wheel_ry)))
# Richtig:
math.atan((self.wheel_rx + self.wheel_fx) / self.wheel_ry))

Fahrmodi

Modus Taste (Controller) Taste (Web-GUI)
Ackermann A Schaltfläche „Ackermann"
Point Turn (Drehen auf der Stelle) X Schaltfläche „Turn on Point"
Crab (Seitwärtsfahrt) Y Schaltfläche „Crab"
Motoren ein/aus START Schaltfläche „Motoren"

Latenz-Simulation

Die Latenz-Simulation wird über die Admin-Seite eingestellt und wirkt gleichzeitig auf Steuerung und Kamerabild.

  • Bereich: Admin-Seite http://<IP>:8000/admin.html
  • Einstellbereich: 0 bis 10 Sekunden
  • Steuerbefehle: werden im ROS-Node delay_node gepuffert
  • Kamerabild: läuft über den Delay-Proxy auf Port 8083
  • Rohstream: Port 8081 bleibt ohne Verzögerung für Debug und interne Vorschau
  • Hauptseite: nutzt bewusst 8083, damit die eingestellte Verzögerung auch im Fahrbild sichtbar ist

Signalweg:

Kamera -> 8081 Rohstream -> 8083 Delay-Proxy -> Web-GUI
Joystick/Websteuerung -> /joy -> /delay_node -> /joy_delayed -> Rover-Steuerung

Damit lässt sich eine künstliche Laufzeit simulieren, ohne den eigentlichen Kameradienst umzubauen.


Originales ESA-Projekt