Skip to main content
Version: 3.5.x

03. Print Wireless VerseGrip

Same pattern as tutorial 02 but for a Wireless VerseGrip — adds buttons (A/B/C) and battery level to the streamed state.

What you'll learn:

  • Reading wireless-specific state fields: buttons.{a,b,c}, battery_level, hall
  • Using probe_orientation as a standalone-observer keepalive
  • Same first-message-only handshake pattern as tutorial 02

Workflow

  1. Open a WebSocket to ws://localhost:10001 and wait for the first state frame.
  2. Pick the first Wireless VerseGrip's device_id from the wireless_verse_grip array.
  3. Build a request with the session profile and a per-device probe_orientation keepalive.
  4. Send the request, then strip the session field — it's a one-shot handshake.
  5. On every later frame, convert the quaternion to Euler angles and print throttled telemetry including button states and battery level. Resend the keepalive each tick.

Parameters

NameDefaultPurpose
URIws://localhost:10001Simulation channel WebSocket URL
PRINT_EVERY_MS100Console-output throttle
Session profile nameco.haply.inverse.tutorials:print-wireless-verse-gripIdentifies this simulation in Haply Hub
Euler convention

The conversion is intrinsic Z-X-Y (yaw → pitch → roll) in the application frame +X right, +Y forward, +Z up. Do not use glm::eulerAngles — it follows a different convention and will read wrong here. All three language variants implement the same math; see the sources for the formula.

When probe_orientation is actually needed

probe_orientation is only useful when your session doesn't send any command to an Inverse3. As soon as you command an Inverse3 (force, position, torque...), the service automatically streams the paired VerseGrip's orientation in every state frame — no probe needed. Use probe_orientation only for standalone grip-monitoring tools like this tutorial.

State fields read

From data.wireless_verse_grip[0].state:

  • orientationquaternion (w, x, y, z)
  • hall — integer hall-sensor reading
  • buttons.a, buttons.b, buttons.c — booleans
  • battery_level — float (0.0 – 1.0)
  • transform.rotation — workspace rotation (quaternion); position and scale are not applicable for an orientation-only device and are never emitted
Partial-update semantics

transform.rotation is omitted when it equals the identity quaternion {w:1,x:0,y:0,z:0}. Supply a default when reading. Enable serialization/explicit_fields to always receive it.

Send / receive

Same shape as tutorial 02, just with the wireless_verse_grip device array. The WebSocket loop receives a state frame and sends back the handshake + probe_orientation keepalive; the first outgoing message carries the session profile, every subsequent frame carries only the keepalive.

Single async loop.

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["wireless_verse_grip"][0]["device_id"]
request_msg = {
"session": {"configure": {"profile": {
"name": "co.haply.inverse.tutorials:print-wireless-verse-grip"}}},
"wireless_verse_grip": [{
"device_id": device_id,
"commands": {"probe_orientation": {}} # empty — keepalive
}]
}

await websocket.send(json.dumps(request_msg))
request_msg.pop("session", None) # one-shot handshake

Command-line flags (Python)

The Python variant accepts the same two flags as tutorial 01:

  • --full — pretty-prints the raw JSON payload instead of the one-line summary.
  • --query-config — re-injects session.force_render_full_state on every outbound tick so every frame carries the config block instead of just the state delta.

--query-config is especially useful for the Wireless VerseGrip because the config block carries the WVG-specific sub_type field (stylus / prototype / ruko / kingfisher, added in 3.5) on top of the regular config fields. Running python 03-haply-inverse-print-wireless-verse-grip.py --full --query-config lets you watch config.sub_type update live alongside the other config values.

The C++ variants do not expose these flags.

Shipping with the SDK installer

Tutorial 03 is also installed locally with the SDK — look in tutorials/03-haply-inverse-print-wireless-verse-grip/ under the service install directory.

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

Related: Tutorial 02 (Wired VG) · Types (quaternion) · Control Commands (probe_orientation) · WebSocket Protocol