Zum Hauptinhalt springen

02. Ausgabe von VerseGrip

Streamt die Orientierung (Quaternion + Z-X-Y-Euler-Winkel), den Hall-Sensorwert und den Tastenstatus des ersten kabelgebundenen VerseGrip.

Was Sie lernen werden:

  • Die quaternion-Orientierung aus dem State-Frame auslesen
  • Ein Quaternion in Z-X-Y-Euler-Winkel in Grad umrechnen (+X rechts, +Y vorne, +Z oben)
  • probe_orientation als Keepalive für einen eigenständigen Beobachter verwenden
  • Das Handshake-Muster, das nur in der ersten Nachricht angewendet wird (wie in Tutorial 01)

Ablauf​

  1. Öffnen Sie eine WebSocket-Verbindung zu ws://localhost:10001 und warten Sie auf den ersten State-Frame.
  2. Wählen Sie die device_id des ersten kabelgebundenen VerseGrip aus dem Array verse_grip.
  3. Erstellen Sie eine Anfrage mit dem Sitzungsprofil und einem gerätespezifischen probe_orientation-Keepalive (ein Befehl mit leerem Objekt, der dafür sorgt, dass die Griff-Orientierung fortlaufend in den State-Frames übermittelt wird).
  4. Senden Sie die Anfrage und entfernen Sie anschließend das Feld session — es handelt sich um einen einmaligen Handshake.
  5. Bei jedem weiteren Frame rechnen Sie das Quaternion in Euler-Winkel um und geben gedrosselte Telemetrie aus. Senden Sie den Keepalive in jedem Zyklus erneut.

Parameter​

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

Die Umrechnung ist eine intrinsische Z-X-Y-Rotation (Gieren → Nicken → Rollen) im Koordinatensystem der Anwendung +X right, +Y forward, +Z up. Verwenden Sie nicht glm::eulerAngles — sie folgt einer anderen Konvention und liefert hier falsche Werte. Alle drei Sprachvarianten implementieren dieselbe Mathematik; die Formel finden Sie in den Quellen.

Wann probe_orientation tatsächlich benötigt wird

probe_orientation ist nur sinnvoll, wenn Ihre Sitzung keinen Befehl an Inverse3 sendet. Sobald Sie Inverse3 mit einem Befehl ansteuern (Kraft, Position, Drehmoment ...), streamt der Dienst die Orientierung des gekoppelten VerseGrip automatisch in jedem State-Frame — eine Probe ist dann nicht nötig. Verwenden Sie probe_orientation nur für eigenständige Werkzeuge zur Griffüberwachung wie dieses Tutorial.

Gelesene State-Felder​

Aus data.verse_grip[0].state:

  • orientation — quaternion (w, x, y, z)
  • hall — ganzzahliger Hall-Sensorwert
  • button — boolescher Wert
  • transform.rotation — Rotation des Arbeitsbereichs (quaternion); Position und Skalierung sind für ein Gerät, das nur die Orientierung erfasst, nicht anwendbar und werden nie ausgegeben
Semantik bei Teilaktualisierungen

transform.rotation wird ausgelassen, wenn es dem Identitäts-Quaternion {w:1,x:0,y:0,z:0} entspricht. Legen Sie beim Lesen einen Standardwert fest. Aktivieren Sie serialization/explicit_fields, damit es immer übermittelt wird.

Senden / Empfangen​

Die WebSocket-Schleife empfängt ein State-Frame, erstellt den Handshake und den probe_orientation-Keepalive und sendet sie zurück. Die erste ausgehende Nachricht enthält das Sitzungsprofil; jedes weitere Frame enthält nur den Keepalive.

Einzelne asynchrone Schleife — recv() → Befehl erstellen → send() → wiederholen.

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["verse_grip"][0]["device_id"]
request_msg = {
"session": {"configure": {"profile": {
"name": "co.haply.inverse.tutorials:print-verse-grip"}}},
"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 Python-Variante 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 Takt session.force_render_full_state erneut hinzu, sodass jedes Frame den config-Block (Gerätetyp, Firmware, Montagetransformation …) enthält und nicht nur die Zustandsänderung. Nützlich zum Debuggen von Einstellungsänderungen im laufenden Betrieb.

Beide Flags lassen sich kombinieren. Die C++-Varianten bieten diese Flags nicht an.

Im SDK-Installer enthalten

Tutorial 02 wird ebenfalls lokal mit dem SDK installiert — Sie finden es unter tutorials/02-haply-inverse-print-verse-grip/ im Installationsverzeichnis des Dienstes.

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

Siehe auch: Typen (Quaternion) · Steuerbefehle (probe_orientation) · WebSocket-Protokoll · Tutorial 03 (Wireless VG)