RuView off-axis-mode:基于 Kooima 广义透视投影的 RF 头耦合视差演示(ADR-324 技术解析与实现导读)
导读
本文是 RuView 仓库中架构决策记录 ADR-324(off-axis-mode) 的深度展开与实现导读。该决策把 three.js 实时演示中经典的 head-coupled perspective(头耦合透视,"鱼缸 VR"/"屏幕窗口"幻觉) 技术引入 RuView,同时严格界定 WiFi 射频(RF)感知在这一演示中能做什么、不能做什么:RF 不被包装成"摄像头级头部追踪",而是以"在场门控 + 多人仲裁 + 粗糙视差"的分层方式,诚实提供摄像头无法提供的能力。读完本文,你将掌握:广义透视投影的数学内核与 clean-room 落地形态、RuView 对"RF 能力诚实标注"的实现纪律、分层(Tier A/B/C)集成思路,以及如何从仓库源码构建并运行 07-off-axis-window.html 演示。
1. 背景:这个 ADR 回答的核心问题
ADR-324 要回答的问题非常具体:
能否把开源项目
icurtis1/off-axis-sneaker(一个用 three.js 渲染 3D 模型、依靠摄像头捕捉头部形成"看穿屏幕"效果的 React+TS+Vite 应用)与 RuView 结合?
ADR 给出的结论是三句话:
- 技术可以用(off-axis 投影本身是公开文献中的经典方法);
- 代码不能用(上游仓库未声明许可证,默认版权下不可复制、不可 vendoring);
- RF 部分只能诚实地说"能提供什么"——绝不能宣称摄像头级精度。
因此这个 ADR 记录的是"什么才是真正站得住脚的集成边界",并据此定义了一个纯客户端、仅新增单文件 HTML 的演示:examples/three.js/demos/07-off-axis-window.html(07 号位,06 已由 ADR-170 yoga-mode 预留),不改任何服务端。
1.1 先厘清"off-axis"到底是什么
所谓 head-coupled perspective(鱼缸 VR / fish-tank VR)是指:把屏幕当成一扇"窗户",渲染出的场景根据观察者真实头部位置实时生成一个非对称视锥(asymmetric / off-axis frustum),于是屏幕上的画面随着人左右、前后移动产生真实视差——物体仿佛从屏幕里"探出来",人被"看进"屏幕里。其技术脉络可追溯至 Johnny Chung Lee 2007 年基于 Wii Remote 的桌面 VR 演示与 Ware、Arthur & Booth(CHI '93)的鱼缸 VR 文献,投影数学则出自 Robert Kooima 2008 年发表的 Generalized Perspective Projection(广义透视投影)。这些是公开、有充分文献支撑的通用技术,与具体实现无关,是 RuView 可以 clean-room 复刻的合法基础。
ADR 文档中记录了 off-axis-sneaker 一类实现的关键参数,作为"该技术通常需要什么输入"的背景(这些数值来自上游应用,RuView 自身采用 Rust/WASM 版参数,详见下文 §4):
| 上游实现要素 | 说明 |
|---|---|
| 追踪输入 | MediaPipe Face Mesh(468 个人脸关键点),取双眼中心为头部 (x, y),以瞳距代理深度 (z) |
| 平滑方式 | 指数滑动平均(默认系数 0.3) |
| 灵敏度倍率 | strengthX: 4、strengthY: 3、strengthZ: 2 |
| 投影构造 | makePerspective(left, right, top, bottom, near, far),其中 left/right/top/bottom = (screenBound − eyePosition) · (near / viewerToScreenDistance),即 Kooima 广义透视,并伴随相机平移 |
| 常量 | nearPlane 0.05、farPlane 1000、worldScale 0.01(cm→世界单位)、movementScale 1.5 |
| 标定 | 向导式采集物理屏幕宽/高(cm)、典型观看距离与像素密度,本地存储,使眼位相对物理屏幕计算 |
1.2 该幻觉对物理输入的要求(为什么诚实是必须的)
头耦合幻觉要想可信,追踪到的眼位需要厘米级准确并足够低延迟。VR 文献中舒适的运动到光子(motion-to-photon)延迟约为头戴显示 <20 ms;桌面鱼缸 VR 容忍度更高,但"头动→视差响应"的可见迟滞会直接击穿"窗户"错觉。ADR 明确把这些数值标为 CLAIMED(文献值,RuView 此演示尚无实测),遵守仓库规则:未测就不能写"快"。
2. RuView RF 感知今天究竟能提供什么(能力诚实盘点)
ADR 用四个层面如实盘点 RF 侧现状,这是全文的"诚实基调",也决定了为什么只能做分层集成:
-
场峰位置,不是度量定位。 传感服务器在 v2/crates/wifi-densepose-sensing-server/src/field_localize.rs 中从
/ws/sensing的sensing_update帧携带的 20×20signal_field网格提取最强峰来得到一个位置。其模块文档自己写明 caveat:子载波→角度映射只是一种表示,"单个 ESP32 链路无法解算真正的 (x, z) 房间位置",产出的只是"房间模型中场能量最强的峰",映射常量X_SCALE 0.6、Z_SCALE 0.5,用PEAK_THRESHOLD 0.35门控。它是真实、实时、可追踪运动的信号,但不是标定过的人体坐标,更远达不到眼位精度。 -
RF 姿态是二维、归一化、恒定置信度。 仓库提交的 Cog(ADR-101 pose-estimation-cog、并经 ADR-323 重申)输出 17 个 COCO 关键点的归一化二维坐标,置信度恒定、无逐关节点不确定性。"鼻子"关键点(COCO 索引 0)存在,但并非度量三维头部位置。
-
轨迹是粗粒度、且刻意去标识化的。
ruview-track(ADR-307 persistent-identity-tracking)维护person_N轨迹,仅提供"厨房→走廊"这种容器级连续性、粗粒度的不可逆特征,不承诺任何精度数字,输出默认落在证据等级L1。 -
该用途下的更新频率与延迟尚未测量。 演示管线在 MediaPipe 侧约 30 Hz(见 ADR-170),但 RF 端到端"运动到光子"延迟没有测过;任何 RF 路径数字出现在文档或 UI 前都必须带
MEASURED标注并给出可复现步骤。
能力匹配结论(ADR 原文精神):RF 今天无法独自支撑可信的鱼缸幻觉,本 ADR 也不作此宣称。 但 RF 能提供摄像头给不了的东西:无摄像头的在场感知、区域级位置、人数、接近方向与伪匿名连续性——包括在摄像头关闭时依然生效。这正是本演示的产品差异化所在。
仓库佐证:在 field_localize.rs 中可直接读到常量
X_SCALE: f64 = 0.6、Z_SCALE: f64 = 0.5、PEAK_THRESHOLD: f64 = 0.35以及网格到世界的映射world_x = (ix - nx/2) * X_SCALE,与 ADR 描述完全一致。ruview-offaxis的 RF 模块以注释形式镜像了同一组常量与 caveat。
3. 决策:分层集成 + clean-room 实现 + 许可证纪律
3.1 许可证:采用技术,不采用代码
off-axis-sneaker 仓库没有任何许可证文件。在默认版权(all-rights-reserved)下,它的源码不能被复制、vendoring 或翻译进本仓库;其 GLB 球鞋模型同样未授权复用。ADR 的处置是:
- 不引入上游任何代码、资产或模型,演示只使用
examples/中已有的资源; - off-axis 投影依据公开资料 clean-room 实现:Kooima 2008《Generalized Perspective Projection》的
pa/pb/pc屏幕角点公式 + three.js 官方文档的PerspectiveCamera.projectionMatrix覆写路径;上游仓库仅在本 ADR 中被引用为先例; - 若上游日后补充宽松许可证,是否复用需要新 ADR 记录,不得静默复制。
3.2 分层集成:每一层都标注它"实际是什么"
Tier A(先发布):摄像头精细 + RF 上下文混合
07-off-axis-window.html 用 MediaPipe Face Landmarker(沿用 demo 05 05-skinned-realtime.html 的模式)做精细头部追踪,用 Kooima 视锥做渲染——功能上等价于重写 off-axis-sneaker。RuView RF 在其外围增加摄像头做不到的层:
- 在场门控摄像头:只有当
/ws/sensing的sensing_update报出区域有人时,webcam 管线才启动;并在一段可配置的 RF 空缺超时后停止。隐私姿态因此变好:物理层确认有人之前,摄像头保持关闭。 - 多人仲裁:RF 报出多于一人时,HUD 明示"多人",演示保持最后一个稳定视角而不是在多个面孔间跳动。
- 预热(pre-warm):RF 接近方向(场峰轨迹)在人就座前先预热 MediaPipe 与场景。
Tier B(演示模式,显著标注):纯 RF 粗糙视差
一个开关让 off-axis 眼位完全由 RF 驱动——场峰 (x, z) 叠加(若存在)姿态鼻子关键点——经 one-euro 滤波器、死区(deadband)、硬增益钳制(hard clamp) 处理后喂入。HUD 必须随时显示标签 "RF coarse body parallax — not head tracking"(RF 粗粒度人体视差——不是头部追踪),并展示实时证据等级(默认 L1 启发式,除非有 ADR-318 capability certificates 证书另说,依据 ADR-282 evidence ladder)。期望的体验是缓慢、人体尺度的视差摆动——"房间模型因为你动了而移动,且没有摄像头"——而不是稳定的鱼缸幻觉。演示绝不把 Tier B 宣传成与 Tier A 等价。
Tier C(未来,显式门控,不作承诺):度量级 RF 头位
只有经过标定的多站(multistatic)部署(ADR-297 多节点语义、ADR-311 融合、ADR-303 真值同步)、加上证据引擎账本条目(ADR-304)与能力证书(ADR-318),才允许把 RF 位置送入精细路径。当前没有任何数据支撑它;Tier C 存在于 ADR 中的唯一目的是:防止任何人在未过这些门的情况下非正式地把它发出去。
3.3 实现面与数据流
- 新增单文件
examples/three.js/demos/07-off-axis-window.html,沿用 01–05 号演示的约定:同样的 CSS 自定义属性、同样的 HUD/帮助面板模式,由既有静态演示服务器(http://127.0.0.1:8765/examples/three.js/demos/…)服务。 - 一个小型 clean-room 模块:给定标定所得屏幕角点
pa, pb, pc与眼点pe,每帧经 Kooima 公式设置camera.projectionMatrix。 - 数据输入只用既有流:
/ws/sensing(sensing_update→signal_field→ 场峰,映射常量与field_localize.rs相同)与(若可用)/api/v1/stream/pose的鼻子关键点。WebSocket 走既有票据流程(ws_ticket.rs/bearer_auth.rs),不豁免、不新增任何端点。 - 标定复刻上游"概念"而非"代码":物理屏幕宽/高(cm)与观看距离,以 demo 作用域 key 存进
localStorage,标定数据不离开浏览器。 - 溯源纪律:若演示被指向合成或回放数据源,ADR-295 provenance state machine 的溯源状态必须像 Observatory 一样如实呈现在 HUD——合成数据永远不得伪装成实时数据。
上述文档提及的 WebSocket 票据与 WebSocket 鉴权文件位于传感服务器 crate 下,展示了现有流的接入方式;本 ADR 不新增鉴权面。
4. 源码纵深:ruview-offaxis crate(Rust→WASM 的 clean-room 核心)
ADR-324 的 2026-08-16 修订(§2.5)记录了实现方式的重要升级:投影核心最终以 Rust crate 编译为 WASM 交付,而不是 §2.3 起初设想的行内 JS 模块——同样的接口面、更严格的实现纪律。这就是 v2/crates/ruview-offaxis。
4.1 crate 结构与职责
| 模块 | 职责 | 关键源码 |
|---|---|---|
projection |
Screen(三个屏幕角点,任意朝向)、off_axis() → 非对称投影 + 屏幕对齐视图矩阵(列主序 f64,即 three.js Matrix4.elements 布局);所有失败模式为类型化错误,绝不产出 NaN 矩阵 |
projection.rs |
filter |
OneEuro / OneEuro3 one-euro 滤波器(源自 Casiez 等,CHI 2012);时间戳由调用方注入,crate 从不读时钟 |
filter.rs |
rf |
field_peak()——/ws/sensing signal_field 网格最强单元提取,镜像传感服务器常量;CoarseParallax——Tier B 阶段(死区+增益+硬钳制+one-euro);ScreenCalibration——物理屏幕(cm)+归一化头部 → 度量眼位映射(Tier A 输入钩子) |
rf.rs |
wasm(仅 wasm32) |
OffAxisCamera 与 RfParallax wasm-bindgen 类 |
wasm.rs |
crate 元数据(Cargo.toml) 中有两个值得注意的设计点:crate-type = ["cdylib", "rlib"] 使同一 crate 既能编 WASM 又能原生复用;wasm-bindgen 只在 target_arch = "wasm32" 时被引入,因此原生核心零依赖,workspace 的测试门(cargo test --workspace --no-default-features)不会拉入任何 JS 互操作依赖。
4.2 顶层 API(lib.rs)
use ruview_offaxis::{off_axis, Screen, Vec3};
// 60 cm × 34 cm 屏幕居中于原点;眼位在 65 cm 外、偏右 10 cm。
let screen = Screen::centered(0.60, 0.34)?;
let oa = off_axis(&screen, Vec3::new(0.10, 0.0, 0.65), 0.05, 100.0)?;
let mvp: [f64; 16] = oa.view_projection(); // 列主序,可直接用于 GL/three.js
crate README 记录了关键不变量(对一组眼位网格与倾斜屏幕都有单测覆盖):物理屏幕角点永远精确投影到 NDC 角点——pa→(−1,−1)、pb→(1,−1)、pc→(−1,1)、pd→(1,1)——且屏幕平面上的点对眼位不变。这正是"屏幕是一扇窗"的数学定义。
在 projection.rs 中可见其工程严谨性:屏幕由左下(pa)、右下(pb)、左上(pc)三角点定义并预计算正交基(基与眼位无关,可缓存以让每帧 off_axis 只做眼位相关计算);OffAxisError 枚举覆盖全部退化情形(DegenerateScreen、EyeBehindScreen、InvalidClipPlanes、NonFiniteInput),并定义 MIN_EYE_DISTANCE: f64 = 1e-6 防止近平面退化。
4.3 Tier B 的"不可能过度宣称"设计(rf.rs)
RF 模块把 RuView 既有 RF 面转成"受限、诚实标注"的眼位,其设计哲学是让过度宣称在 API 层面就不可能发生:
pub const FIELD_X_SCALE: f64 = 0.6; // 镜像 field_localize.rs::X_SCALE
pub const FIELD_Z_SCALE: f64 = 0.5; // 镜像 field_localize.rs::Z_SCALE
pub const FIELD_PEAK_THRESHOLD: f64 = 0.35; // 镜像 field_localize.rs::PEAK_THRESHOLD
Tier B 默认参数(CoarseParallaxConfig::default(),均为交互设计选择、标注 CLAIMED):
| 参数 | 默认值 | 含义 |
|---|---|---|
gain |
0.5 | 每米场峰移动产生的眼位米数(≤1 让效果明显"亚物理") |
deadband_m |
0.15 | 小于该值(自会话原点计)的峰移动被完全忽略——RF 场峰有抖动,死区让静止房间在画面上也静止 |
max_offset_m |
0.35 | |
base_distance_m |
0.65 | 无深度调制时眼位的标称 Z 观看距离 |
filter |
min_cutoff 0.4、beta 0.2、d_cutoff 1.0 |
one-euro 参数,Tier B 需要重度平滑,默认 min_cutoff 远低于 Tier A 默认 |
CoarseParallax::update() 的行为契约:
- 首个被接受的峰建立会话原点,后续峰相对它移动眼位;
- 低于阈值的场(
field_peak返回None)保持当前眼位——相机永不跳变; - 深度方向钳制保证眼睛严格在屏幕前方(距离下限为标称距离一半),测试
coarse_parallax_depth_never_crosses_the_screen验证即使 z 偏移趋向 −50 m 眼位也不会越过屏幕。
field_peak() 的实现也值得注意:采用分支精简的 argmax(NaN 因不满足 v > best_v 被自动跳过),并在 f32 域做阈值比较(0.35_f32 升到 f64 会略低于 0.35_f64 阈值,所以代码注释专门说明"比较在 f32 中进行")。模块内置测试验证了峰值网格到世界的精确映射、低于阈值的 None 返回、畸形网格(长度不匹配/空网格)安全处理、NaN 单元被跳过、死区/增益/钳制/保持行为与 reset() 复原。从源码结构看,这一模块的所有默认值都刻意保守,使 Tier B 模式天然读起来就是"人体尺度缓慢视差"而非头部追踪。
ScreenCalibration(Tier A 输入钩子)将任何精细追踪器的归一化头位映射到度量眼位:nx/ny 按图像坐标(左上原点)约定、镜像自拍视图;depth_scale 被钳在 [0.25, 4.0];lateral_range_m 默认可取屏幕宽度。测试覆盖居中头位、图像边缘、越界坐标钳制与深度钳制。
4.4 WASM 面(wasm.rs)
wasm-bindgen 暴露两个小类:
OffAxisCamera——Tier A/B 共用核心:屏幕标定 + one-euro 滤波 + Kooima 投影。构造入参为厘米(人量屏的单位):screen_width_cm, screen_height_cm, viewing_distance_cm,加上以米计的near_m, far_m。方法update_eye(x_m, y_m, z_m, t_s)收度量眼位,update_normalized(...)收归一化头位(Tier A 的宿主追踪器接入点,全程留在浏览器内);set_filter(min_cutoff, beta)调节平滑(min_cutoff 越低静止越平滑、beta 越高运动越跟手)。RfParallax——Tier B 输入级:吃入/ws/sensingsignal_field网格,吐出受限的粗视差眼位。
可失败方法返回 Result<_, JsError>(抛为 JS 异常);每帧更新方法则保留上一次有效状态,渲染循环永不需 try/catch。
5. 演示 HTML:从构建到运行再到验证
5.1 构建 WASM 产物(生成物不入库,属仓库规则)
crate README 给出的构建命令如下:
cd v2
rustup target add wasm32-unknown-unknown
cargo build -p ruview-offaxis --target wasm32-unknown-unknown --release
# 安装匹配版本 CLI 一次:cargo install wasm-bindgen-cli --version 0.2.114
wasm-bindgen --target web --out-dir crates/ruview-offaxis/pkg \
target/wasm32-unknown-unknown/release/ruview_offaxis.wasm
产物为 pkg/ruview_offaxis.js + pkg/ruview_offaxis_bg.wasm(crate README 标注约 54 KB wasm,MEASURED,wasm-bindgen 0.2.114 环境下测得)。演示 07-off-axis-window.html 直接按相对路径 ../../../v2/crates/ruview-offaxis/pkg/ruview_offaxis.js 加载;若找不到产物,页面会弹出一个说明面板,给出上述两条构建命令。
5.2 页面结构:HUD、强制模式标签与标定面板
- 信息 HUD:显示引擎(
ruview-offaxis wasm)、输入模式、眼位 x/y/z(m)、渲染 fps、RF socket 状态、RF 峰值与 0.35 门控状态;快捷键M切鼠标、R切 RF Tier B、滚轮调距离。 - 强制模式标签(对应 ADR §2.4 规则 2):RF 驱动相机时右上角常驻红框标签
RF COARSE BODY PARALLAX — NOT HEAD TRACKING;源码注释明确"没有能隐藏它的配置"。鼠标模式标签为MOUSE SIM — SYNTHETIC INPUT。 - 物理标定面板:屏幕宽(cm,默认 60)、高(cm,默认 34)、观看距离(cm,默认 65),存
localStorage(keyruview-offaxis-demo-cal);"apply calibration"重建相机并让房间比例跟随物理屏。 - 场景约定:屏幕平面
z = 0,屏后内容z < 0,z > 0的物体会"探出屏幕"(演示里有一颗 octahedron 放在z = 0.06);线框房间 + 纵深列柱 + TorusKnot/icosahedron 浮动物体构成视差参照。resize时不更新camera.aspect——视锥由物理屏幕标定决定而非视口。
5.3 three.js 接线(README 给出的全量接线)
import init, { OffAxisCamera, RfParallax } from './pkg/ruview_offaxis.js';
await init();
// 物理标定(cm)——请量你真实屏幕
const cam = new OffAxisCamera(60, 34, 65, 0.05, 100.0);
cam.set_filter(1.2, 0.4); // one-euro: min_cutoff Hz, beta
const camera = new THREE.PerspectiveCamera();
camera.matrixAutoUpdate = false; // 矩阵全部由 WASM 负责
const view = new THREE.Matrix4();
function onFrame(eyeX, eyeY, eyeZ) { // 米,屏幕空间
cam.update_eye(eyeX, eyeY, eyeZ, performance.now() / 1000);
camera.projectionMatrix.fromArray(cam.projection());
camera.projectionMatrixInverse.copy(camera.projectionMatrix).invert();
view.fromArray(cam.view());
camera.matrixWorld.copy(view).invert();
camera.matrixWorldInverse.copy(view);
}
渲染循环里每帧只做"一次 WASM 调用 + 三次矩阵拷贝 + 渲染",见 07-off-axis-window.html 中的 animate()(将 cam.projection() / cam.view() 拷入 camera.projectionMatrix、matrixWorld 并求逆)。
5.4 输入模式与 RF Tier B 数据通路
setMode() 切换 mouse(合成眼位模拟器:指针位置映射为 ±0.3 m 眼位偏移,滚轮调 0.2–2.5 m 距离)与 rf(连接 /ws/sensing)。RF 分支的关键逻辑:
- 以用户可编辑的 ws url(默认
ws://127.0.0.1:8080/ws/sensing)建连,错误态 HUD 提示"server up? ticket needed?"(呼应既有票据鉴权流程); - 解析消息中的
signal_field,取values构建Float32Array,调rf.update(values, nx, nz, t); - HUD 显示峰值:命中显示
value ≥ 0.35 gate,未命中显示below 0.35 gate — holding(保持,不跳变); - 若消息带
provenance/source字段,按 ADR-295 规则原样显示在 HUD(如connected · src: …),合成源永不伪装成实时。
鼠标/SYNTHETIC 标签从代码看是 ADR-295 溯源纪律在 demo 上的直接体现。
5.5 验证清单(ADR §5,手动,沿用 ADR-169/170 实践)
- 从静态服务器可加载;
- Tier A 仅在 RF 在场时激活;
- 只要 RF 驱动相机,Tier B 标签即可见;
- 指向合成源时溯源徽标正确;
- devtools 中确认没有任何网络请求携带 webcam 派生数据。
- 合并前的
rg门:examples/下任何文件不含源自icurtis1/off-axis-sneaker的代码; - 不触发任何 workspace / harness / firmware 校验行——改动是静态 HTML 演示 + 本 ADR 文档。
6. 性能基线(MEASURED,需自行复现)
crate README 公布了一组带复现器与运行环境的基准(MEASURED 标签;复现命令 cd v2 && cargo bench -p ruview-offaxis;环境 Linux x86_64 容器、rustc 1.89.0、criterion 0.5,2026-08-16;README 明确提示"视为数量级,在自有硬件上重跑"):
| 基准 | 中位数耗时 |
|---|---|
off_axis_projection(视锥+视图构建) |
~76 ns |
view_projection 组合(4×4 乘法) |
~27 ns |
one_euro3_step(三轴滤波单步) |
~60 ns |
field_peak_20x20(线上网格尺寸) |
~488 ns |
field_peak_100x100 |
~12.3 µs |
tier_b_full_frame_20x20(扫描→视差→投影整链) |
~598 ns |
即完整 Tier B 每帧路径远低于 1 µs,不足 60 Hz 帧预算的 0.01%。README 还记录了唯一热点 argmax 扫描被改写为分支精简版的实测收益(20×20 −18%、100×100 −33%)。同时明确:端到端 motion-to-photon 延迟(RF 采集→渲染)尚未测量,且主要由传感管线主导而非本 crate,故不宣称任何数字——这与 ADR 的诚实规则一脉相承。
7. 备选方案与取舍(ADR §3)
| 备选方案 | 结论 | 原因 |
|---|---|---|
vendoring off-axis-sneaker(或 fork 后指向 RuView) |
否决 | 无许可证→无再分发权;React/Vite 技术栈与仓库"单文件演示"约定冲突 |
| Clean-room Kooima off-axis 演示(webcam 精细 + RF 上下文,Tier A/B) | 采纳 | 法律干净、符合演示约定、把 RF 用在它真正擅长的场景,诚实展示无摄像头在场价值 |
| 以"纯 RF 头耦合透视"为主打 | 否决 | 过度宣称。单链路场峰只是表示而非度量定位(field_localize.rs caveat),作为"头部追踪"发布违反摄像头级规则;仅以带标注的 Tier B 开关存活 |
| 等 multistatic 度量定位(Tier C)再出任何演示 | 否决 | 把一个有用且诚实的演示阻塞在无交付日期的 phase-2/3 计划(ADR-303/311/318)上;改为记录门禁 |
| 为头位新增专用服务端端点 | 否决 | 无必要——既有 /ws/sensing + /api/v1/stream/pose 足够;新端点只会扩大鉴权面而无能力增益 |
8. 收益、成本与后续(ADR §4)
收益
- 一个公开可读、展示 RF 感知真正差异化能力的演示:在摄像头之前、甚至没有摄像头时,场景就知道你在、你大概在哪、你们有几个人;
- 头追踪类演示的隐私姿态改善:摄像头占空比由 RF 在场约束,而非常开;
- 产出一份有许可证、可供 Observatory 或未来 UI 复用的规范 off-axis 投影代码。
成本 / 风险
- Tier B 可能让被 webcam 演示"养刁"的观众失望——缓解手段是标注与并排开关,而不是虚增增益;
- Tier A 依赖 MediaPipe CDN(与 demo 05 相同),是网络可用性风险;演示必须在缺网时降级到 Tier B 并给出可见提示;
- 屏幕标定摩擦(量 cm)可能劝退普通用户;允许"跳过标定(近似)"路径并标注精度降低;
- 上游
off-axis-sneaker的许可证变化只能人工跟踪。
后续(不在本 ADR 范围内)
- 用可复现器测量端到端 RF"运动到视差"延迟,以
MEASURED发布; - 待 ADR-303 / ADR-311 落地后,对照 ADR-318 证书门评估 Tier C;
- 考虑把 off-axis 相机模块提升进 Observatory 的 3D 视图。
9. 阅读延伸(仓库内一手资料)
- 决策本体:ADR-324 off-axis-mode
- 实现 crate:v2/crates/ruview-offaxis/README.md,核心源码 lib.rs、projection.rs、rf.rs、wasm.rs
- 演示文件:examples/three.js/demos/07-off-axis-window.html(同目录 01–05 为其沿用约定与 MediaPipe 先例)
- 能力边界佐证:v2/crates/wifi-densepose-sensing-server/src/field_localize.rs
- 关联 ADR:ADR-169 adam-mode、ADR-170 yoga-mode(演示级 ADR 先例)、ADR-282 证据阶梯、ADR-295 溯源状态机、ADR-307 持久身份追踪、ADR-318 能力证书、ADR-323 pose refinement
一句话总结:ADR-324 及其 ruview-offaxis 实现示范了 RuView 在面对"热门视觉技术"时的完整方法论——先用文献厘清技术的数学内核(Kooima/Casiez),再用许可证审计划清 clean-room 边界,接着以分层(Tier A/B/C)+ 强制标注把 RF 能力诚实接入,最后把数值默认值标为 CLAIMED、基准标为 MEASURED、把"未测不宣称"写进 crate 的不变量与测试。这种"先诚实、后炫技"的顺序,正是 off-axis 演示与一般 head-tracking demo 最大的区别。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python07
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00