114 lines
5.4 KiB
Markdown
114 lines
5.4 KiB
Markdown
# Vision Anti-Pinch — use-can
|
||
|
||
## 编译与运行
|
||
|
||
目标环境:Jetson AGX Orin、JetPack 5.1.2 / L4T R35.4.1、CUDA 11.4、TensorRT 8.5.x、OpenCV 4.5.4。
|
||
源码编译另需 CMake 3.24+ 和相应开发库。
|
||
|
||
```bash
|
||
./scripts/build.sh # 或 make
|
||
./scripts/initialize_camera.sh # 开机后摄像头尚未初始化时执行
|
||
./run_camera.sh # 执行 build/camera_risk
|
||
./run_camera.sh --visualize # 可选 OpenCV 本地窗口
|
||
```
|
||
|
||
预编译 Orin 包:
|
||
|
||
```bash
|
||
cd orin
|
||
./scripts/initialize_camera.sh
|
||
./run.sh # 脚本直接 exec C++ ELF 程序
|
||
# 也可以直接执行:
|
||
./build/camera_risk --config config/camera.json
|
||
```
|
||
|
||
默认无窗口、不保存文件;Ctrl+C / SIGTERM 停止。`--visualize` 使用 Orin 的图形桌面,关闭窗口仅停止显示、推理继续。没有桌面环境时保持无窗口推理。
|
||
|
||
## 流水线与结果变量
|
||
|
||
```
|
||
V4L2 MMAP 采集 / NPP UYVY 转换(线程 1)
|
||
→ YOLO TensorRT 检测(线程 2)
|
||
→ RTMW TensorRT / 隔离推理 / C++ 时序融合(线程 3)
|
||
→ 前后门多特征归属 / 因果中值 / mask 风险 / CAN 过滤
|
||
→ shared_ptr<const FrameResult> 最新结果变量
|
||
```
|
||
|
||
摄像头使用有界队列并丢弃积压旧帧;可视化独立读取最新结果。
|
||
下游直接链接 `camera_risk_core`,在自己的线程中读取:
|
||
|
||
```cpp
|
||
#include "camera_pipeline.hpp"
|
||
#include "config.hpp"
|
||
|
||
cms::CameraPipeline pipeline(cms::loadConfig("config/camera.json"));
|
||
pipeline.start();
|
||
// 下游自己的循环中读取;首帧前 result 为空。
|
||
auto result = pipeline.latest();
|
||
if (result) {
|
||
const auto& risk = result->risk;
|
||
const auto& front = result->door_risks.at("front");
|
||
const auto& rear = result->door_risks.at("rear");
|
||
const auto& people = result->persons; // 每人 selected/smoothed/temporal 各 133 点
|
||
const auto& assignments = result->door_assignments;
|
||
const auto& can = result->can;
|
||
// risk.risk_type / risk.risk_level / risk.risk_score(std::optional<double>)
|
||
}
|
||
// 退出时:
|
||
pipeline.requestStop();
|
||
pipeline.join();
|
||
```
|
||
|
||
`latest()` 返回拥有数据的只读快照,读者互不消费结果,旧引用不会被新帧修改。慢读者可以跳过中间帧;异常通过 `join()` 传播。停止后的快照只代表最后结果,持续控制应检查运行状态和时间戳。
|
||
公共结构定义见 `include/frame_result.hpp`,接口见 `include/camera_pipeline.hpp`。
|
||
|
||
## CAN 与风险
|
||
|
||
- 0x391 的 data[0..3]:左前、右前、左后、右后。
|
||
- 默认左侧,`--can-side right` 切到右侧;值为 0 时对应门活跃。
|
||
- 缺失或过期(默认 1000 ms)报文输出 `CAN_UNKNOWN`,分数为空,不能解释为 clear。
|
||
- `--no-can --active-door both` 显式模拟门状态;也可选择 front/rear/none。
|
||
- 优先使用有效手部凸包,无有效手部时用人体框兜底;transition 保留 unknown 语义。
|
||
- 最终使用 `risk` 或 `door_risks`;`ungated_risk` 仅用于诊断。当前只接收门状态,不发送执行器指令。
|
||
- mask 和前后门参数来自研发机位,默认 calibration_verified=false;装车后需要重新标定。
|
||
|
||
配置位于 `config/camera.json`,模型位于 `orin/models/engines/`。详细参数:
|
||
|
||
```bash
|
||
./run_camera.sh --help
|
||
./run_camera.sh --duration 30
|
||
./run_camera.sh --save-results /path/results.jsonl
|
||
```
|
||
|
||
显式保存时每帧写一行 JSON,核心字段保留 frame_index、track_ids、boxes、skeletons、door_assignments、door_risks、risk、ungated_risk、can;文件由用户指定路径管理。`--video` 可使用同一 C++ 流程处理视频文件,尺寸需匹配配置。
|
||
|
||
## 目录与打包
|
||
|
||
- `src/`:C++ / CUDA 源文件及 main.cpp。
|
||
- `include/`:头文件及下游数据结构。
|
||
- `third_party/nlohmann/`:C++ JSON 依赖及许可证。
|
||
- `config/`、`annotations/`:运行配置与标定。
|
||
- `scripts/`:编译、摄像头初始化、打包。
|
||
- `orin/`:可单独复制的 ELF 程序、模型、驱动、CAN 库和配置。
|
||
|
||
修改源码后,在 Orin 重新编译并执行 `./scripts/package_orin.sh`,或执行 `make package`。运行、打包均不使用 Python。打包后可在 orin 目录运行 `sha256sum -c SHA256SUMS`。
|
||
|
||
## 可选保存(默认全部关闭)
|
||
|
||
三个独立参数可以单独使用,也可以组合:
|
||
|
||
```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 开销。写入失败时报告错误并停止,不静默丢失文件。
|