09. WebSocket-Arbeitsbereichsnavigator
Durch das Menü eines Geräts navigieren Arbeitsbereichsposition in Echtzeit per Streaming set_transform Befehle über den WebSocket-Kanal. Das Tutorial nutzt HTTP, um die Sitzung und das Gerät zu ermitteln (genau wie Anleitung 08), öffnet dann einen WebSocket, um bei jedem Tick Positionsaktualisierungen zu übermitteln.
Dies veranschaulicht den Unterschied zwischen zwei Transformationsoperationen:
| Betrieb | Tutorial | Typische Verwendung |
|---|---|---|
configure.mount — Persistente Mount-Transformation | 08 | Einmalig (oder selten) festlegen, um die physische Montage des Geräts zu beschreiben |
set_transform — dauerhafte Arbeitsbereichstransformation | 09 (dieses) | Ebenfalls persistent, kann jedoch bei jedem Tick gestreamt werden, um eine Echtzeit-Navigation im Arbeitsbereich zu ermöglichen |
Beide Befehle sind verfügbar über HTTP und WebSocket, und beide sind anhaltend — Der Dienst speichert den zuletzt von Ihnen gesendeten Wert. Der Unterschied liegt im Zweck und in der Aktualisierungsrate: configure.mount ist für seltene Aktualisierungen (physische Einrichtung) optimiert, während set_transform ist für Hochfrequenz-Streaming (Szenennavigation) optimiert.
Verwendung set_transform wenn der Ursprung des Arbeitsbereichs etwas verfolgen muss, das sich zur Laufzeit ändert – etwa eine Hand, die Animation eines prozeduralen Versatzes oder die Möglichkeit für einen Bediener, den virtuellen Arbeitsbereich in Echtzeit zu verschieben.
Einzeln, configure.mount und set_transform scheinen denselben Effekt zu haben, aber sie sind erzogen: Die Arbeitsbereichstransformation wird angewendet zusätzlich die Mount-Datei in der Koordinaten-Pipeline (device → basis → mount → workspace → application). Siehe Halterung & Arbeitsbereich für die gesamte Pipeline.
Anwendungsfälle
- Navigation im Live-Arbeitsbereich. Verschieben Sie den Cursor-Arbeitsbereich des Geräts (den Bereich, den der Endeffektor erreichen kann), ohne die haptische Szene anzuhalten.
- Bedienergeführte Ausrichtung. Ein Benutzer an einem zweiten Terminal kann die Pfeiltasten gedrückt halten, um den Arbeitsbereich zu verschieben, während die haptische Hauptanwendung läuft – nützlich für die benutzerspezifische Kalibrierung des Schreibtisches während einer Live-Sitzung.
- Prozedurale Bewegung des Arbeitsbereichs. Steuern Sie die Position des Arbeitsbereichs über ein Skript (audio-reaktiv, physikgesteuert usw.), indem Sie bei jedem Tick reine Positions-Transformations-Patches senden.
Voraussetzungen
Für Tutorial 09 ist eine aktive WebSocket-Sitzung erforderlich – ein Client, auf dem bereits Inverse3 einer laufenden haptischen Schleife ausgeführt wird. Tutorial 09 verbindet sich dann mit dieser Sitzung und verschiebt seinen Arbeitsbereich in Echtzeit.
Öffnen Sie Haply und starten Sie die Orb-Demo. Es wird eine dauerhafte haptische Sitzung geöffnet, auf die Sie sofort zugreifen können:
./09-haply-inverse-ws-remote-control --session co.haply.hub::demo-orb
python 09-haply-inverse-ws-remote-control.py --session "co.haply.hub::demo-orb"
Die Orb-Szene rendert eine Kugel am Ursprung des Arbeitsbereichs – wenn Sie den Arbeitsbereich mit Tutorial 09 verschieben, wird die gesamte Szene in Echtzeit mitverschoben, sodass Sie sofort visuelles Feedback erhalten.
Jedes andere Tutorial (01 – 07), das eine haptische Schleife ausführt, funktioniert ebenfalls. Starten Sie es in einem Terminal, starten Sie dann Tutorial 09 in einem zweiten Terminal und lassen Sie es die Sitzung interaktiv erkennen.
Verwendung
# Discover session interactively, use first detected device
./09-haply-inverse-ws-remote-control
python 09-haply-inverse-ws-remote-control.py
# Target the Haply Hub Orb demo directly
./09-haply-inverse-ws-remote-control --session co.haply.hub::demo-orb
python 09-haply-inverse-ws-remote-control.py --session "co.haply.hub::demo-orb"
# Target a session directly, specify device
./09-haply-inverse-ws-remote-control --session :my_profile:0 --device A14
python 09-haply-inverse-ws-remote-control.py --session "#42" --device A14
Bedienelemente
- Python
- C++
Halte eine Taste gedrückt, um dich kontinuierlich zu bewegen. Lass die Taste los, um anzuhalten.
| Schlüssel | Aktion |
|---|---|
→ / ← | +X / −X |
↑ / ↓ | +Y / −Y |
Page Up / Page Down | +Z / −Z |
= / - | Navigationsgeschwindigkeit erhöhen / verringern |
0 | Arbeitsbereich auf den Ursprung zurücksetzen |
H | Hilfe anzeigen |
Esc | Beenden (Ctrl+C (funktioniert auch) |
Zeilenbasiert – Geben Sie den Text ein und drücken Sie die Eingabetaste.
| Befehl | Aktion |
|---|---|
x+[N] / x-[N] | Stelle die X-Geschwindigkeit auf ±N mm/Bild ein (ohne x+ (verwendet die aktuelle Standardgeschwindigkeit) |
y+[N] / y-[N] | Geschwindigkeit Y auf ±N mm/Bild einstellen |
z+[N] / z-[N] | Geschwindigkeit Z auf ±N mm/Bild einstellen |
s+[N] / s-[N] | Standardgeschwindigkeit um ±N mm/Bild anpassen |
stop | Geschwindigkeit auf Null setzen |
reset | Nullgeschwindigkeit und Rückkehr zum Ausgangspunkt |
h | Hilfe anzeigen |
Drücke Strg+C (oder Strg+D / EOF), um das Programm zu beenden.
So funktioniert es
Schritt 1 – HTTP-Sitzung und Geräteerkennung
Das Tutorial verwendet dieselbe discover_session() / discover_device() Helfer als Anleitung 08: GET /sessions (oder GET /sessions/<selector> mit --session), dann GET /devices (oder verwende --device (direkt). Beide Hilfsprogramme akzeptieren dieselben CLI-Flags mit identischen SESSION_HELP Text – Ein Selektor aus Tutorial 00 oder 08 funktioniert hier unverändert.
Schritt 2 – WebSocket-Sitzung, Handshake bei der ersten Nachricht
Das Tutorial öffnet einen WebSocket zu ws://localhost:10001. Auf der nur die erste empfangene Nachricht, sendet es die Registrierung des Sitzungsprofils:
{
"session": {"configure": {"profile": {"name": "co.haply.inverse.tutorials:ws-remote-control"}}},
"inverse3": [{"device_id": "...", "commands": {"set_transform": {"transform": {"position": {"x": 0, "y": 0, "z": 0}}}}}]
}
Folgende Ticks werden übersprungen session — nur die inverse3 Das Befehlsarray wird gesendet.
Schritt 3 – Pro Tick set_transform
set_transform akzeptiert ein Teiltransformation — nur die Felder, die Sie ändern möchten. In diesem Tutorial wird nur die Position übermittelt; Rotation und Skalierung bleiben auf ihren Sitzungsstandardwerten (den Werten, die durch configure.mount(falls vorhanden).
{
"inverse3": [{"device_id": "...", "commands": {"set_transform": {"transform": {"position": {"x": 0.02, "y": 0.0, "z": 0.01}}}}}]
}
Die Position wird Tick für Tick berechnet. Bei ~1 kHz wird der Dienst neu angewendet set_transform bei jedem Tick (Zero-Order-Hold), sodass der Arbeitsbereich an der Stelle bleibt, an die Sie ihn zuletzt verschoben haben.
set_transform vs configure.mountBeide Befehle speichern eine dauerhafte Transformation pro Sitzung, aber die Arbeitsbereichstransformation befindet sich zusätzlich das Mount in der Pipeline (siehe Halterung & Arbeitsbereich). Während Tutorial 09 gestreamt wird set_transform Bei jedem Tick ersetzt jeder neue WebSocket-Frame die zuvor gestreamte Arbeitsbereichstransformation – daher wird jeder andere Client, der streamt, set_transform auf dasselbe Gerät werden beim nächsten Takt überschrieben. configure.mount ist unabhängig und behält seinen Wert. Wählen Sie in der Praxis einen Kanal pro Bereich: mount für die physische Konfiguration, set_transform für die Live-Navigation.
Threading-Modell (C++)
Das C++-Tutorial verwendet zwei Threads, die sich einen Positionszähler teilen:
| Thema | Rolle |
|---|---|
| Hauptthema | Lesen std::getline(std::cin, ...), analysiert Token, aktualisiert nav_vel[] und default_step |
| WebSocket-Callback-Thread | Fortschritte nav_pos[] mit nav_vel[] * dt, serialisiert set_transform, sendet |
std::mutex nav_mutex schützt nav_pos[], nav_vel[]und default_step. Die last_tick Zeitstempel und first_ws_msg Diese Flags sind lokal für den WS-Callback und benötigen keinen Mutex.
ws.onmessage = [&](const std::string &) {
float pos_snap[3];
{
std::lock_guard<std::mutex> lk(nav_mutex);
for (int i = 0; i < 3; ++i) nav_pos[i] += nav_vel[i] * 0.001f; // mm/frame → m
for (int i = 0; i < 3; ++i) pos_snap[i] = nav_pos[i];
}
// build and send set_transform with pos_snap
};
Quelle
Tutorial 09 wird lokal mit dem SDK installiert – schau mal unter tutorials/09-haply-inverse-ws-remote-control/ im Installationsverzeichnis des Dienstes.
Siehe auch: set_transform Befehl · Sitzungen – Handshake bei der ersten Nachricht · Halterung & Arbeitsbereich · Auswahlkriterien · Tutorial 08 – HTTP-Remote-Konfiguration · Anleitung 07 – Basis & Halterung