前言
简单分析一下SICK Ranger3源码中断线重连的实现,这一块算是比较容易的,先择出来分析一下。
代码示例仅贴出关键部分以便分析
使用SDK版本为3.4.2.6
断线重连官方例程:Demo_R3_callback_with_heartbeat.cpp
断线检测
断线重连可以划分为两步,首先检测相机断线并通知,然后用户在收到通知后进行重连操作。我们先看SICK如何实现断线检测。
断线检测机制内置于SICK SDK中,由SICK SDK管理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| EXPORT_TO_DLL CAM_STATUS Ranger3::connectCamera(CallbackEvent_HeartBeats pCallback, const uint32_t& microSecond, void * any) { try{ auto e = connectCamera(); if(e == CAM_STATUS::All_OK) { m_heartbeat_is_on = 1; ... auto _thread = std::make_shared<std::thread>(&Ranger3::_check_HeartBeats_run, this); _thread->detach(); } return e; } ... }
void Ranger3::_check_HeartBeats_run() { while (m_heartbeat_is_on==1) { __sleep1MS(m_heartbeat_interval); ... try { Str value(""); m_Param.getParameter(m_deviceNodeMap, "DeviceTemperature", value); ... } catch (...) { ... } } }
|
可以看出,断线检测机制很简单,就是分离一个线程,循环访问相机寄存器(SICK的实现是通过定时获取设备温度访问相机寄存器),若访问不到(失败),就意味着相机已离线。
断线通知
断线通知机制同样内置于SICK SDK中:在检测到设备离线后,调用注册好的回调函数(注册过程将在下文介绍)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| void Ranger3::_check_HeartBeats_run() { while (m_heartbeat_is_on==1) { __sleep1MS(m_heartbeat_interval); ... try { Str value(""); m_Param.getParameter(m_deviceNodeMap, "DeviceTemperature", value); ... } catch (...) { ... auto _thread = std::make_shared<std::thread>(m_on_lost_function, &m_DeviceName, &m_DeviceIP, &m_on_lost_mac, &msg, m_on_lost_inputs); _thread->join(); return; } } }
|
重连实现
重连机制的具体实现由用户进行。在例程Demo_R3_callback_with_heartbeat.cpp
中,由用户自定义一个回调函数(在相机离线时会被调用),回调内循环对相机进行重连操作。用户在连接相机时注册这个回调
用户层代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
void SICK_CALLBACK on_lost_device_Demo_R3_callback_with_heartbeat(std::string* name, std::string* ip, std::string* mac, std::string* msg, void * pR3) { auto pCam = (SickCam::Ranger3*)pR3; while (true) { auto ec = pCam->reconnectCamera(); ... __sleep1MS(1000); } }
auto err = pCam1->connectCamera(on_lost_device_Demo_R3_callback_with_heartbeat, 1000, pCam1.get());
|
在SICK SDK中,注册过程会:
- 将用户注册的
on_lost_device_Demo_R3_callback_with_heartbeat
赋值给m_on_lost_function
- 将用户传递上下文信息
any
赋值给m_on_lost_inputs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| typedef std::function<void(std::string* name, std::string* ip, std::string* mac, std::string* msg, void* any)> CallbackEvent_HeartBeats;
EXPORT_TO_DLL CAM_STATUS Ranger3::connectCamera(CallbackEvent_HeartBeats pCallback, const uint32_t& microSecond, void * any) { try{ auto e = connectCamera(); if(e == CAM_STATUS::All_OK) { ... m_on_lost_function = pCallback; m_on_lost_inputs = any; auto _thread = std::make_shared<std::thread>(&Ranger3::_check_HeartBeats_run, this); _thread->detach(); } return e; } ... }
|
注册完毕后,当相机出现离线情况,就如上文所述,SDK会调用注册的回调函数进行重连。