Vision Anti-Pinch — use-can(纯 C++)
本分支将 CMS run_risk.py 的处理流程移植到 C++,复用 0920 的 TensorRT 模型、CUDA/NPP 预处理及流水线实现。运行入口、时序融合、前后门归属、CAN 门级风险过滤和结果发布均在 C++ 进程中完成,不调用 Python。
编译与运行
目标环境: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+ 和相应开发库。
./scripts/build.sh # 或 make
./scripts/initialize_camera.sh # 开机后摄像头尚未初始化时执行
./run_camera.sh # 执行 build/camera_risk
./run_camera.sh --visualize # 可选 OpenCV 本地窗口
预编译 Orin 包:
cd orin
./scripts/initialize_camera.sh
./run.sh # 脚本直接 exec C++ ELF 程序
# 也可以直接执行:
./build/camera_risk --config config/camera.json
默认无窗口、不保存文件;Ctrl+C / SIGTERM 停止。--visualize 使用 Orin 的图形桌面,关闭窗口仅停止显示、推理继续。没有桌面环境时保持无窗口推理。没有 Python HTTP 预览服务。
流水线与结果变量
V4L2 MMAP 采集 / NPP UYVY 转换(线程 1)
→ YOLO TensorRT 检测(线程 2)
→ RTMW TensorRT / 隔离推理 / C++ 时序融合(线程 3)
→ 前后门多特征归属 / 因果中值 / mask 风险 / CAN 过滤
→ shared_ptr<const FrameResult> 最新结果变量
摄像头使用有界队列并丢弃积压旧帧;可视化独立读取最新结果。
下游直接链接 camera_risk_core,在自己的线程中读取:
#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/。详细参数:
./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。