Files
vision-anti-pinch/README.md
T

102 lines
6.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.
# Vision Anti-Pinch — lazy-inference
从 `inference-only` 分支派生的纯 C++ 惰性推理工程。保留该分支的 YOLO / RTMW / 时序融合 / mask 风险流程,在执行推理前加入 CAN 门状态控制。模型启动时加载、预热一次,暂停期间保持 TensorRT 引擎、上下文及显存,不反复加载。
## 触发规则
接收 CAN / CAN FD `0x391`,`data[0..3]` 按百分比解释,顺序为左前、右前、左后、右后。当前仅使用左前和左后,任一满足即可检测。
| 状态 | 推理行为 |
|---|---|
| 左前或左后开度 **<15%**,且正在增加(开门) | 检测并计算风险 |
| 左前或左后开度 **<15%**,且正在减小(关门) | 检测并计算风险 |
| 恰好 15%、大于 15%,或两门均静止 | 暂停模型推理 |
| 从未收到有效报文、报文超时或左门开度值无效 | 开启检测 |
| CAN 恢复且不满足运动条件 | 停止检测 |
开度不变的重复报文不会立即抹掉运动方向。默认最后一次开度变化后 **300 ms** 仍沿用方向,超过该时间判定静止,避免整数百分比报文导致频繁启停。到达 0% 后也保留这段检测时间。首次报文及超时后的首次报文只建立基线,不将断线前后的差值当作运动。
CAN 默认 **1000 ms** 超时。上述参数可在 `config/camera.json` 的 `lazy_inference` 中调整;15% 使用严格小于。USB CAN 缺失时后台持续重试,恢复后自动接收。当前不发送执行器指令。
相机每次取帧默认等待 **2000 ms**,连续超时 **6 次**才停止流水线(纯超时约 **12 秒**);成功取得有效帧后清零超时计数。重试期间 CAN 继续接收。单次等待时间由 `camera.timeout_ms` 配置;运行中的坏帧、取流错误共用该重试期限;设备失效时尝试重新打开相机,恢复有效帧后继续推理。GPU 错误仍按原有异常处理退出。
## 编译和运行
目标设备:Orin / JetPack 5.1.2 / CUDA 11.4 / TensorRT 8.5 / OpenCV 4.5,构建需 CMake 3.24+。
```bash
./scripts/build.sh
./scripts/initialize_camera.sh # 摄像头尚未初始化时
./run_camera.sh
./run_camera.sh --visualize # 可选本地 OpenCV 窗口
./run_camera.sh --duration 30 # 运行 30 秒后正常退出
```
Orin 独立包可单独复制运行:
```bash
cd orin
./scripts/initialize_camera.sh
./run.sh
```
`orin/build/camera_risk` 是 ARM64 C++ 可执行程序。运行不依赖 Python。修改源码后,在 Orin 编译并运行 `./scripts/package_orin.sh` 更新独立包。`cd orin && sha256sum -c SHA256SUMS` 检查文件完整性。
## 流水线和下游结果
摄像头持续采集、CAN 持续接收。启用时运行采集、YOLO、RTMW/融合/风险三阶段流水线;暂停时继续取帧以保持画面新鲜,但不执行 YOLO、RTMW 或风险计算。暂停前已提交的 GPU 工作可以完成,其结果会被丢弃。状态切换会清空待处理帧,恢复时重置跟踪与时序融合,不使用暂停前的历史人物状态。
```cpp
cms::CameraPipeline pipeline(cms::loadConfig("config/camera.json"));
pipeline.start();
// 下游线程中:
auto state = pipeline.inferenceStatus();
// state.models_ready / enabled / can_valid / reason
// state.positions[0]:左前;state.positions[2]:左后
// state.direction[0..1]:左前/左后,-1 关门,0 静止,+1 开门
auto result = pipeline.latest(); // shared_ptr<const FrameResult>
if (result) {
const auto& risk = result->risk;
const auto& people = result->persons;
}
// 启动、暂停或等待恢复后的首帧时,result 为空;不能解释为风险 clear。
// 退出:pipeline.requestStop(); pipeline.join();
```
`latest()` 不返回旧运行周期的风险;调用者已持有的旧快照不会被修改,应重新读取状态和结果。`FrameResult::inference` 保存生成结果时的 CAN 状态和 generation。状态变化后的下一次读取会反映新的周期。`running()` 表示整个服务在运行,暂停推理时仍为 true。
默认结果仅保存在内存变量,不保存视频或逐帧文件。标准输出记录启停原因和累计推理次数;`stats()` 提供 detector_runs / pose_runs / skipped_idle 等计数。可视化暂停时显示 IDLE,不继续显示旧风险。
## 目录
- `src/`、`include/`:C++ / CUDA 源码及公共接口。
- `config/`:门 mask、摄像头及惰性推理配置。
- `orin/`:模型、可执行程序、CAN 库、相机驱动及配置。
- `scripts/`:编译、初始化、打包;`third_party/`:JSON 依赖。
模型和推理算法沿用纯推理基线。当前门 mask 为研发机位配置,装车需按实际机位标定。
## 可选保存(默认全部关闭)
三个独立参数可以单独使用,也可以组合:
```bash
./run_camera.sh --save-original --save-annotated --save-results
# 独立包:./orin/run.sh --save-original --save-annotated --save-results
```
开启任一项时,程序自动创建可执行文件所属工程的 `output/` 及三个子目录:
- `original/`:`--save-original` 保存未叠加的原图,JPEG 质量 95。
- `annotated/`:`--save-annotated` 保存带框、关键点及风险文字的 JPEG,无需开启可视化窗口。
- `results/`:`--save-results` 每个完成推理的帧保存一个 JSON,包含帧号、检测框、跟踪 ID、关键点及置信度、风险和耗时;有 CAN 的分支还包含相应状态。
同一帧三类文件同名(扩展名不同),文件名包含运行标识和帧号,多次运行不覆盖。JSON 的 `images` 提供相对于 `output/` 的图片路径,未选择保存的图片为 null。源码入口写入工程 `output/`;独立包入口写入 `orin/output/`。默认不创建目录、不保存文件。
保存对象是完成推理的帧;惰性分支暂停时不新增文件。开启保存会增加编码和磁盘 I/O 开销。写入失败时报告错误并停止,不静默丢失文件。
相机超时回归测试:`./tests/run_camera_timeout.sh`;加 `--wall-clock` 验证默认 6 次超时约 12 秒。测试直接编译实际相机代码,使用模拟采集和转换器,无需摄像头、GPU 或 OpenCV;不覆盖视频回放路径。
板端真实摄像头 / TensorRT 恢复与停止测试记录见 [Orin 测试报告](tests/ORIN_TEST_REPORT.md)。