Aller au contenu principal

01. Afficher « Inverse3 »

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

Contenu pédagogique :

  • Établissement d'une connexion WebSocket et réception du message initial d'état complet
  • Envoi d'un keepalive de force nulle via set_cursor_force, afin que la session reste active
  • Enregistrer un profil de session afin que Haply Hub puisse reconnaître votre simulation
  • Le modèle de poignée de main pour le premier message — supprimer « session/configure » après l'envoi du premier message
  • Lecture de l'espace de travail-transform (position, rotation, mise à l'échelle) avec la sémantique des mises à jour partielles
  • Limiter le débit de sortie de la console à un niveau facilement lisible

Déroulement​

  1. Connectez-vous via WebSocket à ws://localhost:10001. Le service envoie immédiatement un Trame d'état complet avec les appareils connectés.
  2. Dans la première image, sélectionnez la device_id Sélectionnez le premier « Inverse3 » et rédigez un message de demande en deux parties :
    • session.configure.profile.name — enregistre la simulation auprès de Hub Haply.
    • Une commande spécifique à un appareil set_cursor_force avec un vecteur nul. Le service l'utilise comme « keepalive » : il envoie des trames d'état tant qu'il continue de recevoir des commandes.
  3. Renvoyez le message. Supprimez ce champ session Avant la trame suivante — le profil de session correspond à une poignée de main unique ; les trames suivantes ne transmettent que la commande.
  4. Pour chaque trame d'état suivante, renseignez les champs du curseur vec3 (position, vitesse, force), avec une fréquence réduite à environ 10 Hz, puis renvoyez le message « Keepalive » avec une force nulle.

Paramètres​

NomValeur par défautObjet
URIws://localhost:10001URL du canal de simulation WebSocket
PRINT_EVERY_MS100Limitation de la puissance de sortie de la console
Nom du profil de sessionco.haply.inverse.tutorials:print-inverse3Cette simulation est répertoriée sur la plateforme « Haply Hub »

Champs d'état lus​

Aus data.inverse3[0].state:

  • cursor_position, cursor_velocity, current_cursor_force — respectivement vec3
  • transform — Transformation de l'espace de travail ; sous-objet avec position (vec3), rotation (quaternion), scale (vec3)
Sémantique des mises à jour partielles

Sous-champs correspondant à la valeur par défaut neutre (position: {0,0,0}, rotation: {w:1,x:0,y:0,z:0}, scale: {1,1,1}), seront exclu de la charge utile, afin d'économiser de la bande passante. Indiquez toujours une valeur par défaut lors de la lecture (par exemple, .value("position", default_pos) en C++, .get("position", default_pos) en Python). Activez serialization/explicit_fields, afin de toujours conserver chaque champ.

Envoyer / Recevoir​

La boucle WebSocket : réception d'une trame d'état, création et renvoi d'une Trames de commande. La première trame de commande contient la procédure d'établissement de la session et un message « keepalive » de force nulle via set_cursor_force; chaque image suivante contient seulement le Keepalive (la session est supprimée).

Une boucle asynchrone isolée — recv() → Créer une 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 version Python accepte deux options permettant de modifier le contenu affiché par le tutoriel :

DrapeauEffet
--fullAffiche la charge utile JSON brute de chaque trame d'état, au lieu du résumé sur une seule ligne. Utile pour identifier les champs renvoyés par le service.
--query-configAjoute à nouveau à chaque mesure sortante session.force_render_full_state: {} afin que le service génère à nouveau un instantané complet à chaque image (y compris le config-Blocs — type d'appareil, micrologiciel, préréglage, support, filtre, …). Sans cet indicateur, config transmis uniquement dans la première trame ; les trames suivantes sont des deltas de streaming.

Ces deux drapeaux peuvent être combinés — python 01-haply-inverse-print-inverse3.py --full --query-config renvoie une charge utile JSON complète, dans laquelle config visible à chaque cycle. Cela s'avère pratique lorsque vous suivez en temps réel les modifications apportées aux paramètres via Haply Hub ou l'API HTTP. Voir session.force_render_full_state pour la commande WebSocket correspondante.

Les variantes C++ ne proposent pas ces options : elles affichent toujours le résumé sur une seule ligne et renvoient config uniquement dans la première image.

Inclus dans le programme d'installation du SDK

Le tutoriel 01 est également installé localement avec le SDK — vous le trouverez dans le répertoire d'installation du service, sous tutorials/01-haply-inverse-print-inverse3/ nach.

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

À lire également : Protocole WebSocket · Commandes de contrôle (set_cursor_force) · Séances · Types (vec3)