fix(packaging): 修复 Windows 安装与固件打包并完善客户端文案
构建客户端 / 检查(类型 + 单元测试) (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(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。未执行实机烧录。
This commit is contained in:
2026-10-21 09:25:17 +08:00
parent 6a0eb14b28
commit 054379dc64
52 changed files with 1070 additions and 280 deletions
+9 -7
View File
@@ -28,6 +28,8 @@ espflash write-bin --chip esp32s3 --port COM5 0x0 target/firmware/esp32s3-merged
去掉导出命令的 `--merge --skip-padding` 可生成独立 App,它需写入 `partitions.csv` 声明的 Factory 偏移,并与板上 Bootloader 和分区表匹配。坏板重编可能改变该偏移;新板优先使用 ELF 或合并镜像。
需要交给桌面维护页的 ZIP 时,使用 `scripts/build.ps1 -Package`,或在构建后运行 `python scripts/package_firmware.py --firmware target/firmware`。Windows 仍需保留构建时的短目录 `CARGO_TARGET_DIR`。打包路径与旧镜像隔离的回归检查为 `python scripts/test-package-firmware.py`;它使用临时样例和模拟导出,不连接设备。
## 主机测试
协议层不依赖 ESP-IDF。进入 `protocol/`,以 Windows MSVC 为例:
@@ -40,7 +42,7 @@ Linux 常见 host 为 `x86_64-unknown-linux-gnu`,Apple Silicon 为 `aarch64-ap
装甲规则从 `armor/` 执行 `cargo +stable test -p armor-protocol`,桌面核心从 `desktop/core/` 执行 `cargo +stable test`,同样按需指定宿主 `--target` 和空的 `build-std`。
限帧、温度回差和 JPEG 压缩回压策略可以独立在主机运行,无需连接板卡。Windows 在根目录执行:
限帧、温度回差和 JPEG 压缩回压策略可在主机上独立测试,无需连接裁判系统。Windows 下在根目录执行:
```powershell
New-Item -ItemType Directory -Force target | Out-Null
@@ -64,8 +66,8 @@ cargo clean --release --target xtensa-esp32s3-espidf -p esp-idf-sys
## 发现与协议
- 图传板每 2 秒广播 Hello;客户端每 800 ms 广播 Subscribe,并向已发现的在线板卡 IP 单播续订,固定绑定 UDP 5600。
- 全局广播可能被 VPN / 虚拟网卡路由到其它接口。收到 Hello 后按设备 IP 定向续订,可以使用通往实际局域网的路由;队伍端仅向绑定的板卡增加单播续订。
- 图传板每 2 秒广播 Hello;客户端每 800 ms 广播 Subscribe,并向已发现的在线裁判系统 IP 单播续订,固定绑定 UDP 5600。
- 全局广播可能被 VPN / 虚拟网卡路由到其它接口。收到 Hello 后按设备 IP 定向续订,可以使用通往实际局域网的路由;队伍端仅向绑定的裁判系统增加单播续订。
- 固件使用订阅包的源地址作为发送目标,6 秒不续订即移除,最多保留 4 个对端。
- 新客户端为每个接收器生成随机会话 ID;同一源 IP 下,同一会话换端口会更新推流目标。旧版公共固定 ID `0x0C110001` 保持按地址区分,避免合并同机旧客户端。
- MAC 派生的 `sender_id` 不随 DHCP 地址变化,适合客户端持久绑定。
@@ -78,7 +80,7 @@ cargo clean --release --target xtensa-esp32s3-espidf -p esp-idf-sys
本次对照测试在保留 TUN 的环境中进行,最终参数与验证边界见 [性能排查](../testing/performance.md)。
下表为原 README 保存的**历史单次测试数据**,不是本次构建实测或性能保证。配置为 OV5640、VGA;原始日志、时长和完整网络条件未随这些数字保存。
下表保留原 README 中的历史单次测试数据,不代表本次构建的实测结果,也不构成性能保证。测试使用 OV5640、VGA;这些数字未附原始日志、时长和完整网络条件。
| 指标 | 早期 HTTP MJPEG / TCP | 后续 UDP |
| --- | --- | --- |
@@ -89,13 +91,13 @@ cargo clean --release --target xtensa-esp32s3-espidf -p esp-idf-sys
这些数据不足以单独证明性能差异的根因或无线链路容量。复测时记录板型、固件版本、分辨率、画质、信号、订阅者数量、时长和丢帧数。
FPS 应按**同一时间窗口的帧数增量 / 窗口秒数**计算。累计帧数与窗口时长混用会产生假数值,UI 轮询间隔也不代表相机出帧间隔。探测脚本的重组状态需按设备及帧隔离,避免测量错误。
FPS 应按同一时间窗口的帧数增量 / 窗口秒数计算。混用累计帧数与窗口时长会使结果失真,UI 轮询间隔也不代表相机出帧间隔。探测脚本需按设备和帧隔离重组状态,避免测量错误。
可重复测量:`python scripts/perf_probe.py <板卡IP> --seconds 30 --json perf.json`。默认使用独立的临时端口和 1 MiB 接收缓冲,每 800 ms 定向续订。脚本只依赖 Python 标准库;`--save-frame frame.jpg` 可保存首张完整 JPEG。公平比较应保持订阅者数量、分辨率、画质与网络条件一致。
可重复测量:`python scripts/perf_probe.py <裁判系统IP> --seconds 30 --json perf.json`。默认使用独立的临时端口和 1 MiB 接收缓冲,每 800 ms 定向续订。脚本只依赖 Python 标准库;`--save-frame frame.jpg` 可保存首张完整 JPEG。公平比较应保持订阅者数量、分辨率、画质与网络条件一致。
`frame_loss_percent` 包含不完整、超时及帧号缺口,不包含开始订阅前或测量结束后的帧。`assembly_p95_ms` 是首末分片到达的时间差,`inter_frame_p95_ms` 是完整帧到达间隔,均使用高精度计时;没有发送时间戳及两端时钟同步,不能称为端到端延迟。
固件日志将采集尝试与完整提交分开计数。`submitted` 只表示全部分片交给了网络,不代表无线确认或客户端显示;`send failures` 可能包含随后重试成功的调用,应结合 `peer frames dropped` 和接收端指标判断。
固件日志分别统计采集尝试和完整提交。`submitted` 只表示全部分片已交给网络,不代表收到无线确认或已在客户端显示。`send failures` 可能包含随后重试成功的调用,需结合 `peer frames dropped` 和接收端指标判断。
画面链路测量使用裁判端 `--latency-report <新文件>`,让相机拍摄校准页左侧标记,固定相机和窗口位置。标记经正常采集、网络与绘制路径回到客户端,源与回显共用主机单调时钟;不需要 ESP 时钟同步。测试期间只保留一个原生客户端,额外的本地 WebSocket 观察器不增加 UDP 订阅。方法、刷新估计边界及最新结果见 [延迟测量](../testing/latency.md)。