09. Navigateur d'espace de travail WebSocket
Naviguer dans les paramètres d'un appareil position de l'espace de travail en temps réel en streaming set_transform commandes via le canal WebSocket. Le tutoriel utilise HTTP pour détecter la session et l'appareil (exactement comme Tutoriel 08), puis ouvre un WebSocket pour envoyer les mises à jour de position à chaque tick.
Cela illustre la différence entre deux opérations de transformation :
| Fonctionnement | Tutoriel | Utilisation courante |
|---|---|---|
configure.mount — transformation de montage persistante | 08 | À définir une seule fois (ou rarement) pour décrire le montage physique de l'appareil |
set_transform — transformation persistante de l'espace de travail | 09 (celui-ci) | Également persistant, mais peut être diffusé à chaque tick pour une navigation en temps réel dans l'espace de travail |
Ces deux commandes sont disponibles via HTTP et WebSocket, et les deux sont persistant — le service mémorise la dernière valeur que vous avez envoyée. La différence réside dans la finalité et la fréquence de mise à jour : configure.mount est optimisé pour les mises à jour peu fréquentes (configuration physique), tandis que set_transform est optimisé pour la lecture en continu à haute fréquence (navigation entre les scènes).
Utilisation set_transform lorsque l'origine de l'espace de travail doit suivre un élément qui évolue en temps réel — suivre le mouvement d'une main, animer un décalage procédural ou permettre à un opérateur de modifier l'espace de travail virtuel en direct.
Chacun, configure.mount et set_transform semblent produire le même effet, mais elles sont élevé par ses parents: la transformation de l'espace de travail est appliquée en plus de le montage dans le pipeline de coordonnées (device → basis → mount → workspace → application). Voir Support et espace de travail pour l'ensemble du processus.
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 que l'effecteur terminal peut atteindre) sans interrompre la scène haptique.
- Alignement piloté par l'opérateur. Permettez à une personne utilisant un deuxième terminal de maintenir les touches fléchées enfoncées pour déplacer l'espace de travail pendant que l'application haptique principale est en cours d'exécution — cette fonctionnalité est utile pour effectuer un calibrage du bureau propre à chaque utilisateur lors d'une session en direct.
- Mouvement 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 tick des patchs de transformation contenant uniquement la position.
Conditions préalables
Le tutoriel 09 nécessite une session WebSocket active, c'est-à-dire un client sur lequel Inverse3 est déjà lancé Inverse3 une boucle haptique. Le tutoriel 09 se connecte ensuite à cette session et synchronise son espace de travail en temps réel.
Ouvrez Haply et lancez la démo Orb. Cela 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 à l'origine de l'espace de travail — le déplacement de l'espace de travail à l'aide du Tutoriel 09 déplace l'ensemble de la scène en temps réel, vous offrant ainsi un retour visuel immédiat.
Tout autre tutoriel (01 à 07) exécutant une boucle haptique fonctionne également. Lancez-le dans un terminal, puis lancez le tutoriel 09 dans un deuxième terminal et laissez-le détecter 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
- Python
- C++
Maintenez une touche enfoncée pour continuer à avancer. Relâchez-la pour vous arrêter.
| Clé | Action |
|---|---|
→ / ← | +X / −X |
↑ / ↓ | +Y / −Y |
Page Up / Page Down | +Z / −Z |
= / - | Augmenter / réduire la vitesse de navigation |
0 | Réinitialiser l'espace de travail à l'origine |
H | Afficher l'aide |
Esc | Quitter (Ctrl+C (ça marche aussi) |
Mode ligne par ligne : tapez votre texte, puis appuyez sur ENTRÉE.
| Commande | Action |
|---|---|
x+[N] / x-[N] | Régler la vitesse X sur ±N mm/image (sans x+ (utilise la vitesse par défaut actuelle) |
y+[N] / y-[N] | Régler la vitesse Y sur ±N mm/image |
z+[N] / z-[N] | Régler la vitesse Z sur ±N mm/image |
s+[N] / s-[N] | Régler la vitesse par défaut de ±N mm/image |
stop | Remettre toutes les vitesses à zéro |
reset | Vitesse nulle et retour à l'origine |
h | Afficher l'aide |
Appuyez sur Ctrl+C (ou Ctrl+D / EOF) pour quitter.
Comment ça marche
Étape 1 — Détection des sessions HTTP et des appareils
Le tutoriel réutilise le même discover_session() / discover_device() auxiliaires en tant que Tutoriel 08: GET /sessions (ou GET /sessions/<selector> avec --session), alors GET /devices (ou utilisez --device (directement). Ces deux aides acceptent les mêmes options de ligne de commande avec des SESSION_HELP texte — un sélecteur issu du tutoriel 00 ou 08 fonctionne ici tel quel.
Étape 2 — Session WebSocket, établissement de la connexion lors du premier message
Le tutoriel ouvre un WebSocket vers ws://localhost:10001. Sur le uniquement le 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 coches suivantes sont omises session — seulement le inverse3 la séquence de commandes est envoyée.
Étape 3 — Par impulsion set_transform
set_transform accepte un transformation partielle — uniquement les champs que vous souhaitez modifier. Ce tutoriel ne transmet que la position ; la rotation et la mise à l'échelle restent aux 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 est mise à jour à chaque impulsion. À environ 1 kHz, le service réapplique set_transform à chaque mise à jour (maintien d'ordre zéro), de sorte que l'espace de travail reste à l'endroit où vous l'avez déplacé en dernier.
set_transform contre configure.mountCes deux commandes enregistrent une transformation persistante par session, mais la transformation de l'espace de travail se trouve en plus de le montage dans le pipeline (voir Support et espace de travail). Pendant que le tutoriel 09 est en cours de lecture set_transform À chaque tick, chaque nouvelle trame WebSocket remplace la transformation de l'espace de travail précédemment diffusée ; ainsi, tout autre client diffusant set_transform vers le même périphérique seront remplacés lors du prochain cycle. configure.mount est indépendant et conserve sa valeur. En pratique, choisissez un canal par aspect : le montage pour la configuration physique, set_transform pour la navigation en temps réel.
Modèle de multithreading (C++)
Le tutoriel C++ utilise deux threads qui partagent un compteur de position :
| Fil de discussion | Rôle |
|---|---|
| Fil principal | Nombre de lectures std::getline(std::cin, ...), analyse les tokens, met à jour nav_vel[] et default_step |
| Thread de rappel WebSocket | Progrès nav_pos[] en utilisant nav_vel[] * dt, sérialise set_transform, envoie |
std::mutex nav_mutex protège nav_pos[], nav_vel[]et default_step. Le last_tick horodatage et first_ws_msg Ces indicateurs sont propres à la fonction de rappel 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
Le tutoriel 09 est installé localement avec le SDK — regardez dans tutorials/09-haply-inverse-ws-remote-control/ dans le répertoire d'installation du service.
À lire également : set_transform commande · Sessions — établissement de la connexion lors du premier message · Support et espace de travail · Sélecteurs · Tutoriel 08 — Configuration à distance via HTTP · Tutoriel 07 — Base et support