Skip to main content
Version : 3.5.x

01. Imprimer Inverse3

Se connecte au WebSocket de simulation et transmet en continu la position, la vitesse et la force du curseur à partir du premier Inverse3 signalé Inverse3 service.

Ce que vous apprendrez :

  • Établissement d'une connexion WebSocket et réception du message initial contenant l'état complet
  • Envoi d'une force nulle set_cursor_force un signal de maintien de connexion pour maintenir la session active
  • Enregistrer un profil de session pour que Haply reconnaisse votre simulation
  • Modèle de négociation de connexion « premier message uniquement » — suppression de la session et de la configuration après le premier envoi
  • Lecture de l'espace de travail transform (position, rotation, échelle) avec une sémantique de mise à jour partielle
  • Limiter le débit de la console à un niveau lisible

Flux de travail

  1. Ouvrir un WebSocket vers ws://localhost:10001. Le service envoie immédiatement une trame à état complet liste des appareils connectés.
  2. À la première image, sélectionnez les premiers Inverse3 device_id et créer un message de requête en deux parties :
    • session.configure.profile.name — enregistre la simulation auprès de Hub Haply.
    • Par appareil set_cursor_force commande avec un vecteur nul. Le service utilise cela comme mécanisme de maintien de connexion : il continue d'émettre des trames d'état tant que des commandes continuent d'arriver.
  3. Renvoie le message. Dénuder le session champ avant le prochain tick — le profil de session correspond à une poignée de main unique ; les ticks suivants n'envoient que la commande.
  4. À chaque nouvelle trame d'état : afficher le curseur vec3 champs (position, vitesse, force), limités à environ 10 Hz, et renvoyer le message de maintien de connexion « force nulle ».

Paramètres

NomPar défautObjectif
URIws://localhost:10001URL WebSocket du canal de simulation
PRINT_EVERY_MS100Régulateur de débit via la console
Nom du profil de sessionco.haply.inverse.tutorials:print-inverse3Identifie cette simulation dans Haply

Champs d'état lus

De data.inverse3[0].state:

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

Les sous-champs dont la valeur par défaut correspond à leur identité (position: {0,0,0}, rotation: {w:1,x:0,y:0,z:0}, scale: {1,1,1}) sont omise 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). Activer serialization/explicit_fields pour toujours recevoir tous les champs.

Envoyer / recevoir

La boucle WebSocket : recevoir une trame d'état, construire et renvoyer une cadre de commande. La première trame de commande contient la procédure d'établissement de la session et une force nulle set_cursor_force keepalive ; chaque trame suivante contient seulement le keepalive (la session est supprimée).

Boucle asynchrone unique — recv() → commande de compilation → 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 permettant de modifier le contenu affiché par le tutoriel :

DrapeauEffet
--fullAffiche le contenu JSON brut de chaque trame d'état sous une forme lisible, au lieu du résumé sur une seule ligne. Utile pour identifier les champs générés par le service.
--query-configRéinjections session.force_render_full_state: {} à chaque tick sortant, afin que le service renvoie un instantané complet (y compris le config bloc — type de périphérique, micrologiciel, préréglage, montage, filtres, …) à chaque trame. Sans cela, config n'arrive que sur la première trame ; les trames suivantes ne contiennent que des différences.

Les deux drapeaux se combinent — python 01-haply-inverse-print-inverse3.py --full --query-config affiche l'intégralité de la charge utile JSON avec config visible à chaque mise à jour, ce qui est pratique pour observer les changements de paramètres en temps réel depuis Haply ou l'API HTTP. Voir session.force_render_full_state pour la commande WebSocket correspondante.

Les variantes C++ ne prennent pas en charge ces indicateurs : elles affichent toujours le résumé sur une seule ligne et reçoivent config uniquement sur la première image.

Fourni avec le programme d'installation du SDK

Le didacticiel 01 est également installé localement avec le SDK — regardez dans tutorials/01-haply-inverse-print-inverse3/ dans le répertoire d'installation du service.

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

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