Zum Hauptinhalt springen

03. Wireless VerseGrip ausgeben

Gleiches Muster wie Tutorial 02, jedoch für ein Wireless VerseGrip — ergänzt Tasten (A/B/C) und Akkustand im gestreamten Zustand.

Was Sie lernen:

  • Auslesen der wireless-spezifischen Zustandsfelder: buttons.{a,b,c}, battery_level, hall
  • Verwendung von probe_orientation als Keepalive für einen eigenständigen Beobachter
  • Dasselbe Handshake-Muster wie in Tutorial 02, bei dem nur die erste Nachricht die Sitzungskonfiguration enthält

Ablauf​

  1. Öffnen Sie eine Verbindung über WebSocket zu ws://localhost:10001 und warten Sie auf die erste Zustands-Nachricht.
  2. Wählen Sie die device_id des ersten Wireless VerseGrip aus dem Array wireless_verse_grip.
  3. Erstellen Sie eine Anfrage mit dem Sitzungsprofil und einem gerätespezifischen Keepalive per probe_orientation.
  4. Senden Sie die Anfrage und entfernen Sie danach das Feld session — es ist ein einmaliger Handshake.
  5. Konvertieren Sie bei jedem weiteren Frame das Quaternion in Euler-Winkel und geben Sie gedrosselte Telemetriedaten aus, einschließlich Tastenzuständen und Akkustand. Senden Sie den Keepalive bei jedem Takt erneut.

Parameter​

NameStandardZweck
URIws://localhost:10001URL des Simulationskanals WebSocket
PRINT_EVERY_MS100Drosselung der Konsolenausgabe
Name des Sitzungsprofilsco.haply.inverse.tutorials:print-wireless-verse-gripIdentifiziert diese Simulation in Haply Hub
Euler-Konvention

Die Umrechnung erfolgt intrinsisch in der Reihenfolge Z-X-Y (Gieren → Nicken → Rollen) im Anwendungskoordinatensystem +X right, +Y forward, +Z up. Verwenden Sie nicht glm::eulerAngles — es folgt einer anderen Konvention und liefert hier falsche Werte. Alle drei Sprachvarianten implementieren dieselbe Mathematik; die Formel finden Sie in den Quelltexten.

Wann probe_orientation tatsächlich benötigt wird

probe_orientation ist nur dann sinnvoll, wenn Ihre Sitzung keinen Befehl an Inverse3 sendet. Sobald Sie Inverse3 ansteuern (Kraft, Position, Drehmoment ...), streamt der Dienst die Orientierung des gekoppelten VerseGrip automatisch in jedem Zustands-Frame — ein Keepalive ist dann nicht nötig. Verwenden Sie probe_orientation nur für eigenständige Grip-Überwachungswerkzeuge wie dieses Tutorial.

Gelesene Zustandsfelder​

Aus data.wireless_verse_grip[0].state:

  • orientation — quaternion (w, x, y, z)
  • hall — ganzzahliger Messwert des Hall-Sensors
  • buttons.a, buttons.b, buttons.c — Boolesche Werte
  • battery_level — Gleitkommazahl (0.0 – 1.0)
  • transform.rotation — Rotation des Arbeitsbereichs (quaternion); Position und Skalierung entfallen bei einem Gerät, das nur die Orientierung liefert, und werden nie übertragen
Semantik bei Teilaktualisierungen

transform.rotation wird weggelassen, wenn es dem Identitäts-Quaternion {w:1,x:0,y:0,z:0} entspricht. Hinterlegen Sie beim Auslesen einen Standardwert. Aktivieren Sie serialization/explicit_fields, um es immer zu erhalten.

Senden / Empfangen​

Gleicher Aufbau wie in Tutorial 02, lediglich mit dem Geräte-Array wireless_verse_grip. Die Schleife von WebSocket empfängt einen Zustands-Frame und sendet den Handshake sowie den Keepalive per probe_orientation zurück; die erste ausgehende Nachricht enthält das Sitzungsprofil, jeder weitere Frame enthält nur den Keepalive.

Einzelne asynchrone Schleife.

async with websockets.connect(URI) as websocket:
while True:
msg = await websocket.recv()
data = json.loads(msg)

if first_message:
first_message = False
device_id = data["wireless_verse_grip"][0]["device_id"]
request_msg = {
"session": {"configure": {"profile": {
"name": "co.haply.inverse.tutorials:print-wireless-verse-grip"}}},
"wireless_verse_grip": [{
"device_id": device_id,
"commands": {"probe_orientation": {}} # empty — keepalive
}]
}

await websocket.send(json.dumps(request_msg))
request_msg.pop("session", None) # one-shot handshake

Kommandozeilen-Flags (Python)​

Die Variante Python akzeptiert dieselben zwei Flags wie Tutorial 01:

  • --full — gibt die rohe JSON-Nutzlast formatiert aus, statt der einzeiligen Zusammenfassung.
  • --query-config — fügt bei jedem ausgehenden Tick session.force_render_full_state erneut hinzu, sodass jeder Frame den config-Block statt nur der Zustandsänderung enthält.

--query-config ist besonders nützlich in der drahtlosen Variante von VerseGrip, da der config-Block zusätzlich zu den regulären Konfigurationsfeldern das WVG-spezifische Feld sub_type (stylus / prototype / ruko / kingfisher, ab 3.5 hinzugekommen) enthält. Wenn Sie python 03-haply-inverse-print-wireless-verse-grip.py --full --query-config ausführen, können Sie live verfolgen, wie sich config.sub_type zusammen mit den übrigen Konfigurationswerten aktualisiert.

Die Varianten C++ stellen diese Flags nicht bereit.

Mitgeliefert mit dem SDK-Installer

Tutorial 03 wird außerdem lokal mit dem SDK installiert – zu finden unter tutorials/03-haply-inverse-print-wireless-verse-grip/ im Installationsverzeichnis des Dienstes.

Quelle: Python · C++ · C++ Glaze

Verwandte Themen: Tutorial 02 (kabelgebundenes VG) · Typen (Quaternion) · Steuerbefehle (probe_orientation) · WebSocket-Protokoll