docs: 整理项目文档并统一界面表述
将项目说明按主题集中到 docs,补齐根目录 README 和 AGENTS,移除弃用方案并保留有效测试记录与未实现提案。同步文档索引、引用及改动日志生成路径,README 增加 GitHub Markdown 导航和 Mermaid 图。 - fix(client): 统一状态与操作文案,录制和截图成功后再显示完成提示 - test(client): 按文件名核对媒体类型,避免依赖时间戳排序 验证:23 份项目文档、144 处本地引用、27 条外链、2 张 Mermaid 图;前端构建和 12 项测试;截图与录制的 4 条异步反馈路径;Windows Rust 编译检查和后端测试。后端 40 项返回成功,其中 3 项 ffmpeg 集成用例因本机缺少工具而未实际执行。
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
# 约 30 fps、Wi-Fi 重连与画面链路延迟验证(2026-10-18)
|
||||
|
||||
当前交付已增加阻塞恢复与新鲜度处理,见 [最新帧处理](realtime.md)。本页保留此前减光确认和画面延迟对照;所列 SHA 与测量结果均属于当时构建,不是当前固件的重测结果。
|
||||
|
||||
## 先前三缓冲与小幅减光记录
|
||||
|
||||
根据用户长程运行反馈,双缓冲在峰值负载下丢帧明显,当前交付恢复 **`CAM_FB_COUNT=3`**,为突发发送留出采集余量。约 30 fps 完整 PLL 配置、VGA 彩色、正常白平衡、Wi-Fi 自动重连和自适应 JPEG 都没有改动。双缓冲作为试验选项保留,下面的短时延迟对照属于历史记录,不能证明长程峰值稳定性。
|
||||
|
||||
针对现场轻微过亮,增加 `CAM_AE_LEVEL=-1`,将 OV5640 AE 目标从 55 微调到 45,目标比值约 −0.29 EV;`CAM_EXPOSURE_EV=0`,自动曝光和增益仍联动,曝光上限保持 592 行(约 20 ms)。这会小幅降低亮度目标,不保证实际快门必然缩短。当前 50 Hz 抗频闪步长约 10 ms,直接小减曝光上限可能跨越一整档,因此使用 AE 目标细调。该目标比值不等于经过照度标定的实际 EV。
|
||||
|
||||
本次烧录经 COM8 完成,Bootloader、分区表和 App 均通过独立校验。重新启动后串口观察 45.15 秒,复位和采集错误均为 0,订阅已恢复;末个窗口提交 29.7 fps。观察中仍有 UDP 发送回压,三缓冲不代表完全消除路由器拥塞。本次未重新测量原生完整接收损失率或画布延迟,也未重新进行长程峰值测试。
|
||||
|
||||
用户已确认当前三缓冲、小幅减光版本亮度合适、颜色稳定。
|
||||
|
||||
该阶段 App SHA-256:`05aff1f53519fbb52b89ca526c3be11cc78f37a3356f588986336cf7870924eb`。完整选择理由、当前参数与短测记录见制品 `BUFFER-DECISION.json`;下面的 90 秒/五分钟对照、CDF 和旧接收曲线保留为历史数据,不能套用到本次亮度微调后的镜像。
|
||||
|
||||
## 此前短时对照(历史)
|
||||
|
||||
此前试验使用 VGA 彩色、完整 PLL 配置和双缓冲。保留 Mihomo TUN,只有一个 UDP 订阅者,使用 Windows 生产客户端的真实视频绘制路径,非演示模式。用户已确认新时钟配置亮度够用、颜色正常,未再出现短 HTS 方案的绿紫闪烁。
|
||||
|
||||
| 指标 | 三缓冲基线 | 双缓冲试验配置 |
|
||||
| --- | --- | --- |
|
||||
| 原生接收窗口 | 90.008 s | 300.003 s |
|
||||
| 完整接收帧 | 2659 | 8909 |
|
||||
| 帧损失 | 32 / 1.189% | 61 / 0.680% |
|
||||
| 完整接收帧率 | 29.54 fps | 29.70 fps |
|
||||
| 本地 JPEG 通道 | 27.23 fps | 27.90 fps |
|
||||
| 标记回显有效样本 | 767 | 2641 |
|
||||
| 标记回显采样跨度 | 109.68 s | 295.08 s |
|
||||
| 标记 → 首次可解码画布回显 P50 | 128.4 ms | 121.5 ms |
|
||||
| 标记 → 首次可解码画布回显 P95 | 230.7 ms | 193.4 ms |
|
||||
| 回显估计 P99 / 最大值 | 285.3 / 443.2 ms | 248.9 / 461.5 ms |
|
||||
|
||||
这次窗口的 P50 降低 6.8 ms、P95 降低 37.3 ms。双缓冲减少潜在采集排队,同时保住接近 30 fps 的实际交付。两个窗口的网络回压、JPEG 自适应档位和时长不同,属于连续实机对照,不能把全部改善归因于缓冲数,也不是所有路由器或场景的保证。此前约 22 fps 的测试保留在 [持续运行记录](stability.md)。
|
||||
|
||||
双缓冲试验五分钟全程在线,复位、采集错误、通道断开和计数重置均为 0 次。抽取 61 张 JPEG 均完整解码为 640×480 RGB;没有用灰度或降低色深换帧率。最小内部空闲堆 118771 B;实际 JPEG 档位 18–28,温度 58–60°C,未触发减载。
|
||||
|
||||
## 该测试阶段的配置与时钟
|
||||
|
||||
```dotenv
|
||||
CAM_RES=vga
|
||||
CAM_CLOCK_PROFILE=vga30
|
||||
CAM_FB_COUNT=3
|
||||
CAM_QUALITY=18
|
||||
CAM_QUALITY_MAX=30
|
||||
CAM_MAX_FPS=0
|
||||
CAM_GRAYSCALE=0
|
||||
CAM_EXPOSURE_EV=0
|
||||
CAM_AE_LEVEL=-1
|
||||
CAM_SHUTTER_LINES=0
|
||||
CAM_EXPOSURE_MAX_LINES=592
|
||||
CAM_GAIN_CEILING=32
|
||||
CAM_HTS=0
|
||||
CAM_THERMAL_LIMIT_C=75
|
||||
WIFI_TX_POWER_DBM=14
|
||||
UDP_PACKET_GAP_US=0
|
||||
WIFI_TEST_DROP_AFTER_S=0
|
||||
```
|
||||
|
||||
XCLK 保持 20 MHz,使用完整 PLL 分频组合:VCO 610 MHz、SYSCLK 61 MHz、DVP PCLK 15.25 MHz;保持默认 HTS 2060 / VTS 984 和读出窗口,名义节拍约 30.09 fps。此前缩短 HTS 至 1500 / 1800 的方案会闪色,未采用。驱动回调的参数顺序与私有 PLL 辅助函数不同,必须按 `sensor_t.set_pll` 的签名调用。
|
||||
|
||||
下列实际曝光、增益范围属于此前双缓冲试验。当前 AE 目标改为 45/55,自动增益保留,曝光上限 592 行约 19.99 ms;实际曝光 590–590 行,估算 19.92–19.92 ms,增益 8.00–13.50×。最大 50 Hz band 数保留为 2,避免提升 SYSCLK 后向下取整只剩一个 band 导致画面过暗。未强制负 EV 或固定低快门。行数与毫秒换算依赖当前时钟,不能直接套用其他配置。
|
||||
|
||||
参考:[OV5640 数据手册资源页](<https://www.waveshare.com/wiki/OV5640_Camera_Board_(A)>)、[Espressif OV5640 驱动](https://github.com/espressif/esp32-camera/blob/master/sensors/ov5640.c)。Waveshare 资源页的 Datasheets 部分提供手册入口。新组合的 VCO 和 PCLK 在该手册列出的范围内;这不代替板上信号完整性和画面验证。
|
||||
|
||||
## Wi-Fi 运行时恢复
|
||||
|
||||
断开、失去有效 IP 或地址变化后停止 UDP 发送并清理订阅目标。关联和 DHCP 分别使用 15 秒期限;首次立即尝试,失败按 1、2、4、8、16、30 秒退避。事件回调只更新状态,主循环负责调用驱动;认证进行中不会反复 connect。取址后重建 socket、恢复无线参数、丢弃旧采集帧并重新广播,保留摄像头、曝光、增益、设备 ID 和帧序号。
|
||||
|
||||
实机诊断构建主动断开并保持 5 秒:检测断线后 9021 ms 恢复网络,其中重试发起到恢复日志为 4029 ms(含取址和恢复处理);无需重启,客户端随后自动续订恢复视频。该测试使用同一恢复逻辑、60 MHz SYSCLK 的预检构建;最终交付为 61 MHz,故障注入参数为 0。恢复到同一个 IP 已验证,路由器长时间关机、密码改变和 DHCP 换址尚未分别做硬件测试。启动阶段第一次联网仍使用原有扫描和认证模式探测逻辑。
|
||||
|
||||
处理方式遵循 [ESP-IDF 断线事件说明](https://docs.espressif.com/projects/esp-idf/en/v5.5.5/esp32s3/api-guides/wifi.html#wifi-event-sta-disconnected):有效 IP 恢复后再重建上层 socket。4 项恢复策略测试覆盖认证阶段不被重启、关联/DHCP 超时、指数退避和新断线重置状态。
|
||||
|
||||
## 延迟测量方法与边界
|
||||
|
||||
Windows 客户端使用裁判配置和 `--latency-report <新的NDJSON路径>` 启动。相机固定对准左侧四角标记,右侧沿正常 `VideoSurface` 路径绘制真实回显。源标记每 50 ms 更新,记录每个编号首次可解码的画布回显;四角透视校正、Gray 码和互补行拒绝无法可靠识别的曝光混合帧。最初逐刷新更新在 180 Hz 屏幕上会让一次曝光跨越多个编号,已在正式对照前修正。
|
||||
|
||||
源标记和回显均使用同一客户端 `performance.now()`,无需 ESP 时钟同步。绘制时刻以相邻 rAF 夹定,表中为上下界中点;此前双缓冲样本的区间宽度中位数为 11.4 ms。该范围包括相机取样等待、曝光、采集、无线传输、重组、本地 WebSocket、解码和画布绘制。它是**屏幕标记事件到首次可解码画布回显的估计**,没有测量源/输出面板扫描或像素响应;严格的物理光学端到端延迟需用高速相机复核。未识别帧不成为样本,首次可解码回显可能晚于较早的模糊回显,不能把有效样本分布当作每一帧的延迟。
|
||||
|
||||
此前双缓冲试验中,解码完成到画布绘制平均 2.72 ms;标记分析平均 2.02 ms。该分析只在校准模式运行,正常客户端不做画布回读。字段 `decodeToDrawMs` 从解码完成开始,不代表 JPEG 解码耗时。接收间隔、分片组装耗时及发送函数耗时各有独立口径,不能替代本测量。
|
||||
|
||||
`scripts/analyze_latency.py` 可按半开区间行号复算 NDJSON。完整结果、参数、行号范围和边界见制品 `LATENCY-RESULT.json`,分布图见 `LATENCY.png`。原始校准记录保存在本机 `target/latency/`,不把画面、私有配置或令牌日志打进制品。
|
||||
|
||||
## 交付与硬件限制
|
||||
|
||||
该阶段 App SHA-256:`05aff1f53519fbb52b89ca526c3be11cc78f37a3356f588986336cf7870924eb`。Bootloader、分区表和 App 已经 COM8 烧录并独立校验,ZIP 内含校验清单。
|
||||
|
||||
本模组除原有 `0xFADE7` 坏点,还发现 `0x10863` 的 bit 6 异常读回为 1,整段回读只差这一字节,是否永久故障尚未单独擦写复核;已把应用分区移至 `0x50000` 并验证 `0xFADE7` 对应字节可写。该兼容布局针对故障模组,每次重编仍需重新核对,详见 [图传板硬件](../hardware/camera.md)。
|
||||
@@ -0,0 +1,53 @@
|
||||
# 图传性能排查与验证(2026-10-18)
|
||||
|
||||
本文保留早期短时对照;当前交付已回退到 15 dBm,功率、距离与发送拥塞分析见 [功率与拥塞记录](power.md),阻塞处理见 [最新帧处理](realtime.md),此前约 30 fps 与回显延迟数据见 [延迟测量](latency.md),更早的验证见 [持续运行记录](stability.md)。下列数字对应当时的传感器时序和网络状态。
|
||||
|
||||
## 环境与结论
|
||||
|
||||
测试使用当前 ESP32-S3-N16R8 / OV5640,VGA 640×480、8 MB PSRAM、CPU 240 MHz、ESP-IDF v5.5.5。板端连接 2.4 GHz Wi-Fi,实际协商 HT20 / CCMP,主要有效窗口的信号约 −18~−32 dBm;Windows 通过同一路由器通信,Mihomo TUN 始终保持启用。单客户端对照使用 1 MiB 接收缓冲,每 800 ms 单播续订。
|
||||
|
||||
传感器在 CPU0 和 CPU1 均可输出约 22.2 fps。低帧率期间持续出现 `sendto` 的 `ENOMEM`(errno 12),完整帧提交率低于采集率,客户端收到不完整分片。普通系统内存仍有约 100 KiB 以上可用,证据指向无线发送拥塞与驱动缓冲回压。核绑定和单独扩大 Windows 缓冲均未解决主要瓶颈。
|
||||
|
||||
降低最大发射功率、改用视频队列、减小单帧大小后有所改善。功率切换对照中,20 dBm 的窗口明显恶化,10 dBm 的两次窗口约 12 fps;14 dBm 的结果仍有波动。仅凭这些数据无法确定供电、天线、射频或 AP 的具体物理原因。
|
||||
|
||||
## 接收端对照
|
||||
|
||||
| 配置 | 时长 | 完整帧 | 窗口 fps | 帧损失 | 完整帧间隔 P95 | 分片组装 P95 |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| 问题复测:20 dBm / 普通队列 / quality 12 | 30 s | 165 | 5.49 | 74.69% | 672.0 ms | 109.0 ms |
|
||||
| 14 dBm / 普通队列 / quality 12 | 30 s | 477 | 15.88 | 27.84% | 242.2 ms | 145.4 ms |
|
||||
| 14 dBm / 视频队列 / quality 12 | 60 s | 1091 | 18.18 | 17.41% | 194.4 ms | 103.2 ms |
|
||||
| 该阶段选择:14 dBm / 视频队列 / quality 18 | 60 s | 1177 | 19.62 | 11.30% | 192.8 ms | 94.2 ms |
|
||||
|
||||
表中 fps = 完整帧数 / 整个测量时长。帧损失包括被替换的不完整帧、超时及帧号缺口;末尾仍在接收的帧不计损失。丢帧率与旧客户端的口径不同,旧版会低估实际丢帧。
|
||||
|
||||
无线链路有明显时变,早期其它窗口也出现过约 5~15 fps。表中的数字不构成长期保证,这些配置也不是所有板卡的通用最优参数。前两行使用 CPU0,后两行使用 CPU1;核绑定对照未消除发送拥塞,最终保留显式 CPU1 配置。关闭 AMPDU 的试验几乎无法得到完整帧,已撤回;忙等重试也已撤回。另一次 40 ms 重试预算试验期间,有新客户端加入导致两个订阅者,且信号和画面复杂度变化;该轮约 12.6 fps,不能用于证明重试预算的单项影响,未作为最终配置依据。
|
||||
|
||||
## 最终参数与改动
|
||||
|
||||
- 该测试阶段本机 `.env` 选择 `CAM_QUALITY=18`、`WIFI_TX_POWER_DBM=14`。分辨率保持 VGA;quality 数字增大表示压缩更强,细节会有所损失。仓库默认 quality 仍为 12,未设置发射功率时保留 SDK 默认上限;当前功率选择见 [功率与拥塞记录](power.md)。
|
||||
- 视频 socket 设置 `IP_TOS=128`,使用 AC_VI,并保留 AMPDU;64 个动态 TX 缓冲、TX BA window 32、FreeRTOS 1000 Hz。JPEG 在 PSRAM 中原地读取,仅复用一个数据报缓冲;临时发送失败让出调度重试,等待预算为每帧 25 ms。
|
||||
- 客户端按发现的设备 IP 定向续订,接收缓冲请求 1 MiB。随机会话 ID 让同一会话的端口变化更新目标地址;旧固定 ID 保留按地址区分。实测迁移后旧端口无新视频,新端口继续接收;两个旧版订阅仍各自收到数据。
|
||||
- 接收器拒绝迟到旧帧、重复完成帧和矛盾分片,处理帧号回绕、设备重启及超时。视频 WebSocket 只保留各路最新帧;前端每路至多一次解码与一张最新待解码帧,避免持续积压。
|
||||
|
||||
## Windows 实际客户端验证
|
||||
|
||||
使用已构建的 release EXE 和独立裁判端测试配置,非演示模式。原用户配置、密码和绑定保留。
|
||||
|
||||
约 30 秒窗口中,后端完整帧增量 624、丢帧增量 38,窗口帧损失约 5.74%。界面连接存在,独立观察连接收到 619 张完整 JPEG,通道帧率 20.62 fps,帧间隔 P95 为 103.0 ms,无损坏 JPEG。
|
||||
|
||||
这项验证覆盖真实板卡、UDP 接收与重组、GUI 的 WebSocket 连接及二进制视频通道。当时另有 20 项协议测试、83 项客户端核心测试、9 项后端视频通道测试、5 项前端解码队列测试;Windows 类型检查和生产打包也通过。未将整个后端测试集或录制功能记为已验证。
|
||||
|
||||
**时间边界:**组装耗时是首末分片到达的差值,帧间隔是相邻完整帧到达的差值,均不是摄像头到屏幕的端到端延迟。未做两端时钟同步或实际屏幕的光学延迟测量,也未自动验证 WebView 最终绘制像素。
|
||||
|
||||
## 复测与原始记录
|
||||
|
||||
先退出其它图传接收进程,避免增加订阅负载:
|
||||
|
||||
```text
|
||||
python scripts/perf_probe.py <板卡IP> --seconds 60 --json perf.json --save-frame frame.jpg
|
||||
```
|
||||
|
||||
本机原始 JSON、抽帧和串口日志在 `target/camera-diagnostics/`,随构建缓存忽略;主要文件为 `fps-core0-raw.json`、`fps-tx14-raw.json`、`fps-quality12-raw.json`、`fps-final-raw.json`、`fps-final-client-result.json`、`session-migration.json`。固件与 Windows 制品的 `BUILD-INFO.json` 记录最终测量及验证范围,ZIP 不包含用户运行配置。
|
||||
|
||||
设计依据:[ESP-IDF 5.5.5 的 UDP 发送回压说明](https://docs.espressif.com/projects/esp-idf/en/v5.5.5/esp32s3/api-guides/lwip.html#limitations)、[Wi-Fi QoS 的 IP precedence / AC_VI 映射](https://docs.espressif.com/projects/esp-idf/en/v5.5.5/esp32s3/api-guides/wifi.html#wi-fi-qos)。这些文档说明机制,性能数字来自上述本机测量。
|
||||
@@ -0,0 +1,64 @@
|
||||
# 发射功率、断连距离与拥塞分析(2026-10-18)
|
||||
|
||||
当前交付请求 `WIFI_TX_POWER_DBM=15`,实板驱动回读 **15.00 dBm**。根据用户的距离与拥塞反馈,从 17 dBm 回退;启动和 Wi-Fi 重连后应用同一设置,压缩与温控控制器不自动降低发射功率。三缓冲、VGA 彩色、AE 目标 45、约 20 ms 曝光上限和 PLL 时钟保持不变。
|
||||
|
||||
这里的数值是驱动配置的发射功率上限。API 回读不能代替功率计,也不能据此认为所有 PHY 速率下、每个数据包的天线端输出都恰好相同。
|
||||
|
||||
## 先前 17 dBm 记录说明了什么
|
||||
|
||||
| 记录 | 时间 | 原生接收帧率 | 原生帧损失率 | 板端发送失败 / 应用重试 / 放弃目标帧 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 17 dBm 第一轮 | 视频 30 s / 串口 75 s | 29.78 fps | 0.667% | 90 / 80 / 10(整段串口) |
|
||||
| 17 dBm 第二轮,增加周期回读 | 视频 30 s / 串口 75 s | 27.92 fps | 6.889% | 498 / 446 / 52(整段串口) |
|
||||
|
||||
两轮的发射上限、曝光与缓冲参数相同,但无线状态、场景内容和时间并未锁定,且第二轮多了周期功率读数。因此这些记录不构成严格 A/B 对照,不能单凭它们断定“增加 3 dB 必然导致某个百分比的丢帧”。用户反馈是回退依据,日志用于定位失败发生在哪一层。
|
||||
|
||||
第二轮内部空闲堆最少 120039 字节、最大连续块最少 43008 字节,温度 57–58°C,无温控限帧、复位或采集错误,只有一个 UDP 订阅者。出现发送失败时伴有 `errno 12 / ENOMEM`,优先指向网络发送资源的瞬时耗尽。堆仍有余量,不能排除受配额限制的 Wi-Fi TX 缓冲已满,也不能把这个错误直接当成内存泄漏。
|
||||
|
||||
ESP-IDF 明确说明,UDP 连续 `send/sendto` 可以因底层驱动 TX 缓冲全部占用而返回 `ENOMEM`。目前日志中的“446 次重试”是**应用调用 sendto 的重试**,不是已测得的 802.11 空口重传次数。来源:[ESP-IDF v5.5.5 lwIP 文档](https://docs.espressif.com/projects/esp-idf/en/v5.5.5/esp32s3/api-guides/lwip.html#limitations)。
|
||||
|
||||
## 为什么距离改善不明显
|
||||
|
||||
1. **功率差只有 3 dB。** 14→17 dBm 的配置上限约为两倍功率,不是两倍距离。按简化路径损耗模型 `距离倍率 = 10^(3/(10n))`,自由空间 `n=2` 时约 1.41 倍,假设室内 `n=3–4` 时约 1.19–1.26 倍。这只是模型估算,不是本次测得的距离。
|
||||
2. **收发链路必须同时成立。** 增强板卡发射不能增强板卡接收;AP 信标、应答、订阅和数据回程仍依赖另一方向。ESP-IDF 的断连说明包含持续丢失信标等原因。当前记录没有最远点的断连 reason、AP 侧接收强度或重传统计,不能确定距离边界由哪一方向限制。来源:[ESP-IDF 断连事件说明](https://docs.espressif.com/projects/esp-idf/en/v5.5.5/esp32s3/api-guides/wifi.html#wifi-event-sta-disconnected)。
|
||||
3. **回读是上限,RSSI 有方向。** 板端日志里的 RSSI 是板卡接收到 AP 的信号,不是 AP 接收到板卡的信号。17 dBm 第二轮 RSSI 为 −25 至 −14 dBm,属于近距离记录,不能拿来证明远距离的上行链路已经改善。
|
||||
|
||||
## 为什么拥塞仍会加重
|
||||
|
||||
已确认的应用行为是:每约 33 ms 取得一张 JPEG,再把它拆成多个数据报连续提交,分片间隔为 0;成功返回只表示本地网络栈接受,不能证明 AP 或电脑已经收到。每帧 8 ms 重试预算和 25 ms 持有期限限制应用等待,但不能撤回已经进入 SDK 的旧分片。
|
||||
|
||||
提高发射上限不会增加信道带宽或路由器的排队能力。若空口竞争、速率回退或重传使驱动排空变慢,突发提交仍会填满 TX 缓冲。这是与日志一致的机制推断;本次没有 CCA 忙占比、MAC 重传、实际发送 MCS 或 AP 队列数据,尚不能确认其中任何一项是功率变化造成的根因。来源:[ESP-IDF TX 数据路径与缓冲说明](https://docs.espressif.com/projects/esp-idf/en/v5.5.5/esp32s3/api-guides/wifi.html#how-to-improve-wi-fi-performance)。
|
||||
|
||||
更高功率改变干扰覆盖、射频线性度或供电瞬态,也可能间接影响链路,但这里没有相应测量,不将“接收端过载”“功放饱和”或“电压跌落”写成已确认原因。无 Brownout 记录也不能证明射频供电完全没有瞬态变化。
|
||||
|
||||
电脑当前通过 **5 GHz / 信道 161 / 802.11ac** 连接,摄像头使用 2.4 GHz。因此不能直接声称视频在同一个 2.4 GHz 信道被路由器重复发送了两次;摄像头上行、AP 转发、电脑接收与 TUN 处理仍可能分别排队,TUN 保持原样。
|
||||
|
||||
## 还需区分本地跳帧
|
||||
|
||||
17 dBm 第二轮视频区间中,原生接收了 838 张完整 JPEG,而辅助本地 WebSocket 观察器收到 582 张。两者不是同一个指标:后端采用最新帧覆盖和帧龄期限,慢消费者可能主动跳过已完整收到的帧;少收到的本地消息不能全部算成无线丢帧,更不能直接等同于真实屏幕绘制帧率。
|
||||
|
||||
## 当前回退验证与后续定位
|
||||
|
||||
测试期间用户补充观察:用手握持开发板时丢包明显增多。测试没有逐秒标记握持、位置和朝向,五分钟记录应视作现场连续性观察,不能当作固定摆位的功率 A/B 测试。人体靠近 PCB 天线造成的吸收、失谐或遮挡,是更值得优先排查的线索。
|
||||
|
||||
本轮只把功率上限改到 15 dBm,其他图传参数与单 UDP 订阅保持不变,做五分钟收流观察;结果由交付包 `POWER-RESULT.json` 记录。之前的 17 dBm 记录保留为 `POWER-HISTORY-tx17.json`,14 dBm 的阻塞处理记录保留在 [最新帧处理](realtime.md)。本轮不重新测量最远断连距离或物理屏幕端到端延迟。
|
||||
|
||||
下一项值得单独对照的是**分片突发整形**:固定 15 dBm、曝光和 JPEG 策略,按发送回压逐步比较小批次提交与短暂让出调度,并同时看原生完整帧率、网络丢帧、主动跳帧和帧龄。不能仅通过增大缓冲或延长重试,把丢帧转化为持续排队延迟。若要确认距离瓶颈,需要同步记录远点断连原因、AP 侧板卡 RSSI、MAC 重传和信道忙占比。
|
||||
|
||||
## 蛇形 PCB 天线的握持改善
|
||||
|
||||
手接近天线会改变其周围的电磁环境,人体和外壳可使 PCB 天线失谐;人体也会吸收、遮挡部分射频能量。这是对用户观察的机制解释,本板尚未测量 S11、效率或握持前后的辐射图。TI 的 2.4 GHz PCB 天线实测例子显示,加入外壳并手持后匹配状态明显变化,需要在实际使用条件下匹配。来源:[TI 天线阻抗测量与匹配,章节 6](https://www.ti.com/lit/an/swra726/swra726.pdf)。
|
||||
|
||||
建议按以下顺序改善:
|
||||
|
||||
1. **先改善握持和摆位。** 用塑料支架或绝缘延长握柄固定,让蛇形天线端伸出、远离手掌;握住远离天线的一端。可先尝试让手与天线相距约 3–5 cm,再按实测增加距离,这不是保证性能的固定阈值。
|
||||
2. **留出天线净空。** Espressif 建议成品外壳中天线各方向至少 15 mm 净空;这不是“距离手 15 mm 就一定够”的保证。天线附近避开电池、金属支架、屏蔽片和紧贴的 USB 线或排线,外壳在天线区域使用非金属材料。来源:[ESP32-S3 PCB 天线布局指南](https://docs.espressif.com/projects/esp-hardware-design-guidelines/en/latest/esp32s3/pcb-layout-design.html#general-principles-of-pcb-layout-for-modules-positioning-a-module-on-a-base-board)。
|
||||
3. **固定朝向再比较。** 在同一位置和画面下,保持开发板朝向固定,比较“不接触 → 握远端 → 手靠近天线 → 移开手”,每段 30–60 秒,同时记录完整帧损失和板端 RSSI。单看 RSSI 不能覆盖上行质量,但可帮助区分朝向、遮挡与队列负载变化。
|
||||
4. **需要长期手持时,优先考虑外置天线版本。** `ESP32-S3-WROOM-1` 为 PCB 天线,`WROOM-1U` 为外置天线接口版本。选兼容摄像头接线、Flash/PSRAM 配置的板卡,将合适的 2.4 GHz 天线安放在握持区域之外;具体封装、接口和射频连接须按实际板卡核对。外置天线也应远离手和金属。来源:[Espressif 模组数据手册](https://documentation.espressif.com/esp32-s3-wroom-1_wroom-1u_datasheet_en.pdf)。
|
||||
5. **必须贴近人体使用时,按最终结构调谐。** 外壳、支架、馈线和手持姿态都参与最终匹配,需要 VNA/射频测量后调整匹配网络。直接延长蛇形走线、随意焊线或并接两根天线不能代替调谐;在现板上先做可逆的机械隔离更容易验证。
|
||||
|
||||
## 15 dBm 本轮结果
|
||||
|
||||
当前 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-RESULT.json`。
|
||||
|
||||
按时间近似对齐的板端五分钟区间有 731 次发送失败、653 次应用重试、78 次目标帧放弃;温度 56–58°C,RSSI -35 至 -11 dBm。板端区间由五秒采样的结束时间选择,边界并非逐包精确对齐。与此前短测时长、现场无线状态和 JPEG 内容不同,不能将差值归因于功率这一项。
|
||||
@@ -0,0 +1,73 @@
|
||||
# 阻塞恢复与最新帧处理(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`,不包含私有日志、用户配置或相机抽帧。
|
||||
@@ -0,0 +1,135 @@
|
||||
# 彩色图传调度与持续运行验证(2026-10-18)
|
||||
|
||||
本文保留此前约 22 fps 配置及更早长测的历史记录。后续约 30 fps PLL 配置、缓冲选择、运行中断线恢复与画布回显延迟测量见 [延迟测量](latency.md);以下参数与 SHA 属于当时的测试阶段,当前交付以新报告和制品 `BUILD-INFO.json` 为准。
|
||||
|
||||
## 测试目标与配置
|
||||
|
||||
使用 ESP32-S3-N16R8 / OV5640、VGA、8 MB PSRAM、CPU 240 MHz、Windows 原生客户端,保留 Mihomo TUN。每轮只运行一个 UDP 订阅者,串口记录器与本地 WebSocket 观察器不会新增 UDP 推流目标。Windows 到板卡的实际路由走 WLAN;电脑连接 5 GHz、板卡连接 2.4 GHz。
|
||||
|
||||
优化目标为彩色、内容可辨、较短曝光和尽可能高的完整接收帧率,每轮有效测量为 5 分钟。下文保留了亮度与时序调整过程;不同轮次的场景、曝光、压缩和网络状态有变化,接收数字是描述性对照,不能作为严格单因素实验。
|
||||
|
||||
```dotenv
|
||||
CAM_RES=vga
|
||||
CAM_QUALITY=18
|
||||
CAM_QUALITY_MAX=30
|
||||
CAM_MAX_FPS=0
|
||||
CAM_GRAYSCALE=0
|
||||
CAM_EXPOSURE_EV=0
|
||||
CAM_SHUTTER_LINES=0
|
||||
CAM_EXPOSURE_MAX_LINES=440
|
||||
CAM_GAIN_CEILING=32
|
||||
CAM_HTS=0
|
||||
CAM_THERMAL_LIMIT_C=75
|
||||
WIFI_TX_POWER_DBM=14
|
||||
UDP_PACKET_GAP_US=0
|
||||
```
|
||||
|
||||
这些参数在编译时生效。该阶段配置的板上无网络采集探针为 22.20 fps,保留驱动默认 HTS 2060 / VTS 984 / XCLK 20 MHz;未采用颜色异常的短 HTS,也未采用此前导致采集下降至 8.1 fps 的 VTS 调整。
|
||||
|
||||
## 曝光与彩色
|
||||
|
||||
OV5640 驱动的 AE 档位不是 EV 数值:名义零档目标为 55,档位 −3 的目标为 25,目标比值约为 −1.14 EV;档位 −4 的目标为 15,约为 −1.87 EV。固件的 `CAM_EXPOSURE_EV=-1/-2` 使用这两个近似档位;这不是经过照度标定的绝对 EV。
|
||||
|
||||
早期仅降低 AE 目标后,实际曝光仍为 885 行;固定 220 行约为 10 ms,用户反馈太暗;固定约 20 ms 仍然太暗,均已撤回。其他时钟或分辨率下,行数对应的时间不同,不能直接套用行数。
|
||||
|
||||
该阶段采用正常亮度目标、自动 AEC / AGC、440 行曝光上限,关闭夜景延帧,并按现有 50/60 Hz band step 同步约束最大 band 数。自动增益上限由原来的 15.5× 扩至 31.94×,给短曝光补偿空间;增益会放大噪点。预检实际曝光为 295 行,按 SYSCLK 45 MHz / HTS 2060 估算约 13.5 ms,约为早期 885 行曝光的三分之一。440 行上限约 20.1 ms,实际值由场景与频闪步长决定。
|
||||
|
||||
用户已确认新配置**亮度够用、颜色稳定**。它仍使用传感器硬件彩色 JPEG,不通过降低色深来提帧。
|
||||
|
||||
彩色 JPEG 抽帧已解码为 640×480 RGB。曝光行数日志用于验证快门配置,未进行运动靶拖影或照度标定测量。驱动依据:[Espressif OV5640 源码](https://github.com/espressif/esp32-camera/blob/master/sensors/ov5640.c)。
|
||||
|
||||
## 最终配置的五分钟验证
|
||||
|
||||
本轮测量从 `2026-10-18T12:24:10.381357+00:00` 到 `2026-10-18T12:29:10.384000+00:00`,持续 300.004 秒。下表对照前一轮固定约 20 ms、quality 18 的完整五分钟记录;前一轮用户确认过暗,本轮用户确认亮度够用、颜色稳定。
|
||||
|
||||
| 指标 | 固定快门对照 | 自动曝光上限 + 压缩调节 |
|
||||
| --- | --- | --- |
|
||||
| 完整接收帧 | 5220 | 6520 |
|
||||
| 丢帧 | 1430(21.50%) | 34(0.52%) |
|
||||
| 完整接收帧率 | 17.40 fps | 21.73 fps |
|
||||
| 本地 JPEG 通道帧率 | 13.45 fps | 20.99 fps |
|
||||
| 通道帧间隔 P95 | 277.473 ms | 102.841 ms |
|
||||
| 通道帧间隔最大值 | 1163.792 ms | 419.825 ms |
|
||||
| 平均 JPEG 大小 | 12099 字节 | 16346 字节 |
|
||||
|
||||
本轮全程在线,无复位、采集错误、本地通道断开、计数重置或诊断计数缺失。视频包长度与首尾标记错误为 0;另抽取 148 张 JPEG 完整解码,均为 640×480 RGB。
|
||||
|
||||
测量窗口内曝光为 295–295 行;JPEG 档位为 18–22,实际增益 11.00–18.00×。内部堆最小 129455 字节,平均提交耗时 2.60 ms/帧,温度 54–59°C,未触发温度减载。
|
||||
|
||||
这次完整接收帧率接近当前可靠彩色时序的约 22.2 fps 上限。亮度、画面内容、JPEG 大小和网络负载在各轮之间变化,不能把全部差异归因于单一控制参数,也不能将五分钟结果作为长期或所有路由器的保证。帧间隔不是摄像头到屏幕的光学延迟。
|
||||
|
||||
本轮固件 SHA-256 为 `e297069e190dcccefbae6d95591703c6848f4e523f910e2c0cb44af91f698936`,当时与交付及板上镜像一致;当前交付以 [项目说明](../../README.md) 和交付包的 `BUILD-INFO.json` 为准。配套 Bootloader、分区表及 App 均已独立读回校验。曲线和完整数据位于制品包内的 `STABILITY.png` / `SCHEDULING-RESULT.json`,不包含相机抽帧或令牌日志。
|
||||
|
||||
## 较早的五分钟彩色基线
|
||||
|
||||
以下为较早的完整 300.002 秒测量,HTS 保持驱动默认 2060,快门 220 行,UDP 分片间隔为 0。真实 Windows 客户端接收,非演示模式,单 UDP 订阅者。该场景 JPEG 约 9 KB,用户随后确认这一曝光方案过暗,因此不再作为最终交付配置。
|
||||
|
||||
| 指标 | 结果 |
|
||||
| --- | --- |
|
||||
| 完整接收帧 | 6647 |
|
||||
| 丢帧 | 12,0.1802% |
|
||||
| 完整接收帧率 | 22.1565 fps |
|
||||
| 本地 JPEG 通道帧率 | 20.8365 fps,6251 帧 |
|
||||
| 接收通道帧间隔 P95 / 最大值 | 102.459 / 408.082 ms |
|
||||
| 平均 JPEG 大小 | 9113 字节 |
|
||||
| 实际曝光 | 全程 220 行 |
|
||||
| 采集错误 / 复位 / 本地连接断开 | 0 / 0 / 0 |
|
||||
|
||||
图传完整帧率已接近该采集配置的约 22.2 fps 上限;本地通道采用 latest 模式,突发到达的多帧可能被合并,不能用其帧数代表屏幕已绘制帧数。不同场景下 JPEG 大小和无线负载会变化。
|
||||
|
||||
## 间隔发送的中止轮次
|
||||
|
||||
1000 μs 最小分片间隔轮次在设备运行约 235 秒时出现串口 I/O 错误,随后系统不再枚举开发板串口,摄像头同时离线。观察器提前停止,未完成有效的五分钟对照,断连尾段不能归因于调度。
|
||||
|
||||
断连前 3 个完整在线窗口合计 181.192 秒,接收 21.58 fps、帧损失 1.96%,本地通道 17.25 fps,没有显示出逐包间隔的收益。这个间隔可能影响 AMPDU 聚合效率,但未抓取空口包,不能确认唯一原因。保留突发发送作为已验证基线,不采用这轮的完整汇总作性能结论。
|
||||
|
||||
## 已撤回的行时序提帧试验
|
||||
|
||||
新增可选 `CAM_HTS`,仅改变 OV5640 水平总时长,保留有效读出窗口及消隐余量,PLL、XCLK、VTS 不变。候选参数为 HTS 1500、快门 300 行,估算保持约 10 ms 曝光,采集节拍目标约 30.5 fps。
|
||||
|
||||
USB 恢复后,HTS 1500 的板上采集探针达到 30.49 fps,但白光环境出现明显绿紫闪烁,用户确认不可用。HTS 1800 的探针为 25.41 fps,仍出现明显偏紫,也已中止;两者均不作为有效五分钟彩色结果或交付配置。恢复默认 HTS 2060 后,用户确认颜色稳定。
|
||||
|
||||
1500 轮次开始时队伍 release 模式隐藏接收计数,因此该轮汇总中的接收 fps / 丢帧为无效值,不能当作零丢帧;观察脚本现已要求裁判诊断计数并记录诊断可用性。`0x380C/0x380D` 的水平总长定义见 [OV5640 数据手册资源页](<https://www.waveshare.com/wiki/OV5640_Camera_Board_(A)>)中 Datasheets 部分的手册。几何检查和 JPEG 成功解码都不足以证明彩色稳定。
|
||||
|
||||
## 室内亮度回归
|
||||
|
||||
用户确认,−1 EV / 固定 10 ms,以及恢复名义 0 EV 后固定约 20 ms,都仍然太暗。因此最终方案不再固定短快门,而是让 AEC / AGC 自动联动,并以曝光上限控制拖影。手册说明 AGC 通常在 AEC 到达上限后继续增加;仅保留 AGC 开关不能当作亮度已经补足的证据。需要结合实际曝光、增益和画面验证。
|
||||
|
||||
固定 20 ms 的完整五分钟轮次接收 5220 帧、丢帧 1430(21.50%),接收 17.40 fps,本地 JPEG 通道 13.45 fps,接收间隔 P95 277.473 ms、最大 1163.792 ms;全程在线、无采集错误。它保留为拥塞对照,未被选为最终配置。
|
||||
|
||||
## 发送调度
|
||||
|
||||
当前启用有界 JPEG 压缩调节,`CAM_QUALITY=18` 为画质恢复目标,`CAM_QUALITY_MAX=30` 为压缩上限。每 5 秒检查本机发送窗口:对端帧放弃比例达到 2%,或平均提交耗时达到 8 ms 时,压缩数字增加 3 档;连续 3 个无放弃且提交小于 4 ms 的窗口后,才降低 1 档恢复细节。无订阅或流量不足时不会当作健康窗口。
|
||||
|
||||
该反馈来自板端提交回压,不包含接收端 ACK;不能据此声称消除了路由器后续丢包。调节不改变彩色、分辨率或采集时钟,运行日志记录实际 JPEG 档位、曝光行数和增益。
|
||||
|
||||
视频数据报使用 WMM AC_VI、保留 AMPDU。`UDP_PACKET_GAP_US` 控制成功提交数据报的最小间隔,调度 tick 可能使实际等待更长。等待期间让出 CPU,避免在帧开始时集中向 Wi-Fi 队列灌入全部分片。
|
||||
|
||||
每帧预算为 25 ms 加计划分片间隔,总等待上限 40 ms;没有调度间隔时仍为 25 ms。超过预算则放弃该对端的剩余旧帧,不追赶补发。分片数量较多时需要重新选择间隔,不能把某个 VGA 配置的结果直接套到更大图像。
|
||||
|
||||
`submitted` 只表示分片全部交给了网络,不代表无线确认或屏幕显示。帧损失包含接收端未完成帧与帧号缺口;设置帧率上限后,latest 模式有意覆盖的旧采集帧不进入 UDP 帧编号,不计入该丢帧率。
|
||||
|
||||
## 此前中止的灰度长测
|
||||
|
||||
原计划 30 分钟的灰度 / 15 fps 长测按用户要求提前停止,保留了 **18 个完整分钟窗口**,合计 1080.15 秒:完整帧 15307、丢帧 806,平均 14.17 fps,帧损失 5.00%。板端记录温度约 48–58°C,无复位和采集错误。
|
||||
|
||||
早期丢帧上升时温度没有同步上升,温度下降期间也出现过明显发送失败。内存紧张后能够恢复;发送失败与队列回压更符合当前证据。这一轮不计为完成 30 分钟验证,且配置不同,不能与彩色不限帧试验直接作单因素对照。
|
||||
|
||||
温度控制仍可选:达到 75°C 时将已设置的帧率减半(向上取整),原来不限帧时降至 8 fps;降到 70°C 后恢复。阈值可设 40–95°C,`0` 禁用。75°C 是主动减载策略,不是芯片损坏温度规格。本轮未触发该策略。ESP 内部温度不能代表 OV5640 或环境温度:[ESP-IDF v5.5.5 温度传感器说明](https://docs.espressif.com/projects/esp-idf/en/v5.5.5/esp32s3/api-reference/peripherals/temp_sensor.html)。
|
||||
|
||||
## 复测与记录
|
||||
|
||||
退出其他图传客户端,使用一个非演示模式的 Windows 裁判端。release 队伍模式隐藏技术计数,不能用于本脚本的接收 fps / 丢帧测量;用户在本机切换身份后可继续使用原进程,本次没有改写用户配置。`RUST_LOG=cam_desktop=debug,cam_core=info` 会记录本地 WebSocket 地址及令牌,原始日志仅供本机诊断,不应公开。
|
||||
|
||||
从仓库根目录分别运行,串口及设备 ID 换成实际值:
|
||||
|
||||
```text
|
||||
python scripts/serial_soak.py --port COM7 --seconds 330 --out target/soak/device --stop-file target/soak/stop
|
||||
node desktop/scripts/soak-stream.mjs --log target/soak/referee-stderr.log --out target/soak/client --seconds 300 --warmup 10 --stop-file target/soak/stop --sample-every 5
|
||||
```
|
||||
|
||||
串口脚本依赖 `pyserial`;观察脚本使用 Node.js 22 内置 WebSocket。默认设备 ID 为 `0x3D4D8A9A`,换板用 `--camera 0x设备ID`。创建 stop 文件可提前结束并保存部分窗口;新一轮使用不存在的 stop 文件路径。
|
||||
|
||||
串口每 5 秒保存温度、曝光行数、增益、JPEG 档位、内部堆、采集错误、发送重试、订阅数与帧率。客户端每分钟保存完整帧率、帧损失、JPEG 通道帧率、间隔 P95 / 最大值与连接状态,并标记离线、诊断不可用与末尾无视频时长。`--sample-every` 可选,单位为秒,抽帧仅留本机。JSON 标记实际时长与是否提前停止,不能将部分窗口称为完成 5 分钟。原始记录位于本机 `target/soak/`,随构建缓存忽略。
|
||||
|
||||
JPEG 长度与首尾标记校验不等于每张图的完整解码验证;本地 WebSocket 通道不代表 WebView 最终绘制。接收间隔与分片组装耗时均不是摄像头到屏幕的光学延迟。
|
||||
@@ -0,0 +1,33 @@
|
||||
# 图传故障排查
|
||||
|
||||
以下命令均在仓库根目录执行。
|
||||
|
||||
## 常见问题
|
||||
|
||||
| 现象 | 检查方法 |
|
||||
| --- | --- |
|
||||
| 提示缺少 `esp-1.97.0.0` | 按上述命令安装指定名称的工具链,重新打开终端后检查版本 |
|
||||
| `espup` 查询 GitHub 版本返回 403 | 对上述固定版本安装命令追加 `--skip-version-parse`,或稍后重试 |
|
||||
| 找不到 `ldproxy` / `libclang` | 安装链接工具;Unix 加载 `export-esp.sh`,Windows 重开终端 |
|
||||
| ESP-IDF 路径或版本错误 | 清除旧 `IDF_PATH` 或指向 v5.5.5 SDK |
|
||||
| Windows 路径过长 | 缩短仓库和工具链路径,见开发说明 |
|
||||
| Wi-Fi 连不上 | 核对 2.4 GHz、凭据和认证方式,再重新编译烧录 |
|
||||
| 相机无输出 / 初始化失败 | 核对板型接线、供电与 Octal PSRAM |
|
||||
| `NO-EOI`、几帧后停止 | 确认 `CONFIG_CAMERA_PSRAM_DMA=n` |
|
||||
| 在线但没有画面 | 检查客户端订阅、UDP 5600、防火墙及 AP 隔离 |
|
||||
| 界面提示协议不匹配 | 板子与客户端的线路协议号不同;按提示重新烧录同版本的固件 |
|
||||
| 开启 VPN / 虚拟网卡后设备在线但无画面 | 使用支持按已发现设备 IP 定向续订的客户端;仅发送 `255.255.255.255` 广播可能走错网卡 |
|
||||
| 改 C 组件后无变化 | 清理 `esp-idf-sys` 构建缓存后重编,见开发说明 |
|
||||
| 主机项目被编为 Xtensa | 显式指定宿主 target,见各子项目说明 |
|
||||
|
||||
用 `python scripts/udp_probe.py 10` 可独立检查视频协议;装甲板用 `python scripts/armor_probe.py 15`。这些脚本需要板卡在线,构建通过不代表已完成硬件验证。
|
||||
|
||||
测量帧率和丢帧可运行以下命令,将 IP 换成板卡实际地址。对照测试时先退出桌面客户端,避免额外订阅者增加无线负载:
|
||||
|
||||
```text
|
||||
python scripts/perf_probe.py 192.168.1.139 --seconds 30 --json perf.json
|
||||
```
|
||||
|
||||
脚本定向续订,支持保留 VPN / TUN 的环境。输出包含完整帧率、帧损失率、接收间隔和组装耗时;这些时间不等于摄像头到屏幕的端到端延迟。
|
||||
|
||||
运动图传保持 `CAM_GRAYSCALE=0`,优先使用自动曝光上限和自动增益协同控制拖影。室内强制 −1 EV / 固定短快门在本机过暗,已撤回;提高增益上限也会增加噪点。需要限流时设 `CAM_MAX_FPS=15`,追求帧率时用 `0`;可启用有界 JPEG 压缩调节应对发送回压,分片间隔按网络实测选择。灰度效果仍保留硬件 JPEG,不是改为 RGB565 或降低 JPEG 采样位数。75°C 是主动减载阈值,温度来自 ESP 芯片内部,不能代表摄像头或环境温度,也不是芯片损坏温度规格。五分钟彩色对照与此前中止的灰度长测见 [持续运行记录](stability.md)。
|
||||
Reference in New Issue
Block a user