Aller au contenu principal

01. Afficher Inverse3

Se connecte à la simulation WebSocket et diffuse la position du curseur, la vitesse et la force à partir du premier Inverse3 signalé par le service.

Ce que vous allez apprendre :

  • Ouvrir une connexion WebSocket et recevoir le message initial contenant l'état complet
  • Envoyer un signal de maintien en activité (keepalive) à force nulle avec set_cursor_force pour que la session reste active
  • Enregistrer un profil de session afin que Haply Hub reconnaisse votre simulation
  • Le modèle de poignée de main limité au premier message : retirer session/configure après le premier envoi
  • Lire le transform de l'espace de travail (position, rotation, échelle) avec la sémantique de mise à jour partielle
  • Limiter le débit d'affichage dans la console à une cadence lisible

Déroulement​

  1. Ouvrir une connexion WebSocket vers ws://localhost:10001. Le service envoie immédiatement une trame d'état complet qui liste les appareils connectés.
  2. À la première trame, choisir le device_id du premier Inverse3 et construire un message de requête en deux parties :
    • session.configure.profile.name : enregistre la simulation auprès de Haply Hub.
    • Une commande set_cursor_force par appareil, avec un vecteur nul. Le service s'en sert comme signal de maintien : il continue d'émettre des trames d'état tant que des commandes arrivent.
  3. Renvoyer le message. Retirer le champ session avant le cycle suivant : le profil de session est une poignée de main ponctuelle, et les cycles suivants n'envoient que la commande.
  4. Pour chaque trame d'état suivante : afficher les champs vec3 du curseur (position, vitesse, force), à une cadence limitée à environ 10 Hz, puis renvoyer le signal de maintien à force nulle.

Paramètres​

NomDéfautRôle
URIws://localhost:10001URL du canal de simulation WebSocket
PRINT_EVERY_MS100Limite de l'affichage dans la console
Nom du profil de sessionco.haply.inverse.tutorials:print-inverse3Identifie cette simulation dans Haply Hub

Champs d'état lus​

Depuis data.inverse3[0].state :

  • cursor_position, cursor_velocity, current_cursor_force : de type vec3 chacun
  • transform : transformation de l'espace de travail; sous-objet avec position (vec3), rotation (quaternion) et scale (vec3)
Sémantique de mise à jour partielle

Les sous-champs égaux à leur valeur d'identité (position: {0,0,0}, rotation: {w:1,x:0,y:0,z:0}, scale: {1,1,1}) sont omis de la charge utile afin d'économiser la bande passante. Fournissez toujours une valeur par défaut à la lecture (p. ex. .value("position", default_pos) dans C++, .get("position", default_pos) dans Python). Activez serialization/explicit_fields pour toujours recevoir chaque champ.

Envoi et réception​

La boucle WebSocket : recevoir une trame d'état, construire puis renvoyer une trame de commande. La première trame de commande transporte la poignée de main de session et un signal de maintien à force nulle avec set_cursor_force; chaque trame suivante ne transporte que le signal de maintien (la session est retirée).

Boucle asynchrone unique : recv() → construire la commande → send() → répéter.

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["inverse3"][0]["device_id"]
request_msg = {
"session": {"configure": {"profile": {
"name": "co.haply.inverse.tutorials:print-inverse3"}}},
"inverse3": [{
"device_id": device_id,
"commands": {"set_cursor_force":
{"vector": {"x": 0.0, "y": 0.0, "z": 0.0}}},
}]
}

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

Options de ligne de commande (Python)​

La variante Python accepte deux options qui modifient ce qu'affiche le tutoriel :

OptionEffet
--fullAffiche la charge utile brute JSON de chaque trame d'état, avec mise en forme, au lieu du résumé d'une ligne. Utile pour découvrir les champs émis par le service.
--query-configRéinjecte session.force_render_full_state: {} à chaque cycle sortant afin que le service réémette un instantané complet (y compris le bloc config : type d'appareil, micrologiciel, préréglage, montage, filtres, …) à chaque trame. Sans cette option, config n'arrive que sur la première trame, et les trames suivantes ne contiennent que des mises à jour différentielles diffusées en continu.

Les deux options se combinent : python 01-haply-inverse-print-inverse3.py --full --query-config affiche une charge utile JSON complète avec le bloc config visible à chaque cycle, ce qui est pratique pour observer les changements de paramètres en direct depuis Haply Hub ou depuis l'API HTTP. Voir session.force_render_full_state pour la commande WebSocket sous-jacente.

Les variantes C++ n'exposent pas ces options : elles affichent toujours le résumé d'une ligne et ne reçoivent config que sur la première trame.

Inclus dans l'installateur du SDK

Le tutoriel 01 est aussi installé localement avec le SDK : consultez tutorials/01-haply-inverse-print-inverse3/ dans le répertoire d'installation du service.

Source : Python · C++ · C++ Glaze

Voir aussi : Protocole WebSocket · Commandes de contrôle (set_cursor_force) · Sessions · Types (vec3)