#ifndef WORKPIECEHOLEPRESENTER_H #define WORKPIECEHOLEPRESENTER_H #include #include #include #include #include #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 #include #include #include #include #include // 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>& 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>& 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 m_clibMatrixList; // 配置变化监听器代理 std::shared_ptr m_pConfigListener; // PLC Modbus 客户端 PLCModbusClient* m_pPLCModbusClient = nullptr; // PLC Modbus 客户端实例 bool m_bPLCConnected = false; // PLC 连接状态 bool m_bRobotConnected = false; // 机械臂连接状态 }; #endif // WORKPIECEHOLEPRESENTER_H