跳转至正文

01. 输出Inverse3

通过连接到模拟 WebSocket,实时传输服务报告的第一个 Inverse3 的光标位置、速度和力。

学习内容:

  • 建立 WebSocket 连接并接收初始完整状态消息
  • 零力,确保会话持续运行 set_cursor_force 发送“Keep Alive”
  • Haply 注册会话配置文件,以便 Hub 能够识别模拟
  • 仅在首次消息中执行的握手模式——首次传输后移除 session/configure
  • 基于部分更新语义的工作区 transform读取(位置、旋转、缩放)
  • 以易于阅读的速度对控制台输出进行限速

工作流​

  1. ws://localhost:10001打开 WebSocket 连接。该服务列出了已连接的设备, 整体状态帧将立即发送。
  2. 在第一帧中,第一个 Inverse3 的 device_id选择,并创建由两部分组成的请求消息:
    • session.configure.profile.name — Haply Hub将该仿真注册到系统中。
    • 基于零向量的按设备 set_cursor_force 命令。该服务将其用作保持活动机制,只要命令持续到达,就会不断发送状态帧。
  3. 将重新发送消息。在下一个时标之前 session 删除字段 — 由于会话配置文件是一次性的握手过程,因此在后续的帧中仅传输命令。
  4. 此后,在每个状态帧中,光标 vec3 将场(位置、速度、力)的输出频率限制在约10 Hz,并重新发送零力保持信号。

参数​

姓名默认值用途
URIws://localhost:10001仿真通道 WebSocket URL
PRINT_EVERY_MS100控制台输出限流
会话配置文件名称co.haply.inverse.tutorials:print-inverse3Haply 在 Hub 中识别此模拟

“正在阅读”字段​

data.inverse3[0].state摘自以下内容:

  • cursor_position, cursor_velocity, current_cursor_force — 各自 vec3
  • transform — 工作区转换子对象。 position(vec3), rotation(quaternion), scale(vec3) 包含该字段。
部分更新语义

与恒等默认值相同的子字段(position: {0,0,0}, rotation: {w:1,x:0,y:0,z:0}, scale: {1,1,1})为了节省带宽,在有效载荷中 此处省略. 读取值时,请务必指定默认值(例如:C++中的 .value("position", default_pos), Python的 .get("position", default_pos)). 若要始终接收所有字段, serialization/explicit_fields请启用该功能。

发送 / 接收​

WebSocket 循环:接收状态帧, 命令帧生成并重新发送。第一个命令帧包含会话握手和零力 set_cursor_force 其中包含“KeepAlive”,此后所有帧中都包含 仅“Keep Alive” 已包含(该会话将被删除)。

单个异步循环 — recv() → 生成命令 → send() → 重复。

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"]
request_msg = {
"session": {"configure": {"profile": {
"name": "co.haply.inverse.tutorials:print-inverse3"}}},
"inverse3": [{
"device_id": device_id,
"commands": {"set_cursor_force":
{"vector": {"x": 0.0, "y": 0.0, "z": 0.0}}},
}]
}

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

命令行参数(Python)​

Python 变体支持两个可改变教程输出结果的标志:

标志效果
--full它不会显示一行摘要,而是将所有状态帧的原始 JSON 有效载荷以易于阅读的方式输出。这有助于确认服务导出了哪些字段。
--query-config在每个输出时钟周期中 session.force_render_full_state: {}通过重新注入,使服务在每个帧中 config 允许重新导出包含块(设备类型、固件、预设、挂载、过滤器等)的完整快照。如果没有此标志,则 config仅在第一个帧中传递,后续帧均为流式增量。

这两个标志可以一起使用 — python 01-haply-inverse-print-inverse3.py --full --query-config运行该程序后,每隔一个时钟周期 config将输出标有 的完整 JSON 有效载荷。这在观察通过Haply Hub 或 HTTP API 实时更改的设置时非常有用。其基础的 WebSocket 命令是 session.force_render_full_state请参阅。

C++ 变体不提供此标志——它始终只输出一行摘要,并且, config仅在第一个帧中接收。

随SDK安装程序一起提供

教程 01 已随 SDK 一起安装在本地 — 位于服务安装目录下的 tutorials/01-haply-inverse-print-inverse3/您可以在……处查看。

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

相关: WebSocket 协议 · 控制命令 (set_cursor_force) · 会话 · 类型 (vec3)