Baumer工业相机堡盟相机如何使用PnPEventHandler实现相机掉线自动重连(C++新)
项目场景:
Baumer工业相机堡盟相机传统开发包BGAPI SDK进行工业视觉软件整合时,常常需要将SDK中一些功能整合到图像处理软件中,方便项目的推进使用;
在项目的图像处理任务中,可能会因为一些硬件比如线缆网卡的原因导致出现偶尔掉线,而软件重启则可以重新连上,这时为了适用于自动化设备不停线的情况下,需要图像处理软件可以自动进行断线重新连接。
注意:本文是基于Baumer的BGAPI SDK的基础上使用C++语言来实现相机的掉线重新连接。
注意:该方法与上一篇自动重连机制有所不同,更加的便捷,更符合PnPEventHandler事件定义:
Baumer工业相机堡盟相机如何实现相机掉线重连(C++)_格林威的博客-CSDN博客
如何发现掉线
Baumer工业相机BGAPI SDK中在相机事件中存在一种PnpEvent事件可以监控相机是否掉线,从而能够及时发现相机的问题。
在BGAPI SDK的C++开发包里存在PnpEvent的事件例程,关键字为:013_PnPEventMode_Handler
下面为例程中PnPEvent事件核心代码,已经进行优化
// CALLBACK
void BGAPI2CALL PnPEventHandler(void * callbackOwner, BGAPI2::Events::PnPEvent * pPnPEvent) {if (NULL != pPnPEvent) {std::cout << std::endl;std::cout << std::endl;std::cout << " [callback of " << ((BGAPI2::Interface *)callbackOwner)->GetDisplayName() << "] ";std::cout << " EventID " << pPnPEvent->GetId() << " PnPType: "<< ((pPnPEvent->GetPnPType() == 0) ? "removed" : "added ")<< " SerialNumber: " << pPnPEvent->GetSerialNumber() << std::endl;std::cout << std::endl;return;
}
相机掉线重连实现方法:
1、在相机初始化的过程中,在相机对应的网口中注册SDK中PnPEvent回调函数
代码如下所示:
//为相机对应数据流注册掉线触发事件 m_pInterface->RegisterPnPEvent(BGAPI2::Events::EVENTMODE_EVENT_HANDLER); m_pInterface->RegisterPnPEventHandler(this, (Events::PnPEventHandler) &PnPEventHandler);
2、在PnPEvent回调函数里进行相机掉线事件的分析并对应实现相机的再次查找
注意在回调里尽量不要处理太多任务,可以从回调里发出信息,在外部处理回调发出的任务信息。本例在回调里处理任务方便参考,请大家理解。
PnPEvent回调函数代码如下所示:
BOOL BGAPI2CALL PnPEventHandler(void * callBackOwner, BGAPI2::Events::PnPEvent * pPnPEvent) {if (NULL != pPnPEvent){const char* EventTypeStrC = ((pPnPEvent->GetPnPType() == 0)? "removed" : "added");CString EventTypeStr(EventTypeStrC);BaumerCameraDriver* pCamera = (BaumerCameraDriver*)callBackOwner;if(EventTypeStr == _T("removed")){//AfxMessageBox(_T("相机离线")); pCamera->ReleaseCamera(); //释放相机资源 }if(EventTypeStr == _T("added")){//AfxMessageBox(_T("相机在线"));#pragma region//网口资源的初始化pCamera->systemList = SystemList::GetInstance();pCamera->systemList->Refresh();int sysindex = 0; int devcount = 0;for(SystemList::iterator sysIterator = pCamera->systemList->begin();sysIterator != pCamera->systemList->end();sysIterator++){CString sysModel0 = A2W(sysIterator->second->GetModel()); //bgapi_gigeif(sysModel0.Find(_T("gige"))!=-1) //此例程只连接网口Gige相机{ pCamera->pSystem = sysIterator->second;break;}sysindex++;}pCamera->interfaceList = pCamera->pSystem->GetInterfaces();pCamera->interfaceList->Refresh(100);int infcount =pCamera-> interfaceList->size(); //可以找到多个interface网络接口(包含实际接口和虚拟接口)for(InterfaceList::iterator ifIterator = pDlg->interfaceList->begin(); ifIterator != pDlg->interfaceList->end();ifIterator++){CString infType = A2W(ifIterator->second->GetTLType());CString infName = A2W(ifIterator->second->GetDisplayName());BGAPI2::Interface* m_pInterface0 = ifIterator->second;if(m_pInterface0->IsOpen()) //检查网口是否开启{BGAPI2::DeviceList* m_pDeviceList = m_pInterface0->GetDevices();m_pDeviceList->Refresh(100); int devcount = m_pDeviceList->size(); //一般为1if(devcount>0){bool devListRefresh_reqiured = false;BGAPI2::Device * m_pDevice = (*m_pDeviceList)[0];if(m_pDevice->IsOpen()){if(pPnPEvent->GetSerialNumber()==m_pDevice->GetSerialNumber()){m_pDevice->Close();devListRefresh_reqiured = true;}}if (devListRefresh_reqiured){m_pDeviceList->Refresh(200);}}}}#pragma endregion//相机的再连接pCamera->RelinkCamera();}return TRUE;} }
3、在PnPEvent掉线发生后需要释放对应的资源,防止内存泄漏;
代码如下所示:
void CGigeDemoDlg::ReleaseCamera() {//m_pDatastreamList = CurDevice->GetDataStreams();//获取相机设备数据流序列int iDscount = m_pDatastreamList->size();//一般为1 if(iDscount>0)m_pDataStream = (*m_pDatastreamList)[0];try{ m_pDataStream->StopAcquisition(); //停止采集相机数据流}catch (BGAPI2::Exceptions::IException& ex){} try{m_pBufferList = m_pDataStream->GetBufferList();//获取相机设备数据流的Buffer序列while (m_pBufferList->size() > 0) //对Bufferlist里每个buffer对象进行释放删除{BGAPI2::Buffer* m_pBuffer = m_pBufferList->begin()->second;m_pBufferList->RevokeBuffer(m_pBuffer); //对当前buffer对象进行释放delete m_pBuffer; //对当前buffer对象进行删除}}catch (BGAPI2::Exceptions::IException& ex){}try{ m_pDataStream->Close(); //关闭相机数据流 }catch (BGAPI2::Exceptions::IException& ex){}}
4、在对应相机进行一定程度的释放资源后,相机的PnPEventHandler回调函数事件是一直再运行中,若相机重新连接上后,该回调函数事件回同步得到触发,因此可以同步执行相机资源的初始化和相机的自动重连;
void CGigeDemoDlg::ReConnectCamera(BGAPI2::Interface* CurInterface) {USES_CONVERSION;m_pDeviceList = m_pInterface->GetDevices();m_pDeviceList->Refresh(100); int devcount = m_pDeviceList->size();m_pDevice = (*m_pDeviceList)[0];m_pDevice->Open();CString devName = A2W(m_pDevice->GetDisplayName());m_pDatastreamList = m_pDevice->GetDataStreams();m_pDatastreamList->Refresh();int iDscount = m_pDatastreamList->size(); BGAPI2::DataStream *m_pDataStream0 = (*m_pDatastreamList)[0]; //这里的DataStream需要使用临时变量m_pDataStream0->Open();m_pBufferList = m_pDataStream0->GetBufferList();for(int i=0; i<4; i++){m_pBuffer = new BGAPI2::Buffer();m_pBufferList->Add(m_pBuffer);}for (BGAPI2::BufferList::iterator bfIterator = m_pBufferList->begin();bfIterator != m_pBufferList->end();bfIterator++){bfIterator->second->QueueBuffer();}int iQBuffer = m_pBufferList->GetQueuedCount();int x=0;m_pDataStream0->RegisterNewBufferEvent(BGAPI2::Events::EVENTMODE_EVENT_HANDLER);m_pDataStream0->RegisterNewBufferEventHandler(this,(Events::NewBufferEventHandler) &BufferHandler);String strTrgStatus;strTrgStatus = m_pDevice->GetRemoteNode("TriggerMode")->GetString();CString strTrgStatusC = A2W(strTrgStatus);m_pDataStream0->StartAcquisitionContinuous();AfxMessageBox(devName+_T("已连接"));}
5、上述相机将会在回调函数中自动完成重连操作,然后重新点击采图可以发现相机已经恢复正常。
相机连接代码如下所示:
void CGigeDemoDlg::OnBnClickedBtnplay() {// TODO: 在此添加控件通知处理程序代码USES_CONVERSION;if(m_pDevice != NULL){try{m_pDevice->GetRemoteNode("TriggerMode")->SetString("Off"); //关闭触发模式,进入自由采集图片流模式m_pDevice->GetRemoteNode("AcquisitionStart")->Execute();#pragma region 线程显示帧率和网口数据通量(做参考)m_bRun0 = true;//AfxBeginThread(ShowFrame_hThread1, (void*)this); #pragma endregion }catch (BGAPI2::Exceptions::IException& ex){CString str1;str1.Format(_T("ExceptionType:%s! ErrorDescription:%s in function:%s"),ex.GetType(),ex.GetErrorDescription(),ex.GetFunctionName());MessageBox(str1);}}}
6、完成上面操作后,就可以及时对掉线相机进行断线重连操作,可以尝试重新连接,也可以检查对应相机状态,需要对应掉线事件操作什么,取决于开发者想要什么的功能实现。
结论要点
工业相机的重连机制依托于相机的PnPEvent事件触发,并且出现PnPEvent事件后可以触发一个间隔1-2s的线程,反复刷新对应网口interface的相机,找到相机后,然后线程终止,然后再触发一个重新连接的功能或者方法。
PnPEvent事件类型有移除和增加两种类型,可以针对两种类型做相应的自定义处理。
事件类型如下图所示:
并且在刷新工业相机List的过程中可以根据类的构成和习惯有所不同,比如锁定好接口,方便快速只刷新这个接口,从而适用于多相机的系统。
注意
工业相机的重连功能基本上是属于软件层面的重新连接,若是涉及到硬件层面的变更和重连则需要更为严格的对象设计和逻辑优化。
本文的重连则采用了上述的PnPEvent事件类型来进行判断。
相关文章:

Baumer工业相机堡盟相机如何使用PnPEventHandler实现相机掉线自动重连(C++新)
项目场景: Baumer工业相机堡盟相机传统开发包BGAPI SDK进行工业视觉软件整合时,常常需要将SDK中一些功能整合到图像处理软件中,方便项目的推进使用; 在项目的图像处理任务中,可能会因为一些硬件比如线缆网卡的原因导…...
Windows 命令行基础
1. 引言:为什么要使用命令行在 DOS 时代,人们只能依靠输入命令同计算机互交。而现在,微软的 Windows 操作系统已得到了广泛使用,我们处理日常事务也大多使用基于图形用户界面(GUI,Graphics User Interface&…...

面试官: 谈下音视频同步原理,音频和视频能绝对同步吗?
作者:波哥 心理分析:音视频同步本身比较难,一般使用ijkplayer 第三方做音视频同步。不排除有视频直播 视频通话需要用音视频同步,可以从三种 音频为准 视频为准 自定义时钟为准三种方式实现音视频同步 求职者:如果被问到 放正心态…...

CFS三层靶机安装与配置
CFS三层靶机安装与配置 环境下载 百度网盘 提取码:Chen 环境安装 下载完成后,有三个文件夹,每个文件夹对应一个靶机 进入三个文件夹,双击打开后缀为.ovf的文件,按提示安装虚拟机 环境配置 网段划分 target1&#…...
爬虫入门教程-Spider
Spider 爬虫是定义如何抓取某个网站(或一组网站)的类,包括如何执行抓取(即关注链接)以及如何从其网页中提取结构化数据(即抓取项目)。换句话说,Spider是您定义用于为特定网站&#x…...

Python|蓝桥杯进阶第二卷——贪心
欢迎交流学习~~ 专栏: 蓝桥杯Python组刷题日寄 蓝桥杯进阶系列: 🏆 Python | 蓝桥杯进阶第一卷——字符串 🔎 Python | 蓝桥杯进阶第二卷——贪心 💝 Python | 蓝桥杯进阶第三卷——动态规划(待续…...

Chrome开发使用技巧总结
Chrome一个程序员开发神器,但是好多猿子们不会或者没有正确使用。今天教大家如何利用它快速高效的开发调试工作。代码格式化有很多css/js的代码都会被 minify 掉,你可以点击代码窗口左下角的那个 { } 标签,chrome会帮你给格式化掉。强制DOM状…...

你真的会在阳光下拍照片么?
你好,我是小麥。 上节课我们讲了如何通过影子判断光的质量,也就是光的软硬,这节课我们来接着说一说光的方向和环境光的实际运用。 虽然在现实生活里,我们可能没有从软硬的角度观察过光线,但我相信你在拍照片的时候一…...

量化择时——均线策略及改进方法(第1部分—因子测算)
文章目录道氏理论个股股价走势阶段板块、行业股价走势均线策略交易逻辑均线策略效果测算改进一:设置策略信号偏移量改进二:生成止盈止损信号道氏理论 使用盘面数据,根据计算出的一条或多条均线,判断入场与离场的时机,…...
封装几个有用的 Vue3 组合式API
本文将介绍如何使用Vue3来封装一些比较有用的组合API,主要包括背景、实现思路以及一些思考。 就我自己的感觉而言,Hook与Composition API概念是很类似的,事实上在React大部分可用的Hook都可以使用Vue3再实现一遍。 为了拼写方便,下文内容均使用Hook代替Composition API。相…...

MyBatisPlus中的条件构造器Wrapper
引言为什么要了解Wrapper?Wrapper解决的了什么问题?一、Wrapper:条件构造抽象类,用来解决单表操作出现的一些复杂问题,例如排序,和模糊查询等等结构图文字解释AbstractWrapper : 用于查询条件封装ÿ…...
类和对象及其构造方法
类和对象 现实世界的事物由什么组成? 属性 行为 类也可以包含属性和行为,所以使用类描述现实世界事物是非常合适的类和对象的关系是什么? 类是程序中的“设计图纸” 对象是基于图纸生产的具体实体什么是面向对象编程? 面向对象编…...

HStream Console、HStreamDB 0.14 发布
近两个月,HStreamDB 相继发布了 0.13 和 0.14 版本,包含多项已知问题修复。同时,我们也发布了全新的 HStream Console 组件,为 HStreamDB 带来了简洁友好的图形化管理界面,将帮助用户更轻松地使用和管理 HStreamDB. H…...

参考文献怎么查找,去哪里查找?一篇文章讲明白这些问题
在我们撰写论文查找参考文献时,往往不知道从哪里入手,本文小编就针对下面这三个方面给大家详细讲解下: 一、查找参考文献方法 二、参考文献资料查找网站 三、参考文献格式规范 一、查找参考文献方法: 1、知网全球最大的中文数据…...

docker-compose+HAProxy+Keepalived搭建高可用 RabbitMQ 集群
基础环境准备 系统环境:Centos7.6 Docker version: 1.13.1, build 7d71120/1.13.1 Docker Compose version: v2.2.2 三个节点: 10.10.11.79 (这一台做rabbitmq集群根节点) 10.10.11.80 (这台做haproxyke…...

自动化框架如何搭建?让10年阿里自动化测试老司机帮你搞定!自动化测试脚本怎么写?
一、何为框架?何为自动化测试框架? 无论是日常技术交流,还是在自动化测试实践中,经常会听到一个词叫:框架。之前对“框架”这个词知其然不知其所以然。现在看过一些资料以及加上我自己的一些实践有了我自己的一些看法…...
剑指 Offer 15. 二进制中1的个数
剑指 Offer 15. 二进制中1的个数 难度:easy\color{Green}{easy}easy 题目描述 编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为 汉明重量).…...

CHAPTER 3 磁盘管理
磁盘管理1 磁盘管理1.1 块设备信息(lsblk)1.2 挂载硬盘1.2.1 挂载单个硬盘(mkfs、mount)1.2.2 磁盘分区工具(fdisk)1.2.3 创建分区1.2.4 相关命令1. df2. partprobe3. mkfs1.3 逻辑卷管理器(LVM)1. 涉及概念2. 使用LVM流程1.4 磁盘检测及修复(fsck)1 磁盘…...

MS python学习(7)
Managing Keys - dotenv Managing keys usage of .env module 项目地址:https://github.com/theskumar/python-dotenv Reads the key,value pair from .env and adds them to environment variable. 将key明文(hard code)形式写在script里…...

工业物联网“杀手级”应用—预测性维护
一、预测性维护的必要性 随着新一轮科技革命和产业变革的兴起,工业物联网、大数据、人工智能等技术正与经济社会各领域加速渗透融合。由于市场竞争对精细化成本管控的要求,设备的重要性越来越凸显,设备的维护对策也必然从响应式维护…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...

在 Spring Boot 中使用 JSP
jsp? 好多年没用了。重新整一下 还费了点时间,记录一下。 项目结构: pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...
HTML前端开发:JavaScript 获取元素方法详解
作为前端开发者,高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法,分为两大系列: 一、getElementBy... 系列 传统方法,直接通过 DOM 接口访问,返回动态集合(元素变化会实时更新)。…...

解析两阶段提交与三阶段提交的核心差异及MySQL实现方案
引言 在分布式系统的事务处理中,如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议(2PC)通过准备阶段与提交阶段的协调机制,以同步决策模式确保事务原子性。其改进版本三阶段提交协议(3PC…...

Java数组Arrays操作全攻略
Arrays类的概述 Java中的Arrays类位于java.util包中,提供了一系列静态方法用于操作数组(如排序、搜索、填充、比较等)。这些方法适用于基本类型数组和对象数组。 常用成员方法及代码示例 排序(sort) 对数组进行升序…...

Linux基础开发工具——vim工具
文章目录 vim工具什么是vimvim的多模式和使用vim的基础模式vim的三种基础模式三种模式的初步了解 常用模式的详细讲解插入模式命令模式模式转化光标的移动文本的编辑 底行模式替换模式视图模式总结 使用vim的小技巧vim的配置(了解) vim工具 本文章仍然是继续讲解Linux系统下的…...
Java中栈的多种实现类详解
Java中栈的多种实现类详解:Stack、LinkedList与ArrayDeque全方位对比 前言一、Stack类——Java最早的栈实现1.1 Stack类简介1.2 常用方法1.3 优缺点分析 二、LinkedList类——灵活的双端链表2.1 LinkedList类简介2.2 常用方法2.3 优缺点分析 三、ArrayDeque类——高…...