Aller au contenu principal

07. Base et support – Terrain d'entraînement

Commander un appareil de manière interactive transformation de montage, et faire une démonstration configure.basis,configure.preset et configure.mount Comment travailler en collaboration au niveau des messages de communication ? Maintenir un niveau de base constant afin que l'interaction reste toujours centrée sur la commande « configure ».

Vous apprendrez :

  • Paramètres translation de l'axe de référence("XZY" → (système de coordonnées de l'application sur l'axe Y)
  • Sélectionner Préréglages(arm_front), et comprendre quels éléments il configure
  • Remplacer « mount » à l'exécution en faisant pivoter un quaternion (à l'aide du clavier)
  • Règles d'exclusion mutuelle :mount et preset Ne peuvent pas apparaître simultanément dans le même Configuration du matériel dans le bloc
  • à usage unique configure Signification : une seule commande « configure » est envoyée à chaque pression sur une touche.
  • (C++ Glaze) Utilisation std::optional Modélisation des champs mutuellement exclusifs

Processus de travail​

  1. À la réception du premier message : envoyer Fichier de configuration de session,configure.basis: "XZY" ainsi que configure.preset: arm_front。Pour stabiliser le sol, commencer à envoyer en continu set_cursor_force。
  2. À chaque tick : lire la coordonnée Y du curseur, calculer force_y = max(0, (floor_pos - y) * stiffness) et l'envoyer.
  3. Lorsque l'utilisateur appuie sur la touche de rotation « mount », pending_configure = true Position.
  4. Au prochain tick : créer un configure.mount bloc, dont la transformation rotation Pour les quaternions unitaires (composés selon l'ordre Z puis X en fonction des angles actuels de tangage et de lacet). Omis preset——Ces deux éléments s'excluent mutuellement dans le protocole de communication.
  5. Touche de réinitialisation (R) Effacer les paramètres de remplacement ; lors de la prochaine exécution de `configure`, le système reviendra à preset。

Paramètres​

NomValeur par défautUtilisation
BASIS"XZY"Décalage des axes — Système de coordonnées de l'application sur l'axe Y
DEVICE_PRESET / DEVICE_CONFIG_PRESET"arm_front"Préréglage nommé — Point d'origine situé à la base de l'appareil
FLOOR_POS_Y0.0 mPlan de référence fixe (axe Y du système de coordonnées utilisé)
STIFFNESS1000 N/mConstante de ressort au sol
MOUNT_STEP_DEG10°Angle de rotation à chaque pression sur une touche
PRINT_EVERY_MS200Intervalle de régulation par télémesure

Contrôle​

toucheOpération
W / SRotation autour de l'axe +X (inclinaison) de l'équipement : ±10°
A / DRotation autour de l'axe +Z (lacet) de l'équipement : ±10°
RRéinitialiser le montage — Rétablir les paramètres par défaut
HTouches de commande d'affichage
QQuitter
mount et preset Exclusion mutuelle

Le service refusera les demandes contenant à la fois les deux éléments. Configuration du matériel Bloc. Dès que l'utilisateur aura remplacé le fichier « mount », ce tutoriel l'omettra lors de chaque commande « configure » suivante. preset。Appuyez sur R Ensuite, la prochaine commande « configure » réactivera cette option. preset et supprimer mount。

Différents modes de saisie

La variante C++ lit les entrées ligne par ligne sur le thread stdin en arrière-plan (il faut appuyer sur ENTRÉE après chaque lettre). Python, quant à lui, utilise dans sa boucle asynchrone principale keyboard Le système effectue une interrogation en temps réel des touches, sans qu'il soit nécessaire d'appuyer sur la touche ENTRÉE. Les touches sont les mêmes, tout comme les commandes.

Champs d'état lus​

Source : data.inverse3[i].state:

  • cursor_position.y — vec3, servant à calculer la profondeur de pénétration dans le sol
  • current_cursor_force — Destiné à la transmission de données de télémétrie

Envoyer / Recevoir​

La structure de chargement est identique pour toutes les variantes ; la véritable différence réside dans la manière dont chacune d'entre elles met en place les mécanismes d'exclusion mutuelle. mount / preset les branches, ainsi que la manière dont les threads d'entrée informent les threads WebSocket.

Une boucle asynchrone unique, via keyboard Effectuer une interrogation en temps réel des touches du boîtier.pending_configure Il s'agit d'un indicateur global, activé par la fonction de gestion des touches, à chaque envoi configure Effacer après le bloc.

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 + basis + preset
request_msg = {
"session": {"configure": {"profile": {"name": SLUG}}},
"inverse3": [{
"device_id": device_id,
"configure": build_configure_block(first_handshake=True),
# -> {"basis": {"permutation": "XZY"},
# "preset": {"preset": "arm_front"}}
}],
}
else:
handle_key_inputs() # may set pending_configure = True (classic, not shown)

y = data["inverse3"][0]["state"]["cursor_position"]["y"]
force_y = 0.0 if y > FLOOR_POS_Y else (FLOOR_POS_Y - y) * STIFFNESS

entry = {
"device_id": device_id,
"commands": {"set_cursor_force":
{"vector": {"x": 0.0, "y": force_y, "z": 0.0}}},
}
if pending_configure:
entry["configure"] = build_configure_block(first_handshake=False)
# -> {"mount": {...}} OR {"preset": {...}} (never both)
pending_configure = False

request_msg = {"inverse3": [entry]}

await websocket.send(json.dumps(request_msg))
Fourni avec le programme d'installation du SDK

Le tutoriel 07 est également installé localement avec le SDK — vous pouvez le retrouver dans le répertoire d'installation du service. tutorials/07-haply-inverse-basis-and-mount/。

Code source : Python · C++ · C++ Glaze

Contenu associé : Décalage de l'axe de base · Mount et l'espace de travail · Configuration du matériel · Commandes de contrôle (set_cursor_force) · Type (transformation) · Tutoriel 04 (Hello Floor)