# Industrial Vision Station Demo **Repository Path**: SimianBin/industrial-vision-station-demo ## Basic Information - **Project Name**: Industrial Vision Station Demo - **Description**: 基于事件驱动的多相机视觉上位机架构示例(C# + Cognex VisionPro) - **Primary Language**: C# - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 2 - **Created**: 2026-03-02 - **Last Updated**: 2026-03-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Industrial Vision Station Demo #### 介绍 基于 C# + Cognex VisionPro 的多相机视觉上位机架构示例 - 事件驱动模块解耦 - 生产者-消费者流水线设计 - 多线程隔离与线程安全控制 - 高频数据流下的背压策略 - 设备抽象与协议扩展结构 ------ # 整体架构 系统采用 **分层 + 事件驱动 + 流水线模型** 设计: ``` Frame Source (Camera / Offline) ↓ EventBus ↓ InspectionService (有界队列 + 后台线程) ↓ EventBus ↓ ConnectionManager (发送队列 + 后台线程) ↓ TCP / Serial / PLC ``` UI 层通过订阅事件获取数据,仅负责显示与交互。 ------ # 架构设计原则 ## 1. 线程隔离 系统明确划分不同线程职责: - UI 线程:界面渲染与交互 - 采集回调线程:接收帧数据,不做耗时操作 - 检测线程:串行执行算法 - 通信线程:独立发送数据 约束: - UI 不能参与耗时计算 - 算法执行要避免并发访问 - 通信阻塞不能影响检测吞吐 ------ ## 2. 事件驱动解耦 模块之间通过 `EventBus` 通信,而非直接调用。 典型事件包括: - FrameArrived - InspectionCompleted - LogLine - SystemFault 目的: - 降低模块耦合 - 易于扩展(新增日志、统计、持久化无需修改核心流程) - 逻辑结构清晰 ------ ## 3. 生产者-消费者流水线 系统设计满足至少两条核心流水线: ### 检测流水线 - 生产者:帧源 - 缓冲区:`BlockingCollection`(有界) - 消费者:检测线程 设计重点: - 队列设置容量限制 - 在线模式支持“丢旧保新”策略 - 防止算法变慢导致内存持续增长 ------ ### 通信流水线 - 生产者:检测完成事件 - 缓冲区:发送队列 - 消费者:通信线程 目的: - 隔离网络/串口阻塞风险 - 避免影响检测链路 > 如果要做多相机独立检测实例增加一条流水线即可 ------ ## 4. 设备抽象层 系统通过接口抽象设备和协议: - `IFrameSource` - `ICamera` - `IToolRunner` - `IConnection` 实现类包括: - 在线相机 / 离线图像源 - TCP / Serial / PLC - VisionPro ToolBlock 适配器 业务逻辑只依赖抽象接口,降低对具体 SDK 的耦合。 ------ ## 5. 生命周期管理 `AppHost` 作为系统的组合根,负责: - 组件初始化 - 依赖组装 - 事件订阅 - 模式切换 - 优雅关闭 避免生命周期逻辑分散在 UI 层。 ------ # 线程安全策略 应尽量通过架构设计减少锁的使用: - 使用线程隔离避免共享状态 - 通过 `BlockingCollection` 实现线程安全队列 - UI 更新统一封送回主线程 - 共享状态集中在管理器内部 - 文件写入采用单写入点策略 有界队列用于实现背压控制,防止采集帧积压导致系统不稳定。 ------ # 运行模式 支持两种运行模式: - Camera(在线采集) - Offline(离线图片处理) 模式切换时: - 停止当前帧源 - 清空检测队列 - 启动新模式 保证数据一致性。 ------ # 日志与配置 - 日志采用滚动文件方式写入 - 配置使用 INI 存储 - 支持连接绑定关系持久化 日志集中写入,避免多线程并发写文件导致冲突。 ------ # TODO 当前架构为单工位设计,未来可扩展为: - 多相机独立检测实例 - 异步 EventBus - 插件化驱动加载 - 多进程算法隔离 - 状态机驱动流程控制 > 检测是 CPU-bound,而且 ToolBlock算法往往非线程安全,所以并行扩展不要让一个实例多线程 > 应满足: > - 每相机一个执行实例(ToolRunner/ToolBlockRunner) > - 每相机一个队列 > - 每相机一个 worker loop ------ #### 代码导览 核心类与方法(6个): 1. App/AppHost.cs - 组合根:初始化所有核心模块 - ApplyRunMode():切换帧源(Camera/Offline)并清队列 - OnInspectionCompletedForComm():输出 OK 到通信 2. Infrastructure/EventBus.cs - 事件总线:Publish/Subscribe 的核心实现 3. Services/InspectionService.cs - 有界队列 + 单线程 Worker - 统一处理相机/离线输入 4. Infrastructure/CameraManager.cs + VisionPro/VPCamera.cs - 有界队列 + 单线程 Worker - 统一处理相机/离线输入 5. VisionPro/ToolRunnerRouter.cs + VisionPro/ToolBlockRunner.cs - 相机枚举与生命周期管理 - BeatMs 连续运行:StartPlay() 内部 Task + Delay 6. Forms/MainWindow.cs - ToolBlock 的加载与相机绑定 - 结果封装为 ToolRunResult(Record + Outputs)