09. WebSocket-Arbeitsbereich-Navigator
set_transform Durch das Streamen von Befehlen über einen WebSocket-Kanal werden die Den Standort des Arbeitsbereichs in Echtzeit Durchsuchen. In diesem Tutorial werden Sitzungen und Geräte auf HTTP-Basis durchsucht (Tutorial 08(genau auf dieselbe Weise), und eröffnet anschließend eine WebSocket-Verbindung, um bei jedem Tick Positionsaktualisierungen zu übertragen.
Diese Tabelle veranschaulicht den Unterschied zwischen zwei Umrechnungsvorgängen:
| Rechenoperation | Tutorial | Allgemeine Verwendungszwecke |
|---|---|---|
configure.mount — Umwandlung in eine permanente Verknüpfung | 08 | Einmalige (oder seltene) Einrichtung zur Erläuterung der physischen Montage des Geräts |
set_transform — Umwandlung in einen permanenten Arbeitsbereich | 09 (dieses Tutorial) | Es ist zwar ebenfalls dauerhaft, kann aber zur Echtzeit-Erkundung des Arbeitsbereichs bei jedem Tick gestreamt werden. |
Beide Befehle HTTP und WebSocket kann in dieser Umgebung verwendet werden, und beide dauerhaft. Der Dienst speichert den zuletzt gesendeten Wert. Der Unterschied zwischen den beiden Befehlen liegt im Zweck und in der Häufigkeit der Aktualisierung. configure.mountist zwar auf seltene Aktualisierungen (physikalische Einstellungen) optimiert, während set_transformist für hochfrequentes Streaming (Szenensprung) optimiert.
Wenn Objekte verfolgt werden müssen, deren Arbeitsbereichs-Ursprung sich zur Laufzeit ändert set_transformVerwenden Sie diese Funktion. Sie wird beispielsweise verwendet, um Handbewegungen nachzuverfolgen, prozedurale Versätze als Animation umzusetzen oder dem Bediener die Möglichkeit zu geben, den virtuellen Arbeitsbereich in Echtzeit fein abzustimmen.
Einzeln betrachtet configure.mountWow set_transformscheint zwar denselben Effekt zu haben, doch die beiden Werte sind Eltern-Kind-BeziehungDas ist die Koordinaten-Pipeline (device → basis → mount → workspace → application) erfolgt die Workspace-Konvertierung über das Einbinden oben gilt. Die gesamte Pipeline ist Mounts und ArbeitsbereicheSiehe dazu.
Anwendungsbeispiele
- Navigation im Arbeitsbereich in Echtzeit. Verschieben Sie den Cursor-Arbeitsbereich des Geräts (den Bereich, den der Endeffektor erreichen kann), ohne die haptische Szene anzuhalten.
- Benutzergesteuerte Ausrichtung. Während die Haupt-Haptic-App ausgeführt wird, kann ein anderer Benutzer auf einem zweiten Terminal mithilfe der Pfeiltasten den Arbeitsbereich verschieben. Dies ist nützlich für die benutzerspezifische Kalibrierung des Arbeitsbereichs während einer Live-Sitzung.
- Prozedurale Bewegung des Arbeitsbereichs. Bei jedem Takt wird ein reiner Positions-Transformations-Patch gesendet, um die Position des Arbeitsbereichs über Skripte (z. B. audioabhängige oder physikbasierte) zu steuern.
Voraussetzungen
Für Tutorial 09 ist eine aktive WebSocket-Sitzungerforderlich. Das bedeutet, dass es sich um einen Client handeln muss, der Inverse3 in einer bereits laufenden Haptic-Schleife verwendet. In Tutorial 09 wird eine Verbindung zu dieser Sitzung hergestellt und der Arbeitsbereich in Echtzeit verschoben.
Haply Öffnen Sieden Hubund starten Sie die Orb-Demo. Daraufhin wird eine permanente haptische Sitzung geöffnet, die Sie sofort als Ziel festlegen 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"
In der „Orb“-Szene wird eine Kugel am Ursprung des Arbeitsbereichs gerendert. Wenn Sie den Arbeitsbereich gemäß Tutorial 09 verschieben, bewegt sich die gesamte Szene in Echtzeit mit und liefert so sofortiges visuelles Feedback.
Auch die anderen Tutorials zur Ausführung von Haptic Loop (01 – 07) funktionieren alle. Starten Sie diese Tutorials in einem Terminal und führen Sie anschließend in einem zweiten Terminal Tutorial 09 aus, um die Sitzung interaktiv zu erkunden.
Anleitung
# 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
- Python
- C++
Wenn Sie die Taste gedrückt halten, bewegen Sie sich kontinuierlich weiter. Sobald Sie die Taste loslassen, bleiben Sie stehen.
| Schlüssel | Bewegung |
|---|---|
→ / ← | +X / −X |
↑ / ↓ | +Y / −Y |
Page Up / Page Down | +Z / −Z |
= / - | Navigationsgeschwindigkeit erhöhen / verringern |
0 | Arbeitsbereich auf den Ausgangszustand zurücksetzen |
H | Hilfe anzeigen |
Esc | Ende (Ctrl+C(auch in Betrieb) |
Die Eingabe erfolgt zeilenweise. Geben Sie den Befehl ein und drücken Sie anschließend die ENTER-Taste.
| Befehl | Bewegung |
|---|---|
x+[N] / x-[N] | Geschwindigkeit X auf ±N mm/Frame einstellen (x+(Wenn Sie nur dies eingeben, wird die aktuelle Standardgeschwindigkeit verwendet.) |
y+[N] / y-[N] | Geschwindigkeit Y auf ±N mm/Frame einstellen |
z+[N] / z-[N] | Z-Geschwindigkeit auf ±N mm/Frame einstellen |
s+[N] / s-[N] | Die Standardgeschwindigkeit um ±N mm/Bild anpassen |
stop | Alle Geschwindigkeiten auf 0 setzen |
reset | Geschwindigkeit auf 0 einstellen und zum Ursprung zurückkehren |
h | Hilfe anzeigen |
Um das Programm zu beenden, drücken Sie bitte Strg+C(oder Strg+D / EOF).
Funktionsprinzip
Schritt 1 – HTTP-Sitzungen und Geräteerkennung
Dieses Tutorial ist Tutorial 08und dasselbe discover_session() / discover_device() Der Helper wird wiederverwendet. GET /sessions(oder --sessionin Verbindung mit GET /sessions/<selector>) aufgerufen und anschließend GET /devicesaufrufen oder --devicewird direkt verwendet. Beide Helper verwenden dieselbe SESSION_HELP Es akzeptiert dieselben CLI-Flags wie der Text, und die Selektoren aus den Tutorials 00 oder 08 funktionieren auch hier ohne Änderungen.
Schritt 2 – WebSocket-Sitzung, Handshake bei der ersten Nachricht
Dieses Tutorial ist ws://localhost:10001Öffnet eine WebSocket-Verbindung. Nur für die zuerst empfangene Nachricht Die Registrierungsdaten des Sitzungsprofils werden übertragen:
{
"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}}}}}]
}
Im folgenden Tick sessionwobei man … weglässt, inverse3 Es werden nur Befehlsarrays übertragen.
Schritt 3 – Bei jedem Ticken set_transform Ausführen
set_transform은 Teilumwandlungzulässt. Das heißt, Sie müssen lediglich die Felder angeben, die Sie ändern möchten. In diesem Tutorial wird nur die Position übertragen, während Drehung und Skalierung den Standardwerten der Sitzung entsprechen (sofern festgelegt configure.mount (den im Befehl angegebenen Wert) unverändert beibehält.
{
"inverse3": [{"device_id": "...", "commands": {"set_transform": {"transform": {"position": {"x": 0.02, "y": 0.0, "z": 0.01}}}}}]
}
Die Position wird tickweise kumuliert. Bei etwa 1 kHz führt der Dienst bei jedem Tick set_transformwird erneut angewendet (Zero-Order-Hold). Daher verbleibt der Arbeitsbereich unverändert an der zuletzt übertragenen Position.
set_transformund configure.mountDer UnterschiedBeide Befehle speichern dauerhafte Konvertierungen pro Sitzung, doch in der Pipeline werden die Arbeitsbereichskonvertierungen gemountet oben wird abgelegt (Mounts und Arbeitsbereiche (siehe). Tutorial 09 wird bei jedem Takt set_transformWährend des Streamings wird die zuvor gestreamte Workspace-Transformation bei jedem Eintreffen eines neuen WebSocket-Frames ersetzt. Daher wird auf demselben Gerät set_transformAndere Clients, die dies streamen, werden beim nächsten Tick überschrieben. configure.mountist unabhängig und behält seinen eigenen Wert bei. In der Praxis sollten Sie für jeden Anwendungsbereich einen eigenen Kanal auswählen. Für physikalische Einstellungen verwenden Sie „Mount“, für die Echtzeit-Navigation set_transformwird verwendet.
Threading-Modell (C++)
Das C++-Tutorial verwendet zwei Threads, die sich einen Positionszähler teilen:
| Thread | Rolle |
|---|---|
| Hauptthread | Eingabe lesen (std::getline(std::cin, ...)), Token-Parsing, nav_vel[] sowie default_step Aktualisierung |
| WebSocket-Callback-Thread | nav_vel[] * dt unter Verwendung des Werts nav_pos[]voranzutreiben und, set_transformserialisieren und übertragen |
std::mutex nav_mutexist nav_pos[], nav_vel[], default_stepschützt. last_tick Zeitstempel und first_ws_msg Da „flag“ eine lokale Variable ist, die auf den WS-Callback beschränkt ist, wird kein Mutex benötigt.
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
};
Quellcode
Tutorial 09 wird zusammen mit dem SDK lokal installiert. Im Installationsverzeichnis des Dienstes unter tutorials/09-haply-inverse-ws-remote-control/Bitte sehen Sie dort nach.
Verwandte Dokumente: set_transform Befehl · Sitzung – Handshake bei der ersten Nachricht · Mounts und Arbeitsbereiche · Selektor · Tutorial 08 – HTTP-Fernkonfiguration · Tutorial 07 – Basis und Mount