303 lines
11 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef WORKPIECEPRESENTER_H
#define WORKPIECEPRESENTER_H
#include <condition_variable>
#include <thread>
#include <map>
#include <mutex>
#include <memory>
#include "IVrConfig.h"
#include "IVrEyeDevice.h"
#include "ConfigManager.h"
#include "TCPServerProtocol.h"
#include "IYWorkpieceStatus.h"
#include "SG_baseDataType.h"
#include "VrConvert.h"
#include "LaserDataLoader.h"
#include <QImage>
#include <QPainter>
#include <QColor>
#include <QObject>
#include <QTimer>
#include <memory>
// Forward declarations
class DetectPresenter;
// 2D点结构体替代cv::Point2f
struct Point2D
{
double x = 0.0;
double y = 0.0;
Point2D() = default;
Point2D(double _x, double _y) : x(_x), y(_y) {}
};
// 3D点结构体替代cv::Point3f
struct Point3D
{
double x = 0.0;
double y = 0.0;
double z = 0.0;
Point3D() = default;
Point3D(double _x, double _y, double _z) : x(_x), y(_y), z(_z) {}
};
// 工件检测结果结构
struct WorkpieceDetectionResult
{
int cameraIndex; // 相机索引
double timestamp; // 检测时间戳
bool success; // 检测是否成功
std::vector<Point2D> corners; // 检测到的角点坐标(图像坐标)
std::vector<Point3D> worldCorners; // 世界坐标系中的角点
QImage detectionImage; // 检测结果图像
QImage originalImage; // 原始图像
std::string errorMessage; // 错误信息
double confidence; // 置信度
};
// Note: DetectionResult is defined in IYWorkpieceStatus.h and uses WorkpiecePosition
// 工件角点提取算法参数结构
struct WorkpieceCornerParams
{
double threshold1 = 50.0; // Canny边缘检测阈值1
double threshold2 = 150.0; // Canny边缘检测阈值2
double minLineLength = 50.0; // 最小线段长度
double maxLineGap = 10.0; // 最大线段间隙
double minCornerDistance = 20.0; // 最小角点距离
double areaThreshold = 1000.0; // 面积阈值
bool enablePerspectiveCorrection = true; // 是否启用透视校正
double targetAspectRatio = 1.0; // 目标长宽比
};
// 当前执行参数结构
struct CurrentExecutionParams
{
int cameraIndex = 1; // 相机序号
WorkpieceCornerParams cornerParams; // 角点提取参数
};
class WorkpiecePresenter : public QObject, public IConfigChangeListener, public IVrConfigChangeNotify
{
Q_OBJECT
public:
explicit WorkpiecePresenter(QObject *parent = nullptr);
~WorkpiecePresenter();
// 初始化
int Init();
// 设置状态回调
void SetStatusCallback(IYWorkpieceStatus* status);
// 开始检测
int StartDetection(int cameraIndex = -1, bool isAuto = true); // cameraIndex: -1表示所有相机1/2...表示特定相机
// 停止检测
int StopDetection();
// 加载调试数据进行检测
int LoadDebugDataAndDetect(const std::string& filePath);
// 为所有相机设置状态回调
void SetCameraStatusCallback(VzNL_OnNotifyStatusCBEx fNotify, void* param);
// 设置默认相机索引
void SetDefaultCameraIndex(int cameraIndex);
// 获取当前默认相机索引
int GetDefaultCameraIndex() const { return m_currentCameraIndex; }
// 获取配置对象
IVrConfig* GetConfig() { return m_vrConfig; }
// 获取配置结果对象
ConfigResult* GetConfigResult() { return &m_configResult; }
// 获取相机列表
std::vector<std::pair<std::string, IVrEyeDevice*>> GetCameraList() const { return m_vrEyeDeviceList; } // 返回相机列表包括IP地址和设备指针
// 手眼标定矩阵管理
CalibMatrix GetClibMatrix(int index) const;
// 实现IConfigChangeListener接口
virtual void OnSystemConfigChanged(const SystemConfig& config) override;
virtual void OnCameraParamChanged(int cameraIndex, const CameraUIParam& cameraParam) override;
virtual void OnAlgorithmParamChanged(const VrAlgorithmParams& algorithmParams) override;
// 实现IVrConfigChangeNotify接口
virtual void OnConfigChanged(const ConfigResult& configResult) override;
// 配置管理
ConfigManager* GetConfigManager() { return m_pConfigManager.get(); }
// 获取检测数据缓存的副本(用于保存数据)
int GetDetectIndex() const { return m_currentCameraIndex; }
int GetDetectionDataCacheSize() const { return m_detectionDataCache.size(); }
// 保存检测数据到文件(默认实现)
int SaveDetectionDataToFile(const std::string& filePath);
// 获取角点提取参数
WorkpieceCornerParams GetWorkpieceCornerParams() const { return m_currentExecutionParams.cornerParams; }
// 设置角点提取参数
void SetWorkpieceCornerParams(const WorkpieceCornerParams& params);
// 发送JSON格式检测结果给客户端
void SendDetectionResultToClient(const WorkpieceDetectionResult& result);
static void _StaticCameraNotify(EVzDeviceWorkStatus eStatus, void* pExtData, unsigned int nDataLength, void* pInfoParam);
static void _StaticDetectionCallback(EVzResultDataType eDataType, SVzLaserLineData* pLaserLinePoint, void* pParam);
private:
// 相机协议相关方法
int InitCamera(std::vector<DeviceInfo>& cameraList);
// TCP服务器相关方法
int InitTcpServer(int nPort);
int InitTCPServer(); // 初始化TCP服务器协议使用配置端口
// 初始化TCP服务器
bool startServer(quint16 port = 0); // port = 0 表示使用配置文件中的端口
void stopServer();
// TCP服务器回调处理方法
void onTcpDataReceivedFromCallback(const TCPClient* pClient, const char* pData, const unsigned int nLen);
// TCP客户端连接状态回调处理方法
void onTcpClientEventFromCallback(const TCPClient* pClient, TCPServerEventType eventType);
// TCP连接状态改变回调
void OnTCPConnectionChanged(bool connected);
// TCP检测触发回调
bool OnTCPDetectionTrigger(bool startWork, int cameraIndex, qint64 timestamp);
// 发送检测结果给TCP客户端
void _SendDetectionResultToTCP(const DetectionResult& detectionResult, int cameraIndex);
// 算法初始化接口
int InitAlgorithmParams();
// 连接状态检查和更新
void CheckAndUpdateWorkStatus();
// 打开相机
int _OpenDevice(int cameraIndex, const char* cameraName, const char* cameraIp, ProjectType& projectType);
bool _SinglePreDetection(int cameraIndex);
int _SingleDetection(int cameraIndex, bool isStart);
// 静态回调函数,供外部使用
void _CameraNotify(EVzDeviceWorkStatus eStatus, void* pExtData, unsigned int nDataLength, void* pInfoParam);
// 检测数据回调函数
void _DetectionCallback(EVzResultDataType eDataType, SVzLaserLineData* pLaserLineData, void* pParam);
// 算法检测线程
void _AlgoDetectThread();
int _DetectTask();
// 释放缓存的检测数据
void _ClearDetectionDataCache();
// 根据相机索引获取调平参数
SSG_planeCalibPara _GetCameraCalibParam(int cameraIndex);
// 更新当前执行参数
void _UpdateCurrentExecutionParams();
// 工件角点提取算法实现
bool _ExtractWorkpieceCorners(const QImage& inputImage, std::vector<Point2D>& corners,
std::vector<Point3D>& worldCorners, QImage& resultImage,
std::string& errorMessage);
// 透视校正
bool _PerspectiveCorrection(const std::vector<Point2D>& srcCorners,
const std::vector<Point2D>& dstCorners,
QImage& correctedImage);
// 相机重连定时器相关方法
void _StartCameraReconnectTimer();
void _StopCameraReconnectTimer();
void _OnCameraReconnectTimer();
bool _TryReconnectCameras();
private:
IVrConfig* m_vrConfig = nullptr;
ConfigResult m_configResult; // 配置结果
std::vector<std::pair<std::string, IVrEyeDevice*>> m_vrEyeDeviceList;
IYWorkpieceStatus* m_pStatus = nullptr;
// TCP服务器相关
IYTCPServer* m_pTcpServer = nullptr;
TCPServerProtocol* m_pTCPServer = nullptr; // TCP服务器协议实例
quint16 m_port = 0;
bool m_bTcpClientConnected = false; // TCP客户端连接状态
bool m_bTCPConnected = false; // TCP客户端连接状态新协议
// 连接状态标志
bool m_bCameraConnected = false; // 相机连接状态
int m_currentCameraIndex = 0; // 当前使用的相机编号
std::atomic<bool> m_bAlgoDetectThreadRunning = false;
std::mutex m_algoDetectMutex;
std::condition_variable m_algoDetectCondition;
std::thread m_algoDetectThread; // 算法检测线程
// 检测数据缓存
std::mutex m_detectionDataMutex;
std::vector<std::pair<EVzResultDataType, SVzLaserLineData>> m_detectionDataCache; // 统一存储数据
// 项目类型
ProjectType m_projectType;
// 配置管理器
std::unique_ptr<ConfigManager> m_pConfigManager;
// 相机重连定时器相关成员变量
QTimer* m_pCameraReconnectTimer = nullptr;
std::vector<DeviceInfo> m_cameraConfigList; // 保存配置的相机列表
int m_expectedCameraCount = 0; // 期望的相机数量
// 当前执行参数
CurrentExecutionParams m_currentExecutionParams; // 当前执行参数
// 检测处理器
DetectPresenter* m_pDetectPresenter = nullptr;
// 工作状态
WorkStatus m_currentWorkStatus = WorkStatus::Error;
// 手眼标定矩阵列表
std::vector<CalibMatrix> m_clibMatrixList;
// 调试参数
VrDebugParam m_debugParam;
// 算法参数
VrAlgorithmParams m_algorithmParams;
// 激光数据加载器
LaserDataLoader m_dataLoader;
// 工件角点提取算法库句柄
void* m_cornerExtractionLib = nullptr;
typedef bool (*ExtractCornersFunc)(const unsigned char* imageData, int width, int height,
double threshold1, double threshold2, double minLineLength,
double maxLineGap, double minCornerDistance, double areaThreshold,
std::vector<Point2D>* corners, std::vector<Point3D>* worldCorners,
QImage* resultImage, double* confidence, char* errorMessage);
ExtractCornersFunc m_extractCornersFunc = nullptr;
};
#endif // WORKPIECEPRESENTER_H