Files
sloray 6a0eb14b28
构建客户端 / 检查(类型 + 单元测试) (push) Waiting to run
构建客户端 / Linux x64(deb + AppImage) (push) Blocked by required conditions
构建客户端 / Windows x64(NSIS 安装包) (push) Blocked by required conditions
构建客户端 / macOS 通用(.app + .dmg) (push) Blocked by required conditions
docs: 整理项目文档并统一界面表述
将项目说明按主题集中到 docs,补齐根目录 README 和 AGENTS,移除弃用方案并保留有效测试记录与未实现提案。同步文档索引、引用及改动日志生成路径,README 增加 GitHub Markdown 导航和 Mermaid 图。

- fix(client): 统一状态与操作文案,录制和截图成功后再显示完成提示
- test(client): 按文件名核对媒体类型,避免依赖时间戳排序

验证:23 份项目文档、144 处本地引用、27 条外链、2 张 Mermaid 图;前端构建和 12 项测试;截图与录制的 4 条异步反馈路径;Windows Rust 编译检查和后端测试。后端 40 项返回成功,其中 3 项 ffmpeg 集成用例因本机缺少工具而未实际执行。
2026-10-19 11:26:26 +08:00

293 lines
13 KiB
Markdown
Raw Permalink 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.
<p align="center">
<img src="desktop/src-tauri/icons/128x128.png" width="88" height="88" alt="Simba Robotics 队标">
</p>
# RMIC::2026 · 视野链路系统
**黑龙江大学 602 实验室 · Simba Robotics**
面向机器人对抗赛的局域网图传与装甲板系统。ESP32-S3 采集 OV5640 的硬件 JPEG,经 UDP 发送到桌面端;ESP32-C3 上报装甲板血量,桌面端提供操作手视野、裁判双路监看、截图录制和 USB 固件维护。
[![Firmware: ESP32-S3](https://img.shields.io/badge/Firmware-ESP32--S3-00979D)](docs/setup/firmware.md)
[![Armor: ESP32-C3](https://img.shields.io/badge/Armor-ESP32--C3-00979D)](docs/hardware/armor.md)
[![Desktop: Tauri 2 + React 19](https://img.shields.io/badge/Desktop-Tauri_2_%2B_React_19-24C8D8)](docs/desktop/client.md)
[![Transport: UDP](https://img.shields.io/badge/Transport-UDP-5865F2)](docs/protocol/udp.md)
[文档首页](docs/index.md) · [硬件接线](docs/hardware/camera.md) · [故障排查](docs/testing/troubleshooting.md) · [改动记录](docs/releases/changelog.md) · [开发约定](AGENTS.md)
> [!NOTE]
> 版本、构建号与线路协议号以 [`version.json`](version.json) 为准。改动记录从 Git 历史生成,维护方式见[版本说明](docs/development/versioning.md)。
## 导航
- [系统架构](#系统架构)
- [功能与验证范围](#功能与验证范围)
- [快速开始](#快速开始)
- [发现与收流时序](#发现与收流时序)
- [仓库结构](#仓库结构)
- [开发与验证](#开发与验证)
- [文档与后续工作](#文档与后续工作)
## 系统架构
```mermaid
flowchart LR
subgraph Camera["图传板 · ESP32-S3"]
Sensor["OV5640<br/>硬件 JPEG"] --> Firmware["采集与分片<br/>最新帧发送"]
end
subgraph Armor["装甲板 · ESP32-C3"]
Piezo["四路压电片"] --> Rules["受击规则与整车血量"]
Rules --> LEDs["四路 WS2812"]
end
subgraph Desktop["RMIC::2026 · 桌面端"]
Core["Rust 核心<br/>发现、重组与血量状态"]
Backend["Tauri 后端<br/>本地通道、截图与录制"]
UI["React / WebView<br/>用户端或裁判端"]
Core --> Backend
Backend -->|"本地 WebSocket:JPEG 与状态"| UI
UI -->|"IPC:配置与操作"| Backend
end
Firmware -->|"UDP 5600:Hello 与视频分片"| Core
Core -->|"Subscribe:广播与定向续订"| Firmware
Rules -->|"UDP 5601:血量广播"| Core
```
两块图传板各自发送,裁判端同时接收两路;用户端只接收绑定图传板的画面。装甲板主板连接四路传感器和灯带,其余从板不含 MCU。
| 网络项 | 配置 | 说明 |
| :--- | :--- | :--- |
| 图传板 Wi-Fi | 2.4 GHz | 板卡与客户端需处于可互通的局域网 |
| 视频与发现 | UDP `5600` | Hello、Subscribe 与 JPEG 分片 |
| 装甲板上报 | UDP `5601` | 每 200 ms 广播四路血量 |
| 本地界面通道 | 回环 WebSocket + Tauri IPC | JPEG 由 WebView 解码,网络接收线程不做视频解码 |
> [!IMPORTANT]
> 网络需要允许广播和设备间互访。请关闭 AP 客户端隔离,并允许客户端通过防火墙。VPN / 虚拟网卡可能影响广播路由,排查方法见[客户端说明](docs/desktop/client.md#windows-x64-构建)。
## 功能与验证范围
| 模块 | 已有功能 | 使用条件与边界 |
| :--- | :--- | :--- |
| 图传固件 | VGA 彩色 JPEG、UDP 分片、多端订阅、Wi-Fi 重连、过期帧放弃 | 当前记录约 30 fps;不同网络、板卡与画质下需复测[^performance] |
| 用户端 | 本队画面、双方装甲条、瞄准器、偏移校准、命中反馈 | 先绑定图传板与装甲板;改绑、切换模式和退出受密码限制 |
| 裁判端 | 双路画面、队名编辑、装甲板发现、槽位分配、截图、录制与回放 | 录制需要 ffmpeg;图传槽位可手动指定 |
| 装甲板 | 四路受击检测与灯带、整车血量、UDP 上报 | 初始 100 血,每次受击扣 3 点;队伍号在编译期选择 |
| 固件维护 | USB 读取设备、检查固件包、选择候选槽位、备份和写后回读 | App 写入与回读已有实机记录;完整分区切换尚未验证 |
发送端在有限预算内提交当前帧,超时后转向新帧;本地视频通道与 WebView 会放弃滞留超过 100 ms 的旧帧。这个期限约束的是本机积压,**不代表相机到屏幕的端到端延迟**。
> [!WARNING]
> 固件维护会写入设备 Flash。使用前核对芯片、分区和备份,并阅读[已验证与未验证范围](docs/maintenance/firmware.md#已验证--未验证)。ESP32-S3 与 ESP32-C3 的固件不能混用。
[^performance]: [最新帧处理记录](docs/testing/realtime.md)、[功率与拥塞记录](docs/testing/power.md)和[延迟测量](docs/testing/latency.md)保留了配置、观察窗口与测量限制。历史数字不是所有部署环境的性能保证。
## 快速开始
### 1. 无板卡:先看界面
安装 Node.js 和 pnpm 后,在仓库根目录执行:
```sh
cd desktop
pnpm install --frozen-lockfile
pnpm dev
```
打开 [用户端预览](http://127.0.0.1:1420/) 或 [裁判端预览](http://127.0.0.1:1420/?preview=referee)。预览由浏览器合成状态和画面,无需 Rust 后端或板卡。
> [!TIP]
> 检查首次启动流程时,可使用 `?preview=first-run` 和 `?preview=password`。需要测试实际接收、重组和录制路径时,使用原生客户端的 `--demo` 模式;两种方式显示的都是合成数据。
### 2. 连接板卡:运行桌面端
先按[客户端说明](docs/desktop/client.md#快速开始)安装宿主平台依赖。Windows x64 需要 Rust stable MSVC、Visual Studio C++ Build Tools、Windows SDK 和 WebView2;录制另需 ffmpeg。
<details>
<summary><strong>Windows x64:开发运行与安装包</strong></summary>
在 `desktop/` 执行。显式指定目标,并清空从根固件项目继承的 `build-std`:
```powershell
pnpm install --frozen-lockfile
pnpm app --target x86_64-pc-windows-msvc -- --locked --config 'unstable.build-std=[]'
```
生成 NSIS 安装包:
```powershell
pnpm tauri build --target x86_64-pc-windows-msvc --bundles nsis --ci -- --locked --config 'unstable.build-std=[]'
```
安装包位于 `desktop/src-tauri/target/x86_64-pc-windows-msvc/release/bundle/nsis/`。显示名为 **RMIC::2026**,Windows 可执行文件和安装包使用 **RMIC-2026**。
</details>
<details>
<summary><strong>macOS / Linux:目标选择与演示模式</strong></summary>
`desktop/.cargo/config.toml` 默认目标为 `aarch64-apple-darwin`。Intel Mac 使用 `x86_64-apple-darwin`,常见 Linux x64 使用 `x86_64-unknown-linux-gnu`;其他架构先用 `rustc +stable -vV` 核对 host。
以 Linux x64 为例,在 `desktop/` 执行:
```sh
pnpm install --frozen-lockfile
pnpm app --target x86_64-unknown-linux-gnu -- --locked --config 'unstable.build-std=[]'
```
同一命令末尾追加 `-- --demo` 可启动原生演示模式。它将合成数据报送入正常接收与重组路径,适合检查截图、录制和命中反馈;预览与演示的区别见[客户端说明](docs/desktop/client.md#演示模式没有板子也能把整条链路跑起来)。
</details>
首次启动选择用户端或裁判端。用户端需要设置现场密码并绑定本车板卡;裁判端自动分配图传槽位,装甲板按上报队伍分配。对应关系不符时,在设置中手动指定。
### 3. 编译图传或装甲固件
| 硬件 | 构建目标 | 入门文档 |
| :--- | :--- | :--- |
| Freenove ESP32-S3-WROOM CAM + OV5640 | `xtensa-esp32s3-espidf` | [环境、参数与烧录](docs/setup/firmware.md) |
| ESP32-C3 装甲板主板 | `riscv32imc-esp-espidf` | [接线、规则与构建](docs/hardware/armor.md) |
<details>
<summary><strong>已装好图传工具链:构建命令</strong></summary>
先按[固件入门](docs/setup/firmware.md)安装固定的 `esp-1.97.0.0` 工具链与 ESP-IDF 依赖。在仓库根目录准备 `.env`;已有文件时不要覆盖。
Windows PowerShell:
```powershell
if (-not (Test-Path -LiteralPath .env)) {
Copy-Item -LiteralPath .env.example -Destination .env
}
# 用编辑器填写 .env 中的 Wi-Fi 配置后再构建。
.\scripts\build.ps1 -Package
```
Linux / macOS(Bash):
```bash
test -f .env || cp .env.example .env
# 用编辑器填写 .env 中的 Wi-Fi 配置后再构建。
. "$HOME/export-esp.sh"
scripts/build.sh --package
```
上述命令只构建和打包。烧录步骤、引脚与分区偏移请按[固件入门](docs/setup/firmware.md)核对;不要将 ELF 当作 BIN 写入。
</details>
Wi-Fi 凭据会编入固件。`.env` 已被 Git 忽略,分享固件前也需检查其中的凭据。
## 发现与收流时序
```mermaid
sequenceDiagram
participant Board as ESP32-S3 图传板
participant Client as 桌面 Rust 核心
participant View as WebView 画面
Board-->>Client: Hello 广播(每 2 秒,含版本与协议号)
Client->>Board: Subscribe(每 800 ms 续订)
Note over Board,Client: 按订阅包源地址推流;6 秒未续订则移除
loop 采集与发送
Board-->>Client: JPEG 分片(27 字节头 + 最多 1400 字节载荷)
alt 分片完整且通过接收检查
Client->>View: 本地通道投递完整 JPEG
View->>View: 解码并绘制最新有效帧
else 缺片或超时
Client->>Client: 丢弃未完成帧,等待后续帧
end
end
```
分片按 `sender_id` 和 `frame_id` 隔离,不重传缺失分片。线路格式、去重和拒收条件见 [UDP 协议](docs/protocol/udp.md)。
## 仓库结构
| 路径 | 职责 | 说明 |
| :--- | :--- | :--- |
| [`src/`](src/) | ESP32-S3 固件 | 采集、分片、发现订阅、发送与重连 |
| [`components/`](components/) | C 组件与 FFI | 本地相机驱动、封装及补丁 |
| [`protocol/`](protocol/) | 共享线路协议 | 编解码与帧重组,可在主机测试 |
| [`desktop/core/`](desktop/core/) | 桌面核心 | 网络、装甲板、配置、密码与槽位 |
| [`desktop/src-tauri/`](desktop/src-tauri/) | Tauri 后端 | 本地通道、命令、录制与固件维护 |
| [`desktop/src/`](desktop/src/) | React 前端 | 用户端、裁判端、维护与延迟校准 |
| [`armor/`](armor/) | ESP32-C3 独立 workspace | 受击规则、灯带与血量广播 |
| [`scripts/`](scripts/) | 构建与诊断工具 | 烧录、打包、版本、协议与性能探测 |
| [`reference/armor/`](reference/armor/) | 早期 C 版参考工程 | 用于核对硬件与实现差异 |
| [`docs/`](docs/index.md) | 项目文档 | 入门、开发、硬件、测试、发布与提案 |
> [!CAUTION]
> `components/esp32-camera/target/` 是按芯片分类的**驱动源码**,包含本地补丁。它不是构建缓存,不能随其他 `target/` 目录一起清理。
## 开发与验证
按修改范围运行对应检查。主机 Rust 测试需显式选择宿主目标,避免继承 ESP32 的构建配置;各平台说明见[开发与验证](docs/development/firmware.md)。
<details>
<summary><strong>前端检查与 Windows 主机 Rust 检查</strong></summary>
前端命令在 `desktop/` 执行:
```sh
pnpm build
pnpm test:stream
pnpm test:latency
```
以下 Rust 命令在仓库根目录执行:
```powershell
cargo +stable test --locked --manifest-path protocol/Cargo.toml --target x86_64-pc-windows-msvc --config 'unstable.build-std=[]'
cargo +stable test --locked --manifest-path desktop/core/Cargo.toml --target x86_64-pc-windows-msvc --config 'unstable.build-std=[]'
cargo +stable check --locked --manifest-path desktop/src-tauri/Cargo.toml --target x86_64-pc-windows-msvc --config 'unstable.build-std=[]'
```
录制相关测试会调用 ffmpeg / ffprobe。主机测试、前端构建通过后,仍需按变更范围检查真实 WebView、板卡与网络行为。
</details>
提交使用 Conventional Commits,如 `docs(readme): 完善项目入口`。版本由 Git 历史计算,在根目录执行:
```sh
node scripts/version.mjs --write
node scripts/version.mjs --check
```
生成的改动记录位于 `docs/releases/`;派生文件清单见[版本维护](docs/development/versioning.md)。
## 文档与后续工作
文档沿用 Firefox 仓库的分类与索引思路:根目录保留项目入口和协作约定,详细说明集中到 [`docs/index.md`](docs/index.md)。
| 要做什么 | 从哪里开始 |
| :--- | :--- |
| 首次准备图传板 | [固件入门](docs/setup/firmware.md) → [硬件接线](docs/hardware/camera.md) |
| 使用或调试桌面端 | [客户端说明](docs/desktop/client.md) → [故障排查](docs/testing/troubleshooting.md) |
| 更新设备固件 | [固件维护](docs/maintenance/firmware.md) |
| 修改受击规则或灯带 | [装甲板说明](docs/hardware/armor.md) |
| 复核帧率和延迟 | [最新帧记录](docs/testing/realtime.md) → [延迟测量](docs/testing/latency.md) |
| 参与开发 | [AGENTS.md](AGENTS.md) → [开发与验证](docs/development/firmware.md) |
实现状态与待验证事项分开记录:
- [x] UDP 图传、发现订阅与桌面双模式
- [x] 装甲板血量上报、HUD、命中反馈与录制
- [x] USB 固件包校验、App 写入与回读
- [ ] 完成固件维护的完整实机分区切换验证
- [ ] 确认并实现[比赛控制与直播提案](docs/design/match-and-broadcast.md)
<details>
<summary><strong>仓库地址</strong></summary>
仓库已由 `ESP32S3_vt` 改名为 `simba-rmic-2026`,旧地址会重定向。SSH 地址:
```text
git@git.simba-robotics.com:PRAM/simba-rmic-2026.git
```
</details>