diff --git a/GrabBagApp/Presenter/Inc/GrabBagPresenter.h b/GrabBagApp/Presenter/Inc/GrabBagPresenter.h index 29c0769e..ebbbb8fa 100644 --- a/GrabBagApp/Presenter/Inc/GrabBagPresenter.h +++ b/GrabBagApp/Presenter/Inc/GrabBagPresenter.h @@ -39,20 +39,21 @@ public: // 加载调试数据进行检测 int LoadDebugDataAndDetect(const std::string& filePath); - - IVrEyeDevice* GetEyeDevice(int index); - - // 相机列表管理相关函数 - std::vector GetCameraList(); - int GetCameraCount(); - void GetCameraListWithNames(std::vector& cameraList, std::vector& cameraNames); - bool IsCameraConnected(int index); // 为所有相机设置状态回调 void SetCameraStatusCallback(VzNL_OnNotifyStatusCBEx fNotify, void* param); + // 设置默认相机索引 + void SetDefaultCameraIndex(int cameraIndex); + + // 获取当前默认相机索引 + int GetDefaultCameraIndex() const { return m_currentCameraIndex; } + // 获取配置对象 IVrConfig* GetConfig() { return m_vrConfig; } + + // 获取相机列表 + std::vector> GetCameraList() const { return m_vrEyeDeviceList; } // 返回相机列表,包括IP地址和设备指针 // 手眼标定矩阵管理 const CalibMatrix GetClibMatrix(int index) const; @@ -115,7 +116,7 @@ private: private: IVrConfig* m_vrConfig = nullptr; - std::vector m_vrEyeDeviceList; + std::vector> m_vrEyeDeviceList; IYGrabBagStatus* m_pStatus = nullptr; DetectPresenter* m_pDetectPresenter = nullptr; @@ -134,9 +135,8 @@ private: std::condition_variable m_algoDetectCondition; // 检测数据缓存 - 直接存储算法格式数据 - std::vector m_detectionDataCache; - std::mutex m_detectionDataMutex; - + std::mutex m_detectionDataMutex; + std::vector m_detectionDataCache; std::vector m_detectionDataCacheRGBD; // 算法参数成员变量 diff --git a/GrabBagApp/Presenter/Src/DetectPresenter.cpp b/GrabBagApp/Presenter/Src/DetectPresenter.cpp index b2a8d9b5..0ca26f2b 100644 --- a/GrabBagApp/Presenter/Src/DetectPresenter.cpp +++ b/GrabBagApp/Presenter/Src/DetectPresenter.cpp @@ -171,8 +171,9 @@ int DetectPresenter::DetectBag(std::vector& detectionData } // 从点云数据生成投影图像 - detectionResult.image = PointCloudImageUtils::GeneratePointCloudImage(static_cast(detectionDataCache.data()), - detectionDataCache.size(), objOps); + detectionResult.image = PointCloudImageUtils::GeneratePointCloudImage( + static_cast(detectionDataCache.data()), + detectionDataCache.size(), objOps); // 转换检测结果为UI显示格式(使用机械臂坐标系数据) for (size_t i = 0; i < objOps.size(); i++) { diff --git a/GrabBagApp/Presenter/Src/GrabBagPresenter.cpp b/GrabBagApp/Presenter/Src/GrabBagPresenter.cpp index 26e7abbc..64981620 100644 --- a/GrabBagApp/Presenter/Src/GrabBagPresenter.cpp +++ b/GrabBagApp/Presenter/Src/GrabBagPresenter.cpp @@ -12,6 +12,7 @@ #include #include +#include "Version.h" #include "VrTimeUtils.h" #include "VrDateUtils.h" #include "SG_bagPositioning_Export.h" @@ -28,7 +29,8 @@ GrabBagPresenter::GrabBagPresenter() , m_bRobotConnected(false) , m_currentWorkStatus(WorkStatus::Error) { - + m_detectionDataCache.clear(); + m_detectionDataCacheRGBD.clear(); } GrabBagPresenter::~GrabBagPresenter() @@ -63,8 +65,10 @@ GrabBagPresenter::~GrabBagPresenter() // 释放其他资源 for(auto it = m_vrEyeDeviceList.begin(); it != m_vrEyeDeviceList.end(); it++) { - (*it)->CloseDevice(); - delete (*it); + if (it->second != nullptr) { + it->second->CloseDevice(); + delete it->second; + } } m_vrEyeDeviceList.clear(); @@ -78,6 +82,7 @@ GrabBagPresenter::~GrabBagPresenter() int GrabBagPresenter::Init() { + LOG_DEBUG("Start APP Version: %s\n", GRABBAG_FULL_VERSION_STRING); // 初始化连接状态 m_bCameraConnected = false; m_currentWorkStatus = WorkStatus::InitIng; @@ -115,17 +120,22 @@ int GrabBagPresenter::Init() // 通知UI相机个数 int cameraCount = configResult.cameraList.size(); + + // 初始化相机列表,预分配空间 + m_vrEyeDeviceList.resize(cameraCount, std::make_pair("", nullptr)); + for(int i = 0; i < cameraCount; i++) + { + m_vrEyeDeviceList[i] = std::make_pair(configResult.cameraList[i].name, nullptr); + } m_pStatus->OnCameraCountChanged(cameraCount); - - m_currentCameraIndex = cameraCount > 1 ? 2 : 1; - + if(cameraCount > 0){ if (cameraCount >= 1) { // 尝试打开相机1 LOG_INFO("Attempting to connect to camera 1 with IP: %s\n", configResult.cameraList[0].ip.c_str()); // 发送页面提示信息 - m_pStatus->OnStatusUpdate(QString("正在连接相机一: %1").arg(configResult.cameraList[0].ip.c_str()).toStdString()); + m_pStatus->OnStatusUpdate(QString("正在连接%1: %2").arg(configResult.cameraList[0].name.c_str()).arg(configResult.cameraList[0].ip.c_str()).toStdString()); // 初始化VrEyeDevice模块 IVrEyeDevice* pDevice = nullptr; @@ -139,24 +149,26 @@ int GrabBagPresenter::Init() ERR_CODE_RETURN(nRet); // 再打开设备 - nRet = pDevice->OpenDevice(configResult.cameraList[0].ip.c_str()); + nRet = pDevice->OpenDevice(configResult.cameraList[0].ip.c_str(), ProjectType::DirectBag == m_projectType); // 通过回调更新相机1状态 bool camera1Connected = (SUCCESS == nRet); if(camera1Connected){ - m_vrEyeDeviceList.push_back(pDevice); LOG_INFO("Camera 1 connection successful, IP: %s\n", configResult.cameraList[0].ip.c_str()); - m_pStatus->OnStatusUpdate(QString("相机一连接成功").toStdString()); + m_pStatus->OnStatusUpdate(QString("%1连接成功").arg(configResult.cameraList[0].name.c_str()).toStdString()); } else { LOG_ERROR("Camera 1 connection failed, IP: %s, error code: %d\n", configResult.cameraList[0].ip.c_str(), nRet); - m_pStatus->OnStatusUpdate(QString("相机一连接失败: %1").arg(nRet).toStdString()); + m_pStatus->OnStatusUpdate(QString("%1连接失败: %2").arg(configResult.cameraList[0].name.c_str()).arg(nRet).toStdString()); + delete pDevice; // 释放失败的设备 + pDevice = nullptr; } + m_vrEyeDeviceList[0] = std::make_pair(configResult.cameraList[0].name, pDevice); // 直接存储到索引0 m_pStatus->OnCamera1StatusChanged(camera1Connected); - m_pStatus->OnStatusUpdate(camera1Connected ? "相机一连接成功" : "相机一连接失败"); + m_pStatus->OnStatusUpdate(camera1Connected ? QString("%1连接成功").arg(configResult.cameraList[0].name.c_str()).toStdString() : QString("%1连接失败").arg(configResult.cameraList[0].name.c_str()).toStdString()); m_bCameraConnected = camera1Connected; } else { LOG_WARNING("Camera count is 0, setting camera 1 as disconnected\n"); - m_pStatus->OnStatusUpdate("配置文件中未找到相机配置,设置相机一为离线状态"); + m_pStatus->OnStatusUpdate("配置文件中未找到相机配置,设置相机为离线状态"); m_pStatus->OnCamera1StatusChanged(false); m_bCameraConnected = false; } @@ -172,15 +184,20 @@ int GrabBagPresenter::Init() ERR_CODE_RETURN(nRet); // 尝试打开相机2 - nRet = pDevice->OpenDevice(configResult.cameraList[1].ip.c_str()); + nRet = pDevice->OpenDevice(configResult.cameraList[1].ip.c_str(), ProjectType::DirectBag == m_projectType); // 通过回调更新相机2状态 bool camera2Connected = (SUCCESS == nRet); if(camera2Connected) { - m_vrEyeDeviceList.push_back(pDevice); + LOG_INFO("Camera 2 connection successful, IP: %s\n", configResult.cameraList[1].ip.c_str()); + } else { + LOG_ERROR("Camera 2 connection failed, IP: %s, error code: %d\n", configResult.cameraList[1].ip.c_str(), nRet); + delete pDevice; // 释放失败的设备 + pDevice = nullptr; } + m_vrEyeDeviceList[1] = std::make_pair(configResult.cameraList[1].name, pDevice); // 直接存储到索引1 m_pStatus->OnCamera2StatusChanged(camera2Connected); - m_pStatus->OnStatusUpdate(camera2Connected ? "相机二连接成功" : "相机二连接失败"); + m_pStatus->OnStatusUpdate(camera2Connected ? QString("%1连接成功").arg(configResult.cameraList[1].name.c_str()).toStdString() : QString("%1连接失败").arg(configResult.cameraList[1].name.c_str()).toStdString()); // 只要有一个相机连接成功就认为相机连接正常 if (camera2Connected) { m_bCameraConnected = true; @@ -202,18 +219,32 @@ int GrabBagPresenter::Init() ERR_CODE_RETURN(nRet); // 尝试打开相机1 - nRet = pDevice->OpenDevice(nullptr); + nRet = pDevice->OpenDevice(nullptr, ProjectType::DirectBag == m_projectType); // 通过回调更新相机1状态 bool camera1Connected = (SUCCESS == nRet); if(camera1Connected) { - m_vrEyeDeviceList.push_back(pDevice); + m_vrEyeDeviceList.resize(1); + m_vrEyeDeviceList[0] = std::make_pair("相机", pDevice); // 直接存储到索引0 + } else { + delete pDevice; // 释放失败的设备 } m_pStatus->OnCamera1StatusChanged(camera1Connected); - m_pStatus->OnStatusUpdate(camera1Connected ? "相机一连接成功" : "相机一连接失败"); + m_pStatus->OnStatusUpdate(camera1Connected ? "相机连接成功" : "相机连接失败"); m_bCameraConnected = camera1Connected; } + // 设置默认相机索引为第一个连接的相机 + m_currentCameraIndex = 1; // 默认从1开始 + for (int i = 0; i < static_cast(m_vrEyeDeviceList.size()); i++) { + if (m_vrEyeDeviceList[i].second != nullptr) { + m_currentCameraIndex = i + 1; // 找到第一个连接的相机 + break; + } + } + + LOG_INFO("Camera initialization completed. Connected cameras: %zu, default camera index: %d\n", + m_vrEyeDeviceList.size(), m_currentCameraIndex); // 初始化机械臂协议 nRet = InitRobotProtocol(); @@ -254,7 +285,8 @@ int GrabBagPresenter::Init() // 注册为配置变化监听器 m_pConfigManager->AddConfigChangeListener(std::shared_ptr(this, [](IConfigChangeListener*){})); #endif - m_pStatus->OnStatusUpdate("配置管理器初始化成功"); + QString str = QString("%1 配置初始化成功").arg(ProjectTypeToString(configResult.projectType)); + m_pStatus->OnStatusUpdate(str.toStdString()); LOG_INFO("ConfigManager initialized successfully\n"); return SUCCESS; @@ -571,13 +603,17 @@ bool GrabBagPresenter::OnRobotWorkSignal(bool startWork, int cameraIndex) int nRet = SUCCESS; if (startWork) { - QString message = QString("收到开始工作信号,启动相机 %1 检测").arg(cameraIndex); + QString cameraName = (cameraIndex >= 1 && cameraIndex <= static_cast(m_vrEyeDeviceList.size())) ? + QString::fromStdString(m_vrEyeDeviceList[cameraIndex - 1].first) : QString("相机%1").arg(cameraIndex); + QString message = QString("收到信号,启动%1检测").arg(cameraName); if (nullptr != m_pStatus) { m_pStatus->OnStatusUpdate(message.toStdString()); } nRet = StartDetection(cameraIndex); } else { - QString message = QString("收到停止工作信号,停止相机 %1 检测").arg(cameraIndex); + QString cameraName = (cameraIndex >= 1 && cameraIndex <= static_cast(m_vrEyeDeviceList.size())) ? + QString::fromStdString(m_vrEyeDeviceList[cameraIndex - 1].first) : QString("相机%1").arg(cameraIndex); + QString message = QString("收到信号,停止%1检测").arg(cameraName); if (nullptr != m_pStatus) { m_pStatus->OnStatusUpdate(message.toStdString()); } @@ -638,22 +674,35 @@ int GrabBagPresenter::StartDetection(int cameraIndex, bool isAuto) // 启动指定相机(cameraIndex为相机ID,从1开始编号) int arrayIndex = cameraIndex - 1; // 转换为数组索引(从0开始) + + // 检查相机是否连接 + if (arrayIndex < 0 || arrayIndex >= static_cast(m_vrEyeDeviceList.size()) || + m_vrEyeDeviceList[arrayIndex].second == nullptr) { + LOG_ERROR("Camera %d is not connected\n", cameraIndex); + QString cameraName = (arrayIndex >= 0 && arrayIndex < static_cast(m_vrEyeDeviceList.size())) ? + QString::fromStdString(m_vrEyeDeviceList[arrayIndex].first) : QString("相机%1").arg(cameraIndex); + m_pStatus->OnStatusUpdate(QString("%1 未连接").arg(cameraName).toStdString()); + return ERR_CODE(DEV_NOT_FIND); + } + if (arrayIndex >= 0 && arrayIndex < static_cast(m_vrEyeDeviceList.size())) { // 注册状态 - m_vrEyeDeviceList[arrayIndex]->SetStatusCallback(&GrabBagPresenter::_StaticCameraNotify, this); + m_vrEyeDeviceList[arrayIndex].second->SetStatusCallback(&GrabBagPresenter::_StaticCameraNotify, this); EVzResultDataType eDataType = keResultDataType_Position; if(m_projectType == ProjectType::DirectBag){ eDataType = keResultDataType_PointXYZRGBA; } // 开始 - nRet = m_vrEyeDeviceList[arrayIndex]->StartDetect(&GrabBagPresenter::_StaticDetectionCallback, eDataType, this); + nRet = m_vrEyeDeviceList[arrayIndex].second->StartDetect(&GrabBagPresenter::_StaticDetectionCallback, eDataType, this); LOG_INFO("Camera ID %d start detection nRet: %d\n", cameraIndex, nRet); if (nRet == SUCCESS) { - m_pStatus->OnStatusUpdate(QString("启动相机 %1 检测成功").arg(cameraIndex).toStdString()); + QString cameraName = QString::fromStdString(m_vrEyeDeviceList[arrayIndex].first); + m_pStatus->OnStatusUpdate(QString("启动%1检测成功").arg(cameraName).toStdString()); } else { LOG_ERROR("Camera ID %d start detection failed with error: %d\n", cameraIndex, nRet); - m_pStatus->OnStatusUpdate(QString("启动相机 %1 检测失败").arg(cameraIndex).toStdString()); + QString cameraName = QString::fromStdString(m_vrEyeDeviceList[arrayIndex].first); + m_pStatus->OnStatusUpdate(QString("启动%1检测失败").arg(cameraName).toStdString()); } } else { LOG_ERROR("Invalid camera ID: %d, valid range is 1-%zu\n", cameraIndex, m_vrEyeDeviceList.size()); @@ -670,7 +719,7 @@ int GrabBagPresenter::StopDetection() // 停止所有相机的检测 for (size_t i = 0; i < m_vrEyeDeviceList.size(); ++i) { - IVrEyeDevice* pDevice = m_vrEyeDeviceList[i]; + IVrEyeDevice* pDevice = m_vrEyeDeviceList[i].second; if (pDevice) { int ret = pDevice->StopDetect(); if (ret == 0) { @@ -706,7 +755,7 @@ int GrabBagPresenter::StopDetection() int GrabBagPresenter::LoadDebugDataAndDetect(const std::string& filePath) { LOG_INFO("Loading debug data from file: %s\n", filePath.c_str()); - + m_currentWorkStatus = WorkStatus::Working; if (m_pStatus) { @@ -766,54 +815,11 @@ int GrabBagPresenter::LoadDebugDataAndDetect(const std::string& filePath) return result; } -IVrEyeDevice *GrabBagPresenter::GetEyeDevice(int index) -{ - if(m_vrEyeDeviceList.size() <= index) return nullptr; - return m_vrEyeDeviceList[index]; -} - -// 获取所有相机设备列表 -std::vector GrabBagPresenter::GetCameraList() -{ - return m_vrEyeDeviceList; -} - -// 获取相机数量 -int GrabBagPresenter::GetCameraCount() -{ - return static_cast(m_vrEyeDeviceList.size()); -} - -// 获取相机列表和名称 -void GrabBagPresenter::GetCameraListWithNames(std::vector& cameraList, std::vector& cameraNames) -{ - cameraList.clear(); - cameraNames.clear(); - - for (size_t i = 0; i < m_vrEyeDeviceList.size(); i++) { - if (m_vrEyeDeviceList[i] != nullptr) { - cameraList.push_back(m_vrEyeDeviceList[i]); - cameraNames.push_back(QString("相机 %1").arg(i + 1)); - } - } -} - -// 检查指定索引的相机是否连接 -bool GrabBagPresenter::IsCameraConnected(int index) -{ - if (index < 0 || index >= static_cast(m_vrEyeDeviceList.size())) { - return false; - } - - IVrEyeDevice* pDevice = m_vrEyeDeviceList[index]; - return (pDevice != nullptr); -} - // 为所有相机设置状态回调 void GrabBagPresenter::SetCameraStatusCallback(VzNL_OnNotifyStatusCBEx fNotify, void* param) { for (size_t i = 0; i < m_vrEyeDeviceList.size(); i++) { - IVrEyeDevice* pDevice = m_vrEyeDeviceList[i]; + IVrEyeDevice* pDevice = m_vrEyeDeviceList[i].second; if (pDevice) { pDevice->SetStatusCallback(fNotify, param); LOG_DEBUG("Status callback set for camera %zu\n", i + 1); @@ -923,7 +929,7 @@ void GrabBagPresenter::_DetectionCallback(EVzResultDataType eDataType, SVzLaserL } - if(m_projectType == ProjectType::DirectBag){ + if(keResultDataType_PointXYZRGBA == eDataType){ SVzNLXYZRGBDLaserLine laser3DLine; laser3DLine.nTimeStamp = pLaserLinePoint->llTimeStamp; laser3DLine.nPointCnt = pLaserLinePoint->nPointCount; @@ -932,12 +938,10 @@ void GrabBagPresenter::_DetectionCallback(EVzResultDataType eDataType, SVzLaserL memcpy(laser3DLine.p3DPoint, pLaserLinePoint->p3DPoint, sizeof(SVzNLPointXYZRGBA) * pLaserLinePoint->nPointCount); std::lock_guard lock(m_detectionDataMutex); m_detectionDataCacheRGBD.push_back(laser3DLine); - }else{ + }else if(keResultDataType_Position == eDataType){ // 转换数据格式:从SVzLaserLineData转换为SVzNL3DLaserLine并存储到缓存 SVzNL3DLaserLine laser3DLine; - - // 复制基本信息 laser3DLine.nTimeStamp = pLaserLinePoint->llTimeStamp; laser3DLine.nPositionCnt = pLaserLinePoint->nPointCount; @@ -972,15 +976,18 @@ void GrabBagPresenter::_AlgoDetectThread() return m_currentWorkStatus == WorkStatus::Working; }); + if(!m_bAlgoDetectThreadRunning){ + break; + } + // 检查设备状态是否准备就绪 int nRet = _DetectTask(); + LOG_ERROR("DetectTask result: %d\n", nRet); if(nRet != SUCCESS){ m_currentWorkStatus = WorkStatus::Error; - if(m_pStatus){ - m_pStatus->OnWorkStatusChanged(m_currentWorkStatus); - } } + LOG_DEBUG("Algo Thread end\n"); } } @@ -988,6 +995,7 @@ int GrabBagPresenter::_DetectTask() { LOG_INFO("[Algo Thread] Start real detection task using algorithm\n"); + std::lock_guard lock(m_detectionDataMutex); // 1. 获取缓存的点云数据 if (m_detectionDataCache.empty() && m_detectionDataCacheRGBD.empty()) { LOG_WARNING("No cached detection data available\n"); @@ -1064,7 +1072,6 @@ void GrabBagPresenter::_ClearDetectionDataCache() { std::lock_guard lock(m_detectionDataMutex); - LOG_DEBUG("Clearing detection data cache, current size: %zu\n", m_detectionDataCache.size()); // 释放缓存的内存 for (auto& cachedLine : m_detectionDataCache) { @@ -1073,10 +1080,17 @@ void GrabBagPresenter::_ClearDetectionDataCache() cachedLine.p3DPosition = nullptr; } } + + for (auto& cachedLine : m_detectionDataCacheRGBD) { + if (cachedLine.p3DPoint) { + delete[] cachedLine.p3DPoint; + cachedLine.p3DPoint = nullptr; + } + } // 清空缓存容器 m_detectionDataCache.clear(); - + m_detectionDataCacheRGBD.clear(); LOG_DEBUG("Detection data cache cleared successfully\n"); } @@ -1123,10 +1137,12 @@ void GrabBagPresenter::_SendDetectionResultToRobot(const DetectionResult& detect LOG_INFO("[Robot TCP] SetMultiTargetData result: %d for camera ID: %d\n", result, cameraIndex); if (m_pStatus) { + QString cameraName = (cameraIndex >= 1 && cameraIndex <= static_cast(m_vrEyeDeviceList.size())) ? + QString::fromStdString(m_vrEyeDeviceList[cameraIndex - 1].first) : QString("相机%1").arg(cameraIndex); if (result != SUCCESS) { - m_pStatus->OnStatusUpdate(QString("发送多目标坐标给机械臂(TCP)失败,相机ID: %1").arg(cameraIndex).toStdString()); + m_pStatus->OnStatusUpdate(QString("写坐标给机械臂失败,%1").arg(cameraName).toStdString()); } else { - m_pStatus->OnStatusUpdate(QString("发送多目标坐标给机械臂(TCP)成功,相机ID: %1").arg(cameraIndex).toStdString()); + m_pStatus->OnStatusUpdate(QString("写坐标给机械臂成功,%1").arg(cameraName).toStdString()); } } } else { @@ -1142,10 +1158,12 @@ void GrabBagPresenter::_SendDetectionResultToRobot(const DetectionResult& detect LOG_INFO("[Serial] SendMultiTargetData result: %d for camera ID: %d\n", result, cameraIndex); if (m_pStatus) { + QString cameraName = (cameraIndex >= 1 && cameraIndex <= static_cast(m_vrEyeDeviceList.size())) ? + QString::fromStdString(m_vrEyeDeviceList[cameraIndex - 1].first) : QString("相机%1").arg(cameraIndex); if (result != SUCCESS) { - m_pStatus->OnStatusUpdate(QString("发送多目标坐标给串口失败,相机ID: %1").arg(cameraIndex).toStdString()); + m_pStatus->OnStatusUpdate(QString("写坐标给串口失败,%1").arg(cameraName).toStdString()); } else { - m_pStatus->OnStatusUpdate(QString("发送多目标坐标给串口成功,相机ID: %1").arg(cameraIndex).toStdString()); + m_pStatus->OnStatusUpdate(QString("写坐标给串口成功,%1").arg(cameraName).toStdString()); } } } else { @@ -1246,8 +1264,8 @@ void GrabBagPresenter::OnCameraParamChanged(int cameraIndex, const CameraUIParam // 应用相机参数到实际设备 if (cameraIndex >= 1 && cameraIndex <= static_cast(m_vrEyeDeviceList.size())) { - IVrEyeDevice* device = m_vrEyeDeviceList[cameraIndex - 1]; - if (device && IsCameraConnected(cameraIndex - 1)) { + IVrEyeDevice* device = m_vrEyeDeviceList[cameraIndex - 1].second; + if (device) { // 设置曝光时间 if (cameraParam.exposeTime > 0) { @@ -1309,7 +1327,9 @@ void GrabBagPresenter::OnCameraParamChanged(int cameraIndex, const CameraUIParam } if (m_pStatus) { - m_pStatus->OnStatusUpdate(QString("相机 %1 参数已更新").arg(cameraIndex).toStdString()); + QString cameraName = (cameraIndex >= 1 && cameraIndex <= static_cast(m_vrEyeDeviceList.size())) ? + QString::fromStdString(m_vrEyeDeviceList[cameraIndex - 1].first) : QString("相机%1").arg(cameraIndex); + m_pStatus->OnStatusUpdate(QString("%1参数已更新").arg(cameraName).toStdString()); } } @@ -1326,7 +1346,6 @@ void GrabBagPresenter::OnAlgorithmParamChanged(const VrAlgorithmParams& algorith } } - void GrabBagPresenter::OnSerialConnectionChanged(bool connected) { if (connected) { @@ -1369,4 +1388,30 @@ bool GrabBagPresenter::OnSerialWorkSignal(bool startWork, int cameraIndex) } } +// 设置默认相机索引 +void GrabBagPresenter::SetDefaultCameraIndex(int cameraIndex) +{ + LOG_INFO("Setting default camera index from %d to %d\n", m_currentCameraIndex, cameraIndex); + + // 验证相机索引的有效性(cameraIndex是配置中的索引,从1开始) + if (cameraIndex < 1 || cameraIndex > static_cast(m_vrEyeDeviceList.size())) { + LOG_WARNING("Invalid camera index: %d, valid range: 1-%zu\n", cameraIndex, m_vrEyeDeviceList.size()); + if (m_pStatus) { + m_pStatus->OnStatusUpdate(QString("无效的相机索引: %1,有效范围: 1-%2").arg(cameraIndex).arg(m_vrEyeDeviceList.size()).toStdString()); + } + return; + } + + // 更新默认相机索引 + m_currentCameraIndex = cameraIndex; + + LOG_INFO("Default camera index updated to %d\n", m_currentCameraIndex); + + if (m_pStatus) { + QString cameraName = (cameraIndex >= 1 && cameraIndex <= static_cast(m_vrEyeDeviceList.size())) ? + QString::fromStdString(m_vrEyeDeviceList[cameraIndex - 1].first) : QString("相机%1").arg(cameraIndex); + m_pStatus->OnStatusUpdate(QString("设置%1为默认相机").arg(cameraName).toStdString()); + } +} + diff --git a/GrabBagApp/Utils/Inc/PointCloudImageUtils.h b/GrabBagApp/Utils/Inc/PointCloudImageUtils.h index 38e34d74..93b77d6c 100644 --- a/GrabBagApp/Utils/Inc/PointCloudImageUtils.h +++ b/GrabBagApp/Utils/Inc/PointCloudImageUtils.h @@ -17,6 +17,10 @@ public: static QImage GeneratePointCloudImage(SVzNLXYZRGBDLaserLine* scanData, int lineNum, const std::vector& objOps); + + // 新的点云图像生成函数 - 基于X、Y范围创建图像 + static QImage GeneratePointCloudImage(SVzNLXYZRGBDLaserLine* scanData, + int lineNum); private: // 定义线特征颜色和大小获取函数 diff --git a/GrabBagApp/Utils/Src/LaserDataLoader.cpp b/GrabBagApp/Utils/Src/LaserDataLoader.cpp index 8ef3917d..8550e4c6 100644 --- a/GrabBagApp/Utils/Src/LaserDataLoader.cpp +++ b/GrabBagApp/Utils/Src/LaserDataLoader.cpp @@ -42,7 +42,7 @@ int LaserDataLoader::LoadLaserScanData(const std::string& fileName, &clockPerSecond); if (rawData == nullptr) { - m_lastError = "Failed to read laser scan data from file: " + fileName; + m_lastError = "Failed to laser from file: " + fileName; LOG_ERROR("Failed to load laser scan data from file: %s\n", fileName.c_str()); return ERR_CODE(FILE_ERR_NOEXIST); } @@ -400,7 +400,7 @@ int LaserDataLoader::LoadLaserScanData(const std::string& fileName, &clockPerSecond); if (rawData == nullptr) { - m_lastError = "Failed to read RGBD laser scan data from file: " + fileName; + m_lastError = "Failed to RGBD from file: " + fileName; LOG_ERROR("Failed to load RGBD laser scan data from file: %s\n", fileName.c_str()); return ERR_CODE(FILE_ERR_NOEXIST); } diff --git a/GrabBagApp/Utils/Src/PointCloudImageUtils.cpp b/GrabBagApp/Utils/Src/PointCloudImageUtils.cpp index 21a0298a..ffa297fc 100644 --- a/GrabBagApp/Utils/Src/PointCloudImageUtils.cpp +++ b/GrabBagApp/Utils/Src/PointCloudImageUtils.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "SG_bagPositioning_Export.h" #include "SG_baseDataType.h" #include "VrLog.h" @@ -177,6 +178,83 @@ QImage PointCloudImageUtils::GeneratePointCloudImage(SVzNLXYZRGBDLaserLine* scan return image; } +// 新的点云图像生成函数 - 基于X、Y范围创建图像 +QImage PointCloudImageUtils::GeneratePointCloudImage(SVzNLXYZRGBDLaserLine* scanData, int lineNum) +{ + if (!scanData || lineNum <= 0) { + return QImage(); + } + + // 1. 遍历X, Y的范围,计算最小和最大值 + double xMin = std::numeric_limits::max(); + double xMax = std::numeric_limits::lowest(); + double yMin = std::numeric_limits::max(); + double yMax = std::numeric_limits::lowest(); + + for (int i = 0; i < lineNum; i++) { + if (scanData[i].p3DPoint && scanData[i].nPointCnt > 0) { + for (int j = 0; j < scanData[i].nPointCnt; j++) { + const SVzNLPointXYZRGBA& point = scanData[i].p3DPoint[j]; + + // 更新X范围 + if (point.x < xMin) xMin = point.x; + if (point.x > xMax) xMax = point.x; + + // 更新Y范围 + if (point.y < yMin) yMin = point.y; + if (point.y > yMax) yMax = point.y; + } + } + } + + // 检查范围是否有效 + if (xMin >= xMax || yMin >= yMax) { + return QImage(); + } + + // 2. 根据范围创建图像大小 + // 设置图像分辨率,可以根据需要调整 + const int imageWidth = xMax - xMin; + const int imageHeight = yMax - yMin; + + + // 3. 创建默认黑底图像 + QImage image(imageWidth, imageHeight, QImage::Format_RGB888); + image.fill(Qt::black); + + // 4. 遍历点云数据,将3D X, Y对应的颜色值赋值给图像 + for (int i = 0; i < lineNum; i++) { + if (scanData[i].p3DPoint && scanData[i].nPointCnt > 0) { + for (int j = 0; j < scanData[i].nPointCnt; j++) { + const SVzNLPointXYZRGBA& point = scanData[i].p3DPoint[j]; + + // 将3D坐标转换为图像坐标 + int imageX = static_cast((point.x - xMin)); + int imageY = static_cast((point.y - yMin)); + + // 确保坐标在图像范围内 + if (imageX >= 0 && imageX < imageWidth && + imageY >= 0 && imageY < imageHeight) { + + // 解析RGB颜色 - 参考_RGBDto2DImage函数的解析方式 + int nRGB = point.nRGB; + int r = nRGB & 0xff; + nRGB >>= 8; + int g = nRGB & 0xff; + nRGB >>= 8; + int b = nRGB & 0xff; + + QColor pointColor(r, g, b); + // 设置图像像素颜色 + image.setPixel(imageX, imageY, pointColor.rgb()); + } + } + } + } + + return image; +} + void PointCloudImageUtils::GetLineFeatureStyle(int vType, int hType, int objId, QColor& pointColor, int& pointSize) { @@ -438,4 +516,4 @@ void PointCloudImageUtils::DrawDetectionTargets(QPainter& painter, painter.drawText(px + 15, py - 10, QString("%1").arg(i + 1)); } } -} \ No newline at end of file +} diff --git a/GrabBagApp/Version.h b/GrabBagApp/Version.h index 5bd759fe..779f980c 100644 --- a/GrabBagApp/Version.h +++ b/GrabBagApp/Version.h @@ -3,8 +3,8 @@ #define GRABBAG_VERSION_STRING "1.1.0" -#define GRABBAG_BUILD_STRING "0" -#define GRABBAG_FULL_VERSION_STRING "V1.1.0_0" +#define GRABBAG_BUILD_STRING "1" +#define GRABBAG_FULL_VERSION_STRING "V1.1.0_1" // 获取版本信息的便捷函数 inline const char* GetGrabBagVersion() { diff --git a/GrabBagApp/devstatus.cpp b/GrabBagApp/devstatus.cpp index 6e0ee4bf..cdc9065b 100644 --- a/GrabBagApp/devstatus.cpp +++ b/GrabBagApp/devstatus.cpp @@ -7,6 +7,9 @@ devstatus::devstatus(QWidget *parent) : QWidget(parent) , ui(new Ui::devstatus) + , m_selectedCameraIndex(0) + , m_camera1Name("") + , m_camera2Name("") { ui->setupUi(this); @@ -16,6 +19,9 @@ devstatus::devstatus(QWidget *parent) // 初始化时设置样式 setItemStyle(); + // 初始化点击事件 + initClickEvents(); + // 初始化设备状态(离线状态) updateCamera1Status(false); updateCamera2Status(false); @@ -58,24 +64,66 @@ void devstatus::setRobotStatusImage(QWidget* widget, bool isOnline) { // widget->setFixedSize(32, 32); // 调整大小以适应图片 } +// 设置相机1名称 +void devstatus::setCamera1Name(const QString& name) +{ + m_camera1Name = name; + // 如果相机1已经初始化过状态,则更新显示文本 + if (ui->dev_camera_1_txt) { + updateCamera1DisplayText(ui->dev_camera_1_txt->text().contains("在线")); + } +} + +// 设置相机2名称 +void devstatus::setCamera2Name(const QString& name) +{ + m_camera2Name = name; + // 如果相机2已经初始化过状态,则更新显示文本 + if (ui->dev_camera_2_txt) { + updateCamera2DisplayText(ui->dev_camera_2_txt->text().contains("在线")); + } +} + // 更新相机1状态 void devstatus::updateCamera1Status(bool isConnected) { setCameraStatusImage(ui->dev_camer_1_img, isConnected); - - QString statusText = isConnected ? "相机1在线" : "相机1离线"; - QString colorStyle = isConnected ? "color: rgb(140, 180, 60);" : "color: rgb(220, 60, 60);"; - - ui->dev_camera_1_txt->setText(statusText); - ui->dev_camera_1_txt->setStyleSheet(colorStyle); + updateCamera1DisplayText(isConnected); } // 更新相机2状态 void devstatus::updateCamera2Status(bool isConnected) { setCameraStatusImage(ui->dev_camer_2_img, isConnected); + updateCamera2DisplayText(isConnected); +} + +// 更新相机1显示文本的私有方法 +void devstatus::updateCamera1DisplayText(bool isConnected) +{ + QString statusText; + if (m_camera1Name.isEmpty()) { + statusText = isConnected ? "相机1在线" : "相机1离线"; + } else { + statusText = isConnected ? QString("%1在线").arg(m_camera1Name) : QString("%1离线").arg(m_camera1Name); + } + + QString colorStyle = isConnected ? "color: rgb(140, 180, 60);" : "color: rgb(220, 60, 60);"; + + ui->dev_camera_1_txt->setText(statusText); + ui->dev_camera_1_txt->setStyleSheet(colorStyle); +} + +// 更新相机2显示文本的私有方法 +void devstatus::updateCamera2DisplayText(bool isConnected) +{ + QString statusText; + if (m_camera2Name.isEmpty()) { + statusText = isConnected ? "相机2在线" : "相机2离线"; + } else { + statusText = isConnected ? QString("%1在线").arg(m_camera2Name) : QString("%1离线").arg(m_camera2Name); + } - QString statusText = isConnected ? "相机2在线" : "相机2离线"; QString colorStyle = isConnected ? "color: rgb(140, 180, 60);" : "color: rgb(220, 60, 60);"; ui->dev_camera_2_txt->setText(statusText); @@ -200,3 +248,80 @@ void devstatus::adjustFramesForSingleCameraHorizontalLayout() ui->frame_robot->setGeometry(frameWidth + spacing, 0, frameWidth, frameHeight); } } + +// 初始化点击事件 +void devstatus::initClickEvents() +{ + // 为相机1的frame添加点击事件 + if (ui->frame_camera_1) { + ui->frame_camera_1->installEventFilter(this); + ui->frame_camera_1->setMouseTracking(true); + ui->frame_camera_1->setCursor(Qt::PointingHandCursor); // 设置鼠标样式为手型 + } + + // 为相机2的frame添加点击事件 + if (ui->frame_camera_2) { + ui->frame_camera_2->installEventFilter(this); + ui->frame_camera_2->setMouseTracking(true); + ui->frame_camera_2->setCursor(Qt::PointingHandCursor); // 设置鼠标样式为手型 + } +} + +// 事件过滤器,处理鼠标点击事件 +bool devstatus::eventFilter(QObject *obj, QEvent *event) +{ + if (event->type() == QEvent::MouseButtonPress) { + QMouseEvent *mouseEvent = static_cast(event); + if (mouseEvent->button() == Qt::LeftButton) { + if (obj == ui->frame_camera_1) { + onCamera1Clicked(); + return true; + } else if (obj == ui->frame_camera_2) { + onCamera2Clicked(); + return true; + } + } + } + return QWidget::eventFilter(obj, event); +} + +// 相机1点击槽函数 +void devstatus::onCamera1Clicked() +{ + if (m_selectedCameraIndex != 1) { + m_selectedCameraIndex = 1; + setCameraSelectedStyle(1); + emit cameraClicked(1); + } +} + +// 相机2点击槽函数 +void devstatus::onCamera2Clicked() +{ + if (m_selectedCameraIndex != 2) { + m_selectedCameraIndex = 2; + setCameraSelectedStyle(2); + emit cameraClicked(2); + } +} + +// 设置相机选中状态的样式 +void devstatus::setCameraSelectedStyle(int cameraIndex) +{ + // 重置所有相机的样式 + if (ui->frame_camera_1) { + ui->frame_camera_1->setStyleSheet("background-color: rgb(37, 38, 42);"); + } + if (ui->frame_camera_2) { + ui->frame_camera_2->setStyleSheet("background-color: rgb(37, 38, 42);"); + } + + // 设置选中相机的样式 + QString selectedStyle = "QFrame { background-color: rgb(67, 68, 72);}"; + + if (cameraIndex == 1 && ui->frame_camera_1) { + ui->frame_camera_1->setStyleSheet(selectedStyle); + } else if (cameraIndex == 2 && ui->frame_camera_2) { + ui->frame_camera_2->setStyleSheet(selectedStyle); + } +} diff --git a/GrabBagApp/devstatus.h b/GrabBagApp/devstatus.h index 904a6fbe..0633b8ec 100644 --- a/GrabBagApp/devstatus.h +++ b/GrabBagApp/devstatus.h @@ -5,6 +5,10 @@ #include #include #include +#include +#include +#include +#include namespace Ui { class devstatus; @@ -24,12 +28,35 @@ public: void updateRobotStatus(bool isConnected); void updateSerialStatus(bool isConnected); + // 设置相机名称方法 + void setCamera1Name(const QString& name); + void setCamera2Name(const QString& name); + // 设置相机数量(用于控制相机二的显示和布局方向) void setCameraCount(int cameraCount); + + // 事件过滤器 + bool eventFilter(QObject *obj, QEvent *event) override; + +signals: + // 相机点击信号 + void cameraClicked(int cameraIndex); + +private slots: + // 相机点击槽函数 + void onCamera1Clicked(); + void onCamera2Clicked(); private: Ui::devstatus *ui; + // 当前选中的相机索引 + int m_selectedCameraIndex; + + // 相机名称 + QString m_camera1Name; + QString m_camera2Name; + // 设置状态图片的私有成员函数 void setCameraStatusImage(QWidget* widget, bool isOnline); void setRobotStatusImage(QWidget* widget, bool isOnline); @@ -37,11 +64,21 @@ private: // 设置样式的私有成员函数 void setItemStyle(); + // 设置相机选中状态的样式 + void setCameraSelectedStyle(int cameraIndex); + // 布局管理的私有成员函数 void setVerticalLayout(); void setHorizontalLayoutForSingleCamera(); void adjustFramesForVerticalLayout(); void adjustFramesForSingleCameraHorizontalLayout(); + + // 初始化点击事件 + void initClickEvents(); + + // 更新相机显示文本的私有方法 + void updateCamera1DisplayText(bool isConnected); + void updateCamera2DisplayText(bool isConnected); }; #endif // DEVSTATUS_H diff --git a/GrabBagApp/dialogcamera.cpp b/GrabBagApp/dialogcamera.cpp index 395c0708..f314509e 100644 --- a/GrabBagApp/dialogcamera.cpp +++ b/GrabBagApp/dialogcamera.cpp @@ -4,13 +4,11 @@ #include "VrLog.h" #include "StyledMessageBox.h" -DialogCamera::DialogCamera(const std::vector& deviceList, - const std::vector& cameraNames, +DialogCamera::DialogCamera(const std::vector>& deviceList, QWidget *parent) : QDialog(parent), ui(new Ui::DialogCamera), - m_deviceList(deviceList), - m_cameraNames(cameraNames) + m_deviceList(deviceList) { ui->setupUi(this); @@ -27,7 +25,7 @@ DialogCamera::DialogCamera(const std::vector& deviceList, // 设置默认选择第一个相机 m_currentCameraIndex = 0; - m_currentDevice = m_deviceList[0]; + m_currentDevice = m_deviceList[0].second; // 连接ComboBox的信号槽 connect(ui->combo_camera, QOverload::of(&QComboBox::currentIndexChanged), @@ -48,24 +46,21 @@ void DialogCamera::InitCameraComboBox() ui->combo_camera->clear(); // 添加相机选项 - for (size_t i = 0; i < m_cameraNames.size(); ++i) { - ui->combo_camera->addItem(m_cameraNames[i]); + for (size_t i = 0; i < m_deviceList.size(); ++i) { + ui->combo_camera->addItem(QString::fromStdString(m_deviceList[i].first)); } // 默认选择第一个 - if (!m_cameraNames.empty()) { + if (!m_deviceList.empty()) { ui->combo_camera->setCurrentIndex(0); } - - // 设置ComboBox样式 - ui->combo_camera->setStyleSheet("QComboBox { font-size: 18pt; color: white; }"); } void DialogCamera::on_camera_selection_changed(int index) { if (index >= 0 && index < static_cast(m_deviceList.size())) { m_currentCameraIndex = index; - m_currentDevice = m_deviceList[index]; + m_currentDevice = m_deviceList[index].second; // 重新加载当前选择相机的参数 InitCameraParameters(); diff --git a/GrabBagApp/dialogcamera.h b/GrabBagApp/dialogcamera.h index 7bbfdc58..51d6f382 100644 --- a/GrabBagApp/dialogcamera.h +++ b/GrabBagApp/dialogcamera.h @@ -16,8 +16,7 @@ class DialogCamera : public QDialog public: // 支持多相机的构造函数 - explicit DialogCamera(const std::vector& deviceList, - const std::vector& cameraNames, + explicit DialogCamera(const std::vector>& deviceList, QWidget *parent = nullptr); ~DialogCamera(); @@ -38,8 +37,7 @@ private: private: Ui::DialogCamera *ui; - std::vector m_deviceList; // 相机设备列表 - std::vector m_cameraNames; // 相机名称列表 + std::vector> m_deviceList; // 相机设备列表 IVrEyeDevice* m_currentDevice = nullptr; // 当前选择的相机设备 int m_currentCameraIndex = 0; // 当前选择的相机索引 }; diff --git a/GrabBagApp/dialogcamera.ui b/GrabBagApp/dialogcamera.ui index 52c65b21..b038a276 100644 --- a/GrabBagApp/dialogcamera.ui +++ b/GrabBagApp/dialogcamera.ui @@ -19,7 +19,7 @@ - 30 + 50 10 491 41 @@ -371,12 +371,17 @@ background-color: rgb(47, 48, 52); - 30 + 50 60 211 41 + + + 16 + + color: rgb(221, 225, 233); selection-color: rgb(255, 255, 255); diff --git a/GrabBagApp/dialogcameralevel.cpp b/GrabBagApp/dialogcameralevel.cpp index 720ce3f4..c84bfade 100644 --- a/GrabBagApp/dialogcameralevel.cpp +++ b/GrabBagApp/dialogcameralevel.cpp @@ -46,12 +46,10 @@ DialogCameraLevel::~DialogCameraLevel() delete ui; } -void DialogCameraLevel::setCameraList(const std::vector& cameraList, - const std::vector& cameraNames, +void DialogCameraLevel::setCameraList(const std::vector>& cameraList, GrabBagPresenter* presenter) { m_cameraList = cameraList; - m_cameraNames = cameraNames; m_presenter = presenter; // 重新初始化相机选择框 @@ -62,13 +60,13 @@ void DialogCameraLevel::initializeCameraCombo() { ui->combo_camera->clear(); - if (m_cameraNames.empty()) { + if (m_cameraList.empty()) { ui->combo_camera->setEnabled(false); ui->label_level_result->setText("无可用相机设备"); ui->label_level_result->setAlignment(Qt::AlignCenter); } else { - for (const auto& name : m_cameraNames) { - ui->combo_camera->addItem(name); + for (const auto& camera : m_cameraList) { + ui->combo_camera->addItem(QString::fromStdString(camera.first)); } ui->combo_camera->setEnabled(true); @@ -220,8 +218,8 @@ bool DialogCameraLevel::performCameraLeveling() cameraName = QString("Camera_%1").arg(cameraIndex); #else // 正常模式下从列表获取名称 - if (selectedIndex >= 0 && selectedIndex < m_cameraNames.size()) { - cameraName = m_cameraNames[selectedIndex]; + if (selectedIndex >= 0 && selectedIndex < m_cameraList.size()) { + cameraName = QString::fromStdString(m_cameraList[selectedIndex].first); } else { cameraName = QString("Camera_%1").arg(cameraIndex); } @@ -290,7 +288,7 @@ bool DialogCameraLevel::startCameraScan(int cameraIndex) return false; } - IVrEyeDevice* camera = m_cameraList[cameraIndex]; + IVrEyeDevice* camera = m_cameraList[cameraIndex].second; if (!camera) { LOG_ERROR("Camera device is null at index: %d\n", cameraIndex); return false; @@ -315,7 +313,7 @@ bool DialogCameraLevel::stopCameraScan(int cameraIndex) return false; } - IVrEyeDevice* camera = m_cameraList[cameraIndex]; + IVrEyeDevice* camera = m_cameraList[cameraIndex].second; if (!camera) { LOG_ERROR("Camera device is null at index: %d\n", cameraIndex); return false; @@ -708,8 +706,9 @@ void DialogCameraLevel::simulateScanProcess() // 相机选择改变的槽函数 void DialogCameraLevel::on_combo_camera_currentIndexChanged(int index) { - if (index >= 0 && index < m_cameraNames.size()) { - LOG_INFO("Camera selection changed to index: %d (%s)\n", index, m_cameraNames[index].toUtf8().constData()); + if (index >= 0 && index < m_cameraList.size()) { + LOG_INFO("Camera selection changed to index: %d (%s)\n", index, + QString::fromStdString(m_cameraList[index].first).toUtf8().constData()); checkAndDisplayCalibrationStatus(index); } else { LOG_WARNING("Invalid camera index selected: %d\n", index); @@ -768,14 +767,14 @@ bool DialogCameraLevel::loadCameraCalibrationData(int cameraIndex, const QString // 检查并显示相机标定状态 void DialogCameraLevel::checkAndDisplayCalibrationStatus(int cameraIndex) { - if (cameraIndex < 0 || cameraIndex >= m_cameraNames.size()) { + if (cameraIndex < 0 || cameraIndex >= m_cameraList.size()) { LOG_WARNING("Invalid camera index for status check: %d\n", cameraIndex); ui->label_level_result->setText("无效的相机索引"); ui->label_level_result->setAlignment(Qt::AlignCenter); return; } - QString cameraName = m_cameraNames[cameraIndex]; + QString cameraName = QString::fromStdString(m_cameraList[cameraIndex].first); int configCameraIndex = cameraIndex + 1; // 转换为1-based索引 // 尝试加载该相机的标定数据 diff --git a/GrabBagApp/dialogcameralevel.h b/GrabBagApp/dialogcameralevel.h index 5993ae06..5aae68e4 100644 --- a/GrabBagApp/dialogcameralevel.h +++ b/GrabBagApp/dialogcameralevel.h @@ -29,7 +29,7 @@ public: ~DialogCameraLevel(); // 设置相机列表和presenter - void setCameraList(const std::vector& cameraList, const std::vector& cameraNames, + void setCameraList(const std::vector>& cameraList, GrabBagPresenter* presenter); private slots: @@ -41,8 +41,7 @@ private: Ui::DialogCameraLevel *ui; // 相机列表和名称 - std::vector m_cameraList; - std::vector m_cameraNames; + std::vector> m_cameraList; GrabBagPresenter* m_presenter = nullptr; // 扫描数据缓存 diff --git a/GrabBagApp/dialogcameralevel.ui b/GrabBagApp/dialogcameralevel.ui index e8dca123..f5d74d1f 100644 --- a/GrabBagApp/dialogcameralevel.ui +++ b/GrabBagApp/dialogcameralevel.ui @@ -114,7 +114,7 @@ - 9 + 16 diff --git a/GrabBagApp/mainwindow.cpp b/GrabBagApp/mainwindow.cpp index 96f93131..4695c719 100644 --- a/GrabBagApp/mainwindow.cpp +++ b/GrabBagApp/mainwindow.cpp @@ -76,8 +76,6 @@ MainWindow::MainWindow(QWidget *parent) // 初始化日志模型 m_logModel = new QStringListModel(this); ui->detect_log->setModel(m_logModel); - - // 原有的状态指示器已删除,状态显示统一在devstatus中处理 // 注册自定义类型,使其能够在信号槽中跨线程传递 qRegisterMetaType("DetectionResult"); @@ -139,11 +137,16 @@ void MainWindow::Init() m_deviceStatusWidget = new devstatus(); //因为初始化回调的数据要存储,所以要在init前创建好 + // 连接devstatus的相机点击信号到MainWindow的槽函数 + connect(m_deviceStatusWidget, SIGNAL(cameraClicked(int)), + this, SLOT(onCameraClicked(int))); + // 将设备状态widget添加到frame_dev中 QVBoxLayout* frameDevLayout = new QVBoxLayout(ui->frame_dev); frameDevLayout->setContentsMargins(0, 0, 0, 0); frameDevLayout->addWidget(m_deviceStatusWidget); + // 设置列表视图模式 ui->detect_result_list->setViewMode(QListView::IconMode); ui->detect_result_list->setResizeMode(QListView::Adjust); @@ -302,6 +305,19 @@ void MainWindow::OnCameraCountChanged(int cameraCount) // 设置设备状态widget中的相机数量 if (m_deviceStatusWidget) { m_deviceStatusWidget->setCameraCount(cameraCount); + + // 设置相机名称(从配置文件中读取) + if (m_presenter) { + const auto& cameraList = m_presenter->GetCameraList(); + if (cameraList.size() >= 1) { + QString camera1Name = QString::fromStdString(cameraList[0].first); + m_deviceStatusWidget->setCamera1Name(camera1Name); + } + if (cameraList.size() >= 2) { + QString camera2Name = QString::fromStdString(cameraList[1].first); + m_deviceStatusWidget->setCamera2Name(camera2Name); + } + } } // 根据相机个数调整页面布局 @@ -482,15 +498,10 @@ void MainWindow::on_btn_camera_clicked() setButtonSelectedState(ui->btn_camera, true); // 使用新的相机列表获取功能 - std::vector availableCameras; - std::vector cameraNames; - - // 获取相机列表和名称 - m_presenter->GetCameraListWithNames(availableCameras, cameraNames); // 如果对话框不存在,创建新的DialogCamera if (nullptr == ui_dialogCamera) { - ui_dialogCamera = new DialogCamera(availableCameras, cameraNames, this); + ui_dialogCamera = new DialogCamera(m_presenter->GetCameraList(), this); // 连接对话框关闭信号 connect(ui_dialogCamera, &QDialog::finished, this, [this]() { @@ -570,13 +581,8 @@ void MainWindow::on_btn_camera_levelling_clicked() }); } - // 获取相机列表和名称 - std::vector availableCameras; - std::vector cameraNames; - m_presenter->GetCameraListWithNames(availableCameras, cameraNames); - // 设置相机列表和presenter到对话框 - ui_dialogCameraLevel->setCameraList(availableCameras, cameraNames, m_presenter); + ui_dialogCameraLevel->setCameraList(m_presenter->GetCameraList(), m_presenter); ui_dialogCameraLevel->show(); } @@ -636,7 +642,7 @@ void MainWindow::on_btn_test_clicked() if (result == 0) { updateStatusLog(tr("调试数据加载和检测成功")); } else { - QString errorMsg = tr("调试数据加载失败,错误码: %1").arg(result); + QString errorMsg = tr("调试数据复检失败: %1").arg(result); updateStatusLog(errorMsg); } @@ -817,3 +823,11 @@ void MainWindow::setupMultiCameraLayout() updateStatusLog(tr("页面布局已调整为多相机模式")); } +// 处理相机点击事件 +void MainWindow::onCameraClicked(int cameraIndex) +{ + if (m_presenter) { + m_presenter->SetDefaultCameraIndex(cameraIndex); + } +} + diff --git a/GrabBagApp/mainwindow.h b/GrabBagApp/mainwindow.h index 7fd61075..8f298dec 100644 --- a/GrabBagApp/mainwindow.h +++ b/GrabBagApp/mainwindow.h @@ -67,6 +67,9 @@ private slots: // 清空日志槽函数 void clearDetectionLogUI(); + + // 处理相机点击事件 + void onCameraClicked(int cameraIndex); // UI操作相关槽 void on_btn_start_clicked(); diff --git a/VrEyeDevice/Inc/IVrEyeDevice.h b/VrEyeDevice/Inc/IVrEyeDevice.h index 67148dae..6c60c7af 100644 --- a/VrEyeDevice/Inc/IVrEyeDevice.h +++ b/VrEyeDevice/Inc/IVrEyeDevice.h @@ -26,7 +26,7 @@ public: /** * Open设备 */ - virtual int OpenDevice(const char* sIP) = 0; + virtual int OpenDevice(const char* sIP, bool bRGBD = false) = 0; /** * 获取版本信息 diff --git a/VrEyeDevice/Src/VrEyeDevice.cpp b/VrEyeDevice/Src/VrEyeDevice.cpp index bbb70064..3b56d949 100644 --- a/VrEyeDevice/Src/VrEyeDevice.cpp +++ b/VrEyeDevice/Src/VrEyeDevice.cpp @@ -31,7 +31,7 @@ int CVrEyeDevice::SetStatusCallback(VzNL_OnNotifyStatusCBEx fNotify, void *param return SUCCESS; } -int CVrEyeDevice::OpenDevice(const char* sIP) +int CVrEyeDevice::OpenDevice(const char* sIP, bool bRGBD) { int nErrCode = SUCCESS; // 搜索设备 @@ -110,9 +110,9 @@ int CVrEyeDevice::OpenDevice(const char* sIP) LOG_DEBUG("SenddataLen ret : %d\n", nnnRet); -#if 0 //启用RGBD - VzNL_EnableRGB(m_pHandle, VzTrue); + VzNL_EnableRGB(m_pHandle, bRGBD ? VzTrue : VzFalse); +#if 0 float exposeThres = VzNL_GetRGBAutoExposeThres(m_pHandle, &nnnRet); //白平衡 @@ -170,6 +170,7 @@ int CVrEyeDevice::StartDetect(VzNL_AutoOutputLaserLineExCB fCallFunc, EVzResultD { int nErrCode = SUCCESS; if(!m_pHandle) return ERRCODE(DEV_NO_OPEN); + LOG_DEBUG("StartDetect eDataType: %d\n", eDataType); nErrCode = VzNL_StartAutoDetectEx(m_pHandle, eDataType, keFlipType_None, fCallFunc, param); return nErrCode; } diff --git a/VrEyeDevice/_Inc/VrEyeDevice.h b/VrEyeDevice/_Inc/VrEyeDevice.h index aea54c78..0b7ddcb9 100644 --- a/VrEyeDevice/_Inc/VrEyeDevice.h +++ b/VrEyeDevice/_Inc/VrEyeDevice.h @@ -30,7 +30,7 @@ public: /** * Open设备 */ - int OpenDevice(const char* sIP) override; + int OpenDevice(const char* sIP, bool bRGBD = false) override; /** * 获取版本信息