239 lines
8.8 KiB
C++
239 lines
8.8 KiB
C++
#ifndef WORKPIECEHOLEPRESENTER_H
|
||
#define WORKPIECEHOLEPRESENTER_H
|
||
|
||
#include <condition_variable>
|
||
#include <thread>
|
||
#include <map>
|
||
#include <mutex>
|
||
#include <memory>
|
||
|
||
#include "BasePresenter.h"
|
||
#include "IVrEyeDevice.h"
|
||
#include "ConfigManager.h"
|
||
#include "TCPServerProtocol.h"
|
||
#include "IYWorkpieceHoleStatus.h"
|
||
#include "SG_baseDataType.h"
|
||
#include "workpieceHolePositioning_Export.h" // 算法输出类型定义
|
||
#include "VrConvert.h"
|
||
#include "LaserDataLoader.h"
|
||
#include "CommonDialogCameraLevel.h" // 引入通用对话框的接口
|
||
#include "CoordinateTransform.h" // 坐标转换库
|
||
#include "PLCModbusClient.h" // PLC Modbus 客户端
|
||
#include <QImage>
|
||
#include <QPainter>
|
||
#include <QColor>
|
||
#include <QObject>
|
||
#include <QTimer>
|
||
#include <memory>
|
||
|
||
// Forward declarations
|
||
class DetectPresenter;
|
||
class WorkpieceHolePresenter;
|
||
|
||
// 配置变化监听器代理类
|
||
class ConfigChangeListenerProxy : public IConfigChangeListener
|
||
{
|
||
public:
|
||
explicit ConfigChangeListenerProxy(WorkpieceHolePresenter* presenter) : m_presenter(presenter) {}
|
||
|
||
void OnSystemConfigChanged(const SystemConfig& config) override;
|
||
void OnCameraParamChanged(int cameraIndex, const CameraUIParam& cameraParam) override {}
|
||
void OnAlgorithmParamChanged(const VrAlgorithmParams& algorithmParams) override {}
|
||
|
||
private:
|
||
WorkpieceHolePresenter* m_presenter;
|
||
};
|
||
|
||
class WorkpieceHolePresenter : public BasePresenter, public IVrConfigChangeNotify,
|
||
public ICameraLevelCalculator, public ICameraLevelResultSaver
|
||
{
|
||
Q_OBJECT
|
||
|
||
// 声明友元类,允许访问 protected 成员
|
||
friend class ConfigChangeListenerProxy;
|
||
|
||
public:
|
||
explicit WorkpieceHolePresenter(QObject *parent = nullptr);
|
||
~WorkpieceHolePresenter();
|
||
|
||
// 初始化
|
||
int InitApp() override;
|
||
|
||
// 获取配置管理器
|
||
ConfigManager* GetConfigManager() { return m_pConfigManager; }
|
||
|
||
// 手眼标定矩阵管理
|
||
CalibMatrix GetClibMatrix(int index) const;
|
||
|
||
// ============ 坐标转换接口 ============
|
||
|
||
/**
|
||
* @brief 将算法检测结果(相机坐标系)转换为机器人坐标系
|
||
*
|
||
* @param workpieceInfo 算法输出的工件信息(相机坐标系)
|
||
* @param robotPose 机器人当前位姿
|
||
* @param handEye 六轴手眼标定矩阵
|
||
* @param targetPose 输出的目标抓取位姿(机器人坐标系)
|
||
*
|
||
* 使用说明:
|
||
* - Eye-in-Hand 模式:相机固定在机器人末端
|
||
* - 算法输出的 x_dir, y_dir, z_dir 为方向向量
|
||
* - 输出的 targetPose 为机器人基坐标系下的位姿
|
||
*/
|
||
void ConvertWorkpieceToRobotPose(const WD_workpieceInfo& workpieceInfo,
|
||
const CTRobotPose& robotPose,
|
||
const CTSixAxisCalibResult& handEye,
|
||
CTRobotPose& targetPose);
|
||
|
||
/**
|
||
* @brief 将算法检测结果转换为机器人坐标系(Eye-to-Hand模式)
|
||
*
|
||
* @param workpieceInfo 算法输出的工件信息(相机坐标系)
|
||
* @param cameraToBase 相机到机器人基座的标定矩阵
|
||
* @param targetPose 输出的目标抓取位姿(机器人坐标系)
|
||
*
|
||
* 使用说明:
|
||
* - Eye-to-Hand 模式:相机固定在外部
|
||
*/
|
||
void ConvertWorkpieceToRobotPoseEyeToHand(const WD_workpieceInfo& workpieceInfo,
|
||
const CTSixAxisCalibResult& cameraToBase,
|
||
CTRobotPose& targetPose);
|
||
|
||
// 实现IVrConfigChangeNotify接口
|
||
virtual void OnConfigChanged(const ConfigResult& configResult) override;
|
||
|
||
// ============ 实现 ICameraLevelCalculator 接口 ============
|
||
|
||
/**
|
||
* @brief 计算平面调平参数
|
||
*/
|
||
bool CalculatePlaneCalibration(
|
||
const std::vector<std::pair<EVzResultDataType, SVzLaserLineData>>& scanData,
|
||
double planeCalib[9],
|
||
double& planeHeight,
|
||
double invRMatrix[9]) override;
|
||
|
||
// ============ 实现 ICameraLevelResultSaver 接口 ============
|
||
|
||
/**
|
||
* @brief 保存相机调平结果到配置文件
|
||
*/
|
||
bool SaveLevelingResults(double planeCalib[9], double planeHeight, double invRMatrix[9],
|
||
int cameraIndex, const QString& cameraName) override;
|
||
|
||
/**
|
||
* @brief 从配置文件加载相机调平结果
|
||
*/
|
||
bool LoadLevelingResults(int cameraIndex, const QString& cameraName,
|
||
double planeCalib[9], double& planeHeight, double invRMatrix[9]) override;
|
||
|
||
protected:
|
||
// ============ 实现 BasePresenter 纯虚函数 ============
|
||
|
||
/**
|
||
* @brief 初始化算法参数(实现纯虚函数)
|
||
*/
|
||
int InitAlgoParams() override;
|
||
|
||
/**
|
||
* @brief 执行算法检测(实现纯虚函数)
|
||
* @param detectionDataCache 检测数据缓存的引用
|
||
*/
|
||
int ProcessAlgoDetection(std::vector<std::pair<EVzResultDataType, SVzLaserLineData>>& detectionDataCache) override;
|
||
|
||
/**
|
||
* @brief 获取检测数据类型(实现纯虚函数)
|
||
* 工件孔定位项目只使用Position点云数据
|
||
*/
|
||
EVzResultDataType GetDetectionDataType() override {
|
||
return keResultDataType_Position;
|
||
}
|
||
|
||
/**
|
||
* @brief 相机状态变化通知(实现纯虚函数)
|
||
*/
|
||
void OnCameraStatusChanged(int cameraIndex, bool isConnected) override;
|
||
|
||
/**
|
||
* @brief 工作状态变化通知(重写虚函数)
|
||
*
|
||
* 当BasePresenter的工作状态改变时,此方法会被调用
|
||
* 在此调用UI回调接口通知状态变化
|
||
*/
|
||
void OnWorkStatusChanged(WorkStatus status) override;
|
||
|
||
/**
|
||
* @brief 相机数量变化通知(重写虚函数)
|
||
*
|
||
* 当相机初始化时,此方法会被调用
|
||
* 在此调用UI回调接口通知相机数量
|
||
*/
|
||
void OnCameraCountChanged(int count) override;
|
||
|
||
/**
|
||
* @brief 状态文字更新通知(重写虚函数)
|
||
*
|
||
* 当需要更新状态文字时,此方法会被调用
|
||
* 在此调用UI回调接口通知状态消息
|
||
*/
|
||
void OnStatusUpdate(const std::string& statusMessage) override;
|
||
|
||
private:
|
||
// TCP服务器相关方法
|
||
int InitTcpServer(int nPort);
|
||
int InitTCPServer(); // 初始化TCP服务器协议(使用配置端口)
|
||
bool startServer(quint16 port = 0); // port = 0 表示使用配置文件中的端口
|
||
void stopServer();
|
||
|
||
// TCP服务器回调处理方法
|
||
void onTcpDataReceivedFromCallback(const TCPClient* pClient, const char* pData, const unsigned int nLen);
|
||
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 WorkpieceHoleDetectionResult& detectionResult, int cameraIndex);
|
||
|
||
// 连接状态检查和更新
|
||
void CheckAndUpdateWorkStatus();
|
||
|
||
// 根据相机索引获取调平参数
|
||
SSG_planeCalibPara _GetCameraCalibParam(int cameraIndex);
|
||
|
||
// PLC Modbus 相关方法
|
||
int InitPLCModbus(); // 初始化 PLC Modbus 客户端
|
||
void OnPLCPhotoRequested(int cameraIndex); // PLC 拍照请求回调
|
||
void SendCoordinateDataToPLC(const WorkpieceHoleDetectionResult& result); // 发送坐标数据到 PLC
|
||
|
||
private:
|
||
// WorkpieceHolePresenter 特有的成员变量
|
||
ConfigManager* m_pConfigManager = 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客户端连接状态(新协议)
|
||
|
||
// 检测处理器
|
||
DetectPresenter* m_pDetectPresenter = nullptr;
|
||
|
||
// 手眼标定矩阵列表(从独立文件加载,暂时保留在Presenter中)
|
||
std::vector<CalibMatrix> m_clibMatrixList;
|
||
|
||
// 配置变化监听器代理
|
||
std::shared_ptr<ConfigChangeListenerProxy> m_pConfigListener;
|
||
|
||
// PLC Modbus 客户端
|
||
PLCModbusClient* m_pPLCModbusClient = nullptr; // PLC Modbus 客户端实例
|
||
bool m_bPLCConnected = false; // PLC 连接状态
|
||
bool m_bRobotConnected = false; // 机械臂连接状态
|
||
};
|
||
|
||
#endif // WORKPIECEHOLEPRESENTER_H
|