增加相机选择;相机名称修改为配置文件中的名字;修复如果相机1打开失败,相机打开成功 序号错误问题

This commit is contained in:
yiyi 2025-07-26 01:10:21 +08:00
parent da33aa0b2a
commit 4fcf1cd20a
20 changed files with 475 additions and 171 deletions

View File

@ -39,20 +39,21 @@ public:
// 加载调试数据进行检测
int LoadDebugDataAndDetect(const std::string& filePath);
IVrEyeDevice* GetEyeDevice(int index);
// 相机列表管理相关函数
std::vector<IVrEyeDevice*> GetCameraList();
int GetCameraCount();
void GetCameraListWithNames(std::vector<IVrEyeDevice*>& cameraList, std::vector<QString>& 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<std::pair<std::string, IVrEyeDevice*>> GetCameraList() const { return m_vrEyeDeviceList; } // 返回相机列表,包括IP地址和设备指针
// 手眼标定矩阵管理
const CalibMatrix GetClibMatrix(int index) const;
@ -115,7 +116,7 @@ private:
private:
IVrConfig* m_vrConfig = nullptr;
std::vector<IVrEyeDevice*> m_vrEyeDeviceList;
std::vector<std::pair<std::string, IVrEyeDevice*>> m_vrEyeDeviceList;
IYGrabBagStatus* m_pStatus = nullptr;
DetectPresenter* m_pDetectPresenter = nullptr;
@ -134,9 +135,8 @@ private:
std::condition_variable m_algoDetectCondition;
// 检测数据缓存 - 直接存储算法格式数据
std::vector<SVzNL3DLaserLine> m_detectionDataCache;
std::mutex m_detectionDataMutex;
std::mutex m_detectionDataMutex;
std::vector<SVzNL3DLaserLine> m_detectionDataCache;
std::vector<SVzNLXYZRGBDLaserLine> m_detectionDataCacheRGBD;
// 算法参数成员变量

View File

@ -171,8 +171,9 @@ int DetectPresenter::DetectBag(std::vector<SVzNLXYZRGBDLaserLine>& detectionData
}
// 从点云数据生成投影图像
detectionResult.image = PointCloudImageUtils::GeneratePointCloudImage(static_cast<SVzNLXYZRGBDLaserLine*>(detectionDataCache.data()),
detectionDataCache.size(), objOps);
detectionResult.image = PointCloudImageUtils::GeneratePointCloudImage(
static_cast<SVzNLXYZRGBDLaserLine*>(detectionDataCache.data()),
detectionDataCache.size(), objOps);
// 转换检测结果为UI显示格式(使用机械臂坐标系数据)
for (size_t i = 0; i < objOps.size(); i++) {

View File

@ -12,6 +12,7 @@
#include <QImage>
#include <QThread>
#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<int>(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<IConfigChangeListener>(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<int>(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<int>(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<int>(m_vrEyeDeviceList.size()) ||
m_vrEyeDeviceList[arrayIndex].second == nullptr) {
LOG_ERROR("Camera %d is not connected\n", cameraIndex);
QString cameraName = (arrayIndex >= 0 && arrayIndex < static_cast<int>(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<int>(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<IVrEyeDevice*> GrabBagPresenter::GetCameraList()
{
return m_vrEyeDeviceList;
}
// 获取相机数量
int GrabBagPresenter::GetCameraCount()
{
return static_cast<int>(m_vrEyeDeviceList.size());
}
// 获取相机列表和名称
void GrabBagPresenter::GetCameraListWithNames(std::vector<IVrEyeDevice*>& cameraList, std::vector<QString>& 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<int>(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<std::mutex> 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<std::mutex> 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<std::mutex> 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<int>(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<int>(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<int>(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<int>(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<int>(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<int>(m_vrEyeDeviceList.size())) ?
QString::fromStdString(m_vrEyeDeviceList[cameraIndex - 1].first) : QString("相机%1").arg(cameraIndex);
m_pStatus->OnStatusUpdate(QString("设置%1为默认相机").arg(cameraName).toStdString());
}
}

View File

@ -17,6 +17,10 @@ public:
static QImage GeneratePointCloudImage(SVzNLXYZRGBDLaserLine* scanData,
int lineNum,
const std::vector<SSG_peakOrienRgnInfo>& objOps);
// 新的点云图像生成函数 - 基于X、Y范围创建图像
static QImage GeneratePointCloudImage(SVzNLXYZRGBDLaserLine* scanData,
int lineNum);
private:
// 定义线特征颜色和大小获取函数

View File

@ -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);
}

View File

@ -2,6 +2,7 @@
#include <QPainter>
#include <cmath>
#include <algorithm>
#include <limits>
#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<double>::max();
double xMax = std::numeric_limits<double>::lowest();
double yMin = std::numeric_limits<double>::max();
double yMax = std::numeric_limits<double>::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<int>((point.x - xMin));
int imageY = static_cast<int>((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));
}
}
}
}

View File

@ -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() {

View File

@ -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<QMouseEvent*>(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);
}
}

View File

@ -5,6 +5,10 @@
#include <QLabel>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QEvent>
#include <QMouseEvent>
#include <QObject>
#include <QString>
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

View File

@ -4,13 +4,11 @@
#include "VrLog.h"
#include "StyledMessageBox.h"
DialogCamera::DialogCamera(const std::vector<IVrEyeDevice*>& deviceList,
const std::vector<QString>& cameraNames,
DialogCamera::DialogCamera(const std::vector<std::pair<std::string, IVrEyeDevice*>>& 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<IVrEyeDevice*>& deviceList,
// 设置默认选择第一个相机
m_currentCameraIndex = 0;
m_currentDevice = m_deviceList[0];
m_currentDevice = m_deviceList[0].second;
// 连接ComboBox的信号槽
connect(ui->combo_camera, QOverload<int>::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<int>(m_deviceList.size())) {
m_currentCameraIndex = index;
m_currentDevice = m_deviceList[index];
m_currentDevice = m_deviceList[index].second;
// 重新加载当前选择相机的参数
InitCameraParameters();

View File

@ -16,8 +16,7 @@ class DialogCamera : public QDialog
public:
// 支持多相机的构造函数
explicit DialogCamera(const std::vector<IVrEyeDevice*>& deviceList,
const std::vector<QString>& cameraNames,
explicit DialogCamera(const std::vector<std::pair<std::string, IVrEyeDevice*>>& deviceList,
QWidget *parent = nullptr);
~DialogCamera();
@ -38,8 +37,7 @@ private:
private:
Ui::DialogCamera *ui;
std::vector<IVrEyeDevice*> m_deviceList; // 相机设备列表
std::vector<QString> m_cameraNames; // 相机名称列表
std::vector<std::pair<std::string, IVrEyeDevice*>> m_deviceList; // 相机设备列表
IVrEyeDevice* m_currentDevice = nullptr; // 当前选择的相机设备
int m_currentCameraIndex = 0; // 当前选择的相机索引
};

View File

@ -19,7 +19,7 @@
<widget class="QLabel" name="label_camera_title">
<property name="geometry">
<rect>
<x>30</x>
<x>50</x>
<y>10</y>
<width>491</width>
<height>41</height>
@ -371,12 +371,17 @@ background-color: rgb(47, 48, 52);</string>
<widget class="QComboBox" name="combo_camera">
<property name="geometry">
<rect>
<x>30</x>
<x>50</x>
<y>60</y>
<width>211</width>
<height>41</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>16</pointsize>
</font>
</property>
<property name="styleSheet">
<string notr="true">color: rgb(221, 225, 233);
selection-color: rgb(255, 255, 255);

View File

@ -46,12 +46,10 @@ DialogCameraLevel::~DialogCameraLevel()
delete ui;
}
void DialogCameraLevel::setCameraList(const std::vector<IVrEyeDevice*>& cameraList,
const std::vector<QString>& cameraNames,
void DialogCameraLevel::setCameraList(const std::vector<std::pair<std::string, IVrEyeDevice*>>& 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索引
// 尝试加载该相机的标定数据

View File

@ -29,7 +29,7 @@ public:
~DialogCameraLevel();
// 设置相机列表和presenter
void setCameraList(const std::vector<IVrEyeDevice*>& cameraList, const std::vector<QString>& cameraNames,
void setCameraList(const std::vector<std::pair<std::string, IVrEyeDevice*>>& cameraList,
GrabBagPresenter* presenter);
private slots:
@ -41,8 +41,7 @@ private:
Ui::DialogCameraLevel *ui;
// 相机列表和名称
std::vector<IVrEyeDevice*> m_cameraList;
std::vector<QString> m_cameraNames;
std::vector<std::pair<std::string, IVrEyeDevice*>> m_cameraList;
GrabBagPresenter* m_presenter = nullptr;
// 扫描数据缓存

View File

@ -114,7 +114,7 @@
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
<pointsize>16</pointsize>
</font>
</property>
<property name="styleSheet">

View File

@ -76,8 +76,6 @@ MainWindow::MainWindow(QWidget *parent)
// 初始化日志模型
m_logModel = new QStringListModel(this);
ui->detect_log->setModel(m_logModel);
// 原有的状态指示器已删除,状态显示统一在devstatus中处理
// 注册自定义类型,使其能够在信号槽中跨线程传递
qRegisterMetaType<DetectionResult>("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<IVrEyeDevice*> availableCameras;
std::vector<QString> 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<IVrEyeDevice*> availableCameras;
std::vector<QString> 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);
}
}

View File

@ -67,6 +67,9 @@ private slots:
// 清空日志槽函数
void clearDetectionLogUI();
// 处理相机点击事件
void onCameraClicked(int cameraIndex);
// UI操作相关槽
void on_btn_start_clicked();

View File

@ -26,7 +26,7 @@ public:
/**
* Open设备
*/
virtual int OpenDevice(const char* sIP) = 0;
virtual int OpenDevice(const char* sIP, bool bRGBD = false) = 0;
/**
* 获取版本信息

View File

@ -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;
}

View File

@ -30,7 +30,7 @@ public:
/**
* Open设备
*/
int OpenDevice(const char* sIP) override;
int OpenDevice(const char* sIP, bool bRGBD = false) override;
/**
* 获取版本信息