Zum Hauptinhalt springen

09. WebSocket-Arbeitsbereichsnavigator

über einen WebSocket-Kanal set_transform Durch das Streamen von Befehlen kann das GerätIn Echtzeit durch den Arbeitsbereich navigierenDas ist möglich. In diesem Tutorial werden Sitzungen und Geräte mithilfe von HTTP erkannt (Tutorial 08 (Das funktioniert genau auf dieselbe Weise). Anschließend wird ein WebSocket geöffnet, über den bei jedem Tick Positionsaktualisierungen gesendet werden.

Hier werden die Unterschiede zwischen zwei Umwandlungsvorgängen dargestellt:

BedienungTutorialTypische Anwendungsbereiche
configure.mount — Permanente Mount-Konvertierung08Wird nur einmal (oder in seltenen Fällen) festgelegt und beschreibt die physische Montage des Geräts
set_transform — Dauerhafte Umgestaltung des Arbeitsbereichs09(dieses Tutorial)Auch dies ist dauerhaft, kann jedoch für die Echtzeit-Navigation im Arbeitsbereich bei jedem Tick gestreamt werden

Beide Befehle HTTP und WebSocket ist über … verfügbar, und beidedauerhaft. Der Dienst speichert den zuletzt übermittelten Wert. Der Unterschied liegt im Zweck und in der Aktualisierungshäufigkeit.configure.mount während es für seltene Aktualisierungen (physische Konfiguration) optimiert ist,set_transform ist für häufiges Streaming (Navigation durch Szenen) optimiert.

Wenn Objekte, deren Ursprung sich zur Laufzeit ändert (z. B. Nachführung der Hand, prozedurale Offset-Animationen, Live-Feinanpassungen des virtuellen Arbeitsbereichs durch den Bediener usw.), im Arbeitsbereich verfolgt werden müssen, dannset_transform Bitte verwenden Sie dies.

Mounts und Arbeitsbereiche stehen in einer Eltern-Kind-Beziehung zueinander.

Im Einzelnen betrachtet,configure.mount und set_transform Es scheint, als hätten beide denselben Effekt, doch die beiden sindstehen in einer Eltern-Kind-Beziehung。Koordinaten-Pipeline (device → basis → mount → workspace → application) wird die Arbeitsbereichskonvertierung bei der Einbindung dernach obenDies gilt. Für die gesamte Pipeline gilt:Halterung und ArbeitsbereichSiehe dazu.

Anwendungsfall​

  • Navigation im Arbeitsbereich während des Live-Betriebs. Der Cursor-Arbeitsbereich des Geräts (der Bereich, den der Endeffektor erreichen kann) wird verschoben, ohne die haptische Szene anzuhalten.
  • Ausrichtung durch den Bediener. Während der Ausführung der Hauptanwendung für haptisches Feedback kann eine Person an einem zweiten Terminal durch Gedrückthalten der Pfeiltasten den Arbeitsbereich verschieben. Dies ist nützlich, wenn während einer Live-Sitzung eine benutzerspezifische Kalibrierung des Schreibtisches durchgeführt werden soll.
  • Prozedurale Arbeitsbereichsfunktionen. Durch das Senden von Transformations-Patches, die bei jedem Tick ausschließlich die Position angeben, wird die Position im Arbeitsbereich über Skripte (z. B. sprachgesteuerte oder physikalisch gesteuerte) gesteuert.

Voraussetzungen​

Für Tutorial 09 isteine aktive WebSocket-Sitzungerforderlich. Das heißt, es muss ein Client vorhanden sein, der im laufenden Haptic Loop bereits eine Verbindung zu Inverse3 unterhält. Tutorial 09 verbindet sich mit dieser Sitzung und verschiebt den Arbeitsbereich in Echtzeit.

So starten Sie eine Sitzung am schnellsten

Haply Öffnen Sie Hub und starten Sie dieOrb-Demo. Es wird eine dauerhafte haptische Sitzung eröffnet, die Sie sofort nutzen 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 zeichnet eine Kugel am Ursprung des Arbeitsbereichs. Wenn Sie den Arbeitsbereich in Tutorial 09 verschieben, bewegt sich die gesamte Szene in Echtzeit mit, sodass Sie sofort visuelles Feedback erhalten.

Die anderen Tutorials zur Ausführung der taktilen Schleife (01 – 07) funktionieren auf die gleiche Weise. Starten Sie eines davon in einem Terminal und das Tutorial 09 in einem anderen Terminal, damit die Sitzung interaktiv erkannt wird.

Gebrauchsanweisung​

# 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

Bedienungsanleitung​

Wenn Sie die Taste gedrückt halten, bewegen Sie sich kontinuierlich weiter. Wenn Sie die Taste loslassen, bleiben Sie stehen.

SchlüsselBedienung
→ / ←+X / −X
↑ / ↓+Y / −Y
Page Up / Page Down+Z / −Z
= / -Navigationsgeschwindigkeit erhöhen / verringern
0Arbeitsbereich auf den Ausgangszustand zurücksetzen
HHilfe anzeigen
EscEnde (Ctrl+C (Sie können es aber auch beenden.)

Funktionsweise​

Schritt 1 – Erkennung von HTTP-Sitzungen und Geräten​

Dieses Tutorial behandelt,Tutorial 08 genauso wie discover_session() / discover_device() Wir verwenden den Helper erneut. Zunächst GET /sessions(--session Wenn Sie … angeben möchten, GET /sessions/<selector>) und anschließend GET /devices(oder --device (direkt verwendet) auf. Beide Helper verwenden dieselben CLI-Flags und dieselben SESSION_HELP Um Text einzugeben, können Sie den Selektor aus Tutorial 00 oder 08 auch hier unverändert verwenden.

Schritt 2 – Handshake für die WebSocket-Sitzung und die erste Nachricht​

In diesem Tutorial wird erläutert,ws://localhost:10001 Eröffnet eine WebSocket-Verbindung zu.Nur die zuerst empfangene NachrichtAls Anlass dafür wird die Registrierung des Sitzungsprofils gesendet:

{
"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}}}}}]
}

In den folgenden Ticks session wegzulassen undinverse3 Es werden ausschließlich Befehlssequenzen gesendet.

Schritt 3 – Pro Tick set_transform​

set_transform はTeilweise Umwandlungwerden akzeptiert. Das heißt, Sie können nur die Felder angeben, die Sie ändern möchten. In diesem Tutorial wird nur die Position übermittelt, während Drehung und Skalierung auf den Standardwerten der Sitzung belassen werden (configure.mount (falls ein Wert festgelegt wurde, dann dieser Wert).

{
"inverse3": [{"device_id": "...", "commands": {"set_transform": {"transform": {"position": {"x": 0.02, "y": 0.0, "z": 0.01}}}}}]
}

Die Position wird bei jedem Tick kumuliert. Bei einer Frequenz von etwa 1 kHz führt der Dienst bei jedem Tick set_transform wird erneut angewendet (Hold der Ordnung Null). Daher verbleibt der Arbeitsbereich an der zuletzt übermittelten Position.

set_transform und configure.mount Vergleich

Beide Befehle speichern dauerhafte Konvertierungen pro Sitzung. Allerdings werden Workspace-Konvertierungen in der Pipeline bei der Einbindungnach obenbefindet sich (Halterung und Arbeitsbereich(siehe dort). In Tutorial 09 wird bei jedem Tick set_transform Während des Streamings wird bei jedem Empfang eines neuen WebSocket-Frames die zuletzt gestreamte Workspace-Transformation überschrieben. Daher wird auf demselben Gerät set_transform Andere Clients, die dies streamen, werden beim nächsten Tick überschrieben.configure.mount ist unabhängig und behält seinen Wert bei. Wählen Sie in der Praxis bitte für jeden Anwendungsbereich einen Kanal aus: für die physische Einrichtung den Kanal „Mount“ und für die Live-Navigation den Kanal set_transform wird verwendet.

Thread-Modell (C++)​

Im C++-Tutorial werden zwei Threads verwendet, die sich einen Positionszähler teilen:

ThreadRolle
Hauptthreadstd::getline(std::cin, ...) auslesen, das Token analysieren undnav_vel[] und default_step aktualisieren
WebSocket-Callback-Threadnav_vel[] * dt mit nav_pos[] fortfahren und,set_transform serialisieren und senden

std::mutex nav_mutex は nav_pos[]、nav_vel[]、default_step schützt.last_tick der Zeitstempel und first_ws_msg Das Flag ist ein lokaler Wert für den WS-Callback, sodass kein Mutex erforderlich ist.

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​

Im SDK-Installationsprogramm enthalten

Tutorial 09 ist zusammen mit dem SDK lokal installiert. Im Installationsverzeichnis des Dienstes befindet sich tutorials/09-haply-inverse-ws-remote-control/ Bitte überprüfen Sie dies.

Siehe auch: set_transform Befehl · Sitzung – Handshake anhand der ersten Nachricht · Halterung und Arbeitsbereich · Selektor · Tutorial 08 – HTTP-Fernkonfiguration · Tutorial 07 – Sockel und Halterung