Zum Hauptinhalt springen

WebSocket-Protokoll

Der Simulationskanal ist eine WebSocket-Verbindung aufPort 10001. Er dient dem Echtzeit-Befehls- und Statusaustausch zwischen Ihrer Anwendung und dem Dienst.

Grundregel: Jede Nachricht entspricht einer Antwort​

Der Dienst sendet fürjedevom Client empfangeneNachrichtgenaueine Statusaktualisierung:

Es gibt keine Abfragen, Abonnements oder Out-of-Band-Benachrichtigungen. Der Aktualisierungsrhythmus richtet sich ausschließlich nach Ihrer Sendefrequenz.


Schritt 1 – Erstliste (die erste Nachricht vom Dienst)​

Bei der Verbindung sendet der Dienst für jedes erkannte Gerät eineVollständiger Schnappschuss, das Folgendes enthält: config、state und status:

{
"session_id": 7,
"inverse3": [
{
"device_id": "049D",
"config": {
"type": "inverse3",
"port": "COM12",
"device_info": { "major_version": 7, "minor_version": 4, "id": "049D", "device_type": 4, "uuid": "…" },
"extended_device_id": "…",
"extended_firmware_version": "…",
"gravity_compensation": { "enabled": true, "scaling_factor": 1.0 },
"handedness": "right",
"streaming_mode": "USB",
"torque_scaling": { "enabled": true },
"home_return": { "enabled": false },
"preset": "defaults",
"basis": { "permutation": "XYZ" },
"mount": { "position": { "x": 0, "y": 0, "z": 0 }, "rotation": { "w": 1, "x": 0, "y": 0, "z": 0 }, "scale": { "x": 1, "y": 1, "z": 1 } },
"filters": {
"force_gate": { "gain": 0.3 },
"damping": { "scalar": 0.0 }
}
},
"state": {
"cursor_position": { "x": 0.0, "y": -0.12, "z": 0.15 },
"cursor_velocity": { "x": 0.0, "y": 0.0, "z": 0.0 },
"angular_position": { "a0": 0.0, "a1": 0.0, "a2": 0.0 },
"angular_velocity": { "a0": 0.0, "a1": 0.0, "a2": 0.0 },
"body_orientation": { "w": 1.0, "x": 0.0, "y": 0.0, "z": 0.0 },
"current_cursor_force": { "x": 0.0, "y": 0.0, "z": 0.0 },
"current_cursor_position": { "x": 0.0, "y": 0.0, "z": 0.0 },
"current_angular_torques": { "a0": 0.0, "a1": 0.0, "a2": 0.0 },
"current_angular_position": { "a0": 0.0, "a1": 0.0, "a2": 0.0 },
"control_domain": "cartesian",
"control_mode": "idle",
"transform": { "position": { "x": 0, "y": 0, "z": 0 }, "rotation": { "w": 1, "x": 0, "y": 0, "z": 0 }, "scale": { "x": 1, "y": 1, "z": 1 } },
"transform_velocity": { "position": { "x": 0, "y": 0, "z": 0 }, "rotation": { "w": 1, "x": 0, "y": 0, "z": 0 }, "scale": { "x": 0, "y": 0, "z": 0 } }
},
"status": {
"calibrated": true,
"in_use": false,
"power_supply": true,
"ready": true,
"started": true
}
}
],
"verse_grip": [],
"wireless_verse_grip": []
}

Die Aktualisierungshäufigkeit dieser drei Datenblöcke ist unterschiedlich:

DatenblockInhaltÄnderungshäufigkeit
configFirmware-Informationen, Voreinstellungen, Basis, Mount, FilterSelten – nur bei einer expliziten Änderung der Konfiguration
statePosition, Geschwindigkeit, Kraft, Lage, TransformationPro Tick (Hochfrequenz)
statusBereit, kalibriert, Stromversorgung, in_useGelegentlich (selten)

Schritt 2 – Den ersten Befehl senden​

Analysieren Sie die anfängliche Liste, um Ihre Geräte-ID zu ermitteln, und senden Sie anschließend eine Nachricht zurück, die Ihre Sitzungskonfiguration sowie etwaige Anfangskonfigurationen und/oder Steuerbefehle enthält:

{
"session": {
"configure": {
"profile": { "name": "co.haply.inverse.tutorials:hello-floor" }
}
},
"inverse3": [
{
"device_id": "049D",
"configure": {
"preset": { "preset": "arm_front_centered" }
},
"commands": {
"set_cursor_force": { "vector": { "x": 0.0, "y": 0.0, "z": 0.0 } }
}
}
]
}

Schritt 3 – Weitere Statusaktualisierungen​

Nach der ersten Interaktion sendet der Dienst nur dann Daten, wenn Konfigurationsänderungen die Übertragung eines vollständigen Snapshots auslösen. state + status(ohne config):

{
"session_id": 7,
"inverse3": [
{
"device_id": "049D",
"state": { "cursor_position": { … }, "cursor_velocity": { … }, … },
"status": { "ready": true, "calibrated": true, … }
}
]
}

Schritt 4 – Wiederholen​

Befehl senden → Statusaktualisierung empfangen. Der Zyklus läuft entsprechend deiner Sendegeschwindigkeit weiter.


configure und commands​

In den von dir gesendeten Nachrichten kann jeder Geräteeintrag zwei Zuordnungen enthalten:

AbbildungVerwendungszweckBeständigkeit
configureEinmalige Einstellungen: Voreinstellungen, Basis, Einbindung, Filter, ModulkonfigurationGültig, bis eine Änderung erfolgt
commandsZyklusweise Regelung: Kraft, Position, DrehmomenteNur einmal anwendbar, danach verliert es seine Wirksamkeit

Zu configure Eine vollständige Liste der Tasten finden Sie unter Sitzungskonfiguration; bezüglich commands Eintrag, siehe Steuerbefehle。

Anmerkung
set_transform Das ist ein Sonderfall.

set_transform gelegen in commands unten, aber es istDauerhaftigkeit——Der Dienst behält den letzten Wert so lange bei, bis du einen neuen Wert sendest. Der Grund dafür ist, dass er für die Szenennavigation verwendet wird: Du sendest die Transformationen während der Kamerabewegung in Echtzeit, möchtest aber die letzte Position zwischen zwei Tastendrücken beibehalten.


execute Logo​

Jedes configure oder commands Einträge können Folgendes enthalten "execute": false, damit der DienstAnalyse und ÜberprüfungLaden, ohne es anzuwenden.

{
"inverse3": [{
"device_id": "049D",
"configure": {
"preset": { "preset": "arm_front", "execute": true },
"damping": { "scalar": 0.0, "execute": false }
}
}]
}

Das gilt fürReflektionsbasierter Serializer(zum Beispiel Unity) JsonUtility) Sehr nützlich, denn solche Serializer geben immer alle Felder aus: Nicht verwendete Einträge werden auf execute: false, damit sie die tatsächliche Konfiguration nicht überschreiben. Der Standardwert lautet true——Wird dieses Symbol weggelassen, bedeutet dies „normale Anwendung“.


Warnung​

Wenn Sie bereits einen Befehl gesendet haben, führen Sie bitte keine weitere Abfrage durch.

probe_position und probe_orientation Dies sind reine Keep-Alive-Nachrichten zur Überwachung, die für Sitzungen gelten, bei denen keine Steuerbefehle gesendet werden (z. B. „ Haply -Hub“). Wenn Ihre Sitzung bereits set_cursor_force、set_cursor_position Befehle wie,Bitte senden Sie nicht erneut gleichzeitig mehrere Testnachrichten.——Der Gerätestatus ist bereits in jeder Antwort enthalten. Die gleichzeitige Verwendung beider Optionen verschwendet Bandbreite und kann zudem dazu führen, dass session-probe-dropped Ereignis.

Unbekannte Tasten werden stillschweigend ignoriert.

Wenn ein Befehl offenbar keine Wirkung zeigt, ist der Feldname höchstwahrscheinlich falsch. Der Dienst ignoriert derzeit nicht erkannte JSON-Schlüssel, ohne eine Fehlermeldung auszugeben. Bitte überprüfen Sie das Dienstprotokoll und vergleichen Sie die Feldnamen mit der API-Referenz. Dieses Verhalten soll in zukünftigen Versionen geändert werden.