Aller directement au corps du texte

04. Bonjour Floor

Le premier effet haptique est un sol virtuel horizontal. Lorsque le curseur appuie sur le sol, celui-ci exerce une force de répulsion. La force est stiffness × penetration_depthil s'agit d'un simple ressort de pénalité basé sur [...], et set_cursor_forceest appliquée le long de l'axe Z.

Contenu pédagogique :

  • set_cursor_forceUtilisation de pour appliquer la force d'un ressort de pénalité
  • cursor_positionCalculer la force en temps réel à partir de la lecture
  • (Python) Pour que le point d'origine soit au centre de l'espace de travail Préréglages d'espace de travail(arm_front_centered) Configuration
  • (Python) keyboard Réglage interactif de la hauteur et de la rigidité du plancher à l'aide du clavier via le module

Flux de travail​

  1. ws://localhost:10001Ouvre une connexion WebSocket et attend la première trame d'état.
  2. Dans la première image, Profil de sessionL'enregistre. La variante Python ajoute en outre une modification pour que le point d'origine soit situé au centre de l'espace de travail. configure.preset: arm_front_centeredtout en transmettant les données ; la variante C++ utilise telle quelle la configuration déjà activée sur l'appareil.
  3. À chaque image cursor_position.zaprès avoir lu, force_z = max(0, (floor_pos - z) * stiffness)après avoir calculé cela, on set_cursor_force Je le renvoie par commande.
  4. Par la suite, chaque « tick » ne transmet que des commandes de force. Le profil de session correspond à une poignée de main unique.
  5. (Python) En interrogeant les touches directionnelles du clavier à chaque tick pour floor_pos / stiffnessest mis à jour en temps réel.

Paramètres​

NomValeur par défautUtilisation
floor_pos0.10 mCoordonnée Z du plan du sol virtuel
stiffness1000 N/mConstante de ressort (penétration de 1 mm → 1 N)
PRINT_EVERY_MS100–200Limite d'intervalle de sortie de télémétrie
Nom du profil de sessionco.haply.inverse.tutorials:hello-floorHaply Identifier cette simulation dans Hub
Interactif (Python uniquement)

Les variantes de Python sont keyboard Utilisez le paquet (sous Linux, des droits d'accès élevés sont nécessaires) :

  • ↑ / ↓ — Relever / abaisser le plancher
  • ← / → — Diminution / augmentation de la résistance
  • R — Réinitialiser aux paramètres par défaut
Développer ses capacités

Les forces sont additionnéesau niveau du « service tick ». En d'autres termes, les forces provenant de plusieurs sources sont additionnées avant d'être transmises à l'appareil. Le code écrit selon les principes de ce tutoriel permet à différents éléments générateurs de force de fonctionner ensemble sans se bloquer mutuellement.

Champ « État de lecture »​

data.inverse3[i].stateValeur lue à :

  • cursor_position.z — vec3, utilisé pour calculer la profondeur de pénétration
  • current_cursor_force — Signalé comme étant destiné à la télémétrie

Émission / Réception​

À chaque tick, lire la valeur Z du curseur, force_z = max(0, (floor_pos - z) * stiffness)après avoir calculé, set_cursor_forceest envoyé. Le premier message envoyé contient (dans toutes les variantes) le profil de session ; dans le cas de Python, il s'agit de configure.preset: arm_front_centeredest également inclus.

Il s'agit d'une boucle asynchrone unique. Lors de la négociation de la première trame, le profil et configure.preset comprend des paramètres floor_pos = 0.1Il s'aligne sur les coordonnées centrales de cet espace de travail.

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"]
# Handshake: profile + preset (one-shot)
request_msg = {
"session": {"configure": {"profile": {"name": "co.haply.inverse.tutorials:hello-floor"}}},
"inverse3": [{
"device_id": device_id,
"configure": {"preset": {"preset": "arm_front_centered"}}
}]
}
else:
# Per tick: compute force along Z, send set_cursor_force
z = data["inverse3"][0]["state"]["cursor_position"]["z"]
force_z = 0.0 if z > floor_pos else (floor_pos - z) * stiffness
request_msg = {
"inverse3": [{
"device_id": device_id,
"commands": {"set_cursor_force":
{"vector": {"x": 0.0, "y": 0.0, "z": force_z}}}
}]
}

await websocket.send(json.dumps(request_msg))
Programme d'installation du SDK inclus

Le tutoriel 04 est également installé localement avec le SDK. Dans le répertoire d'installation du service, sous le dossier tutorials/04-haply-inverse-hello-floor/Vous pouvez le consulter ici.

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

Documents connexes : Commandes de contrôle (set_cursor_force) · Montage et espace de travail (préréglage) · Type (vec3) · session · Tutoriel 07 (Base et support)