Files
simba-rmic-2026/docs/testing/realtime.md
T
sloray 054379dc64
构建客户端 / 检查(类型 + 单元测试) (push) Canceled after 0s
构建客户端 / Linux x64(deb + AppImage) (push) Canceled after 0s
构建客户端 / Windows x64(NSIS 安装包) (push) Canceled after 0s
构建客户端 / macOS 通用(.app + .dmg) (push) Canceled after 0s
fix(packaging): 修复 Windows 安装与固件打包并完善客户端文案
- fix(installer): 修复低完整性产物无法写入临时目录的问题,并在 CI 打包前后检查完整性标签
- fix(firmware): 从本次 Cargo ELF 打包并同步配套镜像,修正短目录说明与 LLVM 搜索顺序
- fix(installer): 修复中文完成页和页眉遮挡,侧栏使用等比缩放的原始 Logo
- style(client): 应用图标增加圆角,统一“裁判系统客户端”命名
- fix(config): 安装提示改用可选本地热点配置,排除 Wi-Fi 凭据
- docs: 润色项目说明并统一裁判系统术语
- test(packaging): 补充 Windows 完整性和固件打包回归,覆盖外部输出目录、旧镜像与重复生成

验证:Windows NSIS 构建及原生页面预览;通用与本地安装配置编译;固件 release 构建、重复打包和客户端离线校验;6 项固件打包回归与 Windows 权限回归;git diff --check。未执行实机烧录。
2026-10-21 09:25:17 +08:00

76 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 阻塞恢复与最新帧处理(2026-10-18)
## 当前交付
当前 15 dBm 交付 App 的 SHA-256 为 `a6092e4b0cf42819c04424e066651f285b8961312a73822d667532f800e46767`,应用分区为 `0x70000`。COM8 烧录与三段独立校验通过;355.1 秒串口记录中的 71 次功率回读均为 15.00 dBm。
五分钟内,原生完整接收帧率为 **29.68 fps**,丢帧率为 **1.045%**,本地 JPEG 通道帧率为 **28.23 fps**。31 张抽帧均完整解码为 640×480 RGB;未发现无效 JPEG,也未出现设备离线、通道断开、复位或采集错误。但最长到帧间隔仍有 1.646 秒,不能称为无卡顿。距离与拥塞分析、测试边界见 [功率与拥塞记录](power.md) 和制品 `POWER-RESULT.json`。
沿用已确认可用的三块 PSRAM 采集缓冲、OV5640 VGA 彩色、约 30 fps PLL 时钟、AE 目标 45/55、约 20 ms 曝光上限及自动增益;Wi-Fi 自动重连和 TUN 兼容订阅保持不变。没有增加待发送 JPEG FIFO,也没有为了消除队列改成单块 DMA 缓冲。
发送程序一次只持有一张完整 JPEG。阻塞恢复后,通过有限次数的零等待取帧选出最新有效帧,并立即将被替换的旧帧归还驱动。三块采集内存提供捕获余量,并非必须按序播放的三帧队列。相机队列仍有容量上限,应用交接时会跳过其中的旧帧。
完整 JPEG 取得后按 1400 字节载荷分片立即提交,复用一个数据报缓冲,直接读取 PSRAM。当前传感器驱动在 JPEG 结束后交出完整帧,本次没有改成在 DMA 尚未完成时就读取其内容;不完整 JPEG 由接收端整帧丢弃,不进入绘制。
## 阻塞处理
| 阶段 | 处理方式 |
| --- | --- |
| 采集交接 | 首帧最多等待 100 ms,其后零等待、有限次数取更新的有效帧;归还被替代的旧缓冲 |
| 发送帧龄 | 用板内同一单调时钟检查从首个 DMA 缓冲开始的年龄,期限 100 ms |
| 当前帧发送 | 绝对检查期限 25 ms,成功发送分片不会续期,所有订阅者共享 |
| 拥塞重试 | 默认每帧最多 8 ms 让出调度重试;预算用尽或过期后放弃该目标剩余分片,转向新帧 |
| 原生本地通道 | 每路保留最新帧;不重放超过 100 ms 的缓存,写入超过 100 ms 时断开慢端以便重连 |
| WebView / 解码 | 原生端在 JPEG 前发送 `frameTiming`;JS 在解码前后拒绝本机滞留超过 100 ms 的帧并释放旧结果 |
```dotenv
CAM_FB_COUNT=3
CAM_AE_LEVEL=-1
CAM_EXPOSURE_EV=0
CAM_EXPOSURE_MAX_LINES=592
UDP_PACKET_GAP_US=0
UDP_RETRY_BUDGET_US=8000
WIFI_TX_POWER_DBM=15
```
当前交付根据用户反馈回退到 15 dBm。启动和重连应用同一功率上限,拥塞和温控逻辑不自动降功率;此前 17 dBm 的数据作为历史记录保留,见 [功率与拥塞记录](power.md)。
若要在发送回压时立即放弃本帧,可将 `UDP_RETRY_BUDGET_US=0` 后重编烧录。该模式仍保留三块采集内存和完整 JPEG 校验;这里的“零”指不让出调度重试,不是删除驱动和路由器中的所有缓冲。零重试策略已经主机测试,本次五分钟实机使用默认 8000 μs。
分片间隔计入 25 ms 检查期限,不额外延长帧的发送寿命;间隔过大可能使整帧无法按期提交。SDK socket 已接受的分片无法由本策略撤回,应用层也无法强制抢占底层调度和网络排队。因此,这些新鲜度策略只能约束应用层,不能为每帧、无线链路或物理屏幕保证硬实时上限。
本地 JPEG 二进制头仍为 16 字节,旧消费者可忽略新增的文本消息。新前端也可连接旧后端,但由于没有原生发布时间,只能按 JS 收到消息的时刻判断本地队列年龄。本地通道两端使用同机系统时间记录发布时间;这不涉及 ESP 与电脑的时钟同步,也不能用于计算无线单向延迟。JS 内部排队同时使用单调时钟检查。
## 此前 14 dBm 版本的实机五分钟检查
该次测试使用 14 dBm,App SHA-256:`9a7decd59572c3f280e7fd4c0a291645011b779025e56e99ea50087e92b5fa77`,应用分区 `0x60000`。以下五分钟数据属于该历史镜像,不是提高功率后的重测结果。该镜像曾经 COM8 烧录并独立三段校验,三段镜像必须成套使用。运行保留 TUN、只有一个 UDP 订阅者;串口和本地视频观察器不会产生额外 UDP 推流。
| 指标 | 本次结果 |
| --- | --- |
| 本地 JPEG 通道观察时长 | 300.005 s |
| 原生接收计数有效区间 | 180.937 s |
| 完整接收 / 丢帧 | 5390 / 26(仅有效区间) |
| 完整接收帧率 / 帧损失率 | 29.79 fps / 0.480%(仅有效区间) |
| 本地 JPEG 通道 | 29.69 fps |
| 本地 JPEG 通道到达间隔 P95 / 最大值 | 47.648 / 323.146 ms |
| 主动跳过旧采集帧 | 0 |
| 发送前过期帧 / 发送期限目标丢弃 | 0 / 0 |
| 提交时采集帧龄最大观测值 | 74.13 ms |
| 发送持有时间最大观测值 | 11.23 ms |
| 复位 / 采集错误 | 0 / 0 |
观察途中界面切到队伍端,按设计隐藏诊断计数,所以原生完整帧率和损失率只报告隐藏前的有效区间,不提供完整五分钟的原生丢帧率;本地 JPEG 通道则完整观察五分钟。保留用户当前界面选择,没有强制切回裁判端。两个最大值是板端自启动起的观测值,包含预热;帧龄从驱动的首个 DMA 缓冲时间戳开始,不是光子进入传感器到屏幕的时间。主动跳过的采集帧尚未分配网络帧号,不计入接收端丢帧率;两种计数不能混为一谈。另抽取 61 张 JPEG,均完整解码为 640×480 RGB。
部署前的 30 秒基线仅用于检查连通性,画面内容和无线状态有变化,不能据此证明本策略使丢帧率或光学延迟降低。本次未重新测量物理端到端延迟,也未证明所有长程拥塞峰值均已解决。较早的标记回显测量保留在 [延迟测量](latency.md)。
## 阻塞恢复验证
真实原生视频通道上的辅助接收端主动阻塞事件循环 350 ms,生产 `StreamClient` 恢复后拒绝 8 张过期帧,帧号从 1886 前进至 1918。该测试没有新增 UDP 订阅者;JPEG 解码在此辅助测试中使用替身,验证的是本地积压年龄和恢复逻辑,实际 JPEG 完整解码另行检查。
- 12 项 Rust 调度策略测试:绝对帧期限、旧采集帧寿命、共享重试预算、零重试及原有调度策略。
- 4 项 C 驱动交接情景:有限次数追赶、旧缓冲仅归还一次、无有效新帧时保留已有帧、首次超时及单缓冲边界。
- 8 项前端测试:慢解码保留最新待处理帧、500 ms 本机积压拒绝、阻塞解码结果释放、待解码帧超期和原有关闭/重启处理。
- 10 项原生视频通道测试:时间标记先于对应 JPEG、重连不重放过期缓存及原有协议与通道行为。
使用 `python scripts/test-latest-frame.py` 运行驱动交接测试;`desktop/` 中运行 `pnpm test:stream`。实时通道故障测试为 `node desktop/scripts/test-live-freshness.mjs <本机私有调试日志> <结果JSON>`,日志内的通道令牌仅在程序内部读取,不应发布。完整测量与边界见制品 `REALTIME-RESULT.json`,不包含私有日志、用户配置或相机抽帧。