303 lines
11 KiB
C
303 lines
11 KiB
C
|
|
#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
|