Files
simba-rmic-2026/README.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

296 lines
14 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.
<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 配置后再构建。
$env:CARGO_TARGET_DIR = 'C:\s3vt'
.\scripts\build.ps1 -Package
```
Windows 必须使用可写的短输出目录,且不要与其他项目共用。`esp-idf-sys` 检查完整的构建输出路径,超过 88 字符会报 `Too long output directory`;仓库位于用户目录时,默认的 `target/` 通常会超限。这里将构建缓存放到 `C:\s3vt`,无需移动源码;`subst` 不能绕过该限制。固件 ZIP 仍输出到仓库的 `target/firmware/`。该环境变量仅供固件构建使用,切回桌面端前执行 `Remove-Item Env:CARGO_TARGET_DIR`。
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>