288 lines
8.1 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 TUNNELCHANNELPRESENTER_H
#define TUNNELCHANNELPRESENTER_H
#include <condition_variable>
#include <thread>
#include <map>
#include <mutex>
#include <memory>
#include <atomic>
#include <chrono>
#include "BasePresenter.h"
#include "IVrEyeDevice.h"
#include "IHikDevice.h"
#include "ConfigManager.h"
#include "IYTunnelChannelStatus.h"
#include "VrConvert.h"
#include "LaserDataLoader.h"
#include "CommonDialogCameraLevel.h"
#include <QImage>
#include <QPainter>
#include <QColor>
#include <QObject>
#include <QTimer>
#include <memory>
// Forward declarations
class DetectPresenter;
/**
* @brief 隧道通道检测业务逻辑类
*
* 集成两种相机:
* 1. 海康相机 (IHikDevice) - 实时2D图像采集
* 2. 3D相机 (VrEyeDevice/VzNLSDK) - 3D点云采集进行算法检测
*
* 流程与 WorkpieceApp 一致
*/
class TunnelChannelPresenter : public BasePresenter, public IVrConfigChangeNotify,
public ICameraLevelCalculator, public ICameraLevelResultSaver
{
Q_OBJECT
public:
explicit TunnelChannelPresenter(QObject *parent = nullptr);
~TunnelChannelPresenter();
// 初始化
int InitApp() override;
// 获取配置管理器
ConfigManager* GetConfigManager() { return m_pConfigManager; }
/**
* @brief 设置海康相机显示窗口(用于硬件渲染)
* @param hWnd 窗口句柄,设置后将使用硬件解码直接渲染
*/
void SetHikDisplayWindow(void* hWnd) { m_hHikDisplayWnd = hWnd; }
// 实现IVrConfigChangeNotify接口
virtual void OnConfigChanged(const ConfigResult& configResult) override;
// ============ 海康相机相关 ============
/**
* @brief 初始化海康设备
* @return 0: 成功, 其他: 错误码
*/
int InitHikDevice();
/**
* @brief 连接海康相机
* @param config 海康相机配置
* @return 0: 成功, 其他: 错误码
*/
int ConnectHikCamera(const HikCameraConfig& config);
/**
* @brief 断开海康相机
*/
void DisconnectHikCamera();
/**
* @brief 开始海康相机实时预览
* @return 0: 成功, 其他: 错误码
*/
int StartHikPreview();
/**
* @brief 开始海康相机实时预览(直接渲染到窗口,低延迟)
* @param hWnd 窗口句柄
* @return 0: 成功, 其他: 错误码
*/
int StartHikPreviewEx(void* hWnd);
/**
* @brief 停止海康相机实时预览
*/
void StopHikPreview();
/**
* @brief 获取海康相机当前帧图像
* @return 当前帧图像
*/
QImage GetCurrentHikFrame() const;
/**
* @brief 判断海康相机是否已连接
* @return true: 已连接, false: 未连接
*/
bool IsHikCameraConnected() const;
// ============ 实现 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 工作状态变化通知(重写虚函数)
*/
void OnWorkStatusChanged(WorkStatus status) override;
/**
* @brief 相机数量变化通知(重写虚函数)
*/
void OnCameraCountChanged(int count) override;
/**
* @brief 状态文字更新通知(重写虚函数)
*/
void OnStatusUpdate(const std::string& statusMessage) override;
private:
// ============ 海康相机相关私有方法 ============
/**
* @brief 海康相机帧数据回调处理
*/
void OnHikFrameReceived(unsigned char* pRGBData, int dataSize,
const HikFrameInfo& frameInfo);
/**
* @brief 海康相机状态变化回调处理
*/
void OnHikDeviceStatusChanged(EHikDeviceStatus status);
/**
* @brief 海康相机异常回调处理
*/
void OnHikExceptionReceived(EHikExceptionType exceptionType);
/**
* @brief 海康相机重连定时器处理
*/
void OnHikReconnectTimer();
// ============ 连接状态管理 ============
/**
* @brief 检查并更新工作状态
*/
void CheckAndUpdateWorkStatus();
/**
* @brief 通知海康相机状态变化
*/
void NotifyHikCameraStatus(bool isConnected);
/**
* @brief 通知机械臂连接状态变化
*/
void NotifyRobotConnectionStatus(bool isConnected);
/**
* @brief 通知串口连接状态变化
*/
void NotifySerialConnectionStatus(bool isConnected);
signals:
// ============ 跨线程信号用于SDK回调到主线程 ============
/**
* @brief 海康相机图像更新信号(跨线程)
*/
void sigHikImageUpdated(const QImage& image);
/**
* @brief 海康相机状态变化信号(跨线程)
*/
void sigHikStatusChanged(int status);
/**
* @brief 海康相机异常信号(跨线程)
*/
void sigHikException(int exceptionType);
private slots:
// ============ 跨线程槽函数 ============
/**
* @brief 处理海康图像更新(主线程)
*/
void onHikImageUpdatedInMainThread(const QImage& image);
/**
* @brief 处理海康状态变化(主线程)
*/
void onHikStatusChangedInMainThread(int status);
/**
* @brief 处理海康异常(主线程)
*/
void onHikExceptionInMainThread(int exceptionType);
private:
// 配置管理器
ConfigManager* m_pConfigManager = nullptr;
// ============ 海康相机设备(使用封装接口) ============
IHikDevice* m_pHikDevice = nullptr; // 海康相机设备接口
bool m_bHikConnected = false; // 海康相机连接状态
QTimer* m_pHikReconnectTimer = nullptr; // 海康相机重连定时器
// 海康相机当前帧
mutable std::mutex m_hikFrameMutex;
QImage m_currentHikFrame;
// 帧率限制避免过度刷新UI
std::chrono::steady_clock::time_point m_lastHikFrameTime;
static constexpr int HIK_FRAME_INTERVAL_MS = 33; // 约30fps
// 海康相机显示窗口句柄(用于硬件渲染)
void* m_hHikDisplayWnd = nullptr;
// 检测处理器
DetectPresenter* m_pDetectPresenter = nullptr;
};
#endif // TUNNELCHANNELPRESENTER_H