v3.5.0
这是自一年前 API 更新以来的最大规模发布。3.5.0 版本引入了集成的 3D 数学层、对Minverse 的全面支持、类型化事件流、完整的配置 API 以及更加简化的 HTTP 接口。此外,该版本还包含了过去一年中积累的 bug 修复和用户体验改进。
亮点
- 统一的 3D 数学层——通过可组合的变换管道,不仅提供了用于设备基准(帧)、安装变换、工作空间变换和导航变换的一流基元,还支持在本地、会话、应用程序和内部各空间之间进行显式变换。
- 气泡导航——通过具有形状的区域(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将切换至。 - 命名命令字段 — 通用的
values代替数组,position、vector、angles、torques使用。 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 种类型化事件类别。
可观测性
- 在性能分析过程中,日志消息会根据级别以不同颜色显示,并转发至 Tracy。
- 为所有 HTTP 处理程序配置 Tracy 区域。
- 主循环的定时统计事件。
- 可设置日志目录和服务器主机名(支持 Docker)。
计划在 3.6 版本中提供
- SDF 触觉效果(SDF HFX)——其基础架构已在 3.5 版本中引入(包括模块、生命周期以及模块提供的命令/状态序列化)。公开 API 计划在 3.6 版本中连同完整文档一同发布。
改进之处
- 力振动滤波——各轴振动检测、8级渐进式恢复、带滞后效应的进入投票、非对称释放窗口。
- 运行时功率门滤波器 —
configure.force_gate.gain(可通过 WebSocket 或 HTTP)进行配置。具有持久的默认值。 - 针对精密应用,将主循环的最大频率提高至 32 kHz。
- WebSocket 有效载荷的压缩 — 将恒等变换设为默认值的变换子字段(
position = 0、rotation = identity、scale = 1)在默认情况下不会包含在输出中。这样可以减小有效载荷大小,并恢复与旧版 Unity 包中 4 KB 消息上限的兼容性。有两个高级设置(serialization/explicit_fields、serialization/force_complete_transforms)可将所有字段恢复给所需的消费者。 - 减少主循环抖动— 即使在解析 JSON 和进行网络传输期间,WebSocket 消息处理也不会再阻塞主循环的 tick 操作。会话 tick 的调度已移至响应序列化之前。
- 服务器默认仅限本地主机 — 要启用网络访问,
communication/bind_all_interfaces请在设置中选择“加入”。 - 在设备选择器的通配符中使用前缀语法(例如:
inverse*(与 Inverse 系列的所有设备均兼容)。 - 倾销指令 ,
force_gate与……并列configure已跳转至地图。 - 带轮转功能的文件记录器已取代之前的版本,现在可以设置目录了。
- 模块提供的命令和状态— 模块可以在不更改核心模式的情况下,设置自定义命令和字段,并将状态输出嵌入到 WebSocket 帧中。
修正
这是过去一年中修复的漏洞。以下列出了影响较大的漏洞。
- 在特定条件下,会话速度不稳定的问题。
- 当未执行模拟时,**GripHook(Verse Grip Stopper)**无法正确释放的问题。
- 由于Inverse3的超时时间过短,导致在启动较慢的设备上出现了断连循环的问题。
- Windows 中的服务未完全停止— 关机时 HTTP 服务器未必会被彻底清理的问题。
- 当服务向旧版固件发送其不支持的命令时,会导致重连循环。
- 在搭载蓝牙适配器的系统中,因蓝牙设备枚举而导致大量日志输出的问题。
- 连续多次重启服务时发生的崩溃。
- 在Ubuntu笔记本电脑从睡眠状态恢复后,Wireless Verse Grip适配器出现卡死的问题。
- 在 Linux 和 macOS 系统上,Wireless Verse Grip 的握手过程现在可以在首次检测尝试失败时正确地进行回退。
- macOS 设置文件的位置 — 设置中,路径没有错误,而是
~/Library/Application Support/现已保存至该处。 - Linux 和 macOS 上的 SIGSEGV 信号处理— 当启用多线程崩溃捕获时,进程不再因致命信号而陷入循环。
- 跨会话命令的覆盖— 此前曾存在一个问题,即某个会话的配置命令会被另一个会话的命令在不知不觉中覆盖,但现在这些命令已能被正确过滤和合并。
- 通过探针命令覆盖设置 —
probe_position发送监控会话(例如:Haply Hub)现在不会在不知情的情况下覆盖待处理的basis/preset/profile更改了。 - 原型握把的显示— 原型硬件被错误地显示为标准握把而非自定义握把的问题。
- 针对尚未完成迁移的客户端,Legacy的
set_basis行列的规则已重新生效。 - 在会话断开时,Inverse3的“力量踢”不再产生残留力量峰值。
- 在快速反复建立和断开连接的过程中,WebSocket会出现连接丢失的竞态条件。
- 在某些发送有效载荷中,**WebSocket的
session_id**が0此前以……形式序列化的问题。 - 在 Windows 中,
--dev即使与……配合使用时--log-level现已开始反映(以前是在不知不觉中debug已被重置为)。
不建议
虽然目前仍可正常运行,但计划在未来的大版本更新中移除。若涉及此情况,响应中将包含deprecation_warning包含字段。
| 不建议 | 代替 |
|---|---|
POST /force_scale | POST /settings/devices/inverse*/filters/force_scale/gain |
POST /gravity_compensation | 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 | position, vector, angles, torques |
WebSocket set_angular_torque | set_angular_torques |
WebSocket probe_cursor_position | probe_position |
WebSocket set_coordinate_origin | configure.preset |
WebSocket 会话级别的set_basis | configure.basis |
关于兼容性的注意事项
3.4.19 版本中没有破坏性变更。关于现有集成,有以下两点需要注意:
- 已不推荐使用的HTTP端点会在响应中
deprecation_warning现已包含该字段。对于严格验证响应架构的客户端,必须允许此新增字段。 - WebSocket的
command_data位于……values该字段虽不推荐使用,但仍会继续进行解析。建议使用命名字段。
教程与文档
- 新教程:05 位置控制、06 组合(Inverse3 + Verse Grip)、07 基础与安装、08 HTTP 远程配置器、09 WebSocket 远程控制、10 事件流监听器。
- 除了现有的nlohmann/json变体外,所有C++教程中都新增了Glaze变体(
cpp-glz/)已添加。 - 重写所有教程、已支持 v3.1 API(端口 10001、
configure.preset、带名称的命令字段、print_state()(助手)。 - 已删除旧版的Verse Grip Stopper教程。该教程已被新的Combined教程取代。
- 已更新公开文档。更新内容包括 SDK 指南、API 参考以及所有硬件页面。