跳至主要内容

v3.5.0

这是自一年前 API 重写以来规模最大的一次发布。3.5.0 版本引入了统一的 3D 数学层、对Minverse 的全面支持、带类型的事件流、完整的配置 API,以及更简洁的 HTTP 接口,同时还包含了整整一年的缺陷修复和体验优化。

亮点​

  • 统一的 3D 数学层——可组合的变换流水线,为设备基准坐标系(basis/frame)、挂载变换(mount transform)、工作空间变换(workspace transform)和导航变换(navigation transform)提供一等原语,并支持在本地、会话、应用和内部空间之间进行显式转换。
  • 气泡导航(Bubble Navigation)—— 通过成形区域(SDF 元)在大型虚拟工作空间中进行导航,支持基于速度映射的速率控制、具备滞后感知功能的碰撞检测,以及可选的朝光标方向漂移。可通过 HTTP 和 WebSocket 进行全面配置,并支持应用空间的往返转换。
  • 带类型的事件流—— 专用的 WebSocket 事件通道,涵盖设备生命周期、安全警报、校准、电池状态、控制速率警告以及停用提示。
  • API 设置—— 完整的键值设置系统,支持 HTTP 的增删改查(CRUD)、类型提示、范围约束和描述信息,取代了旧的嵌套配置文件。
  • 统一的设备配置 —— 所有设备共用一套 HTTP 路由:basis、mount、preset、transform、filters、handedness、torque_scaling、gravity_compensation、home_return。
  • Minverse 与笔的同步校准—— 设备及其笔现在可以一起进行校准;在校准过程中,握柄在实际安装之前将保持锁定状态。
  • HTTP 的体验优化 —— 基于索引的设备选择器(通过索引指定设备,无需 ID),与 WebSocket 共享的统一请求/响应结构,可选启用 {ok, error, data} 封装结构(?format=json),以及通配符会话选择器。

新功能​

设备​

  • Minverse —— 本版本正式支持:包括检测、就绪流程、安全通知以及同步校准工作流。
  • Ruko和Kingfisher已被认定为官方握把产品类型。
  • 设备模拟器支持—— 可检测软件模拟设备并与之通信,同时兼容真实硬件。
  • 连接循环保护 —— 行为异常的端口将被自动屏蔽;可通过 POST /ports/{port}/reset 重置。
  • 笔挂接心跳检测—— 借助去抖动技术实现可靠的握把挂接/拆卸检测。

会话、命令与 WebSocket​

  • 会话配置文件过滤与持久化—— 会话声明配置文件名称和所需的 SDK 版本,服务会在重新连接后记住这些信息;客户端和监控工具可依据该配置文件过滤并定位会话。
  • 按会话划分的命令缓冲区—— 单个运行缓慢的会话不再会拖慢其他会话。
  • 一次性命令的显式 configure 映射 —— 每台设备的 basis、preset、mount、force_gate、damping,以及每个会话的 profile 和 basis,现在统一放入 configure 其中,与输出配置映射保持一致,因此发送的内容可以与读取回来的内容一一对应。
  • 可自定义的设备挂载 —— 可选择内置的工作区预设(defaults、arm_front、arm_front_centered、led_front、led_front_centered),也可以发送显式的转换;手动修改挂载后,预设会自动切换为 custom。
  • 命名的命令字段 —— position、vector、angles、torques 取代了通用的 values 数组。
  • set_angular_torques 取代了 set_angular_torque(单数形式已废止)。
  • 会话帧扩展 —— v3.0 和 v3.1 的会话帧现在携带可扩展的 config、state 和 status 对象;新的输出字段包括 current_cursor_force、current_cursor_position、current_angular_torques、current_angular_position、control_domain、control_mode、transform、transform_velocity、更丰富的 config.*,以及 status.safety(默认隐藏)。
  • 部分转换更新 —— 在挂载、工作空间变换和形状导航方面,只需发送需要更改的子字段(position、rotation、scale)。

超文本传输协定​

  • GET / —— 服务版本。
  • GET/POST/DELETE /settings 和 /settings/* —— 完整的键值设置 API。
  • GET /sessions/{session} 以及 GET/POST/DELETE /sessions/{session}/profile。
  • GET /devices?session=<selector> —— 将设备坐标转换到指定会话的应用空间中。
  • 基于索引的设备选择器 —— 无需知道设备 ID,即可通过索引指定任意设备(第一个Inverse3 用于 /inverse3/0/...;所有 Inverse 系列设备均采用 /inverse*/*/...)。
  • 统一的请求/响应结构 —— POST/GET 请求体使用与 WebSocket 相同的 command_data JSON 结构;针对其中一种传输方式编写的代码,同样适用于另一种。
  • 可选的封装结构 —— 在任意路由上添加 ?format=json 即可启用;/settings* 和 GET /home_return 默认返回 {ok, error, data}。如需原始结构,请使用 ?format=plain。
  • 会话选择器通配符 —— 个人资料名称中的 *(任意字符序列)和 ?(单个字符)。
  • 百分号编码选择器的解码 —— %2A、%3A 在路由之前,数据会被先进行解码。

事件​

  • 位于 communication/events/port 上的专用 WebSocket 事件流。
  • 共计 24 类带类型的事件,包括设备生命周期、安全事件(电子制动(e-brake)、异物检测、堵转)、校准失败、电池警报、会话警告、控制速率过低/严重过低、输入验证以及弃用提示。

可观测性​

  • 在进行性能分析时,日志消息会被转发到 Tracy,并根据日志级别进行着色。
  • 为每个 HTTP 处理函数添加 Tracy 区域。
  • 主循环用于计时和统计事件。
  • 可配置日志目录和服务器主机名(以便 Docker 使用)。

3.6 版本即将发布​

  • SDF 触觉效果(SDF HFX)—— 基础工作已在 3.5 版本中完成(模块、生命周期、模块提供的命令/状态序列化),公开 API 及完整文档将随 3.6 版本发布。

改进​

  • 力振荡滤波—— 逐轴振荡检测、8 阶段渐进式恢复、带滞后的进入投票,以及非对称的释放窗口。
  • 运行时力门控滤波器 —— 可通过 configure.force_gate.gain 在 WebSocket 或 HTTP 上进行配置,并带有持久化的默认值。
  • 主循环的最高频率提升至 32 kHz,适用于高精度应用。
  • 更小的 WebSocket 负载 —— 恒等(identity)默认值的转换子字段(position = 0、rotation = identity、scale = 1)默认不再输出,从而减小负载体积,并恢复与旧版 Unity 数据包 4 KB 消息上限的兼容性。两个高级设置(serialization/explicit_fields、serialization/force_complete_transforms)可为有需要的用户重新启用所有字段。
  • 降低主循环抖动—— WebSocket 消息处理在 JSON 解析和网络发送期间不再阻塞主循环的节拍;会话节拍调度已移至响应序列化之前。
  • 服务器默认仅监听 localhost —— 如需访问网络,请通过 communication/bind_all_interfaces 设置已开启。
  • 设备选择器通配符改用前缀语法(例如 inverse* (可与所有 Inverse 系列设备兼容)。
  • 阻尼指令 已移入 configure 在映射中,与 force_gate 放在一起。
  • 轮转文件日志器取代了原有的日志器,并支持配置目录。
  • 模块贡献的命令与状态—— 模块可以注入自己的命令、配置字段,并将状态输出写入 WebSocket 帧,而无需修改核心 schema。

修复​

一整年的缺陷修复;其中影响最大的修复如下所示。

  • 会话速度异常,在特定条件下出现。
  • **GripHook(Verse Grip Stopper)**在未运行仿真时无法顺利释放。
  • Inverse3 超时设置过于激进,导致启动较慢的设备陷入断连循环。
  • 在 Windows 上,服务停止得不彻底——关机时并不总能清理 HTTP 服务器。
  • 重连循环——当服务向较旧的固件版本发送不受支持的命令时会出现。
  • 在安装了蓝牙适配器的系统上,蓝牙设备枚举会产生大量日志。
  • 连续多次重启服务时发生崩溃。
  • Ubuntu 笔记本在休眠/唤醒后,无线 Verse Grip 接收器出现卡死现象。
  • 在Linux和macOS上,无线 Verse Grip 握把在首次检测失败后,现在会正确回退。
  • macOS 配置文件的位置——配置目前保存在 ~/Library/Application Support/ 其中,不再使用错误的路径。
  • Linux 和 macOS 上的 SIGSEGV 信号处理——启用多线程崩溃捕获后,进程将不再因致命信号而陷入循环。
  • 跨会话命令覆盖——一个会话中的配置命令可能会被另一个会话中的命令悄然替换;现在这些命令会被正确过滤并合并。
  • 探测命令覆盖配置——监控会话(例如Haply Hub)发送 probe_position 此时,将不再悄然覆盖待生效的 basis / preset / profile 更改。
  • 原型握把显示错误——原型硬件被错误地显示为标准握把,而非自定义握把。
  • 旧版 set_basis 矩阵约定对尚未迁移的客户端重新生效。
  • Inverse3 当会话断开时 ,“力踢”将不再产生残余力峰值。
  • WebSocket 连接丢失的竞争条件——出现在快速连接/断开循环期间。
  • WebSocket session_id 在部分出站负载中被序列化为 0。
  • 在Windows上,同时使用 --dev 现在将遵循 --log-level(此前会被悄然重置为 debug)。

已弃用项​

仍可正常使用,但将在未来的重大版本中移除。在适用情况下,响应中将包含 deprecation_warning 字段。

已弃用备选方案
POST /force_scalePOST /settings/devices/inverse*/filters/force_scale/gain
POST /gravity_compensationPOST /{device}/{id}/config/gravity_compensation
POST /torque_scalingPOST /{device}/{id}/config/torque_scaling
POST /device_handednessPOST /{device}/{id}/config/handedness
POST /serial_enablePOST /settings/communication/serial/enabled
POST /experimental/features/grip_dropped_simulation_stopper设置 API
POST /experimental/features/screensaver_enable设置 API
WebSocket command_data.valuesposition, vector, angles, torques
WebSocket set_angular_torqueset_angular_torques
WebSocket probe_cursor_positionprobe_position
WebSocket set_coordinate_originconfigure.preset
WebSocket 会话级 set_basisconfigure.basis

兼容性说明​

与 3.4.19 相比,本次更新不存在强制性的破坏性变更。针对现有集成,有两点温和的提示:

  1. 已弃用的 HTTP 端点现在会在响应中包含 deprecation_warning 字段——严格验证响应 schema 的客户端应允许该额外字段。
  2. WebSocket command_data 中的 values 该字段已被弃用,但仍会被解析;建议优先使用命名字段。

教程与文档​

  • 新增教程:05 位置控制、06 组合(Inverse3 + Verse Grip)、07 基准与安装、08 HTTP 远程配置器、09 WebSocket 远程控制、10 事件流监听器。
  • 为每个 C++ 教程新增 Glaze 变体(cpp-glz/),与现有的 nlohmann/json 变体并存。
  • 所有教程均已根据 v3.1 API 重写(端口 10001、configure.preset、命名命令字段、print_state() 辅助函数)。
  • 已删除旧版的Verse Grip Stopper 教程,并由新的综合教程取代。
  • 公开文档已更新,涵盖 SDK 指南、API 参考和硬件页面。