09. WebSocket-Arbeitsbereichs-Navigator
Navigieren Sie durch die Arbeitsbereichsposition eines Geräts in Echtzeit, indem Sie set_transform-Befehle über den WebSocket-Kanal streamen. Das Tutorial nutzt HTTP, um die Sitzung und das Gerät zu ermitteln (genau wie Anleitung 08), und öffnet anschließend eine WebSocket-Verbindung, um bei jedem Tick Positionsaktualisierungen zu senden.
Dies veranschaulicht den Unterschied zwischen zwei Transformationsoperationen:
| Betrieb | Tutorial | Typische Verwendung |
|---|---|---|
configure.mount — persistente Mount-Transformation | 08 | Einmal (oder selten) verwenden, um den physischen Einbau des Geräts zu beschreiben |
set_transform — Persistente Arbeitsbereichstransformation | 09 (dieses) | Ebenfalls persistent, kann jedoch bei jedem Tick für die Echtzeit-Navigation im Arbeitsbereich gestreamt werden |
Beide Befehle sind über HTTP und WebSocket verfügbar, und beide sind anhaltend — Der Dienst speichert den zuletzt gesendeten Wert. Der Unterschied liegt im Zweck und in der Aktualisierungsrate: configure.mount ist für seltene Aktualisierungen optimiert (physische Einrichtung), während set_transform für hochfrequentes Streaming (Szenennavigation) optimiert ist.
Verwenden Sie set_transform, wenn der Ursprung des Arbeitsbereichs einer Größe folgen soll, die sich zur Laufzeit ändert, etwa einer Hand, einem animierten prozeduralen Versatz oder einer Bedienperson, die den virtuellen Arbeitsbereich live verschiebt.
Für sich genommen scheinen configure.mount und set_transform denselben Effekt zu erzielen, sie sind jedoch hierarchisch verknüpft: Die Workspace-Transformation wird in der Koordinaten-Pipeline auf den Mount angewendet (device → basis → mount → workspace → application). Die vollständige Pipeline finden Sie unter Halterung & Arbeitsbereich.
Anwendungsfälle
- Live-Navigation im Arbeitsbereich. Verschieben Sie den Cursor-Arbeitsbereich des Geräts (den Bereich, den der Endeffektor erreichen kann), ohne die haptische Szene anzuhalten.
- Vom Benutzer gesteuerte Ausrichtung. Lassen Sie eine Person an einem zweiten Terminal die Pfeiltasten gedrückt halten, um den Arbeitsbereich zu verschieben, während die haptische Hauptanwendung läuft – nützlich für die Kalibrierung am jeweiligen Arbeitsplatz während einer laufenden Sitzung.
- Prozedurale Workspace-Bewegung. Steuern Sie die Position des Workspace aus einem Skript heraus (audiogesteuert, physikbasiert usw.), indem Sie bei jedem Tick reine Positions-Transform-Patches senden.
Voraussetzungen
Für Tutorial 09 ist eine aktive WebSocket-Sitzung erforderlich, d. h. ein Client, dessen „ Inverse3 “ bereits in einer laufenden haptischen Schleife aktiv ist. Tutorial 09 schließt sich dann dieser Sitzung an und verschiebt deren Arbeitsbereich in Echtzeit.
Öffnen Sie den „Haply -Hub“ und starten Sie die Orb-Demo. Es wird eine dauerhafte haptische Sitzung geöffnet, mit der Sie sofort interagieren 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, verschiebt sich die gesamte Szene in Echtzeit, 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 und starten Sie anschließend Tutorial 09 in einem zweiten Terminal, damit es die Sitzung interaktiv erkennt.
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
Steuerung
- Python
- C++
Halten Sie eine Taste gedrückt, um sich kontinuierlich zu bewegen. Lassen Sie die Taste los, um anzuhalten.
| Geschmack | 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 (das funktioniert ebenfalls) |
Zeilenbasiert – Geben Sie den Befehl ein und drücken Sie anschließend die ENTER-Taste.
| Befehl | Aktion |
|---|---|
x+[N] / x-[N] | X-Geschwindigkeit auf ±N mm/Frame einstellen (ohne Zahlenangabe verwendet) x+ (die derzeitige Standardgeschwindigkeit) |
y+[N] / y-[N] | Y-Geschwindigkeit auf ±N mm/Frame einstellen |
z+[N] / z-[N] | Z-Geschwindigkeit auf ±N mm/Frame einstellen |
s+[N] / s-[N] | Standardgeschwindigkeit um ±N mm/Frame anpassen |
stop | Alle Geschwindigkeiten auf Null setzen |
reset | Geschwindigkeit auf Null setzen und zum Ursprung zurückkehren |
h | Hilfe anzeigen |
Drücken Sie Strg+C (oder Strg+D / EOF), um das Programm zu beenden.
Funktionsweise
Schritt 1 – HTTP-Sitzungs- und Geräterkennung
Das Tutorial verwendet dieselben Hilfsfunktionen discover_session() / discover_device() wie Anleitung 08: GET /sessions (oder GET /sessions/<selector> mit --session), danach GET /devices (oder direkt --device verwenden). Beide Hilfsfunktionen akzeptieren dieselben CLI-Flags mit identischem 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 stellt eine WebSocket-Verbindung zu ws://localhost:10001. Nur bei der erste eingegangene 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}}}}}]
}
Nachfolgende Ticks lassen session weg — Es wird nur das Befehls-Array gesendet inverse3.
Schritt 3 — set_transform pro Tick
set_transform akzeptiert eine partielle Transformation, und zwar nur die Felder, die Sie ändern möchten. Dieses Tutorial übermittelt ausschließlich die Position; Rotation und Skalierung bleiben auf den Standardwerten der Sitzung (den Werten, die gegebenenfalls durch configure.mount festgelegt wurden).
{
"inverse3": [{"device_id": "...", "commands": {"set_transform": {"transform": {"position": {"x": 0.02, "y": 0.0, "z": 0.01}}}}}]
}
Die Position summiert sich Tick für Tick. Mit etwa 1 kHz wechselt der Dienst set_transform bei jedem Tick erneut aktiviert (Zero-Order-Hold), sodass der Arbeitsbereich dort bleibt, wohin Sie ihn zuletzt verschoben haben.
set_transform vs configure.mountBeide Befehle speichern pro Sitzung eine persistente Transformation. Die Workspace-Transformation befindet sich in der Pipeline jedoch auf dem Berg (siehe Halterung & Arbeitsbereich). Solange-Tutorial 09 bei jedem Tick set_transform Im Streaming-Modus ersetzt jeder neue WebSocket-Frame die zuvor gestreamte Workspace-Transformation. Ein anderer Client, der set_transform die auf dasselbe Gerät gestreamt werden, werden daher beim nächsten Tick überschrieben. configure.mount ist davon unabhängig und behält seinen Wert. In der Praxis sollten Sie pro Anliegen einen Kanal wählen: „Mount“ für die physische Einrichtung, set_transform für die Live-Navigation.
Threading-Modell (C++)
Das C++-Tutorial verwendet zwei Threads, die sich einen Positionsakkumulator teilen:
| Thema | Rolle |
|---|---|
| Haupt-Thread | Liest std::getline(std::cin, ...), Tokens analysiert, aktualisiert nav_vel[] und default_step |
| WebSocket-Callback-Thread | Schreibt nav_pos[] ähm nav_vel[] * dt fort, als Fortsetzungsroman set_transform und sendet |
std::mutex nav_mutex schützt nav_pos[], nav_vel[] und default_step. Der Zeitstempel last_tick und die Flagge first_ws_msg befinden sich lokal im 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 – Sie finden es unter tutorials/09-haply-inverse-ws-remote-control/ im Installationsverzeichnis des Dienstes.
Verwandte Themen: Befehl set_transform · Sitzungen – Handshake mit der ersten Nachricht · Halterung & Arbeitsbereich · Selektoren · Tutorial 08 – HTTP-Fernkonfiguration · Anleitung 07 – Basis & Halterung