增加相机选择;相机名称修改为配置文件中的名字;修复如果相机1打开失败,相机打开成功 序号错误问题
This commit is contained in:
parent
da33aa0b2a
commit
4fcf1cd20a
@ -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;
|
||||
|
||||
// 算法参数成员变量
|
||||
|
||||
@ -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++) {
|
||||
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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:
|
||||
// 定义线特征颜色和大小获取函数
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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; // 当前选择的相机索引
|
||||
};
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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索引
|
||||
|
||||
// 尝试加载该相机的标定数据
|
||||
|
||||
@ -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;
|
||||
|
||||
// 扫描数据缓存
|
||||
|
||||
@ -114,7 +114,7 @@
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>9</pointsize>
|
||||
<pointsize>16</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -67,6 +67,9 @@ private slots:
|
||||
|
||||
// 清空日志槽函数
|
||||
void clearDetectionLogUI();
|
||||
|
||||
// 处理相机点击事件
|
||||
void onCameraClicked(int cameraIndex);
|
||||
|
||||
// UI操作相关槽
|
||||
void on_btn_start_clicked();
|
||||
|
||||
@ -26,7 +26,7 @@ public:
|
||||
/**
|
||||
* Open设备
|
||||
*/
|
||||
virtual int OpenDevice(const char* sIP) = 0;
|
||||
virtual int OpenDevice(const char* sIP, bool bRGBD = false) = 0;
|
||||
|
||||
/**
|
||||
* 获取版本信息
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@ public:
|
||||
/**
|
||||
* Open设备
|
||||
*/
|
||||
int OpenDevice(const char* sIP) override;
|
||||
int OpenDevice(const char* sIP, bool bRGBD = false) override;
|
||||
|
||||
/**
|
||||
* 获取版本信息
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user