Baumer工业相机堡盟相机如何使用PnPEventHandler实现相机掉线自动重连(C++新)

news2025/7/23 12:51:59

项目场景:

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_gige
				if(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();			  //一般为1
					if(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事件类型来进行判断。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/394934.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

五点CRM系统核心功能是什么

很多企业已经把CRM客户管理系统纳入信息化建设首选&#xff0c;用于提升核心竞争力&#xff0c;改善企业市场、销售、服务、渠道和客户管理等几个方面&#xff0c;并进行创新或转型。CRM系统战略的五个关键要点是&#xff1a;挖掘潜在客户、评估和培育、跟进并成交、分析并提高…

传输层--UDP协议

目录 一.补充知识 1.1传输层​ 1.2端口号 1.3netstat 二.UDP 2.1UDP协议格式 2.2UDP如何将有效载荷上交给上层 2.3UDP如何将报头与有效载荷进行分离&#xff1f; 2.4理解报头 2.5.UDP协议特点 2.6UDP缓冲区 2.6基于UDP的应用层协议 一.补充知识 1.1传输层 之前介绍…

相恨见晚的office办公神器(不坑盒子/打工人Excel插件2023年最新版)

不坑盒子 这是一个非常好用的插件工具&#xff0c;专门应用在Word文档和wps&#xff0c;支持Office 2010以上的版本&#xff0c;操作也简单且实用。 不坑盒子下载及使用说明 一键排版功能 像是下面的自动排版功能&#xff0c;可以在配置里面先设定好需要的格式&#xff0c;…

站内SEO排名不上?或许是这些常见问题导致的

在当今数字化的时代&#xff0c;几乎所有的企业和个人都有自己的网站。 然而&#xff0c;拥有一个网站并不代表着它就一定能够被搜索引擎优先展示。 SEO&#xff08;搜索引擎优化&#xff09;是一门需要技巧和耐心的艺术。在实践SEO的过程中&#xff0c;站内SEO是一个重要的环…

Hive 运行环境搭建

文章目录Hive 运行环境搭建一、Hive 安装部署1、安装hive2、MySQL 安装3、Hive 元数据配置到 Mysql1) 拷贝驱动2) 配置Metastore 到 MySQL3) 再次启动Hive4) 使用元数据服务的方式访问Hive二、使用Dbaver连接HiveHive 运行环境搭建 HIve 下载地址&#xff1a;http://archive.a…

剑指-Offer-09-用两个栈实现队列

剑指-Offer-09-用两个栈实现队列 题目描述&#xff1a; 用两个栈实现一个队列。队列的声明如下&#xff0c;请实现它的两个函数 appendTail 和 deleteHead &#xff0c;分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素&#xff0c;deleteHead 操作…

Qt 事件循环

一、QT消息/事件循环机制   Qt作为一个可视化GUI界面操作系统&#xff0c;是基于事件驱动的&#xff0c;我们程序执行的顺序不再是线性的&#xff0c;而是由一个个应用程序内部或外部的事件进行驱动的&#xff0c;无事件时便阻塞。这个有点类似于while循环&#xff0c;函数体…

智能交通数据集Rope3D(仅限科研使用)

Rope3D Dataset 官网&#xff1a;https://thudair.baai.ac.cn/index &#xff01;&#xff01;&#xff01;如想要使用Rope3D数据集进行2D检测&#xff0c;最后有我们处理完的数据集链接。 &#xff01;&#xff01;&#xff01; 介绍&#xff1a; DAIR-V2X数据集是首个用于…

11 款全能的苹果设备激活锁移除工具

出于安全原因&#xff0c;每个 Apple 用户都可以设置一个 Apple ID和密码来保护他们的信息。但如果您忘记了 Apple ID 和密码&#xff0c;您将无法使用 iCloud 激活锁。如果发生这种情况&#xff0c;您应该怎么办&#xff1f;不用担心。iCloud 激活锁移除工具专为在 iOS 设备上…

【Arduino疑难杂症】:arduino IDE2.0.4安装ESP8266、ESP32库教程

& 项目场景&#xff1a; 2023年3月7日&#xff0c;在使用新版arduino编程ESP8266的时候&#xff0c;发现无法像老版本那样去添加库或添加zip库&#xff0c;这个纯个人原因&#xff0c;以免习惯了老版本的一些同学也会迷茫这个问题&#xff0c;于是这篇文章应运而生&…

汽车标定知识整理(三):CCP报文可选命令介绍

目录 一、可选命令 CRO命令报文的可选命令表&#xff1a; 二、可选命令帧格式介绍 1、GET_SEED——获取被请求资源的种子&#xff08;0x12&#xff09; 2、UNLOCK——解锁保护&#xff08;0x13&#xff09; 3、SET_S_STATUS——设置Session状态&#xff08;0x0C&#xff0…

Webpack打包--优化项目

1. Webpack基本概念 目标: webpack本身是, node的一个第三方模块包, 用于打包代码 2.Webpack能做什么 把很多文件打包整合到一起, 缩小项目体积, 提高加载速度 3.Webpack的官方解释 从本质上来讲&#xff0c;webpack是一个现在的javaScript应用的静态模块化打包工具。&#xff…

leetcode 2187. Minimum Time to Complete Trips(完成行程的最短时间)

(Medium) time数组里面是每个bus完成一次路程需要的时间&#xff0c;假设时间单位是h, 比如time [1,2,3]就表示第1辆bus跑完路程需要1h&#xff0c;第2辆需要2h&#xff0c;第3辆需要3h. 那么把所有bus都考虑进来&#xff0c;总共要跑完totalTrips次路程&#xff0c;问至少需…

数据库之基本功:Where 中常用运算符

1. 运算符及优先级 ( )优先级最高 SQL> show user; USER is "SCOTT" SQL> select ename, job, sal, comm from emp where jobSALESMAN OR jobPRESIDENT and sal> 1500;ENAME JOB SAL COMM …

Pyspark基础入门5_RDD的持久化方法

Pyspark 注&#xff1a;大家觉得博客好的话&#xff0c;别忘了点赞收藏呀&#xff0c;本人每周都会更新关于人工智能和大数据相关的内容&#xff0c;内容多为原创&#xff0c;Python Java Scala SQL 代码&#xff0c;CV NLP 推荐系统等&#xff0c;Spark Flink Kafka Hbase Hi…

回收站清空恢复,4种方法任你选!

案例&#xff1a;不小心清空了回收站怎么恢复&#xff1f; “回收站刚刚清空的文件怎么恢复呀&#xff1f;辛苦收集的材料不小心删除了&#xff0c;请大神来帮我下。” 回收站是我们电脑上的一个非常实用的功能&#xff0c;可以让我们暂时存放不需要的文件或者是可以被删除的…

启动u盘还原成普通u盘(Windows Diskpart)

使用windows系统的diskpart 命令解决系统盘恢复成普通U盘的问题&#xff1a;1. 按Windows R键打开运行窗口。在搜索框中输入“ Diskpart ”&#xff0c;然后按 Enter 键。2. 现在输入“ list disk ”并回车。3. 然后输入“ select disk X ”&#xff08;将 X 替换为可启动U盘的…

围棋高手郭广昌的“假眼”棋局

&#xff08;图片来源于网络&#xff0c;侵删&#xff09;文丨熔财经作者|易不二2022年&#xff0c;在复星深陷债务压顶和变卖资产漩涡的而立之年&#xff0c;“消失”已久的郭广昌&#xff0c;在质疑与非议声中回国稳定军心&#xff0c;强调复星将在未来的五到十年迎来一个全新…

安卓反编译入门03-dex2jar反编译apk得到Java源代码

1.获取工具dex2jar下载地址&#xff1a;http://sourceforge.net/projects/dex2jar/files/直接下载下载完成后&#xff0c;解压得到文件夹dex2jar-2.0jd-gui下载地址&#xff1a;http://jd.benow.ca/ 直接下载&#xff08;官网版本无法复制中文&#xff0c;可以用这个&#xff0…

K8s pod 动态弹性扩缩容 HPA

一、概述Horizontal Pod Autoscaler&#xff08;HPA&#xff0c;Pod水平自动伸缩&#xff09;&#xff0c;根据平均 CPU 利用率、平均内存利用率或你指定的任何其他自定义指标自动调整 Deployment 、ReplicaSet 或 StatefulSet 或其他类似资源&#xff0c;实现部署的自动扩展和…