Zum Hauptinhalt springen

05. Positionssteuerung

durch set_cursor_position Bewegen Sie den Cursor unter Inverse3 an die gewünschte Position.Die Interaktionsmodelle unterscheiden sich je nach Sprache.——C++ verwendet einmalige zufällige Ziele, Python nutzt eine kontinuierliche, tastaturgesteuerte Bewegung.

Lerninhalte:

  • Verwendung set_cursor_position Realisierung der Positionsregelung
  • Zwei verschiedene Interaktionsmodelle, die demselben Basisbefehl entsprechen
  • Das Ziel wird auf die Kugel im Arbeitsbereich beschränkt – der vonMinverse verwendete Radius ist kleiner als der von Inverse3
  • Richten Sie eine Arbeitsbereichsvoreinstellung so ein, dass der Ursprung in der Mitte des Arbeitsbereichs liegt.

Arbeitsablauf​

C++ (Modell mit zufälligen Zielen)​

  1. Starte einen Hintergrund-Eingabethread, der zeilenweise gepufferte Tasteneingaben aus der Standardeingabe (stdin) liest (n、+、-、q).
  2. WebSocket aktivieren. Bei Eintreffen der ersten Frame-Statusdaten registrieren Sitzungsprofil, und legen Sie Folgendes fest: configure.preset: arm_front_centered。Erzeuge das erste zufällige Ziel innerhalb der Kugel (Reject-Sampling, Radius 0,08 m).
  3. In jedem Zyklus wird eine Nachricht an das aktuelle Ziel gesendet set_cursor_position Befehl. Der Cursor folgt dem Ziel sanft – der Server begrenzt die Geschwindigkeit und führt eine Interpolation durch.
  4. Wenn der Benutzer Folgendes eingibt n Wenn Sie die ENTER-Taste drücken, generiert der Eingabe-Thread ein neues zufälliges Ziel.+ / - Geschwindigkeit anpassen;q Beenden.

Python (Modell durch Gedrückthalten verschieben)​

  1. WebSocket aktivieren. Bei Eintreffen der ersten Frame-Statusdaten prüfen, ob status.calibrated——Wenn das Gerät noch nicht kalibriert wurde, wird der Benutzer darauf hingewiesen.
  2. Lesen config.type, um den Radius des Arbeitsbereichs auszuwählen (minverse beträgt 0,04 m, in allen anderen Fällen 0,10 m).
  3. Registrieren Sitzungsprofil, und legen Sie Folgendes fest: configure.preset: arm_front_centered。
  4. In jedem Zyklus: Abfrage des Tastaturstatus (W/A/S/D/Q/E), entlang der Richtung jeder gedrückten Achse drücken SPEED Die Zielposition aktualisieren, sie auf den Arbeitsbereichskugel begrenzen und senden set_cursor_position。Drücken Sie R Das Ziel kann auf den Ursprung zurückgesetzt werden.

Parameter​

BezeichnungStandardwert (C++)Standardwert (Python)Verwendungszweck
workspace_radius / RADIUS_INVERSE30.08 m0.10 m (Inverse3) / 0.04 m (Minverse)Radius der Zielkugel
speed_step / SPEED0.01 / bei jedem Tastendruck0.00005 m / pro ZyklusSchrittweite pro Interaktion
PRINT_EVERY_MS—100Fernsteuerung der Drosselung (Python)
Sitzungsprofilco.haply.inverse.tutorials:position-controlgleichZur Identifizierung im „ Haply Hub“
Kalibrierungsprüfung (Python)

Python-Instanzen werden beginnend mit den Zustandsdaten des ersten Frames überprüft. status.calibrated,Wenn das Gerät nicht kalibriert ist, wird der Benutzer darauf hingewiesen. Die C++-Variante geht davon aus, dass die Kalibrierung bereits abgeschlossen ist.

Gelesene Statusfelder​

  • data.inverse3[0].device_id ——Zur Erstellung von Befehlen
  • data.inverse3[0].state.cursor_position ——Fernmessdaten
  • (Python, nur das erste Bild)data.inverse3[0].config.type ——Zur Auswahl des Radius zwischen Inverse3 und Minverse
  • (Python, nur das erste Bild)data.inverse3[0].status.calibrated ——Wenn der Wert „false“ ist, wird der Benutzer darauf hingewiesen.

Senden / Empfangen​

Kommunikationsablauf​

  • C++ Einen Hintergrund-stdin-Thread ausführen, der Folgendes schreibt: std::atomic<float> Zielwerte vom Typ; der WebSocket-Thread liest diese Werte in jedem Zyklus aus. Eingabe n Wenn Sie die ENTER-Taste drücken, generiert der Eingabethread ein neues zufälliges Ziel; Eingabe q In diesem Fall werden beide Threads beendet.
  • Python Eine single-threaded asynchrone Implementierung – Die WebSocket-Schleife fragt in jedem Zyklus den Tastaturstatus ab und aktualisiert ihn direkt. position。

Die Datenlast der Inverse-API ist identisch: Im ersten Zyklus werden das Sitzungskonfigurationsprofil und configure.preset, in den folgenden Zyklen werden nur set_cursor_position。

Einzelne asynchrone Schleife. Tastaturabfrage (handle_keys) wird in jedem Zyklus inline ausgeführt, ohne Threads zu verwenden.config.type und status.calibrated Wird nur einmal aus den Zustandsdaten des ersten Frames gelesen.

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"]
radius = get_workspace_radius(data["inverse3"][0].get("config", {}))
# Handshake: profile + preset (one-shot)
request_msg = {
"session": {"configure": {"profile": {"name": SLUG}}},
"inverse3": [{
"device_id": device_id,
"configure": {"preset": {"preset": "arm_front_centered"}},
}],
}
else:
# Per tick: update position from keyboard (classic polling, not shown), send command
position = handle_keys(position, radius)
request_msg = {
"inverse3": [{
"device_id": device_id,
"commands": {"set_cursor_position": {"position": position}},
}],
}

await websocket.send(json.dumps(request_msg))
Im Lieferumfang des SDK-Installationsprogramms enthalten

Tutorial 05 wird ebenfalls zusammen mit dem SDK lokal installiert – bitte im Installationsverzeichnis des Dienstes unter tutorials/05-haply-inverse-position-control/ dort suchen.

Quellcode: Python · C++ · C++ Glaze

Verwandte Themen: Steuerbefehle (set_cursor_position) · Einbindungen und Arbeitsbereiche (Voreinstellungen) · Typ (vec3) · Tutorial 06 (Kombinationen)