Zum Hauptinhalt springen

04. Hallo Boden

Ihr erster haptischer Effekt: ein virtueller horizontaler Boden, der zurückdrückt, sobald der Cursor in ihn eindringt. Die Kraft wird durch eine einfache Penalty-Feder dargestellt (stiffness × penetration_depth), die entlang der Z-Achse über set_cursor_force angewendet wird.

Was Sie lernen:

  • Verwendung von set_cursor_force, um eine Straf-Federkraft anzuwenden
  • Auslesen von cursor_position und Berechnung der Kraft in Echtzeit
  • (Python) Festlegen eines Voreinstellungen für den Arbeitsbereich (arm_front_centered), sodass der Ursprung in der Mitte des Arbeitsbereichs liegt
  • (Python) Interaktive Feinabstimmung von Bodenhöhe und Steifigkeit über die Tastatur mithilfe des Pakets keyboard

Ablauf​

  1. Stellen Sie eine WebSocket-Verbindung zu ws://localhost:10001 und warten Sie auf den ersten Zustandsframe.
  2. Erfassen Sie im ersten Frame das Sitzungsprofil. Die Python-Variante sendet zusätzlich configure.preset: arm_front_centered, sodass der Ursprung in der Mitte des Arbeitsbereichs liegt; die C++-Varianten verwenden die Konfiguration, die auf dem Gerät bereits aktiv ist.
  3. Bei jedem Frame lesen Sie cursor_position.z aus, berechnen force_z = max(0, (floor_pos - z) * stiffness) und senden das Ergebnis als Befehl set_cursor_force zurück.
  4. Bei den folgenden Ticks wird nur noch der Befehl „Kraft“ gesendet – das Sitzungsprofil ist ein einmaliger Handshake.
  5. (Python) Bei jedem Tick werden außerdem die Pfeiltasten der Tastatur abgefragt, und floor_pos / stiffness werden in Echtzeit aktualisiert.

Parameter​

NameStandardZweck
floor_pos0.10 mZ-Koordinate der virtuellen Bodenebene
stiffness1000 k. A.Federkonstante (1 mm Eindringtiefe → 1 N)
PRINT_EVERY_MS100–200Einschränkung der Telemetrie
Name des Sitzungsprofilsco.haply.inverse.tutorials:hello-floorKennzeichnet diese Simulation im „ Haply “-Hub
Interaktiv (nur Python)

Die Python-Variante verwendet das Paket keyboard (Unter Linux sind erweiterte Berechtigungen erforderlich):

  • ↑ / ↓ — Bodenebene anheben / absenken
  • ← / → — Steifigkeit verringern / erhöhen
  • R — auf Standardwerte zurücksetzen
Erweiterung der Kraft

Kräfte wirken beim Dienst-Tick additiv – sie werden aus allen Quellen addiert, bevor sie an das Gerät gesendet werden. Ein Tutorial wie dieses kann neben anderen Kraftquellen bestehen, ohne dass eine der beiden die andere blockiert.

Ausgelesene Zustandsfelder​

Aus data.inverse3[i].state:

  • cursor_position.z — vec3, wird zur Berechnung der Eindringtiefe verwendet
  • current_cursor_force — wird für die Telemetrie gemeldet

Senden / Empfangen​

Bei jedem Tick: Z-Wert des Cursors auslesen, force_z = max(0, (floor_pos - z) * stiffness) berechnen und einen Befehl set_cursor_force senden. Die erste ausgehende Nachricht enthält außerdem das Session-Profil (alle Varianten) und bei Python zusätzlich configure.preset: arm_front_centered.

Eine einzige asynchrone Schleife. Der Handshake beim ersten Frame enthält das Profil und configure.preset, sodass floor_pos = 0.1 mit den Koordinaten der Mitte des Arbeitsbereichs übereinstimmt.

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))
Im Lieferumfang des SDK-Installationsprogramms enthalten

Tutorial 04 wird außerdem lokal mit dem SDK installiert – zu finden unter tutorials/04-haply-inverse-hello-floor/ im Installationsverzeichnis des Dienstes.

Quelle: Python · C++ · C++ Glaze

Verwandte Themen: Steuerbefehle (set_cursor_force) · Montage & Arbeitsbereich (Voreinstellungen) · Typ (vec3) · Sitzungen · Tutorial 07 (Grundlagen & Montage)