2026-03-13 09:49:07 +08:00
|
|
|
|
#ifndef WHEELMEASUREPRESENTER_H
|
|
|
|
|
|
#define WHEELMEASUREPRESENTER_H
|
|
|
|
|
|
|
|
|
|
|
|
#include "BasePresenter.h"
|
|
|
|
|
|
#include "IVrWheelMeasureConfig.h"
|
|
|
|
|
|
#include "IWheelMeasureStatus.h"
|
|
|
|
|
|
#include "CommonDialogCameraLevel.h"
|
|
|
|
|
|
#include "WheelMeasureTCPProtocol.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include <QImage>
|
|
|
|
|
|
#include <QString>
|
|
|
|
|
|
#include <QStringList>
|
|
|
|
|
|
#include <QMap>
|
|
|
|
|
|
|
2026-05-25 00:28:08 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 主界面检测模式
|
|
|
|
|
|
*/
|
|
|
|
|
|
enum class WheelDetectMode {
|
|
|
|
|
|
Wheel = 0, // 轮毂检测(默认,调用 wd_wheelArchHeigthMeasure)
|
|
|
|
|
|
Correction = 1, // 工装检测(调用 wd_getCalibrationBlockLength)
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2026-03-13 09:49:07 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 车轮拱高测量Presenter
|
|
|
|
|
|
* 继承BasePresenter,负责相机控制、算法调用和结果处理
|
|
|
|
|
|
*/
|
|
|
|
|
|
class WheelMeasurePresenter : public BasePresenter,
|
|
|
|
|
|
public IVrWheelMeasureConfigChangeNotify,
|
|
|
|
|
|
public ICameraLevelCalculator,
|
|
|
|
|
|
public ICameraLevelResultSaver
|
|
|
|
|
|
{
|
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
|
|
signals:
|
|
|
|
|
|
void configUpdated();
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
explicit WheelMeasurePresenter(QObject* parent = nullptr);
|
|
|
|
|
|
~WheelMeasurePresenter();
|
|
|
|
|
|
|
|
|
|
|
|
// ============ 实现 BasePresenter 纯虚函数 ============
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 私有初始化(实现纯虚函数)
|
|
|
|
|
|
*/
|
|
|
|
|
|
int InitApp() override;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 初始化算法参数(实现纯虚函数)
|
|
|
|
|
|
*/
|
|
|
|
|
|
int InitAlgoParams() override;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 执行算法检测(实现纯虚函数)
|
|
|
|
|
|
*/
|
|
|
|
|
|
int ProcessAlgoDetection(std::vector<std::pair<EVzResultDataType, SVzLaserLineData>>& detectionDataCache) override;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取检测数据类型(实现纯虚函数)
|
|
|
|
|
|
*/
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief Modbus写寄存器回调(重写虚函数)
|
|
|
|
|
|
*/
|
|
|
|
|
|
void OnModbusWriteCallback(uint16_t startAddress, const uint16_t* data, uint16_t count) override;
|
|
|
|
|
|
|
|
|
|
|
|
// ============ 实现 ICameraLevelCalculator 接口 ============
|
|
|
|
|
|
|
|
|
|
|
|
bool CalculatePlaneCalibration(
|
|
|
|
|
|
const std::vector<std::pair<EVzResultDataType, SVzLaserLineData>>& scanData,
|
|
|
|
|
|
double planeCalib[9],
|
|
|
|
|
|
double& planeHeight,
|
|
|
|
|
|
double invRMatrix[9]) override;
|
|
|
|
|
|
|
|
|
|
|
|
// ============ 实现 ICameraLevelResultSaver 接口 ============
|
|
|
|
|
|
|
|
|
|
|
|
bool SaveLevelingResults(double planeCalib[9], double planeHeight, double invRMatrix[9],
|
|
|
|
|
|
int cameraIndex, const QString& cameraName) override;
|
|
|
|
|
|
|
|
|
|
|
|
bool LoadLevelingResults(int cameraIndex, const QString& cameraName,
|
|
|
|
|
|
double planeCalib[9], double& planeHeight, double invRMatrix[9]) override;
|
|
|
|
|
|
|
|
|
|
|
|
// ============ IVrWheelMeasureConfigChangeNotify 接口实现 ============
|
|
|
|
|
|
|
|
|
|
|
|
void OnConfigChanged(const WheelMeasureConfigResult& configResult) override;
|
|
|
|
|
|
|
|
|
|
|
|
// ============ 公共接口 ============
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 设置状态更新接口
|
|
|
|
|
|
*/
|
|
|
|
|
|
void setStatusUpdate(IWheelMeasureStatus* statusUpdate) { m_statusUpdate = statusUpdate; }
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取配置接口
|
|
|
|
|
|
*/
|
|
|
|
|
|
IVrWheelMeasureConfig* GetConfig() const { return m_config; }
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取配置结果
|
|
|
|
|
|
*/
|
|
|
|
|
|
WheelMeasureConfigResult* GetConfigResult() { return &m_configResult; }
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取相机名称列表
|
|
|
|
|
|
*/
|
|
|
|
|
|
QStringList getCameraNames() const;
|
|
|
|
|
|
|
2026-04-02 00:38:50 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取算法版本
|
|
|
|
|
|
*/
|
|
|
|
|
|
QString GetAlgoVersion() const;
|
|
|
|
|
|
|
2026-03-13 09:49:07 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 重新检测
|
|
|
|
|
|
*/
|
|
|
|
|
|
void ResetDetect(int cameraIndex = 0);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 启动所有相机检测(依次执行)
|
|
|
|
|
|
*/
|
|
|
|
|
|
void StartAllDetection();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 停止所有相机检测(完成当前设备后停止)
|
|
|
|
|
|
*/
|
|
|
|
|
|
void StopAllDetection();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 设置默认相机索引
|
|
|
|
|
|
*/
|
|
|
|
|
|
void SetDefaultCameraIndex(int cameraIndex) { m_currentCameraIndex = cameraIndex; }
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取当前默认相机索引
|
|
|
|
|
|
*/
|
|
|
|
|
|
int GetDefaultCameraIndex() const { return m_currentCameraIndex; }
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取TCP协议对象
|
|
|
|
|
|
*/
|
|
|
|
|
|
WheelMeasureTCPProtocol* GetTCPProtocol() { return &m_tcpProtocol; }
|
|
|
|
|
|
|
2026-05-25 00:28:08 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 设置检测模式(轮毂检测 / 工装检测)
|
|
|
|
|
|
*/
|
|
|
|
|
|
void SetDetectMode(WheelDetectMode mode) { m_detectMode = mode; }
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 获取当前检测模式
|
|
|
|
|
|
*/
|
|
|
|
|
|
WheelDetectMode GetDetectMode() const { return m_detectMode; }
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @brief 重写:保存点云文件时按当前模式附加 "轮毂"/"工装" 标签
|
|
|
|
|
|
*/
|
|
|
|
|
|
std::string GetSaveDeviceTag() const override {
|
|
|
|
|
|
return m_detectMode == WheelDetectMode::Wheel ? "轮毂" : "工装";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-13 09:49:07 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief 静态相机状态回调函数
|
|
|
|
|
|
*/
|
|
|
|
|
|
static void _StaticCameraNotify(EVzDeviceWorkStatus eStatus, void* pExtData, unsigned int nDataLength, void* pInfoParam);
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
// 初始化配置
|
|
|
|
|
|
bool initializeConfig(const QString& configPath);
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化相机
|
|
|
|
|
|
bool initializeCameras();
|
|
|
|
|
|
|
|
|
|
|
|
// 处理扫描数据
|
|
|
|
|
|
void processScanData(std::vector<std::pair<EVzResultDataType, SVzLaserLineData>>& detectionDataCache);
|
|
|
|
|
|
|
2026-05-25 00:28:08 +08:00
|
|
|
|
// 处理扫描数据(轮毂检测分支)
|
|
|
|
|
|
void processWheelDetection(std::vector<std::vector<SVzNL3DPosition>>& scanLines);
|
|
|
|
|
|
|
|
|
|
|
|
// 处理扫描数据(工装检测分支)
|
|
|
|
|
|
void processCorrectionDetection(std::vector<std::vector<SVzNL3DPosition>>& scanLines);
|
|
|
|
|
|
|
2026-03-13 09:49:07 +08:00
|
|
|
|
// 根据相机索引获取调平参数
|
|
|
|
|
|
WheelCameraPlaneCalibParam* getPlaneCalibParam(int cameraIndex);
|
|
|
|
|
|
|
2026-05-25 00:28:08 +08:00
|
|
|
|
// 根据当前相机索引获取相机显示名称
|
|
|
|
|
|
QString getCurrentCameraName() const;
|
|
|
|
|
|
|
2026-03-13 09:49:07 +08:00
|
|
|
|
// 相机状态回调处理
|
|
|
|
|
|
void _CameraNotify(EVzDeviceWorkStatus eStatus, void* pExtData, unsigned int nDataLength, void* pInfoParam);
|
|
|
|
|
|
|
|
|
|
|
|
// TCP检测触发回调
|
|
|
|
|
|
bool onTCPDetectionTriggered(int param);
|
|
|
|
|
|
|
2026-05-25 00:28:08 +08:00
|
|
|
|
// 启动“扫描全部相机”流程(顺序/批处理由 simultaneousCount 决定)
|
|
|
|
|
|
// bIsTCPTriggered: 是否由TCP协议触发(决定结束时是否回TCP响应)
|
|
|
|
|
|
bool startScanAllCameras(bool bIsTCPTriggered);
|
|
|
|
|
|
|
|
|
|
|
|
// 启动下一个待扫描相机(顺序模式)
|
|
|
|
|
|
void startNextScanCamera();
|
2026-05-17 19:00:47 +08:00
|
|
|
|
|
2026-03-13 09:49:07 +08:00
|
|
|
|
// 发送TCP测量结果
|
|
|
|
|
|
void sendTCPMeasureResults();
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
IVrWheelMeasureConfig* m_config = nullptr;
|
|
|
|
|
|
WheelMeasureConfigResult m_configResult;
|
|
|
|
|
|
IWheelMeasureStatus* m_statusUpdate = nullptr;
|
|
|
|
|
|
|
|
|
|
|
|
// TCP协议
|
|
|
|
|
|
WheelMeasureTCPProtocol m_tcpProtocol; // TCP服务器协议
|
2026-05-25 00:28:08 +08:00
|
|
|
|
bool m_scanAllMode = false; // 是否处于“扫描全部相机”流程中(按钮/TCP共用)
|
|
|
|
|
|
bool m_isTCPTriggered = false; // 当前“扫描全部”是否由TCP触发(控制是否回TCP响应)
|
|
|
|
|
|
QMap<int, WheelMeasureTCPProtocol::CameraMeasureResult> m_tcpResults; // 检测结果缓存(按相机ID)
|
|
|
|
|
|
std::vector<int> m_scanAllList; // “扫描全部”待扫描的相机列表(1-based)
|
|
|
|
|
|
size_t m_scanAllIndex = 0; // “扫描全部”当前扫描索引
|
|
|
|
|
|
WheelDetectMode m_detectMode = WheelDetectMode::Wheel; // 当前检测模式
|
2026-03-13 09:49:07 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#endif // WHEELMEASUREPRESENTER_H
|