fix: stop point-cloud wait on SDK auto-stop
This commit is contained in:
parent
4fd1b38f73
commit
953921c684
@ -78,6 +78,7 @@ struct VizumCamera::Impl {
|
|||||||
std::mutex scanLineMutex;
|
std::mutex scanLineMutex;
|
||||||
std::atomic<bool> autoDetectRunning{false};
|
std::atomic<bool> autoDetectRunning{false};
|
||||||
std::atomic<bool> isPaused{true};
|
std::atomic<bool> isPaused{true};
|
||||||
|
std::atomic<int> scanCompletionStatus{0};
|
||||||
PointCloud accumulatedCloud;
|
PointCloud accumulatedCloud;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -99,11 +100,27 @@ struct VizumCamera::Impl {
|
|||||||
#define m_scanLineMutex m_impl->scanLineMutex
|
#define m_scanLineMutex m_impl->scanLineMutex
|
||||||
#define m_autoDetectRunning m_impl->autoDetectRunning
|
#define m_autoDetectRunning m_impl->autoDetectRunning
|
||||||
#define m_isPaused m_impl->isPaused
|
#define m_isPaused m_impl->isPaused
|
||||||
|
#define m_scanCompletionStatus m_impl->scanCompletionStatus
|
||||||
#define m_accumulatedCloud m_impl->accumulatedCloud
|
#define m_accumulatedCloud m_impl->accumulatedCloud
|
||||||
|
|
||||||
#ifdef ENABLE_VIZUM_CAMERA
|
#ifdef ENABLE_VIZUM_CAMERA
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
const char* DeviceStatusName(int status)
|
||||||
|
{
|
||||||
|
switch (static_cast<EVzDeviceWorkStatus>(status)) {
|
||||||
|
case keDeviceWorkStatusUnknown: return "Unknown";
|
||||||
|
case keDeviceWorkStatus_Eye_Comming: return "Eye_Comming";
|
||||||
|
case keDeviceWorkStatus_Eye_Reconnect: return "Eye_Reconnect";
|
||||||
|
case keDeviceWorkStatus_Working: return "Working";
|
||||||
|
case keDeviceWorkStatus_Offline: return "Offline";
|
||||||
|
case keDeviceWorkStatus_Device_Swing_Finish: return "Device_Swing_Finish";
|
||||||
|
case keDeviceWorkStatus_Device_Auto_Stop: return "Device_Auto_Stop";
|
||||||
|
case keDeviceWorkStatus_Device_Swing_Running: return "Device_Swing_Running";
|
||||||
|
default: return "Other";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AutoOutputLaserLineExCB(EVzResultDataType eDataType,
|
void AutoOutputLaserLineExCB(EVzResultDataType eDataType,
|
||||||
SVzLaserLineData* pLaserLinePoint,
|
SVzLaserLineData* pLaserLinePoint,
|
||||||
void* pParam)
|
void* pParam)
|
||||||
@ -144,19 +161,40 @@ void VizumCamera::HandleAutoOutputLaserLine(int dataType, void* laserLinePoint)
|
|||||||
void VizumCamera::HandleDeviceStatusChange(int status)
|
void VizumCamera::HandleDeviceStatusChange(int status)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_VIZUM_CAMERA
|
#ifdef ENABLE_VIZUM_CAMERA
|
||||||
LOG_INFO("[VizumCamera] Device status changed: {}", status);
|
const char* statusName = DeviceStatusName(status);
|
||||||
|
LOG_INFO("[VizumCamera] Device status changed: {} ({})", statusName, status);
|
||||||
|
|
||||||
|
const bool completesScan =
|
||||||
|
status == static_cast<int>(keDeviceWorkStatus_Device_Swing_Finish)
|
||||||
|
|| status == static_cast<int>(keDeviceWorkStatus_Device_Auto_Stop);
|
||||||
|
if (completesScan) {
|
||||||
|
if (!m_autoDetectRunning.load()) {
|
||||||
|
LOG_INFO("[VizumCamera] Completion status {} ({}) received outside an active "
|
||||||
|
"scan wait; ignored",
|
||||||
|
statusName, status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size_t scanLines = 0;
|
||||||
|
size_t validPoints = 0;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_scanLineMutex);
|
||||||
|
scanLines = m_accumulatedScanLines.size();
|
||||||
|
validPoints = m_accumulatedCloud.points.size();
|
||||||
|
}
|
||||||
|
m_scanCompletionStatus = status;
|
||||||
|
LOG_INFO("[VizumCamera] Scan completion status received: {} ({}); "
|
||||||
|
"releasing scan wait, scan lines={}, valid points={}",
|
||||||
|
statusName, status, scanLines, validPoints);
|
||||||
|
m_isPaused = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (status == static_cast<int>(keDeviceWorkStatus_Offline)) {
|
if (status == static_cast<int>(keDeviceWorkStatus_Offline)) {
|
||||||
LOG_WARN("[VizumCamera] Camera went offline");
|
LOG_WARN("[VizumCamera] Camera went offline");
|
||||||
} else if (status == static_cast<int>(keDeviceWorkStatus_Device_Swing_Finish)) {
|
|
||||||
LOG_INFO("[VizumCamera] Camera swing finished - setting m_isPaused=true");
|
|
||||||
m_isPaused = true;
|
|
||||||
} else if (status == static_cast<int>(keDeviceWorkStatus_Device_Swing_Running)) {
|
} else if (status == static_cast<int>(keDeviceWorkStatus_Device_Swing_Running)) {
|
||||||
LOG_INFO("[VizumCamera] Camera swing motor started running");
|
LOG_INFO("[VizumCamera] Camera swing motor started running");
|
||||||
} else if (status == static_cast<int>(keDeviceWorkStatus_Eye_Reconnect)) {
|
} else if (status == static_cast<int>(keDeviceWorkStatus_Eye_Reconnect)) {
|
||||||
LOG_INFO("[VizumCamera] Camera reconnected");
|
LOG_INFO("[VizumCamera] Camera reconnected");
|
||||||
} else if (status == static_cast<int>(keDeviceWorkStatus_Device_Auto_Stop)) {
|
|
||||||
LOG_INFO("[VizumCamera] Device auto stop signal received");
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
(void)status;
|
(void)status;
|
||||||
@ -539,8 +577,20 @@ bool VizumCamera::Connect(const std::string& ipAddress)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置设备状态回调
|
// 设置设备状态回调。静态扫描以 Device_Auto_Stop 作为官方完成信号,注册失败不可静默继续。
|
||||||
VzNL_SetDeviceStatusNotify(m_deviceHandle, &DeviceStatusCB, this);
|
const int statusNotifyResult = VzNL_SetDeviceStatusNotify(m_deviceHandle, &DeviceStatusCB, this);
|
||||||
|
if (statusNotifyResult != 0) {
|
||||||
|
char statusErrorMsg[256] = {0};
|
||||||
|
VzNL_GetErrorInfo(statusNotifyResult, statusErrorMsg);
|
||||||
|
LOG_ERROR("[VizumCamera] Failed to register device status callback: {} (error code: {})",
|
||||||
|
statusErrorMsg, statusNotifyResult);
|
||||||
|
VzNL_CloseDevice(m_deviceHandle);
|
||||||
|
m_deviceHandle = nullptr;
|
||||||
|
m_ipAddress.clear();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LOG_INFO("[VizumCamera] Device status callback registered; scan completion events: "
|
||||||
|
"Device_Auto_Stop or Device_Swing_Finish");
|
||||||
|
|
||||||
// OpenDevice 之后立即设置图像输出格式(在此之前设置对本次连接无效)
|
// OpenDevice 之后立即设置图像输出格式(在此之前设置对本次连接无效)
|
||||||
VzNL_SetOutputImageFormat(keVzNLImageType_BGR888);
|
VzNL_SetOutputImageFormat(keVzNLImageType_BGR888);
|
||||||
@ -948,12 +998,15 @@ bool VizumCamera::CapturePointCloudWithAutoDetect(PointCloud& pointCloud, int ti
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 3. 启动自动检测模式(与VznlCamera::StartAutoDetect一致)
|
// 3. 启动自动检测模式(与VznlCamera::StartAutoDetect一致)
|
||||||
|
m_scanCompletionStatus = 0;
|
||||||
m_isPaused = false;
|
m_isPaused = false;
|
||||||
|
m_autoDetectRunning = true;
|
||||||
LOG_INFO("[VizumCamera] Step 2: Starting AutoDetectEx...");
|
LOG_INFO("[VizumCamera] Step 2: Starting AutoDetectEx...");
|
||||||
result = VzNL_StartAutoDetectEx(m_deviceHandle, keResultDataType_PointXYZRGBA,
|
result = VzNL_StartAutoDetectEx(m_deviceHandle, keResultDataType_PointXYZRGBA,
|
||||||
keFlipType_None,
|
keFlipType_None,
|
||||||
&AutoOutputLaserLineExCB, this);
|
&AutoOutputLaserLineExCB, this);
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
|
m_autoDetectRunning = false;
|
||||||
VzNL_GetErrorInfo(result, errorMsg);
|
VzNL_GetErrorInfo(result, errorMsg);
|
||||||
LOG_ERROR("[VizumCamera] Failed to start auto detect: {} (error code: {})", errorMsg, result);
|
LOG_ERROR("[VizumCamera] Failed to start auto detect: {} (error code: {})", errorMsg, result);
|
||||||
// 尝试清理
|
// 尝试清理
|
||||||
@ -967,13 +1020,21 @@ bool VizumCamera::CapturePointCloudWithAutoDetect(PointCloud& pointCloud, int ti
|
|||||||
|
|
||||||
// 检查自动检测状态
|
// 检查自动检测状态
|
||||||
VzBool isDetecting = VzNL_IsAutoDetecting(m_deviceHandle, &errorCode);
|
VzBool isDetecting = VzNL_IsAutoDetecting(m_deviceHandle, &errorCode);
|
||||||
LOG_INFO("[VizumCamera] IsAutoDetecting: {}", isDetecting == VzTrue ? "Yes" : "No");
|
if (errorCode == 0) {
|
||||||
|
LOG_INFO("[VizumCamera] IsAutoDetecting after start: {}",
|
||||||
|
isDetecting == VzTrue ? "Yes" : "No");
|
||||||
|
} else {
|
||||||
|
char detectingErrorMsg[256] = {0};
|
||||||
|
VzNL_GetErrorInfo(errorCode, detectingErrorMsg);
|
||||||
|
LOG_WARN("[VizumCamera] Failed to query IsAutoDetecting after start: {} "
|
||||||
|
"(error code: {})", detectingErrorMsg, errorCode);
|
||||||
|
}
|
||||||
|
|
||||||
// 3. 等待扫描完成
|
// 3. 等待扫描完成
|
||||||
// 策略:等待以下任一条件满足:
|
// 策略:等待以下任一条件满足:
|
||||||
// 1. 收到摆镜完成信号 (m_isPaused = true)
|
// 1. 收到 SDK 扫描完成信号 Device_Auto_Stop 或 Device_Swing_Finish
|
||||||
// 2. 等待超时
|
// 2. 等待超时
|
||||||
// 3. 如果5秒后仍无数据到达,提前退出(可能摆镜未运动)
|
// 5秒后仍无数据时持续告警,但保留等待,避免慢启动时误判失败。
|
||||||
int maxWaitTime = (timeoutMs > 0) ? timeoutMs : 30000;
|
int maxWaitTime = (timeoutMs > 0) ? timeoutMs : 30000;
|
||||||
LOG_INFO("[VizumCamera] Step 3: Waiting up to {}ms for scan to finish...", maxWaitTime);
|
LOG_INFO("[VizumCamera] Step 3: Waiting up to {}ms for scan to finish...", maxWaitTime);
|
||||||
LOG_INFO("[VizumCamera] NOTE: The camera will collect point cloud data while the swing motor is running.");
|
LOG_INFO("[VizumCamera] NOTE: The camera will collect point cloud data while the swing motor is running.");
|
||||||
@ -1006,7 +1067,11 @@ bool VizumCamera::CapturePointCloudWithAutoDetect(PointCloud& pointCloud, int ti
|
|||||||
|
|
||||||
// 如果时间太短且没有点云,可能是虚假的结束信号(例如刚开始时的残留信号),忽略并继续
|
// 如果时间太短且没有点云,可能是虚假的结束信号(例如刚开始时的残留信号),忽略并继续
|
||||||
if (elapsed < 2000) { // 2秒内结束且无数据
|
if (elapsed < 2000) { // 2秒内结束且无数据
|
||||||
LOG_WARN("[VizumCamera] Received Swing_Finish signal too early ({}ms) without data. Ignoring...", elapsed);
|
const int completionStatus = m_scanCompletionStatus.load();
|
||||||
|
LOG_WARN("[VizumCamera] Received completion status {} ({}) too early "
|
||||||
|
"({}ms) without data. Ignoring...",
|
||||||
|
DeviceStatusName(completionStatus), completionStatus, elapsed);
|
||||||
|
m_scanCompletionStatus = 0;
|
||||||
m_isPaused = false;
|
m_isPaused = false;
|
||||||
} else {
|
} else {
|
||||||
LOG_WARN("[VizumCamera] Scan finished but no points received after {}ms.", elapsed);
|
LOG_WARN("[VizumCamera] Scan finished but no points received after {}ms.", elapsed);
|
||||||
@ -1070,14 +1135,36 @@ bool VizumCamera::CapturePointCloudWithAutoDetect(PointCloud& pointCloud, int ti
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 从此处起 StopAutoDetect 触发的 Auto_Stop 仅属于清理动作,不能改写本次完成原因。
|
||||||
|
m_autoDetectRunning = false;
|
||||||
|
|
||||||
int totalDuration = static_cast<int>(std::chrono::duration_cast<std::chrono::milliseconds>(
|
int totalDuration = static_cast<int>(std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||||
std::chrono::steady_clock::now() - startTime).count());
|
std::chrono::steady_clock::now() - startTime).count());
|
||||||
|
|
||||||
|
const int completionStatus = m_scanCompletionStatus.load();
|
||||||
if (m_isPaused) {
|
if (m_isPaused) {
|
||||||
LOG_INFO("[VizumCamera] Scan finished by swing completion signal. Duration: {}ms", totalDuration);
|
LOG_INFO("[VizumCamera] Scan finished by completion status {} ({}). Duration: {}ms",
|
||||||
|
DeviceStatusName(completionStatus), completionStatus, totalDuration);
|
||||||
} else {
|
} else {
|
||||||
LOG_INFO("[VizumCamera] Scan finished by timeout. Duration: {}ms", totalDuration);
|
int detectingError = 0;
|
||||||
|
const VzBool stillDetecting = VzNL_IsAutoDetecting(m_deviceHandle, &detectingError);
|
||||||
|
char detectingErrorMsg[256] = {0};
|
||||||
|
if (detectingError != 0) {
|
||||||
|
VzNL_GetErrorInfo(detectingError, detectingErrorMsg);
|
||||||
|
}
|
||||||
|
size_t timeoutScanLines = 0;
|
||||||
|
size_t timeoutValidPoints = 0;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(m_scanLineMutex);
|
||||||
|
timeoutScanLines = m_accumulatedScanLines.size();
|
||||||
|
timeoutValidPoints = m_accumulatedCloud.points.size();
|
||||||
|
}
|
||||||
|
LOG_WARN("[VizumCamera] Timeout diagnostics: duration={}ms, autoDetecting={}, "
|
||||||
|
"detectError={} ({}), completion status={} ({}), scan lines={}, valid points={}",
|
||||||
|
totalDuration, stillDetecting == VzTrue ? "Yes" : "No", detectingError,
|
||||||
|
detectingError == 0 ? "none" : detectingErrorMsg,
|
||||||
|
DeviceStatusName(completionStatus), completionStatus,
|
||||||
|
timeoutScanLines, timeoutValidPoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 输出扫描过程中的状态
|
// 输出扫描过程中的状态
|
||||||
@ -1578,6 +1665,7 @@ SLCameraPtr CreateVizumCamera()
|
|||||||
#undef m_scanLineMutex
|
#undef m_scanLineMutex
|
||||||
#undef m_autoDetectRunning
|
#undef m_autoDetectRunning
|
||||||
#undef m_isPaused
|
#undef m_isPaused
|
||||||
|
#undef m_scanCompletionStatus
|
||||||
#undef m_accumulatedCloud
|
#undef m_accumulatedCloud
|
||||||
|
|
||||||
} // namespace StructuredLight
|
} // namespace StructuredLight
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user