跳至主要内容
版本:3.5.x

06. 组合款(Inverse3 Wireless VerseGrip)

双设备教程:指向握把并按住按钮,即可将Inverse3 朝该方向移动。光标被限制在球形工作空间内。

您将学到:

  • 在同一个状态帧中读取两种设备类型(inverse3wireless_verse_grip)
  • 从握把中提取其指向方向 四元数 (本地 +Y 轴)
  • 使用 set_cursor_position 将光标移动到计算出的目标位置
  • 将目标固定在安全工作空间球体内——Minverse 半径比Inverse3更小
  • 设置一个 工作区预设 (arm_front_centered) 因此原点位于伸展范围的中间

工作流程

  1. 了解这两款设备:
    • C++ 变体查询 GET /devices 启动时通过 HTTP 连接,然后显示校准提示并等待按 ENTER 键。
    • Python会从第一个 WebSocket 状态帧中读取这两个设备 ID。
  2. 注册 会话配置文件 并设置 configure.preset: arm_front_centered 在第一条消息中(单次握手)。
  3. 每次点击:读取握把的 orientationbuttons.{a, b} 状态。
  4. 如果按住动作按钮,则计算手柄在世界坐标系中的方向(R(q) · ĵ — 旋转后的单元(沿+Y轴)),并将其累加到按 SPEED.
  5. 将目标夹在工作区球体内,并通过 set_cursor_position.
  6. (仅限 Python)根据设备的 config.typeminverse = 0.04 米,其余均为 0.10 米。

参数

名称默认目的
SPEED0.01 m/tick按住按钮时的移动步骤
RADIUS_INVERSE30.10 mInverse3 Inverse3x 的工作区夹紧半径
RADIUS_MINVERSE0.04 mMinverse 的工作区夹持半径Minverse 仅限 Python — C++ 版本为硬编码Minverse 0.10)
PRINT_EVERY_MS200遥测节流阀
会话配置文件名称co.haply.inverse.tutorials:combined在Haply 中标识此模拟
运行前请进行校准
  • 让Inverse3 (或将握柄放在墨水瓶上,等待 LED 指示灯变为常亮)。
  • 将笔握从笔管上取下。
  • 按住 A 或 B 键并旋转手柄——光标将沿着手柄指向的方向移动。

读取状态字段

来自每帧状态帧:

  • data.inverse3[0].state.cursor_positionvec3
  • data.wireless_verse_grip[0].state.orientationquaternion
  • data.wireless_verse_grip[0].state.buttons.{a, b, c} — 布尔值
  • (Python,仅限第一帧) data.inverse3[0].config.type — 选择Inverse3 Minverse
  • (Python,仅限第一帧) data.inverse3[0].status.calibrated — 如果为 false,则提示用户

发送/接收

四元数到方向的数学运算(旋转 +YR(q)) 和球面夹具属于经典的线性代数——请参阅源文件。Inverse-API 部分则涉及握手过程以及每帧 set_cursor_position.

单个异步循环。Python 从第一个状态帧中读取两个设备 ID;握手过程附加配置文件 + configure.preset: arm_front_centered 到第一页 set_cursor_position.

async with websockets.connect(URI) as websocket:
while True:
msg = await websocket.recv()
data = json.loads(msg)

if first_message:
first_message = False
inverse3_id = data["inverse3"][0]["device_id"]
grip_id = data["wireless_verse_grip"][0]["device_id"]
radius = get_workspace_radius(data["inverse3"][0].get("config", {}))

# Handshake: profile + preset + first position command
request_msg = {
"session": {"configure": {"profile": {"name": SLUG}}},
"inverse3": [{
"device_id": inverse3_id,
"configure": {"preset": {"preset": "arm_front_centered"}},
"commands": {"set_cursor_position": {"position": position}},
}],
}
else:
# Per tick: update position from grip pointing direction (classic math, not shown), send
request_msg = {
"inverse3": [{
"device_id": inverse3_id,
"commands": {"set_cursor_position": {"position": position}},
}],
}

await websocket.send(json.dumps(request_msg))

来源: Python·C++·C++ Glaze

相关: 控制命令 (set_cursor_position) · 类型 (四元数, vec3) · 安装与工作区(预设) · 教程 03(无线 VG) · 教程 05(位置控制)