Aller au contenu principal

09. Navigateur d'espace de travail WebSocket

Parcourez la position de l'espace de travail de l'appareil en temps réel en envoyant des commandes en continu set_transform sur le canal WebSocket. Le tutoriel utilise HTTP pour détecter la session et l'appareil (exactement comme le tutoriel 08), puis établit une connexion WebSocket pour transmettre les mises à jour de position à chaque cycle.

Cela illustre la différence entre deux opérations de transformation :

OpérationTutorielUtilisation typique
configure.mount — transformation de montage persistante08Définie une seule fois (ou rarement) pour décrire la configuration physique de l'appareil
set_transform — transformation continue de l'espace de travail09 (ce tutoriel)Également persistante, mais pouvant être transmise en continu à chaque cycle pour permettre une navigation en temps réel dans l'espace de travail

Ces deux commandes sont disponibles via HTTP et WebSocket, et toutes deux sont persistantes : le service enregistre la dernière valeur que vous avez envoyée. La différence réside dans l'objectif et la fréquence de mise à jour : configure.mount est optimisée pour des mises à jour peu fréquentes (installation physique), tandis que set_transform est optimisée pour une diffusion en continu à haute fréquence (navigation dans la scène).

Utilisez set_transform lorsque la position de l'espace de travail doit suivre un élément qui évolue au fur et à mesure de l'exécution : suivre un mouvement de la main, animer un décalage procédural ou permettre à un opérateur de déplacer l'espace de travail virtuel en temps réel.

Le montage et l'espace de travail sont étroitement liés

Pris séparément, configure.mount et set_transform semblent produire le même effet, mais ils sont imbriqués : dans le pipeline de coordonnées, la transformation de l'espace de travail est appliquée par-dessus le montage (device → basis → mount → workspace → application). Voir Montage et espace de travail pour l'ensemble du pipeline.

Cas d'utilisation​

  • Navigation en temps réel dans l'espace de travail. Déplacez l'espace de travail du curseur de l'appareil (la zone délimitée couverte par l'effecteur) sans interrompre l'expérience haptique.
  • Alignement piloté par un opérateur. Demandez à une personne, depuis un deuxième terminal, de maintenir les touches fléchées enfoncées pour décaler l'espace de travail pendant que l'application haptique principale est en cours d'exécution — cette fonction est utile pour l'étalonnage sur le poste de travail lors d'une session en direct.
  • Déplacement procédural de l'espace de travail. Contrôlez la position de l'espace de travail à partir d'un script (réactif au son, basé sur la physique, etc.) en envoyant à chaque cycle des corrections de transformation ne portant que sur la position.

Prérequis​

Le tutoriel 09 nécessite une session WebSocket active — un client disposant déjà d’ Inverse3 , dans une boucle haptique en cours d’exécution. Le tutoriel 09 se connecte ensuite à cette session et décale son espace de travail en temps réel.

La manière la plus rapide de démarrer une session

Ouvrez l'Haply Hub et lancez la démo Orb. Elle ouvre une session haptique persistante que vous pouvez cibler immédiatement :

./09-haply-inverse-ws-remote-control --session co.haply.hub::demo-orb
python 09-haply-inverse-ws-remote-control.py --session "co.haply.hub::demo-orb"

La scène Orb affiche une sphère au centre de l'espace de travail — déplacer l'espace de travail à l'aide du tutoriel n° 09 déplace l'ensemble de la scène en temps réel, ce qui vous offre un retour visuel instantané.

Tout autre tutoriel (du 01 au 07) qui exécute une boucle haptique fonctionne également. Lancez-le dans un premier terminal, puis démarrez le tutoriel 09 dans un deuxième terminal et laissez-le explorer la session de manière interactive.

Utilisation​

# Discover session interactively, use first detected device
./09-haply-inverse-ws-remote-control
python 09-haply-inverse-ws-remote-control.py

# Target the Haply Hub Orb demo directly
./09-haply-inverse-ws-remote-control --session co.haply.hub::demo-orb
python 09-haply-inverse-ws-remote-control.py --session "co.haply.hub::demo-orb"

# Target a session directly, specify device
./09-haply-inverse-ws-remote-control --session :my_profile:0 --device A14
python 09-haply-inverse-ws-remote-control.py --session "#42" --device A14

Commandes​

Maintenez une touche enfoncée pour vous déplacer en continu. Relâchez-la pour vous arrêter.

ToucheAction
→ / ←+X / −X
↑ / ↓+Y / −Y
Page Up / Page Down+Z / −Z
= / -Augmenter / réduire la vitesse de navigation
0Réinitialiser l'espace de travail à son état d'origine
HAfficher l'aide
EscLâcheur (Ctrl+C (ça fonctionne aussi)

Fonctionnement​

Étape 1 — HTTP : identification de la session et de l'appareil​

Le tutoriel réutilise les mêmes fonctions utilitaires discover_session() / discover_device() que le tutoriel 08 : GET /sessions (ou GET /sessions/<selector> avec --session), puis GET /devices (ou utilisation directe de --device). Les deux fonctions acceptent les mêmes options en ligne de commande, avec un texte SESSION_HELP identique : un sélecteur issu du tutoriel 00 ou 08 fonctionne ici sans modification.

Étape 2 — Session WebSocket, négociation dès le premier message​

Le tutoriel ouvre un WebSocket vers ws://localhost:10001. Au seul premier message reçu, il envoie l'enregistrement du profil de session :

{
"session": {"configure": {"profile": {"name": "co.haply.inverse.tutorials:ws-remote-control"}}},
"inverse3": [{"device_id": "...", "commands": {"set_transform": {"transform": {"position": {"x": 0, "y": 0, "z": 0}}}}}]
}

Les cases suivantes ne sont pas cochées session — uniquement le tableau de commande inverse3 est envoyé.

Étape 3 — set_transform à chaque tick​

set_transform accepte une transformation partielle — uniquement les champs que vous souhaitez modifier. Ce tutoriel n'envoie que la position ; la rotation et l'échelle conservent leurs valeurs par défaut de la session (celles définies par configure.mount, le cas échéant).

{
"inverse3": [{"device_id": "...", "commands": {"set_transform": {"transform": {"position": {"x": 0.02, "y": 0.0, "z": 0.01}}}}}]
}

La position s'ajuste tick par tick. À environ 1 kHz, le service réapplique set_transform à chaque tick (ordre zéro), de sorte que l'espace de travail reste à la dernière position envoyée.

set_transform ou configure.mount

Ces deux commandes enregistrent une transformation persistante par session, mais la transformation de l'espace de travail s'effectue par-dessus le montage dans le pipeline (voir Montage et espace de travail). Pendant la diffusion du tutoriel n° 09 set_transform À chaque tick, chaque nouvelle trame WebSocket remplace la transformation de l'espace de travail diffusée précédemment ; ainsi, tout autre client qui diffuse set_transform vers le même instrument sera écrasée au tick suivant. configure.mount est indépendant et conserve sa valeur. En pratique, choisissez un canal par type de problème : le montage pour la configuration physique, set_transform pour la navigation en temps réel.

Modèle de threads (C++)​

Le tutoriel C++ utilise deux threads qui partagent un compteur de position :

Fil de discussionRôle
Fil de discussion principalLit std::getline(std::cin, ...), analyse les jetons, met à jour nav_vel[] et default_step
Thread de rappel WebSocketA fait avancer nav_pos[] avec nav_vel[] * dt, sérialiser set_transform et l'envoie

std::mutex nav_mutex protège nav_pos[], nav_vel[] et default_step. L'horodatage last_tick et l'indicateur first_ws_msg sont des fonctions locales au niveau de l'appel WS et ne nécessitent pas de mutex.

ws.onmessage = [&](const std::string &) {
float pos_snap[3];
{
std::lock_guard<std::mutex> lk(nav_mutex);
for (int i = 0; i < 3; ++i) nav_pos[i] += nav_vel[i] * 0.001f; // mm/frame → m
for (int i = 0; i < 3; ++i) pos_snap[i] = nav_pos[i];
}
// build and send set_transform with pos_snap
};

Source​

Fourni avec le programme d'installation du SDK

Le tutoriel 09 est installé localement avec le SDK — consultez tutorials/09-haply-inverse-ws-remote-control/ dans le répertoire d'installation du service.

Voir aussi : commande set_transform · Sessions — négociation dès le premier message · Montage et espace de travail · Sélecteurs · Tutoriel 08 — Configuration HTTP à distance · Tutoriel 07 — Base et montage