Passer directement au contenu principal

01. Sortie d'Inverse3

Se connecter au WebSocket de simulationet diffuser en continu la position, la vitesse et la force du curseur à partir du premier Inverse3 renvoyé par le service.

Contenu pédagogique :

  • Ouvrir une connexion WebSocket et recevoir le message d'état initial complet
  • Force nulleset_cursor_forceEnvoyer un « keep-alive » pour maintenir la session active
  • Haply Enregistrerle profil de sessionafin que le hub puisse reconnaître la simulation
  • Modèle de « handshake » effectué uniquement lors du premier message — supprimer « session/configure » après l'envoi du premier message
  • Dans le cadre de la sémantique des mises à jour partielles, l'espace de travail transformLire (la position, la rotation, la mise à l'échelle)
  • Limiter la fréquence des messages affichés sur la console afin d'en faciliter la lecture

Flux de travail​

  1. ws://localhost:10001 Ouvre une connexion WebSocket. Le service affiche immédiatement la liste des appareils connectés.Cadre en parfait étatJe vais l'envoyer.
  2. Dans la première image, le premier Inverse3 device_id et crée un message de requête composé de deux parties :
    • session.configure.profile.name — La simulationHub HaplyJe m'inscris.
    • Par périphérique, en spécifiant un vecteur nulset_cursor_forceCommande. Le service l'utilise comme signal de maintien de connexion. Tant que la commande continue d'arriver, il continue d'envoyer des trames d'état.
  3. Je vais vous renvoyer un message.Avant le prochain tick session Veuillez supprimer ce champ。Le profil de session correspond à une poignée de main unique ; lors des ticks suivants, seules les commandes sont envoyées.
  4. À partir de là, à chaque image d'état, le curseurvec3Les données de champ (position, vitesse, force) sont transmises à une fréquence limitée à environ 10 Hz, et le signal de maintien de la force nulle est retransmis.

Paramètres​

NomPar défautUtilisation
URIws://localhost:10001URL du canal de simulation WebSocket
PRINT_EVERY_MS100Intervalle entre les sorties sur la console
Nom du profil de sessionco.haply.inverse.tutorials:print-inverse3Haply Identifiez cette simulation au sein du Hub

Champ d'état de lecture​

data.inverse3[0].state On lit ce qui suit :

  • cursor_position,cursor_velocity,current_cursor_force — Dans tous les casvec3
  • transform — Conversion de l'espace de travail. En tant que sous-objet position(vec3),rotation(quaternion),scale(vec3)
Sémantique des mises à jour partielles

Valeur par défaut de l'identité (élément neutre) (position: {0,0,0},rotation: {w:1,x:0,y:0,z:0},scale: {1,1,1}) sont supprimés de la charge utile afin d'économiser de la bande passante(omission). Veillez à toujours spécifier la valeur par défaut lors de la lecture (par exemple, en C++ : .value("position", default_pos), en Python, .get("position", default_pos)). Pour recevoir systématiquement toutes les données,serialization/explicit_fieldsVeuillez l'activer.

Émission et réception​

Dans la boucle WebSocket, on reçoit une trame d'état, etCadre de commandeNous allons le créer et le renvoyer. La première trame de commande contient la négociation de connexion et la force nulle.set_cursor_forceComprend « Keep-Alive ». Les trames suivantes contiennentUniquement « Keep Alive »est inclus (la session est supprimée).

Il s'agit d'une boucle asynchrone unique — recv() → Créer une commande → send() → Répétition.

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)​

Dans la variante Python, vous pouvez spécifier deux indicateurs permettant de modifier la sortie du tutoriel.

drapeauEffet
--fullAu lieu d'afficher un résumé sur une seule ligne, cet outil formate et affiche la charge utile JSON brute de chaque trame d'état. Cela s'avère pratique pour vérifier les champs envoyés par le service.
--query-configPour chaque tick envoyé, session.force_render_full_state: {} et a ajouté une fonctionnalité permettant au service de générer un instantané complet à chaque image (config Bloc — (type de périphérique, micrologiciel, préréglages, montage, filtres, etc.) sera renvoyé. En l'absence de cet indicateur,config Elle n'est transmise que dans la première trame ; les trames suivantes ne contiennent que les modifications issues du streaming.

Ces deux indicateurs peuvent être utilisés conjointement.python 01-haply-inverse-print-inverse3.py --full --query-config Lorsqu'on l'exécute, à chaque tick config La charge utile JSON complète s'affiche. Cela s'avère pratique pour vérifier en temps réel les modifications apportées aux paramètres depuisHaply Hub ou l'API HTTP. Pour en savoir plus sur les commandes WebSocket sous-jacentes,session.force_render_full_state Veuillez consulter [...].

Dans la variante C++, ces indicateurs ne sont pas disponibles. Le programme affiche toujours un résumé sur une seule ligne, etconfig Il ne reçoit que la première trame.

Inclus dans le programme d'installation du SDK

Le tutoriel 01 est également installé localement avec le SDK. Dans le répertoire d'installation du service, sous le dossier tutorials/01-haply-inverse-print-inverse3/ Veuillez vérifier.

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

À lire également : Protocole WebSocket · Commandes de contrôle (set_cursor_force) · Session · type (vec3)