这是自一年前 API 重写以来我们最大的一次版本更新。3.5.0 引入了统一的 3D 数学层、对 Minverse 的全面支持、带类型的事件流、完整的配置 API 以及更简洁的 HTTP 接口,同时还包含了过去一年中的缺陷修复和体验改进。
亮点 {#highlights}
统一的 3D 数学层——可组合的变换管道,为设备基础坐标系(frame)、安装变换、工作空间变换和导航变换提供基础单元,并支持在本地、会话、应用程序和内部空间之间进行显式转换。气泡导航——通过成形区域(SDF 元元)在大型虚拟工作空间中进行导航,支持基于速度映射的速率控制、感知滞后的碰撞检测,以及可选的朝光标漂移功能。可通过 HTTP 和 WebSocket 进行全面配置,并支持应用空间的往返操作。带类型的事件流— 专用的 WebSocket 事件通道,用于设备生命周期、安全警报、校准、电池状态、控制速率警告和淘汰提示。设置 API— 一个完整的键值设置系统,支持 HTTP CRUD、类型提示、取值范围约束和描述信息,取代了旧的嵌套配置文件。统一的设备配置 — 所有设备共用一套 HTTP 路由:基础、安装、预设、变、过滤器、惯用手、扭矩缩放、重力补偿、首页_返回。Minverse 与笔的同步校准— 设备及其笔现在可以一起进行校准;在握柄实际连接之前,校准状态将保持锁定。HTTP 易用性改进 — 基于索引的设备选择器(无需 ID,通过索引指定设备),与 WebSocket 共享统一的请求/响应结构,可选启用 {成功、错误、数据} 封装(?format=json),以及通配符会话选择器。新功能 {#new-features}
设备 {#devices}
Minverse— 本版本正式支持:设备检测、就绪流程、安全通知以及同步校准工作流。Ruko和Kingfisher已被认定为官方握把产品类型。设备模拟器支持— 可检测并与软件模拟设备通信,并与真实硬件并存。连接循环保护 — 行为异常的端口将被自动屏蔽;可通过 POST /ports/{port}/reset 重置。笔连接心跳——具备抗抖动的可靠握持连接/断开检测功能。会话、命令与 WebSocket {#sessions-commands-websocket}
会话配置文件的过滤与持久化— 会话声明配置文件名称和所需的 SDK 版本,服务会在重新连接后记住这些信息;客户端和监控工具可依据该配置文件过滤和定位会话。按会话划分的命令缓冲区——一个运行缓慢的会话不再会阻塞其他会话。用于单次命令的显式 `configure` 映射 — 每个设备的 基础、预设、安装、force_gate、阻尼,以及每个会话的 个人资料 和 基础,目前均位于 配置 其中,与输出配置映射保持一致,因此发送的内容与读取的内容在往返过程中保持一致。可自定义的设备安装方式 — 可选择内置的工作区预设(默认值、前臂、臂部前侧居中、前大灯、led_front_centered),也可以发送显式的转换;手动修改安装方式时,预设会自动切换为 自定义。具名命令字段 — 位置、向量、角度、扭矩 取代了通用的 价值观 数组。设置角扭矩 取代了 set_angular_torque(单数形式已废止)。会话帧扩展 — v3.0 和 v3.1 的会话帧现在包含可扩展的 配置、状态 和 状态 对象;新增的输出字段包括 current_cursor_force、当前光标位置、当前角扭矩、当前角位置、控制域、控制模式、变、transform_velocity、更丰富的 config.*,以及 状态.安全(默认隐藏)。部分转换更新 — 在安装方式、工作空间转换和导航形状方面,只需发送需要更改的子字段(位置、旋转、比例尺)。HTTP {#http}
GET / — 服务版本。GET/POST/DELETE /settings 及 /settings/* — 完整的键值设置 API。GET /sessions/{session} 及 GET/POST/DELETE /sessions/{session}/profile。GET /devices?session=<selector> — 将设备坐标转换到指定会话的应用空间中。基于索引的设备选择器 — 无需知道 ID 即可通过索引定位任意设备(/inverse3/0/... 指向第一个Inverse3;inverse... (适用于所有 Inverse 系列设备)。统一的请求/响应结构 — POST/GET 的请求体与 WebSocket 使用相同的 command_data JSON 结构;针对一种传输方式编写的代码也可用于另一种。可选的封装结构 — 可在任意路由上使用 ?format=json 即可启用;/设置* 和 GET /home_return 默认使用 {成功、错误、数据}。如需原始结构,请使用 ?format=plain。会话选择器通配符 — 配置文件名称中的 *(任意字符序列)和 ?(单个字符)。百分号解码的选择器 — %2A、%3A 在到达路由器之前会被解码。事件 {#events}
在 沟通/活动/港口 提供专用的 WebSocket 事件流。共有 24 类带类型的事件,包括设备生命周期、安全事件(紧急停止、异物检测、失速)、校准失败、电池警报、会话警告、控制速率过低/严重过低、输入验证和弃用提示。可观测性 {#observability}
启用性能分析时,日志消息会根据级别进行着色,然后转发至 Tracy。每个 HTTP 处理程序都设有 Tracy 区域。主循环用于计时和统计事件。可配置日志目录和服务器主机名(以便 Docker 使用)。3.6 版本即将发布 {#coming-in-36}
SDF 触觉效果(SDF HFX)——基础工作已在 3.5 版本中完成(模块、生命周期、模块提供的命令/状态序列化),公开 API 将随 3.6 版本发布,并附有完整的文档。改进 {#improvements}
力振荡滤波——按轴进行振荡检测、8 阶段渐进式恢复、带滞后的进入投票机制,以及非对称的释放窗口。运行时力门滤波器 — 可通过 WebSocket 或 HTTP 使用 configure.force_gate.gain 进行配置,并设置持久化的默认值。主循环最高频率提升至 32 kHz,适用于精密应用。更小的 WebSocket 负载 — 默认情况下,输出中会省略默认值为恒等变换的子字段(position = 0、旋转 = 单位矩阵、比例 = 1),从而减小负载大小,并恢复与旧版 Unity 软件包 4 KB 消息长度限制的兼容性。两个高级设置(序列化/显式字段、序列化/强制完成转换)可为有需要的用户重新启用所有字段。降低主循环抖动— WebSocket 消息处理在 JSON 解析和网络发送期间不再阻塞主循环周期;会话周期调度已提前至响应序列化之前。服务器默认仅监听 localhost — 如需开启网络访问,请启用 通信/绑定所有接口 设置。设备选择器的通配符采用前缀语法(例如 inverse (适用于所有 Inverse 系列设备)。阻尼指令 已与 force_gate 一起搬进来 配置 正在映射。轮转文件日志记录器取代了原有的记录器,并支持可配置的目录。模块提供的命令与状态— 模块可在不修改核心模式的情况下,向 WebSocket 帧注入自定义命令、配置字段和状态输出。修复 {#fixes}
一年的缺陷修复;其中影响最大的列举如下。
会话速度不稳定,仅在特定条件下出现。GripHook(Verse Grip Stopper)在未进行仿真运行时未能正常释放。Inverse3 超时设置过短,导致启动较慢的设备陷入断连循环。在Windows 上停止服务时未彻底清理— 关闭时 HTTP 服务器并不总能被清理。重连循环,发生在服务向旧版固件发送不受支持的命令时。在安装了蓝牙适配器的系统上,蓝牙设备枚举会产生大量日志。连续多次重启服务时发生崩溃。无线 Verse Grip 接收器卡死,发生在Ubuntu 笔记本电脑进入睡眠/唤醒之后。无线 Verse Grip 握把(Linux 和 macOS)在首次检测尝试失败时,现在能够正确回退。macOS 配置文件位置 — 配置目前存储在 ~/Library/Application Support/ 中,而不是错误的路径。Linux 和 macOS 上的 SIGSEGV 信号处理— 启用多线程崩溃捕获后,进程将不再因致命信号而陷入循环。跨会话命令覆盖— 一个会话中的配置命令可能会被另一个会话中的命令静默替换;现在会得到正确的过滤和合并。探测命令覆盖配置 — 监控会话(例如Haply Hub)发送 探针位置 此时,将不再默认覆盖待处理的基底/预设/配置文件更改。原型手柄显示问题— 原型硬件被错误地显示为标准手柄,而非自定义手柄。旧版 `set_basis` 矩阵约定重新生效,供尚未迁移的客户端使用。Inverse3 当会话断开时 ,“力踢”不再产生残余力峰值。WebSocket 连接丢失的竞争条件出现在快速连接/断开循环期间。WebSocket `session_id` 在部分外发负载中被序列化为 0。在Windows 上,--日志级别 与 --dev 现在在同时使用时会遵循该设置(此前会被静默重置为 调试)。已弃用项 {#deprecations}
仍可正常使用,但将在未来的重大版本中移除。在适用情况下,响应中将包含 弃用警告 字段。
| 已弃用 | 替代项 |
|---|---|
| POST /force_scale | POSTinverse |
| POST /重力补偿 | POST /{device}/{id}/config/gravity_compensation |
| POST /torque_scaling | POST /{device}/{id}/config/torque_scaling |
| POST /device_handedness | POST /{device}/{id}/config/handedness |
| POST /serial_enable | POST /settings/communication/serial/enabled |
| POST /experimental/features/grip_dropped_simulation_stopper | 设置 API |
| POST /experimental/features/screensaver_enable | 设置 API |
| WebSocket command_data.values | 位置, 向量, 角度, 扭矩 |
| WebSocket set_angular_torque | 设置角扭矩 |
| WebSocket 获取光标位置 | 探针位置 |
| WebSocket 设置坐标原点 | 配置预设 |
| WebSocket 会话级 set_basis | configure.basis |
兼容性说明 {#compatibility-notes}
与 3.4.19 相比,没有强制性的破坏性变更。针对现有集成,有两点温和的提示:
已弃用的 HTTP 端点现在会在响应中包含 弃用警告 字段——严格验证响应 schema 的客户端应允许该额外字段。WebSocket command_data 中的 价值观 该字段已被弃用,但仍会被解析;建议优先使用命名字段。教程与文档 {#tutorials-documentation}
新教程:05 位置控制、06 组合(Inverse3 + Verse Grip)、07 基础与安装、08 HTTP 远程配置器、09 WebSocket 远程控制、10 事件流监听器。新增 Glaze 变体:为每个 C++ 教程新增 cpp-glz/ 该变体与现有的 nlohmann/json 变体并存。所有教程均已重写,以适配 v3.1 API(端口 10001、配置预设、命名命令字段、print_state() 辅助函数)。已删除旧版的Verse Grip Stopper 教程——该教程已被新版 Combined 教程取代。公开文档已更新,涵盖 SDK 指南、API 参考和硬件页面。