Aller au contenu principal

02. Affichage VerseGrip

Affiche en continu l'orientation (quaternion + angles d'Euler Z-X-Y), le niveau du capteur à effet Hall et l'état du bouton depuis le premier VerseGrip filaire.

Ce que vous allez apprendre :

  • Lire les instructions quaternion à partir de la trame d'état
  • Convertir un quaternion en angles d'Euler Z-X-Y en degrés (+X vers la droite, +Y vers l'avant, +Z vers le haut)
  • Utiliser probe_orientation comme signal indiquant qu'un observateur autonome est toujours en place
  • Le modèle de poignée de main, envoyé uniquement dans le premier message (identique à celui du tutoriel n° 01)

Déroulement​

  1. Établissez une connexion WebSocket vers ws://localhost:10001 et attendez la première trame d'état.
  2. Sélectionnez le device_id du premier VerseGrip filaire dans le tableau verse_grip.
  3. Construisez une requête avec le profil de session et un signal de maintien probe_orientation par appareil (une commande à objet vide qui conserve le flux d'orientation de la poignée dans les trames d'état).
  4. Envoyez la requête, puis supprimez le champ session : il s'agit d'une poignée de main ponctuelle.
  5. À chaque trame suivante, convertissez le quaternion en angles d'Euler et affichez la télémétrie à fréquence réduite. Renvoyez le signal de maintien à chaque cycle.

Paramètres​

NomValeur par défautRôle
URIws://localhost:10001URL du canal de simulation WebSocket
PRINT_EVERY_MS100Limite de fréquence de rafraîchissement de l'affichage de la console
Nom du profil de sessionco.haply.inverse.tutorials:print-verse-gripIdentifiez cette simulation dans le Hub Haply
Convention d'Euler

La conversion correspond à une rotation intrinsèque Z-X-Y (lacet → tangage → roulis) dans le repère de l'application. +X right, +Y forward, +Z up. N'utilisez pas glm::eulerAngles : cette fonction suit une autre convention et donnerait ici des valeurs erronées. Les trois variantes de langage implémentent les mêmes calculs ; consultez le code source pour connaître la formule.

Quand probe_orientation est-ce vraiment nécessaire ?

probe_orientation n'est utile que si votre session n'envoie aucune commande à un Inverse3. Dès que vous commandez un Inverse3 (force, position, couple...), le service diffuse automatiquement l'orientation de la VerseGrip associée dans chaque trame d'état : aucun signal de maintien n'est nécessaire. Utilisez probe_orientation uniquement pour les outils de suivi de poignée autonomes, comme dans ce tutoriel.

Champs d'État lus​

Depuis data.verse_grip[0].state :

  • orientation — quaternion (w, x, y, z)
  • hall — valeur entière du capteur à effet Hall
  • button — booléen
  • transform.rotation — rotation de l'espace de travail (quaternion) ; la position et l'échelle ne s'appliquent pas à un appareil qui ne fournit que l'orientation et ne sont jamais transmises
Sémantique de la mise à jour partielle

transform.rotation est omis lorsqu'il est égal au quaternion identité {w:1,x:0,y:0,z:0}. Définissez une valeur par défaut pour la lecture. Activez serialization/explicit_fields pour le recevoir systématiquement.

Envoi / réception​

La boucle WebSocket : recevez une trame d'état, puis construisez et renvoyez la poignée de main et le signal de maintien probe_orientation. Le premier message sortant contient le profil de session ; chaque trame suivante ne contient que le signal de maintien.

Boucle asynchrone unique : recv() → construction de la 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["verse_grip"][0]["device_id"]
request_msg = {
"session": {"configure": {"profile": {
"name": "co.haply.inverse.tutorials:print-verse-grip"}}},
"verse_grip": [{
"device_id": device_id,
"commands": {"probe_orientation": {}} # empty — keepalive
}]
}

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 les deux mêmes options que le tutoriel 01:

  • --full — affiche la charge utile JSON brute sous une forme lisible, au lieu du résumé sur une seule ligne.
  • --query-config — réinjecte session.force_render_full_state à chaque cycle de sortie, afin que chaque trame contienne le bloc config (type d'appareil, micrologiciel, modification de configuration, …) au lieu du simple delta d'état. Utile pour déboguer les modifications de paramètres en temps réel.

Ces deux options sont combinables. Les variantes C++ ne proposent pas ces options.

Fourni avec le programme d'installation du SDK

Le tutoriel 02 est également installé localement avec le SDK — consultez tutorials/02-haply-inverse-print-verse-grip/ dans le répertoire d'installation du service.

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

Voir aussi : Types (quaternion) · Commandes de contrôle (probe_orientation) · Protocole WebSocket · Tutoriel n° 3 (VG sans fil)