diff --git a/.gitignore b/.gitignore index ebd7e1b..b134254 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,5 @@ -ssh-zugang-raspberry-pi.txt +*.pyc +__pycache__/ +config/exomy.yaml +.vscode/ +gui/node_modules/ diff --git a/Anleitungen/.gitkeep b/Anleitungen/.gitkeep deleted file mode 100644 index 8b13789..0000000 --- a/Anleitungen/.gitkeep +++ /dev/null @@ -1 +0,0 @@ - diff --git a/Anleitungen/Bedienungsanleitung-Admin.txt b/Anleitungen/Bedienungsanleitung-Admin.txt deleted file mode 100644 index 9c38f46..0000000 --- a/Anleitungen/Bedienungsanleitung-Admin.txt +++ /dev/null @@ -1,244 +0,0 @@ -Bedienungsanleitung ExoMy - Admin -================================= - -Diese Anleitung ist für Administration, Diagnose und technische Bedienung gedacht. -Sie beschreibt die Admin-Seite und die wichtigsten technischen Zusammenhänge. - - -1. Admin-Seite -============== - -Adresse: - -http://:8000/admin.html - -Typische Adressen: -- http://192.168.1.9:8000/admin.html -- http://192.168.1.83:8000/admin.html -- http://192.168.50.1:8000/admin.html - -Passwort: -- cuno - - -2. Zweck der Admin-Seite -======================== - -Die Admin-Seite ist für: -- Neustarts -- Diagnose -- Kameraeinstellungen -- GPS-Aktionen -- Latenz-Simulation -- Überblick über Systemstatus und Dienste - - -3. Wichtige Tabs und Bereiche -============================= - -Aktionen: -- GPS neu starten -- GPS-Kaltstart -- Kameradienst neu starten -- ExoMy-Container neu starten -- Raspberry Pi neu starten -- Raspberry Pi herunterfahren - -Kamera: -- Auswahl der Stream-Auflösung -- nur 4:3-Profile -- aktuelle Vorschau - -GPS: -- GPS-Status -- Satelliten -- Diagnosewerte -- Neustart und Kaltstart - -Systemstatus: -- WLAN -- WLAN-Signal -- CPU-Temperatur -- CPU-Auslastung -- RAM -- Uptime -- freier Speicherplatz -- Unterspannung - - -4. Kamera -========= - -Die Kamera ist bewusst auf 4:3-Profile reduziert. - -Verfügbare Profile: -- 640 x 480 -- 1024 x 768 -- 1296 x 972 - -Grund: -- mit 4:3 bleibt beim vorhandenen Kameramodul das größtmögliche Sichtfeld erhalten -- 16:9-Modi wurden entfernt, weil sie im praktischen Einsatz einen engeren Bildausschnitt liefern - -Wichtig: -- ein Profilwechsel speichert die Auswahl dauerhaft -- danach wird der Kameradienst automatisch neu gestartet - - -5. Kamera-Streams -================= - -Es gibt zwei verschiedene Kamerapfade: - -- Port 8081 - Rohstream ohne Verzögerung - -- Port 8083 - Delay-Proxy mit eingestellter Verzögerung - -Wichtige Zuordnung: -- Hauptseite `index.html` soll bewusst den Stream auf 8083 verwenden -- Admin-Vorschau darf direkt den Rohstream nutzen - -Merksatz: -- 8081 = direkt -- 8083 = verzögert - - -6. Latenz-Simulation -==================== - -Die Latenz-Simulation wird im Admin eingestellt. - -Bereich: -- 0 bis 10 Sekunden - -Die Verzögerung wirkt gleichzeitig auf: -- Steuerbefehle -- Kamerabild - -Technisch bedeutet das: -- Steuerbefehle laufen über den ROS-Knoten `delay_node` -- Kamerabilder laufen über den Dienst `video_delay_proxy` - -Signalweg Kamera: -- Kamera -> 8081 Rohstream -> 8083 Delay-Proxy -> Web-GUI - -Signalweg Steuerung: -- Web-GUI / physischer Controller -> /joy -> /delay_node -> /joy_delayed -> Rover-Steuerung - -Zweck: -- realistische Simulation von Signallaufzeiten -- Test von Fahrverhalten bei Verzögerung - - -7. GPS -====== - -Verwendeter Empfänger: -- GlobalSat BU-353N5 USB-GNSS-Empfänger - -GPS neu starten: -- startet nur den laufenden GPS-Knoten im Container neu - -GPS-Kaltstart: -- sendet einen Kaltstart-Befehl an den Empfänger -- startet danach den GPS-Knoten neu -- der nächste Fix kann deutlich länger dauern - -Die GPS-Porterkennung ist portunabhängig aufgebaut. -Der Node sucht automatisch nach: -- /dev/serial/by-id/* -- /dev/serial/by-path/* -- /dev/ttyUSB* -- /dev/ttyACM* - - -8. ROS und Web-GUI -================== - -Die Hauptseite nutzt: -- Port 8000 für die Web-GUI -- Port 9090 für ROSBridge WebSocket - -Wichtig: -- ROS-Anzeige in der Hauptseite und echte ROS-Laufzeit können sich bei kurzen Verbindungsstörungen unterschiedlich verhalten -- bei GPS-Neustarts kann die Startseite kurz eine fehlerhafte oder zu strenge ROS-Anzeige liefern -- das bedeutet nicht automatisch, dass `rosbridge_websocket` wirklich abgestürzt ist - - -9. Wichtige Dienste auf dem Pi -============================== - -Systemd-Dienste: -- exomy-camera-stream.service -- exomy-video-delay.service -- exomy-admin-api.service -- exomy-wifi-fallback.service - -Bedeutung: -- exomy-camera-stream = direkter MJPEG-Stream -- exomy-video-delay = verzögerter Video-Proxy -- exomy-admin-api = Admin-REST-API -- exomy-wifi-fallback = Netzlogik und Fallback-AP - - -10. Docker und Container -======================== - -Der Rover läuft hauptsächlich im Container: -- exomy_autostart - -Dort laufen unter anderem: -- rosbridge_websocket -- rosapi_node -- gps_node.py -- robot_node.py -- motor_node.py -- joystick_parser_node.py -- f710_joy_node.py -- delay_node - - -11. Netzwerk -============ - -Bevorzugt: -- WLAN 192.168.1.9 - -Alternativ: -- LAN 192.168.1.83 - -Fallback: -- Access Point CUNO -- 192.168.50.1 - - -12. Typische Diagnosefälle -========================== - -Kein Kamerabild auf der Hauptseite: -- prüfen, ob 8083 der verwendete Stream ist -- prüfen, ob exomy-video-delay.service läuft -- prüfen, ob 8081 und 8083 erreichbar sind - -Kein GPS: -- GPS-Tab prüfen -- Satelliten und Diagnose ansehen -- GPS neu starten -- bei Bedarf GPS-Kaltstart - -Hauptseite zeigt komische Verbindungszustände: -- Seite hart neu laden -- Admin-Status gegenprüfen -- prüfen, ob Dienste auf dem Pi laufen - - -13. Zuständigkeit -================= - -Die Hauptseite ist für Bedienung im Betrieb. -Die Admin-Seite ist für technische Eingriffe. - -Auf der Hauptseite sollten keine Wartungsarbeiten gemacht werden. -Für Neustarts, Diagnose und Konfiguration immer den Admin-Bereich nutzen. diff --git a/Anleitungen/Bedienungsanleitung-User.txt b/Anleitungen/Bedienungsanleitung-User.txt deleted file mode 100644 index 7a007e1..0000000 --- a/Anleitungen/Bedienungsanleitung-User.txt +++ /dev/null @@ -1,190 +0,0 @@ -Bedienungsanleitung ExoMy - User -================================ - -Diese Anleitung ist für normale Benutzer gedacht. -Gemeint ist nur die Hauptseite des Rovers: - -http://:8000/ - - -1. Zweck der Hauptseite -======================= - -Über die Hauptseite kann der Rover beobachtet und gesteuert werden. - -Die Seite zeigt: -- das Kamerabild -- den aktuellen Fahrmodus -- den Verbindungsstatus -- die GPS-Anzeige -- den virtuellen Joystick -- wichtige Systemwerte - - -2. Verbindung zum Rover -======================= - -Der Rover ist je nach Netzwerk unter einer dieser Adressen erreichbar: - -- Heimnetz / WLAN: http://192.168.1.9:8000/ -- LAN: http://192.168.1.83:8000/ -- Fallback-Access-Point: http://192.168.50.1:8000/ - -Wenn die Seite nicht lädt: -- prüfen, ob der Rover eingeschaltet ist -- prüfen, ob das richtige WLAN verwendet wird -- Seite neu laden - - -3. Kamerabild -============= - -Das große Bild in der Mitte ist das Kamerabild des Rovers. - -Wichtig: -- Das Bild kann absichtlich verzögert sein, wenn in der Admin-Seite eine Latenz-Simulation eingestellt wurde. -- Die Hauptseite nutzt dafür den verzögerten Videoweg. - -Wenn kein Bild zu sehen ist: -- Seite neu laden -- Netzwerkverbindung prüfen -- bei anhaltendem Problem Admin oder Technik informieren - - -4. Fahrmodi -=========== - -Der Rover kennt mehrere Fahrmodi: - -- Ackermann - Normales Fahren wie bei einem Auto - -- Turn on Point - Drehen auf der Stelle - -- Crab - Seitliches Fahren - -Der aktive Modus wird auf der Hauptseite angezeigt. - - -5. Steuerung über den virtuellen Joystick -========================================= - -Die Steuerung erfolgt mit dem virtuellen Joystick auf der Hauptseite. - -Grundprinzip: -- nach vorne = vorwärts fahren -- nach hinten = rückwärts fahren -- nach links = links lenken -- nach rechts = rechts lenken - -Hinweise: -- kleine Bewegungen vorsichtig ausführen -- bei Verzögerung ruhig bleiben und nicht hektisch gegensteuern -- nach dem Loslassen geht der virtuelle Joystick wieder in die Mitte zurück - - -6. Motoren -========== - -Der Rover fährt nur, wenn die Motoren freigegeben sind. - -Wenn der Rover nicht reagiert: -- prüfen, ob auf der Hauptseite die Motoren aktiviert sind -- prüfen, ob eine Verbindung zum Rover besteht - - -7. GPS-Anzeige -============== - -Auf der Hauptseite wird bei GPS die Anzahl der empfangenen Satelliten angezeigt. - -Beispiele: -- 0 Sat -- 12 Sat -- 21 Sat - -Wenn dort Offline steht: -- hat die Seite gerade keine brauchbaren GPS-Daten -- nach einem GPS-Neustart oder Kaltstart kann das kurz dauern - - -8. Statusanzeigen -================= - -Auf der Hauptseite werden mehrere Statuswerte angezeigt. - -Wichtige Bedeutungen: -- Cuno online - Die Seite hat Verbindung zu den wichtigen Diensten - -- Cuno eingeschränkt - Ein Teil der Funktionen ist erreichbar, aber nicht alles - -- Cuno offline - Die Verbindung ist derzeit gestört oder unterbrochen - -- ROS - Verbindung zur ROS-Schnittstelle des Rovers - -- CAM - Zustand des Kamerastreams - -- GPS - Anzahl empfangener Satelliten oder Offline - - -9. Verhalten bei Verzögerung -============================ - -Es kann sein, dass absichtlich eine Signallaufzeit simuliert wird. - -Dann reagieren: -- Kamerabild später -- Fahrbefehle später - -In diesem Fall: -- nur kleine Steuerbewegungen machen -- auf die Wirkung warten -- nicht mehrfach hektisch nachkorrigieren - - -10. Wenn der Rover nicht reagiert -================================= - -In dieser Reihenfolge prüfen: - -1. Ist das Kamerabild da? -2. Steht die Seite auf online oder eingeschränkt? -3. Sind die Motoren aktiviert? -4. Reagiert der virtuelle Joystick? -5. Seite neu laden - -Wenn das Problem bleibt: -- nicht weiter experimentieren -- Admin oder Technik informieren - - -11. Sicherheit -============== - -Beim Fahren immer beachten: - -- langsam anfangen -- genug Abstand zu Personen halten -- nicht blind fahren -- bei schlechter Verbindung besonders vorsichtig sein -- bei Verzögerung mit großer Reserve steuern - - -12. Kurzfassung -=============== - -Die Hauptseite ist für drei Dinge da: - -- sehen, was die Kamera zeigt -- den Rover fahren -- den Zustand grob überwachen - -Für Wartung, Neustarts, GPS-Aktionen oder Kameraeinstellungen ist die Admin-Seite zuständig. diff --git a/ExoMy_Software-master/CMakeLists.txt b/CMakeLists.txt similarity index 100% rename from ExoMy_Software-master/CMakeLists.txt rename to CMakeLists.txt diff --git a/CUNO-Admin.md b/CUNO-Admin.md deleted file mode 100644 index d7c500d..0000000 --- a/CUNO-Admin.md +++ /dev/null @@ -1,364 +0,0 @@ -# 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 - -### Wichtige Zuordnung der Streams - -- Port `8081`: Kamera-Rohstream ohne Verzögerung -- Port `8083`: Delay-Proxy mit der eingestellten Verzögerung -- Die Hauptseite `index.html` soll bewusst den Stream auf `8083` nutzen -- Der Admin-Kameratab darf für Vorschau und Diagnose direkt auf den Rohstream zeigen - -Damit ist klar getrennt: -- `8081` = direktes Kamerabild -- `8083` = simulierte Laufzeit für den Fahrbetrieb - -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. diff --git a/ExoMy_Software-master/.gitignore b/ExoMy_Software-master/.gitignore deleted file mode 100644 index 4620d75..0000000 --- a/ExoMy_Software-master/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.pyc -config/exomy.yaml \ No newline at end of file diff --git a/ExoMy_Software-master/gui/node_modules/nipplejs/CHANGELOG.md b/ExoMy_Software-master/gui/node_modules/nipplejs/CHANGELOG.md deleted file mode 100644 index 0fbf8b0..0000000 --- a/ExoMy_Software-master/gui/node_modules/nipplejs/CHANGELOG.md +++ /dev/null @@ -1,386 +0,0 @@ - -## [0.8.5](https://github.com/yoannmoinet/nipplejs/compare/v0.8.4...v0.8.5) (2020-01-27) - - - - -## [0.8.4](https://github.com/yoannmoinet/nipplejs/compare/v0.7.3...v0.8.4) (2019-11-28) - - -### Bug Fixes - -* allow older typescript ([c164597](https://github.com/yoannmoinet/nipplejs/commit/c164597)) -* better lockX and lockY mecanism ([8355fb8](https://github.com/yoannmoinet/nipplejs/commit/8355fb8)), closes [#111](https://github.com/yoannmoinet/nipplejs/issues/111) -* joystick in 'dynamic' mode gets stuck on iOS ([94bb784](https://github.com/yoannmoinet/nipplejs/commit/94bb784)), closes [#94](https://github.com/yoannmoinet/nipplejs/issues/94) -* released outside will be considered inside ([9a8a7b4](https://github.com/yoannmoinet/nipplejs/commit/9a8a7b4)), closes [#109](https://github.com/yoannmoinet/nipplejs/issues/109) -* reset direction when below the threshold ([6f41b38](https://github.com/yoannmoinet/nipplejs/commit/6f41b38)), closes [#110](https://github.com/yoannmoinet/nipplejs/issues/110) - - -### Features - -* add an options to use with dynamic pages ([8258501](https://github.com/yoannmoinet/nipplejs/commit/8258501)) -* add raw data on move for data-only usage ([c818fb2](https://github.com/yoannmoinet/nipplejs/commit/c818fb2)), closes [#54](https://github.com/yoannmoinet/nipplejs/issues/54) -* add unit vector representation to move event output ([a4496fe](https://github.com/yoannmoinet/nipplejs/commit/a4496fe)) -* upgrade dev experience with webpack and es6 ([cc1e824](https://github.com/yoannmoinet/nipplejs/commit/cc1e824)) - - - - -## [0.7.3](https://github.com/yoannmoinet/nipplejs/compare/v0.7.2...v0.7.3) (2018-12-11) - - - - -## [0.7.2](https://github.com/yoannmoinet/nipplejs/compare/v0.7.1...v0.7.2) (2018-12-11) - - -### Features - -* Add TypeScript Definitions ([#85](https://github.com/yoannmoinet/nipplejs/issues/85)) ([0b1f4ae](https://github.com/yoannmoinet/nipplejs/commit/0b1f4ae)), closes [#21](https://github.com/yoannmoinet/nipplejs/issues/21) - - - - -## [0.7.1](https://github.com/yoannmoinet/nipplejs/compare/v0.7.0...v0.7.1) (2018-06-06) - - - - -# [0.7.0](https://github.com/yoannmoinet/nipplejs/compare/v0.6.8...v0.7.0) (2018-06-06) - - -### Bug Fixes - -* register touchcancel and pointercancel events ([2c541a6](https://github.com/yoannmoinet/nipplejs/commit/2c541a6)) - - -### Features - -* **joystick:** add lockX and lockY options ([6baba97](https://github.com/yoannmoinet/nipplejs/commit/6baba97)) - - - - -## [0.6.8](https://github.com/yoannmoinet/nipplejs/compare/v0.6.7...v0.6.8) (2017-12-19) - - -### Bug Fixes - -* add touchcancel handling as touchend for events coming from outside ([ebc501e](https://github.com/yoannmoinet/nipplejs/commit/ebc501e)), closes [#61](https://github.com/yoannmoinet/nipplejs/issues/61) [#57](https://github.com/yoannmoinet/nipplejs/issues/57) [#33](https://github.com/yoannmoinet/nipplejs/issues/33) [#31](https://github.com/yoannmoinet/nipplejs/issues/31) [#30](https://github.com/yoannmoinet/nipplejs/issues/30) -* update manager with changing identifier ([45ec1d7](https://github.com/yoannmoinet/nipplejs/commit/45ec1d7)), closes [#64](https://github.com/yoannmoinet/nipplejs/issues/64) - - -### Features - -* add restJoystick option ([55b6482](https://github.com/yoannmoinet/nipplejs/commit/55b6482)) - - - - -## [0.6.7](https://github.com/yoannmoinet/nipplejs/compare/v0.6.6...v0.6.7) (2016-10-27) - - -### Bug Fixes - -* **events:** trigger events with the correct id and not identifier ([17f0fe6](https://github.com/yoannmoinet/nipplejs/commit/17f0fe6)) -* **identifier:** better identifier management ([ff44916](https://github.com/yoannmoinet/nipplejs/commit/ff44916)) -* update dependencies ([73bcda9](https://github.com/yoannmoinet/nipplejs/commit/73bcda9)) - - - - -## [0.6.6](https://github.com/yoannmoinet/nipplejs/compare/v0.6.5...v0.6.6) (2016-08-23) - - -### Bug Fixes - -* **bin:** adapt slashes to windows if needed ([7dffd7c](https://github.com/yoannmoinet/nipplejs/commit/7dffd7c)) -* **bin:** add missing space ([48f6a1f](https://github.com/yoannmoinet/nipplejs/commit/48f6a1f)) -* **bin:** make the copyToGhPages script windows compatible ([11da89a](https://github.com/yoannmoinet/nipplejs/commit/11da89a)) -* **dataOnly:** conserve chainability even with dataOnly ([d1eddd0](https://github.com/yoannmoinet/nipplejs/commit/d1eddd0)) - - - - -## [0.6.5](https://github.com/yoannmoinet/nipplejs/compare/v0.6.4...v0.6.5) (2016-08-15) - - -### Bug Fixes - -* **collection:** avoid any native touch action on the `options.zone` ([bea2c42](https://github.com/yoannmoinet/nipplejs/commit/bea2c42)) - - - - -## [0.6.4](https://github.com/yoannmoinet/nipplejs/compare/v0.6.3...v0.6.4) (2016-07-20) - - -### Bug Fixes - -* **nipple:** remove size of container and apply on children only ([0033342](https://github.com/yoannmoinet/nipplejs/commit/0033342)), closes [#32](https://github.com/yoannmoinet/nipplejs/issues/32) - - - - -## [0.6.3](https://github.com/yoannmoinet/nipplejs/compare/v0.6.2...v0.6.3) (2016-05-29) - - -### Bug Fixes - -* **manager:** add missing closing bracket ([9b99637](https://github.com/yoannmoinet/nipplejs/commit/9b99637)) -* **resize:** listen to resize via event instead of global handler ([14c28f1](https://github.com/yoannmoinet/nipplejs/commit/14c28f1)) - - - - -## [0.6.2](https://github.com/yoannmoinet/nipplejs/compare/v0.6.1...v0.6.2) (2015-12-31) - - - - -## [0.6.1](https://github.com/yoannmoinet/nipplejs/compare/v0.6.0...v0.6.1) (2015-12-26) - - -### Bug Fixes - -* **collection:** trigger `start` event before any potential direction ([c5441fd](https://github.com/yoannmoinet/nipplejs/commit/c5441fd)) -* **nipple:** fragment control of previous directions ([790fa26](https://github.com/yoannmoinet/nipplejs/commit/790fa26)), closes [#25](https://github.com/yoannmoinet/nipplejs/issues/25) - - -### Features - -* **nipple:** add `resetDirection()` to cancel previous directions ([66f6e3b](https://github.com/yoannmoinet/nipplejs/commit/66f6e3b)) - - - - -# [0.6.0](https://github.com/yoannmoinet/nipplejs/compare/v0.5.6...v0.6.0) (2015-11-29) - - -### Bug Fixes - -* clean identifier if not found in any collection ([3496395](https://github.com/yoannmoinet/nipplejs/commit/3496395)) -* handle scrolling offset by resetting zone's box ([6ccd0b5](https://github.com/yoannmoinet/nipplejs/commit/6ccd0b5)) -* remove useless injections ([a0b1d7e](https://github.com/yoannmoinet/nipplejs/commit/a0b1d7e)) -* return the found nipple in `get()` ([439aa69](https://github.com/yoannmoinet/nipplejs/commit/439aa69)) -* unbind document when collection is manually destroyed ([6e66b62](https://github.com/yoannmoinet/nipplejs/commit/6e66b62)) -* **nipple:** call off() after triggering ([bf8e5c3](https://github.com/yoannmoinet/nipplejs/commit/bf8e5c3)) -* **nipple:** only trigger itself, not its manager ([6b39786](https://github.com/yoannmoinet/nipplejs/commit/6b39786)) -* **super:** move internal declarations where needed ([a4c79c2](https://github.com/yoannmoinet/nipplejs/commit/a4c79c2)) -* **utils:** return object on u.extend ([9197c00](https://github.com/yoannmoinet/nipplejs/commit/9197c00)) - - -### Features - -* **nipple:** add an incremental id to absolutely differentiate each ([598a5eb](https://github.com/yoannmoinet/nipplejs/commit/598a5eb)) -* **utils:** add u.map to execute fn in array or single element ([515aa5d](https://github.com/yoannmoinet/nipplejs/commit/515aa5d)) -* **utils:** add u.safeExtend to only replace existent attributes ([5212ffe](https://github.com/yoannmoinet/nipplejs/commit/5212ffe)) - - -### Performance Improvements - -* safety clean if nipple isn't found in collection ([ca20985](https://github.com/yoannmoinet/nipplejs/commit/ca20985)) - - - - -## [0.5.6](https://github.com/yoannmoinet/nipplejs/compare/v0.5.5...v0.5.6) (2015-11-09) - - - - -## [0.5.5](https://github.com/yoannmoinet/nipplejs/compare/v0.5.4...v0.5.5) (2015-11-09) - - -### Bug Fixes - -* **manager:** allow multitouch to be more than 1 ([7569536](https://github.com/yoannmoinet/nipplejs/commit/7569536)) -* **manager:** clean the start process, no duplicate ([7e30551](https://github.com/yoannmoinet/nipplejs/commit/7e30551)) -* **manager:** remove handler only if last touch ([1f03064](https://github.com/yoannmoinet/nipplejs/commit/1f03064)) - - - - -## [0.5.4](https://github.com/yoannmoinet/nipplejs/compare/v0.5.3...v0.5.4) (2015-11-08) - - -### Bug Fixes - -* **manager:** better handle identifiers ([54b3cff](https://github.com/yoannmoinet/nipplejs/commit/54b3cff)), closes [#16](https://github.com/yoannmoinet/nipplejs/issues/16) -* **nipple:** use `document.body.contains` for IE11 doesn't shortcut ([6e5b80a](https://github.com/yoannmoinet/nipplejs/commit/6e5b80a)), closes [#17](https://github.com/yoannmoinet/nipplejs/issues/17) - - - - -## [0.5.3](https://github.com/yoannmoinet/nipplejs/compare/v0.5.2...v0.5.3) (2015-10-04) - - -### Bug Fixes - -* **manager:** add back pressure variable... oups ([a46982f](https://github.com/yoannmoinet/nipplejs/commit/a46982f)) - - - - -## [0.5.2](https://github.com/yoannmoinet/nipplejs/compare/v0.5.1...v0.5.2) (2015-10-04) - - -### Bug Fixes - -* **manager:** correctly unbind all events when destroying manager ([e3f96ef](https://github.com/yoannmoinet/nipplejs/commit/e3f96ef)) -* **utils:** handle touch based on their event's type ([406a7b2](https://github.com/yoannmoinet/nipplejs/commit/406a7b2)) - - -### Features - -* **manager:** better pressure management cross-plateform ([d867812](https://github.com/yoannmoinet/nipplejs/commit/d867812)) - - - - -## [0.5.1](https://github.com/yoannmoinet/nipplejs/compare/v0.5.0...v0.5.1) (2015-10-03) - - -### Bug Fixes - -* **nipple:** remove useless backPosition ([4c76adc](https://github.com/yoannmoinet/nipplejs/commit/4c76adc)) -* **super:** better inheritance ([4a3a8dc](https://github.com/yoannmoinet/nipplejs/commit/4a3a8dc)) - - - - -# [0.5.0](https://github.com/yoannmoinet/nipplejs/compare/v0.4.2...v0.5.0) (2015-09-29) - - -### Bug Fixes - -* **manager:** add default pressure at 0 ([1cb31d0](https://github.com/yoannmoinet/nipplejs/commit/1cb31d0)) -* **nipple:** control dom presence before add or remove ([7cc1d8c](https://github.com/yoannmoinet/nipplejs/commit/7cc1d8c)) -* **nipple:** return the manager's known object in event triggers ([2deb42c](https://github.com/yoannmoinet/nipplejs/commit/2deb42c)) -* remove useless rimraf ([26db70f](https://github.com/yoannmoinet/nipplejs/commit/26db70f)) -* **npm:** add rimraf as a dev dependency ([deb7acc](https://github.com/yoannmoinet/nipplejs/commit/deb7acc)), closes [#12](https://github.com/yoannmoinet/nipplejs/issues/12) - - -### Features - -* **manager:** handle resize and reinit positions ([261fb59](https://github.com/yoannmoinet/nipplejs/commit/261fb59)) -* **nipple:** remove position offset ([be59bc4](https://github.com/yoannmoinet/nipplejs/commit/be59bc4)) -* add dataOnly option ([2f527b1](https://github.com/yoannmoinet/nipplejs/commit/2f527b1)) -* add two modes, static and semi ([347feaa](https://github.com/yoannmoinet/nipplejs/commit/347feaa)) -* **manager:** add destroy method ([295654f](https://github.com/yoannmoinet/nipplejs/commit/295654f)) -* **manager:** expose nippleOptions ([968103c](https://github.com/yoannmoinet/nipplejs/commit/968103c)) -* **nipple:** add destroy method ([713e505](https://github.com/yoannmoinet/nipplejs/commit/713e505)) -* **off:** allow unsubscribing on all events at once ([c30bfad](https://github.com/yoannmoinet/nipplejs/commit/c30bfad)) - - - - -## [0.4.2](https://github.com/yoannmoinet/nipplejs/compare/v0.4.1...v0.4.2) (2015-09-15) - - -### Bug Fixes - -* correctly return directions ([871d782](https://github.com/yoannmoinet/nipplejs/commit/871d782)) - - - - -## [0.4.1](https://github.com/yoannmoinet/nipplejs/compare/v0.4.0...v0.4.1) (2015-09-15) - - -### Bug Fixes - -* return the computed direction ([b3d80b3](https://github.com/yoannmoinet/nipplejs/commit/b3d80b3)) - - - - -# [0.4.0](https://github.com/yoannmoinet/nipplejs/compare/v0.3.1...v0.4.0) (2015-09-15) - - -### Bug Fixes - -* **manager:** streamline events triggered ([76941ec](https://github.com/yoannmoinet/nipplejs/commit/76941ec)) - - -### Features - -* **nipple:** add a callback after show and hide ([5b24124](https://github.com/yoannmoinet/nipplejs/commit/5b24124)) -* **nipple:** add the positions to the instance ([fac981b](https://github.com/yoannmoinet/nipplejs/commit/fac981b)) -* **off:** allow unsubscribing of a type at once ([cbbefca](https://github.com/yoannmoinet/nipplejs/commit/cbbefca)) -* **on:** pass the target in the event ([bc0630d](https://github.com/yoannmoinet/nipplejs/commit/bc0630d)) -* add more events for both nipple and manager ([f7966b9](https://github.com/yoannmoinet/nipplejs/commit/f7966b9)) -* add support for both mouse and touch at the same time ([e8fcba2](https://github.com/yoannmoinet/nipplejs/commit/e8fcba2)) -* add support for pressure ([80e7770](https://github.com/yoannmoinet/nipplejs/commit/80e7770)), closes [#10](https://github.com/yoannmoinet/nipplejs/issues/10) -* attach values to each instance of nipple ([c5bf9ab](https://github.com/yoannmoinet/nipplejs/commit/c5bf9ab)) -* limit the number of simultaneous nipples ([801e91d](https://github.com/yoannmoinet/nipplejs/commit/801e91d)) -* support multitouch correctly ([33bbe23](https://github.com/yoannmoinet/nipplejs/commit/33bbe23)), closes [#2](https://github.com/yoannmoinet/nipplejs/issues/2) [#6](https://github.com/yoannmoinet/nipplejs/issues/6) - - - - -## [0.3.1](https://github.com/yoannmoinet/nipplejs/compare/v0.3.0...v0.3.1) (2015-09-07) - - -### Bug Fixes - -* **on:** allows multiple spaces in event string ([b89bd0e](https://github.com/yoannmoinet/nipplejs/commit/b89bd0e)) -* **on:** removes variable name clash. ([3d70a3c](https://github.com/yoannmoinet/nipplejs/commit/3d70a3c)) - - - - -# [0.3.0](https://github.com/yoannmoinet/nipplejs/compare/v0.2.1...v0.3.0) (2015-09-06) - - -### Features - -* offset angle by 180 for units circle ([3002014](https://github.com/yoannmoinet/nipplejs/commit/3002014)) -* support IE PointerEvents ([ed65d1e](https://github.com/yoannmoinet/nipplejs/commit/ed65d1e)), closes [#1](https://github.com/yoannmoinet/nipplejs/issues/1) - - - - -## [0.2.1](https://github.com/yoannmoinet/nipplejs/compare/v0.2.0...v0.2.1) (2015-09-06) - - -### Bug Fixes - -* correct chrome's clientBoundingBox ([b94bc43](https://github.com/yoannmoinet/nipplejs/commit/b94bc43)) - - - - -# [0.2.0](https://github.com/yoannmoinet/nipplejs/compare/v0.1.1...v0.2.0) (2015-09-06) - - -### Bug Fixes - -* **on:** return self to allow chain ([f068cc9](https://github.com/yoannmoinet/nipplejs/commit/f068cc9)) - - -### Features - -* **on:** let listen to multiple events ([d19ad97](https://github.com/yoannmoinet/nipplejs/commit/d19ad97)) -* **on, off:** allow to chain calls ([c82c580](https://github.com/yoannmoinet/nipplejs/commit/c82c580)) -* **trigger:** trigger only if different direction ([9e334ba](https://github.com/yoannmoinet/nipplejs/commit/9e334ba)) - - - - -## [0.1.1](https://github.com/yoannmoinet/nipplejs/compare/v0.1.0...v0.1.1) (2015-09-06) - - -### Bug Fixes - -* add scroll offset ([7b36fb6](https://github.com/yoannmoinet/nipplejs/commit/7b36fb6)) -* remove useless log ([b958cbf](https://github.com/yoannmoinet/nipplejs/commit/b958cbf)) -* send data to start event ([c1f1688](https://github.com/yoannmoinet/nipplejs/commit/c1f1688)) - - - - -# 0.1.0 (2015-09-05) - - - diff --git a/ExoMy_Software-master/gui/node_modules/nipplejs/LICENSE b/ExoMy_Software-master/gui/node_modules/nipplejs/LICENSE deleted file mode 100644 index 6ad8999..0000000 --- a/ExoMy_Software-master/gui/node_modules/nipplejs/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Yoann Moinet - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/ExoMy_Software-master/gui/node_modules/nipplejs/README.md b/ExoMy_Software-master/gui/node_modules/nipplejs/README.md deleted file mode 100644 index 6cdafde..0000000 --- a/ExoMy_Software-master/gui/node_modules/nipplejs/README.md +++ /dev/null @@ -1,631 +0,0 @@ -![alt tag](./assets/nipplejs.png) -> A vanilla virtual joystick for touch capable interfaces - - -[![npm](https://img.shields.io/npm/v/nipplejs.svg)](https://npmjs.org/package/nipplejs) -[![npm](https://img.shields.io/npm/dm/nipplejs.svg)](https://npmjs.org/package/nipplejs) - -# Table Of Contents -
- - - -- [Install](#install) -- [Demo](#demo) -- [Usage](#usage) -- [Options](#options) - * [`options.zone` defaults to 'body'](#optionszone-defaults-to-body) - * [`options.color` defaults to 'white'](#optionscolor-defaults-to-white) - * [`options.size` defaults to 100](#optionssize-defaults-to-100) - * [`options.threshold` defaults to 0.1](#optionsthreshold-defaults-to-01) - * [`options.fadeTime` defaults to 250](#optionsfadetime-defaults-to-250) - * [`options.multitouch` defaults to false](#optionsmultitouch-defaults-to-false) - * [`options.maxNumberOfNipples` defaults to 1](#optionsmaxnumberofnipples-defaults-to-1) - * [`options.dataOnly` defaults to false](#optionsdataonly-defaults-to-false) - * [`options.position` defaults to `{top: 0, left: 0}`](#optionsposition-defaults-to-top-0-left-0) - * [`options.mode` defaults to 'dynamic'.](#optionsmode-defaults-to-dynamic) - + [`'dynamic'`](#dynamic) - + [`'semi'`](#semi) - + [`'static'`](#static) - * [`options.restJoystick` defaults to true](#optionsrestjoystick-defaults-to-true) - * [`options.restOpacity` defaults to 0.5](#optionsrestopacity-defaults-to-05) - * [`options.catchDistance` defaults to 200](#optionscatchdistance-defaults-to-200) -- [API](#api) - * [NippleJS instance (manager)](#nipplejs-instance-manager) - + [`manager.on(type, handler)`](#managerontype-handler) - + [`manager.off([type, handler])`](#managerofftype-handler) - + [`manager.get(identifier)`](#managergetidentifier) - + [`manager.destroy()`](#managerdestroy) - + [`manager.ids`](#managerids) - + [`manager.id`](#managerid) - * [nipple instance (joystick)](#nipple-instance-joystick) - * [`joystick.on`, `joystick.off`](#joystickon-joystickoff) - * [`joystick.el`](#joystickel) - * [`joystick.show([cb])`](#joystickshowcb) - * [`joystick.hide([cb])`](#joystickhidecb) - * [`joystick.add()`](#joystickadd) - * [`joystick.remove()`](#joystickremove) - * [`joystick.destroy()`](#joystickdestroy) - * [`joystick.setPosition(cb, { x, y })`](#joysticksetpositioncb--x-y-) - * [`joystick.identifier`](#joystickidentifier) - * [`joystick.trigger(type [, data])`](#joysticktriggertype--data) - * [`joystick.position`](#joystickposition) - * [`joystick.frontPosition`](#joystickfrontposition) - * [`joystick.ui`](#joystickui) -- [Events](#events) - * [manager only](#manager-only) - + [`added`](#added) - + [`removed`](#removed) - * [manager and joysticks](#manager-and-joysticks) - + [`start`](#start) - + [`end`](#end) - + [`move`](#move) - + [`dir`](#dir) - + [`plain`](#plain) - + [`shown`](#shown) - + [`hidden`](#hidden) - + [`destroyed`](#destroyed) - + [`pressure`](#pressure) -- [Contributing](#contributing) - + [Commits](#commits) - + [Style](#style) - + [Workflow](#workflow) - + [Build](#build) - - -
- -## Install - -```bash -npm install nipplejs --save -``` - ----- - -## Demo -Check out the [demo here](http://yoannmoinet.github.io/nipplejs/#demo). - ----- - -## Usage - -Import it the way you want into your project : - -```javascript -// CommonJS -var manager = require('nipplejs').create(options); -``` - -```javascript -// AMD -define(['nipplejs'], function (nipplejs) { - var manager = nipplejs.create(options); -}); -``` - -```javascript -// Module -import nipplejs from 'nipplejs'; -``` - -```html - - - -``` - -**:warning: NB :warning:** Your joystick's container **has** to have its CSS `position` property set, either `absolute`, `relative`, `static`, .... - ----- - -## Options -You can configure your joystick in different ways : - -```javascript -var options = { - zone: Element, // active zone - color: String, - size: Integer, - threshold: Float, // before triggering a directional event - fadeTime: Integer, // transition time - multitouch: Boolean, - maxNumberOfNipples: Number, // when multitouch, what is too many? - dataOnly: Boolean, // no dom element whatsoever - position: Object, // preset position for 'static' mode - mode: String, // 'dynamic', 'static' or 'semi' - restJoystick: Boolean, - restOpacity: Number, // opacity when not 'dynamic' and rested - lockX: Boolean, // only move on the X axis - lockY: Boolean, // only move on the Y axis - catchDistance: Number, // distance to recycle previous joystick in - // 'semi' mode - dynamicPage: Boolean, // Enable if the page has dynamically visible elements -}; -``` - -All options are optional :sunglasses:. - -### `options.zone` defaults to 'body' -The dom element in which all your joysticks will be injected. - -```html -
- - - -``` - -This zone also serve as the mouse/touch events handler. - -It represents the zone where all your joysticks will be active. - -### `options.color` defaults to 'white' -The background color of your joystick's elements. - -Can be any valid CSS color. - -### `options.size` defaults to 100 -The size in pixel of the outer circle. - -The inner circle is 50% of this size. - -### `options.threshold` defaults to 0.1 -This is the strength needed to trigger a directional event. - -Basically, the center is 0 and the outer is 1. - -You need to at least go to 0.1 to trigger a directional event. - -### `options.fadeTime` defaults to 250 -The time it takes for joystick to fade-out and fade-in when activated or de-activated. - -### `options.multitouch` defaults to false -Enable the multitouch capabilities. - -If, for reasons, you need to have multiple nipples in the same zone. - -Otherwise, it will only get one, and all new touches won't do a thing. - -Please note that multitouch is off when in `static` or `semi` modes. - -### `options.maxNumberOfNipples` defaults to 1 -If you need to, you can also control the maximum number of instances that could be created. - -Obviously in a multitouch configuration. - -### `options.dataOnly` defaults to false -The library won't draw anything in the DOM and will only trigger events with data. - -### `options.position` defaults to `{top: 0, left: 0}` -An object that will determine the position of a `static` mode. - -You can pass any of the four `top`, `right`, `bottom` and `left`. - -They will be applied as any css property. - -Ex : -- `{top: '50px', left: '50px'}` -- `{left: '10%', bottom: '10%'}` - -### `options.mode` defaults to 'dynamic'. -Three modes are possible : - -#### `'dynamic'` -- a new joystick is created at each new touch. -- the joystick gets destroyed when released. -- **can** be multitouch. - -#### `'semi'` -- new joystick is created at each new touch farther than `options.catchDistance` of any previously created joystick. -- the joystick is faded-out when released but not destroyed. -- when touch is made **inside** the `options.catchDistance` a new direction is triggered immediately. -- when touch is made **outside** the `options.catchDistance` the previous joystick is destroyed and a new one is created. -- **cannot** be multitouch. - -#### `'static'` -- a joystick is positioned immediately at `options.position`. -- one joystick per zone. -- each new touch triggers a new direction. -- **cannot** be multitouch. - -### `options.restJoystick` defaults to true -Reset the joystick's position when it enters the rest state. - -### `options.restOpacity` defaults to 0.5 -The opacity to apply when the joystick is in a rest position. - -### `options.catchDistance` defaults to 200 -This is only useful in the `semi` mode, and determine at which distance we recycle the previous joystick. - -At 200 (px), if you press the zone into a rayon of 200px around the previously displayed joystick, -it will act as a `static` one. - -### `options.lockX` defaults to false -Locks joystick's movement to the x (horizontal) axis - -### `options.lockY` defaults to false -Locks joystick's movement to the y (vertical) axis - -### `options.dynamicPage` defaults to true -Enable if the page has dynamically visible elements such as for Vue, React, Angular or simply some CSS hiding or showing some DOM. - ----- - -## API - -### NippleJS instance (manager) - -Your manager has the following signature : - -```javascript -{ - on: Function, // handle internal event - off: Function, // un-handle internal event - get: Function, // get a specific joystick - destroy: Function, // destroy everything - ids: Array // array of assigned ids - id: Number // id of the manager - options: { - zone: Element, // reactive zone - multitouch: Boolean, - maxNumberOfNipples: Number, - mode: String, - position: Object, - catchDistance: Number, - size: Number, - threshold: Number, - color: String, - fadeTime: Number, - dataOnly: Boolean, - restJoystick: Boolean, - restOpacity: Number - } -} -``` - -#### `manager.on(type, handler)` - -If you wish to listen to internal events like : - -```javascript -manager.on('event#1 event#2', function (evt, data) { - // Do something. -}); -``` - -Note that you can listen to multiple events at once by separating -them either with a space or a comma (or both, I don't care). - -#### `manager.off([type, handler])` - -To remove an event handler : - -```javascript -manager.off('event', handler); -``` - -If you call off without arguments, all handlers will be removed. - -If you don't specify the handler but just a type, all handlers for that type will be removed. - -#### `manager.get(identifier)` - -A helper to get an instance via its identifier. - -```javascript -// Will return the nipple instantiated by the touch identified by 0 -manager.get(0); -``` - -#### `manager.destroy()` - -Gently remove all nipples from the DOM and unbind all events. - -```javascript -manager.destroy(); -``` - -#### `manager.ids` - -The array of nipples' ids under this manager. - -#### `manager.id` - -The incremented id of this manager. - -### nipple instance (joystick) - -Each joystick has the following signature : - -```javascript -{ - on: Function, - off: Function, - el: Element, - show: Function, // fade-in - hide: Function, // fade-out - add: Function, // inject into dom - remove: Function, // remove from dom - destroy: Function, - setPosition: Function, - identifier: Number, - trigger: Function, - position: { // position of the center - x: Number, - y: Number - }, - frontPosition: { // position of the front part - x: Number, - y: Number - }, - ui: { - el: Element, - front: Element, - back: Element - }, - options: { - color: String, - size: Number, - threshold: Number, - fadeTime: Number - } -} -``` - -### `joystick.on`, `joystick.off` - -The same as the manager. - -### `joystick.el` - -Dom element in which the joystick gets created. - -```html -
-
-
-
-``` - -### `joystick.show([cb])` - -Will show the joystick at the last known place. - -You can pass a callback that will be executed at the end of the fade-in animation. - -### `joystick.hide([cb])` - -Will fade-out the joystick. - -You can pass a callback that will be executed at the end of the fade-out animation. - -### `joystick.add()` - -Add the joystick's element to the dom. - -### `joystick.remove()` - -Remove the joystick's element from the dom. - -### `joystick.destroy()` - -Gently remove this nipple from the DOM and unbind all related events. - -### `joystick.setPosition(cb, { x, y })` - -Set the joystick to the specified position, where x and y are distances away from the center in pixels. This does not trigger joystick events. - -### `joystick.identifier` - -Returns the unique identifier of the joystick. - -Tied to its touch's identifier. - -### `joystick.trigger(type [, data])` - -Trigger an internal event from the joystick. - -The same as `on` you can trigger multiple events at the same time. - -### `joystick.position` - -The absolute position of the center of the joystick. - -### `joystick.frontPosition` - -The absolute position of the back part of the joystick's ui. - -### `joystick.ui` - -The object that store its ui elements - -```html -{ - el:
- back:
- front:
-} -``` - ----- - -## Events - -You can listen events both on the manager and all the joysticks. - -But some of them are specific to its instance. - -If you need to listen to each joystick, for example, you can : - -```javascript -manager.on('added', function (evt, nipple) { - nipple.on('start move end dir plain', function (evt) { - // DO EVERYTHING - }); -}).on('removed', function (evt, nipple) { - nipple.off('start move end dir plain'); -}); -``` - -### manager only - -#### `added` - -A joystick just got added. - -Will pass the instance alongside the event. - -#### `removed` - -A joystick just got removed. - -Fired at the end of the fade-out animation. - -Will pass the instance alongside the event. - -Won't be trigger in a `dataOnly` configuration. - -### manager and joysticks - -Other events are available on both the manager and joysticks. - -When listening on the manager, -you can also target **a joystick in particular** by prefixing -the event with its identifier, **`0:start`** for example. - -Else you'll get all events from all the joysticks. - -#### `start` - -A joystick is activated. (the user pressed on the active zone) - -Will pass the instance alongside the event. - -#### `end` - -A joystick is de-activated. (the user released the active zone) - -Will pass the instance alongside the event. - -#### `move` - -A joystick is moved. - -Comes with data : - -```javascript -{ - identifier: 0, // the identifier of the touch/mouse that triggered it - position: { // absolute position of the center in pixels - x: 125, - y: 95 - }, - force: 0.2, // strength in % - distance: 25.4, // distance from center in pixels - pressure: 0.1, // the pressure applied by the touch - angle: { - radian: 1.5707963268, // angle in radian - degree: 90 - }, - vector: { // force unit vector - x: 0.508, - y: 3.110602869834277e-17 - }, - raw: { // note: angle is the same, beyond the 50 pixel limit - distance: 25.4, // distance which continues beyond the 50 pixel limit - position: { // position of the finger/mouse in pixels, beyond joystick limits - x: 125, - y: 95 - } - }, - instance: Nipple // the nipple instance that triggered the event -} -``` - -#### `dir` - -When a direction is reached after the threshold. - -Direction are split with a 45° angle. - -```javascript -// \ UP / -// \ / -// LEFT RIGHT -// / \ -// /DOWN \ -``` - -You can also listen to specific direction like : - -- `dir:up` -- `dir:down` -- `dir:right` -- `dir:left` - -In this configuration only one direction is triggered at a time. - -#### `plain` - -When a plain direction is reached after the threshold. - -Plain directions are split with a 90° angle. - -```javascript -// UP | -// ------ LEFT | RIGHT -// DOWN | -``` - -You can also listen to specific plain direction like : - -- `plain:up` -- `plain:down` -- `plain:right` -- `plain:left` - -In this configuration two directions can be triggered at a time, -because the user could be both `up` and `left` for example. - -#### `shown` - -Is triggered at the end of the fade-in animation. - -Will pass the instance alongside the event. - -Won't be trigger in a `dataOnly` configuration. - -#### `hidden` - -Is triggered at the end of the fade-out animation. - -Will pass the instance alongside the event. - -Won't be trigger in a `dataOnly` configuration. - -#### `destroyed` - -Is triggered at the end of destroy. - -Will pass the instance alongside the event. - -#### `pressure` - -> MBP's [**Force Touch**](http://www.apple.com/macbook-pro/features-retina/#interact), iOS's [**3D Touch**](http://www.apple.com/iphone-6s/3d-touch/), Microsoft's [**pressure**](https://msdn.microsoft.com/en-us/library/hh772360%28v=vs.85%29.aspx) or MDN's [**force**](https://developer.mozilla.org/en-US/docs/Web/API/Touch/force) - -Is triggered when the pressure on the joystick is changed. - -The value, between 0 and 1, is sent back alongside the event. - ----- - -## Contributing -You can follow [this document](./CONTRIBUTING.md) to help you get started. diff --git a/ExoMy_Software-master/gui/node_modules/nipplejs/dist/nipplejs.js b/ExoMy_Software-master/gui/node_modules/nipplejs/dist/nipplejs.js deleted file mode 100644 index 3a777ca..0000000 --- a/ExoMy_Software-master/gui/node_modules/nipplejs/dist/nipplejs.js +++ /dev/null @@ -1 +0,0 @@ -!function(t,i){"object"==typeof exports&&"object"==typeof module?module.exports=i():"function"==typeof define&&define.amd?define("nipplejs",[],i):"object"==typeof exports?exports.nipplejs=i():t.nipplejs=i()}(window,function(){return function(t){var i={};function e(o){if(i[o])return i[o].exports;var n=i[o]={i:o,l:!1,exports:{}};return t[o].call(n.exports,n,n.exports,e),n.l=!0,n.exports}return e.m=t,e.c=i,e.d=function(t,i,o){e.o(t,i)||Object.defineProperty(t,i,{enumerable:!0,get:o})},e.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},e.t=function(t,i){if(1&i&&(t=e(t)),8&i)return t;if(4&i&&"object"==typeof t&&t&&t.__esModule)return t;var o=Object.create(null);if(e.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:t}),2&i&&"string"!=typeof t)for(var n in t)e.d(o,n,function(i){return t[i]}.bind(null,n));return o},e.n=function(t){var i=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(i,"a",i),i},e.o=function(t,i){return Object.prototype.hasOwnProperty.call(t,i)},e.p="",e(e.s=0)}([function(t,i,e){"use strict";e.r(i);var o,n=function(t,i){var e=i.x-t.x,o=i.y-t.y;return Math.sqrt(e*e+o*o)},s=function(t){return t*(Math.PI/180)},r=function(t){return t*(180/Math.PI)},d=function(t,i,e){for(var o,n=i.split(/[ ,]+/g),s=0;s=0&&this._handlers_[t].splice(this._handlers_[t].indexOf(i),1),this},O.prototype.trigger=function(t,i){var e,o=this,n=t.split(/[ ,]+/g);o._handlers_=o._handlers_||{};for(var s=0;ss&&n<3*s&&!t.lockX?i="up":n>-s&&n<=s&&!t.lockY?i="left":n>3*-s&&n<=-s&&!t.lockX?i="down":t.lockY||(i="right"),t.lockY||(e=n>-r&&n0?"up":"down"),t.force>this.options.threshold){var d,a={};for(d in this.direction)this.direction.hasOwnProperty(d)&&(a[d]=this.direction[d]);var p={};for(d in this.direction={x:e,y:o,angle:i},t.direction=this.direction,a)a[d]===this.direction[d]&&(p[d]=!0);if(p.x&&p.y&&p.angle)return t;p.x&&p.y||this.trigger("plain",t),p.x||this.trigger("plain:"+e,t),p.y||this.trigger("plain:"+o,t),p.angle||this.trigger("dir dir:"+i,t)}else this.resetDirection();return t};var T=w;function k(t,i){return this.nipples=[],this.idles=[],this.actives=[],this.ids=[],this.pressureIntervals={},this.manager=t,this.id=k.id,k.id+=1,this.defaults={zone:document.body,multitouch:!1,maxNumberOfNipples:10,mode:"dynamic",position:{top:0,left:0},catchDistance:200,size:100,threshold:.1,color:"white",fadeTime:250,dataOnly:!1,restJoystick:!0,restOpacity:.5,lockX:!1,lockY:!1,dynamicPage:!1},this.config(i),"static"!==this.options.mode&&"semi"!==this.options.mode||(this.options.multitouch=!1),this.options.multitouch||(this.options.maxNumberOfNipples=1),this.updateBox(),this.prepareNipples(),this.bindings(),this.begin(),this.nipples}k.prototype=new _,k.constructor=k,k.id=0,k.prototype.prepareNipples=function(){var t=this.nipples;t.on=this.on.bind(this),t.off=this.off.bind(this),t.options=this.options,t.destroy=this.destroy.bind(this),t.ids=this.ids,t.id=this.id,t.processOnMove=this.processOnMove.bind(this),t.processOnEnd=this.processOnEnd.bind(this),t.get=function(i){if(void 0===i)return t[0];for(var e=0,o=t.length;e