Aller au contenu principal

01. Afficher Inverse3

Se connecte à la simulation WebSocket et transmet 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) de force nulle avec set_cursor_force pour que la session reste active
  • Enregistrer un profil de session afin que Haply Hub reconnaisse votre simulation
  • Modèle de « poignée de main » limité au premier message : supprimer « 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 la vitesse d'affichage dans la console à une cadence lisible

Déroulement​

  1. Établir une connexion WebSocket vers ws://localhost:10001. Le service envoie immédiatement un trame d'état complète qui répertorie les appareils connectés.
  2. À la première trame, choisir le device_id du premier Inverse3 et créer un message de requête en deux parties :
    • session.configure.profile.name : enregistre la simulation auprès de Hub Haply.
    • 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 lui parviennent.
  3. Renvoyer le message. Supprimer le champ session avant le cycle suivant : le profil de session correspond à 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 fréquence 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 d'affichage dans la console
Nom du profil de sessionco.haply.inverse.tutorials:print-inverse3Identifiez cette simulation dans le Hub Haply

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 la mise à jour partielle

Les sous-champs dont la valeur est égale à 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. Indiquez toujours une valeur par défaut pour la lecture (par ex. .value("position", default_pos) en C++, .get("position", default_pos) (en Python). Activez serialization/explicit_fields pour continuer à recevoir chaque champ.

Envoi et réception​

La boucle WebSocket : recevoir une trame d'état, la traiter puis renvoyer une trame de commande. Le premier flux 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 interrompue).

Boucle asynchrone unique : recv() → créer 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 qui s'affiche dans le tutoriel :

OptionEffet
--fullAffiche la charge utile brute au format JSON de chaque trame d'état, mise en forme, au lieu d'un résumé sur une seule ligne. Utile pour découvrir les champs transmis par le service.
--query-configRéinjecter session.force_render_full_state: {} à chaque cycle sortant afin que le service génère à nouveau un instantané complet (y compris le bloc config : type d'appareil, micrologiciel, préréglage, montage, filtres, …) à chaque image. Sans cette option, config n'apparaît 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 en temps réel les modifications des paramètres depuis l'Haply Hub ou via l'API HTTP. Voir session.force_render_full_state pour la commande WebSocket sous-jacente.

Les variantes C++ ne proposent 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 le programme d'installation du SDK

Le tutoriel 01 est également 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) · Séances · Types (vec3)