Zum Hauptinhalt springen
Version: 3.5.x

04. Hallo Boden

Dein erster haptischer Effekt: ein virtueller horizontaler Boden, der zurückdrückt, wenn der Cursor darauf drückt. Die Kraft wird durch eine einfache Feder mit negativer Federkonstante erzeugt — stiffness × penetration_depth — entlang Z über set_cursor_force.

Was Sie lernen werden:

  • Verwendung von set_cursor_force eine Federkraft aufzubringen
  • Lesen cursor_position und die Rechenleistung in Echtzeit
  • (Python) Festlegen einer Arbeitsbereichsvoreinstellung (arm_front_centered), sodass der Ursprung in der Mitte des Arbeitsbereichs liegt
  • (Python) Interaktive Anpassung von Bodenhöhe und -steifigkeit über die keyboard Paket

Arbeitsablauf

  1. Öffne einen WebSocket zu ws://localhost:10001 und auf den ersten Status-Frame warten.
  2. Im ersten Frame: Registriere die Sitzungsprofil. Die Python-Variante sendet zusätzlich configure.preset: arm_front_centered Der Ursprung befindet sich also in der Mitte des Arbeitsbereichs; die C++-Varianten verwenden die auf dem Gerät bereits aktive Konfiguration.
  3. Bei jedem Bild: lesen cursor_position.z, berechnen force_z = max(0, (floor_pos - z) * stiffness), und sende es als set_cursor_force Befehl.
  4. Nachfolgende Ticks senden nur den Befehl „force“ – das Sitzungsprofil ist ein einmaliger Handshake.
  5. (Python) Bei jedem Tick werden auch die Pfeiltasten abgefragt und die Anzeige aktualisiert floor_pos / stiffness live.

Parameter

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

Die Python-Variante verwendet die keyboard Paket (unter Linux sind erweiterte Berechtigungen erforderlich):

  • / — Bodenebene anheben / absenken
  • / — Steifigkeit verringern / erhöhen
  • R — Auf Standardwerte zurücksetzen
Die Macht ausweiten

Die Kräfte werden im Service-Tick addiert – sie werden über alle Quellen hinweg summiert, bevor sie an das Gerät gesendet werden. Ein Tutorial wie dieses kann neben anderen Kraftgeneratoren laufen, ohne dass sich diese gegenseitig blockieren.

Statusfelder gelesen

Von data.inverse3[i].state:

  • cursor_position.zvec3, zur Berechnung der Eindringtiefe
  • current_cursor_force — für die Telemetrie gemeldet

Senden / Empfangen

Bei jedem Tick: Z-Koordinate des Cursors lesen, berechnen force_z = max(0, (floor_pos - z) * stiffness)und senden Sie eine set_cursor_force. Die erste ausgehende Nachricht enthält außerdem das Sitzungsprofil (alle Varianten) und für Python configure.preset: arm_front_centered.

Einzelne asynchrone Schleife. Der Handshake im ersten Frame enthält das Profil + configure.preset also floor_pos = 0.1 richtet sich nach den Koordinaten der Arbeitsbereichsmitte aus.

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))

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

Siehe auch: Steuerbefehle (set_cursor_force) · Mount & Arbeitsbereich (Voreinstellungen) · Typen (vec3) · Sitzungen · Anleitung 07 (Basis & Halterung)