288 lines
8.1 KiB
C++
288 lines
8.1 KiB
C++
#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
|