Aller directement au corps du texte

Protocole WebSocket

Le canal de simulation est une connexion WebSocket sur le port 10001. Ce canal assure la transmission en temps réel des commandes et des états entre l'application et le service.

Règle fondamentale : une réponse par message​

Le service envoie exactement une mise à jour d'étatpour chaque messagereçu du client :

Il n'y a ni polling, ni abonnement, ni notification push hors bande. La fréquence des mises à jour dépend entièrement de la fréquence d'envoi des données par le client.


Étape 1 — Inventaire initial (premier message du service)​

Une fois connecté, le service effectue, pour tous les appareils détectés, config, state, statusy compris Instantané complettransmet :

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

Ces trois blocs ont des fréquences de mise à jour différentes :

blocContenu inclusFréquence des modifications
configInformations sur le micrologiciel, préréglages, base, monture, filtreRarement — uniquement en cas de modification explicite de la configuration
statePosition, vitesse, force, direction, transformationMatic (haute fréquence)
statusPrêt, calibré, sous tension, en cours d'utilisationDe temps en temps (peu fréquemment)

Étape 2 — Envoi de la première commande​

Analysez l'inventaire initial pour identifier l'ID de l'appareil, puis renvoyez un message contenant le profil de session, la configuration initiale et/ou les commandes de contrôle :

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

Étape 3 — Mise à jour de l'état par la suite​

Après le premier échange, à moins qu'un changement de configuration n'entraîne la diffusion d'un instantané complet, le service state + statusJe ne transmets que (config (à l'exception de) :

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

Étape 4 — Répétition​

Envoi d'une commande → Réception d'une mise à jour d'état. La boucle se poursuit en fonction de la vitesse de transmission.


configureWa commandsLa différence entre​

Chaque entrée « appareil » du message envoyé peut contenir les deux cartes suivantes :

CarteUtilisationPersistance
configureParamètres ponctuels : préréglages, base, montage, filtres, paramètres des modulesConserver jusqu'à modification
commandsContrôle par incréments : force, position, couplesÀ jeter après une seule utilisation

configure La liste complète des clés se trouve Organisation de la session을, commands Les éléments sont Commandes de contrôleVeuillez vous reporter à ce document.

Note
set_transformIl s'agit d'un cas exceptionnel.

set_transform은 commands Bien qu'il figure ci-dessous, il s'agit d'un type **persistant**. Le service conserve la dernière valeur jusqu'à ce qu'une nouvelle valeur lui soit envoyée. Cela s'explique par le fait qu'il est destiné à l'exploration de scènes, où l'on souhaite que la dernière position soit conservée entre deux entrées, tout en diffusant en continu les valeurs de transformation pendant que la caméra se déplace.


execute drapeau​

configure ou bien commands Dans la rubrique "execute": falseSi l'on inclut cela, le service n'applique pas la charge utile et Analyse syntaxique et validation uniquement Nous nous en chargeons.

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

Cela permet d'afficher systématiquement tous les champs Sérialiseur basé sur la réflexion(par exemple : dans Unity, le JsonUtility) est utile. Les éléments que vous n'utilisez pas sont execute: falseVeuillez définir ce paramètre de manière à ne pas écraser la configuration réelle. La valeur par défaut est trueSi aucun indicateur n'est spécifié, l'application se fait « normalement ».


Avertissement​

Si vous êtes déjà en train d'envoyer une commande, n'envoyez pas de sonde.

probe_positionet probe_orientationIl s'agit d'un message « keepalive » destiné exclusivement à la surveillance des sessions qui n'envoient pas de commandes de contrôle (par exemple, le hub « Haply »). Si la session est déjà set_cursor_force, set_cursor_position si vous envoyez des messages, etc. N'envoyez pas la sonde avec le colis. L'état de l'appareil est déjà inclus dans toutes les réponses. Utiliser les deux ensemble entraîne un gaspillage de bande passante et session-probe-dropped Un événement peut se produire.

Les clés inconnues sont ignorées sans générer d'erreur.

Si la commande semble ne produire aucun effet, il est fort probable que le nom du champ soit incorrect. Le service ignore sans générer d'erreur les clés JSON qu'il ne reconnaît pas. Vérifiez les journaux du service et assurez-vous que le nom du champ est correct en consultant la documentation de l'API. Ce comportement est susceptible d'être modifié dans les prochaines versions.