# visoscan_cable_detection **Repository Path**: playboy_plus/visoscan_cable_detection ## Basic Information - **Project Name**: visoscan_cable_detection - **Description**: 基于激光雷达 VISIOSCAN RD 2D 点云数据的电缆检测系统。支持实时点云接收、电缆检测算法处理、GPIO 输出控制及 Web 可视化。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-24 - **Last Updated**: 2026-04-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Visoscan Cable Detection 2 基于激光雷达(VISIOSCAN RD)2D 点云数据的电缆检测系统。支持实时点云接收、电缆检测算法处理、GPIO 输出控制及 Web 可视化。 ## 项目结构 ``` . ├── CMakeLists.txt # CMake 构建配置 ├── toolchain-armv7l.cmake # ARM 交叉编译工具链文件 ├── visoscan_cfg.json # 运行时配置文件(界面下发后自动持久化) ├── visoscan-rd-protocol.md # VISIOSCAN RD 通信协议文档 ├── requirements.txt # Python 依赖 ├── cable_detection.py # Python 实现(完整版) ├── src/ │ ├── main_posix.cpp # C++ 服务器实现(当前编译入口) │ └── main.cpp # C++ 旧版/备用实现(未参与编译) └── web/ ├── index.html # MID-360 Web Viewer 主页面 ├── slope.html # 坡度检测页面 ├── app.js # 主页面前端逻辑 ├── slope_app.js # 坡度页面前端逻辑 ├── lc_app.js # LightningChart 图表应用逻辑 └── lcjs.iife.js # LightningChart JS 图表库 ``` ## 系统架构 ``` 激光雷达 (VISIOSCAN RD) │ UDP (点云数据) │ TCP (控制命令 + 污染查询) ▼ ▼ ┌──────────────────────────────────┐ │ visoscan_server │ │ ┌──────────┐ ┌──────────────┐ │ │ │ UDP 接收 │ │ TCP 命令发送 │ │ │ └─────┬────┘ │ (SendMDI + │ │ │ │ │ GetWinStat) │ │ │ ▼ └──────────────┘ │ │ ┌──────────┐ │ │ │ 帧聚合 │ │ │ └─────┬────┘ │ │ ▼ │ │ ┌──────────────────┐ │ │ │ 电缆检测算法 │ │ │ │ (two_point_slope) │ │ │ └─────┬────────────┘ │ │ ▼ │ │ ┌──────────┐ ┌──────────────┐ │ │ │ HTTP 服务 │ │ WebSocket 服务│ │ │ │ (静态文件) │ │ (实时数据推送) │ │ │ └──────────┘ └──────────────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌──────────────────────────┐ │ │ │ 结果 TCP Socket 推送 │ │ │ │ (0.0.0.0:7777) │ │ │ └──────────────────────────┘ │ │ │ │ ┌──────────────────────────┐ │ │ │ GPIO 输出控制 │ │ │ │ PB9 (GPIO41) - 线缆检测 │ │ │ │ PB11 (GPIO43) - 窗口污染 │ │ │ └──────────────────────────┘ │ └──────────────────────────────────┘ │ │ ▼ ▼ Web 浏览器 外部系统 ``` ## 编译 ### 前置条件 - **x86 编译**:GCC 7+ 或 Clang 6+,CMake 3.16+ - **ARM 交叉编译**:`gcc-arm-linux-gnueabihf` 交叉工具链 安装 ARM 交叉编译工具链(Ubuntu/Debian): ```bash sudo apt install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf ``` ### x86 本地编译 ```bash mkdir -p build && cd build cmake .. cmake --build . ``` 生成可执行文件:`build/visoscan_server` ### ARM 交叉编译(目标:ok113i armv7l) ```bash mkdir -p build_arm && cd build_arm cmake -DCMAKE_TOOLCHAIN_FILE=../toolchain-armv7l.cmake -DTOOLCHAIN_ARM=ON .. cmake --build . ``` 生成可执行文件:`build_arm/visoscan_server_arm`(静态链接,可直接部署到目标设备) ### 部署到 ARM 设备 ```bash # 将二进制和 web 目录、配置文件传到设备 scp build_arm/visoscan_server_arm user@:/home/ scp -r web visoscan_cfg.json user@:/home/ ``` ## 运行 ### C++ 版本 ```bash ./visoscan_server [选项] 选项: --web_root 静态文件目录 (默认: web) --http_host HTTP 监听地址 (默认: 0.0.0.0) --http_port HTTP 监听端口 (默认: 8000) --ws_host WebSocket 监听地址 (默认: 0.0.0.0) --ws_port WebSocket 监听端口 (默认: 8765) --mdi_tcp_host MDI TCP 目标地址 (默认: 192.168.1.2) --mdi_tcp_port MDI TCP 目标端口 (默认: 3050) --mdi_udp_bind_ip MDI UDP 绑定地址 (默认: 0.0.0.0) --mdi_udp_port MDI UDP 绑定端口 (默认: 3050) --mdi_udp_enabled <0|1> 启用 UDP 接收 (默认: 1) --mdi_tcp_send_cmd <0|1> 启用 TCP 命令发送 (默认: 1) ``` 启动后访问:`http://:8000/index.html` ### Python 版本 ```bash pip install -r requirements.txt python cable_detection.py ``` ## GPIO 输出控制 程序支持通过 GPIO 输出信号通知外部系统: | GPIO | 引脚 | 功能 | 触发条件 | |------|------|------|----------| | GPIO41 | PB9 | 线缆检测输出 | 检测到线缆时输出 HIGH,线缆消失时输出 LOW | | GPIO43 | PB11 | 窗口污染输出 | 任一扇区污染 ≥ 阈值时输出 HIGH,低于阈值时输出 LOW | ### GPIO 控制流程 1. **线缆检测 GPIO**:每帧检测循环中,若检测到线缆则 PB9 输出 HIGH,否则输出 LOW 2. **窗口污染 GPIO**:SendMDI TCP 线程按配置间隔发送 `cRN GetWinStat` 命令,在同一连接上接收 `cRA GetWinStat Z1 Z2 Z3` 响应,解析三个扇区污染百分比,任一扇区超过阈值则 PB11 输出 HIGH ### 程序退出处理 - **正常退出**:GPIO 输出置 LOW,打印 `[GPIO] ... -> LOW (shutdown)` - **信号退出 (Ctrl+C / SIGTERM)**:信号处理器将 GPIO 置 LOW,打印 `[GPIO] ... -> LOW (signal)` ### GPIO 日志 状态变化时自动打印日志(仅在状态切换时输出,避免高频重复): ``` [GPIO] cable GPIO41 -> HIGH (cable detected) [GPIO] cable GPIO41 -> LOW (cable lost) [GPIO] contam GPIO43 -> HIGH (contamination alert) [GPIO] contam GPIO43 -> LOW (contamination clear) ``` ## 配置说明 运行时配置文件 `visoscan_cfg.json`,界面修改后自动持久化到文件,重启后生效: | 字段 | 说明 | 默认值 | |------|------|--------| | `frame_time_ms` | 帧聚合时间窗口 (ms) | 100 | | `roi.start` / `roi.end` | 感兴趣区域范围 (mm) | 4000 / 6900 | | `rot_deg` | 点云旋转角度 (°) | 0.4 | | `detect_cfg.algo` | 检测算法 | `two_point_slope` | | `detect_cfg.max_cables` | 最大电缆数 | 8 | | `detect_cfg.min_seg_len` | 最小连续段长度 | 13 | | `detect_cfg.sw_slope_thr` | 滑动窗口斜率阈值 | 0.3 | | `detect_cfg.tp_step` | 两点斜率步长 | 15 | | `detect_cfg.exclude_ranges` | 排除区域 (如 "5500-5530") | - | | `detect_cfg.vote_window_frames` | 投票确认窗口帧数 | 45 | | `detect_cfg.confirm_frames` | 确认帧数 | 2 | | `result_socket.enabled` | 启用结果 TCP 推送 | true | | `result_socket.host` / `port` | 结果推送地址 | 0.0.0.0 / 7777 | | `gpio.enabled` | 启用 GPIO 输出控制 | true | | `gpio.cable_id` | 线缆检测 GPIO 编号 | 41 (PB9) | | `gpio.contam_id` | 窗口污染 GPIO 编号 | 43 (PB11) | | `gpio.contam_threshold` | 窗口污染告警阈值 (%) | 30 | | `gpio.contam_query_interval_s` | 污染状态查询间隔 (秒) | 10 | > **注意**:C++ 版本当前仅支持 `detect_cfg` 中的部分参数(`min_seg_len`、`sw_slope_thr`、`tp_step`、`exclude_ranges`),其余参数(平滑、NMS、投票确认等)仅在 Python 版本中实现。 ## 电缆检测算法 采用 **两点斜率法 (two_point_slope)**: 1. 在 ROI 范围内,以 `tp_step` 为步长计算相邻两点斜率 `|dy/dx|` 2. 斜率超过阈值 `sw_slope_thr` 的点标记为 hit 3. 提取长度 ≥ `min_seg_len` 的连续 hit 段 4. 对每个候选段拟合直线,计算直径 (diameter)、宽度 (width)、宽高比 (wh_ratio) 和置信度 (score) 5. 排除指定区域,最多返回 8 条电缆 ## 结果输出格式 检测结果通过 WebSocket 和 TCP Socket 以 JSON 推送: ```json [ { "roi_start": 4000, "roi_end": 6900, "seg_start": 4200, "seg_end": 4250, "diameter_mm": 12.5, "width_mm": 45.0, "wh_ratio": 3.6, "score": 0.85 } ] ```