GrabBag/App/ScrewPosition/ScrewPositionApp/Presenter/Src/ScrewPositionPresenter.cpp
2026-04-19 12:28:59 +08:00

725 lines
25 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.

#include "ScrewPositionPresenter.h"
#include "DetectPresenter.h"
#include "PathManager.h"
#include "ScrewPositionTCPProtocol.h"
#include "Version.h"
#include "VrConvert.h"
#include "VrError.h"
#include "VrLog.h"
#include "VrTimeUtils.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QDateTime>
#include <QtCore/QString>
#include <algorithm>
#include <cstdio>
#include <cstring>
ScrewPositionPresenter::ScrewPositionPresenter(QObject *parent)
: BasePresenter(parent)
{
}
ScrewPositionPresenter::~ScrewPositionPresenter()
{
if (m_pConfigManager) {
delete m_pConfigManager;
m_pConfigManager = nullptr;
}
if (m_pTCPServer) {
m_pTCPServer->Deinitialize();
delete m_pTCPServer;
m_pTCPServer = nullptr;
}
if (m_pDetectPresenter) {
delete m_pDetectPresenter;
m_pDetectPresenter = nullptr;
}
}
int ScrewPositionPresenter::InitApp()
{
LOG_DEBUG("Start APP Version: %s\n", SCREWPOSITION_FULL_VERSION_STRING);
SetWorkStatus(WorkStatus::InitIng);
m_pDetectPresenter = new DetectPresenter();
m_pConfigManager = new ConfigManager();
if (!m_pConfigManager) {
LOG_ERROR("Failed to create ConfigManager instance\n");
if (auto pStatus = GetStatusCallback<IYScrewPositionStatus>()) {
pStatus->OnStatusUpdate("配置管理器创建失败");
}
return ERR_CODE(DEV_CONFIG_ERR);
}
if (!m_pConfigManager->Initialize()) {
LOG_ERROR("Failed to initialize ConfigManager\n");
if (auto pStatus = GetStatusCallback<IYScrewPositionStatus>()) {
pStatus->OnStatusUpdate("配置管理器初始化失败");
}
return ERR_CODE(DEV_CONFIG_ERR);
}
const ConfigResult configResult = m_pConfigManager->GetConfigResult();
SetDebugParam(configResult.debugParam);
m_modbusRegistersInitialized = false;
m_modbusWorkStatus = 0;
std::vector<DeviceInfo> cameraList = configResult.cameraList;
InitCamera(cameraList, false, true);
LOG_INFO("Camera initialization completed. Connected cameras: %zu, default camera index: %d\n",
m_vrEyeDeviceList.size(), m_currentCameraIndex);
int nRet = InitTCPServer();
if (nRet != SUCCESS) {
if (auto pStatus = GetStatusCallback<IYScrewPositionStatus>()) {
pStatus->OnStatusUpdate("TCP服务器初始化失败");
}
m_bTCPConnected = false;
} else {
if (auto pStatus = GetStatusCallback<IYScrewPositionStatus>()) {
pStatus->OnStatusUpdate("TCP服务器初始化成功");
}
}
if (auto pStatus = GetStatusCallback<IYScrewPositionStatus>()) {
pStatus->OnStatusUpdate("设备初始化完成");
}
CheckAndUpdateWorkStatus();
if (auto pStatus = GetStatusCallback<IYScrewPositionStatus>()) {
pStatus->OnStatusUpdate("配置初始化成功");
}
return SUCCESS;
}
int ScrewPositionPresenter::InitAlgoParams()
{
LOG_DEBUG("initializing algorithm parameters\n");
m_clibMatrixList.clear();
const ConfigResult configResult = m_pConfigManager->GetConfigResult();
SetDebugParam(configResult.debugParam);
const VrAlgorithmParams& xmlParams = configResult.algorithmParams;
const double initClibMatrix[16] = {
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
};
if (!configResult.handEyeCalibMatrixList.empty()) {
int cameraCount = static_cast<int>(configResult.cameraList.size());
for (const auto& matrixInfo : configResult.handEyeCalibMatrixList) {
cameraCount = std::max(cameraCount, matrixInfo.cameraIndex);
}
cameraCount = std::max(cameraCount, 1);
m_clibMatrixList.resize(static_cast<size_t>(cameraCount));
for (auto& calibMatrix : m_clibMatrixList) {
std::memcpy(calibMatrix.clibMatrix, initClibMatrix, sizeof(initClibMatrix));
}
for (const auto& matrixInfo : configResult.handEyeCalibMatrixList) {
if (matrixInfo.cameraIndex <= 0 || matrixInfo.cameraIndex > cameraCount) {
continue;
}
std::memcpy(m_clibMatrixList[static_cast<size_t>(matrixInfo.cameraIndex - 1)].clibMatrix,
matrixInfo.matrix,
sizeof(matrixInfo.matrix));
}
LOG_INFO("Loaded %zu hand-eye matrices from config.xml\n",
configResult.handEyeCalibMatrixList.size());
} else {
const QString clibPath = PathManager::GetInstance().GetCalibrationFilePath();
LOG_INFO("Loading hand-eye matrices from legacy ini: %s\n", clibPath.toStdString().c_str());
const int nExistMatrixNum = CVrConvert::GetClibMatrixCount(clibPath.toStdString().c_str());
LOG_INFO("Found %d legacy hand-eye calibration matrices\n", nExistMatrixNum);
for (int matrixIndex = 0; matrixIndex < nExistMatrixNum; ++matrixIndex) {
char matrixIdent[64];
#ifdef _WIN32
sprintf_s(matrixIdent, "CalibMatrixInfo_%d", matrixIndex);
#else
sprintf(matrixIdent, "CalibMatrixInfo_%d", matrixIndex);
#endif
CalibMatrix calibMatrix;
std::memcpy(calibMatrix.clibMatrix, initClibMatrix, sizeof(initClibMatrix));
if (CVrConvert::LoadClibMatrix(clibPath.toStdString().c_str(),
matrixIdent,
"dCalibMatrix",
calibMatrix.clibMatrix)) {
LOG_INFO("Successfully loaded legacy matrix %d\n", matrixIndex);
} else {
LOG_WARNING("Failed to load legacy matrix %d, using identity matrix\n", matrixIndex);
}
m_clibMatrixList.push_back(calibMatrix);
}
}
if (m_clibMatrixList.empty()) {
const int cameraCount = std::max(1, static_cast<int>(configResult.cameraList.size()));
m_clibMatrixList.resize(static_cast<size_t>(cameraCount));
for (auto& calibMatrix : m_clibMatrixList) {
std::memcpy(calibMatrix.clibMatrix, initClibMatrix, sizeof(initClibMatrix));
}
LOG_INFO("No hand-eye matrix found, using identity matrix for %d camera(s)\n", cameraCount);
}
LOG_INFO("Loaded XML params - Screw: rodDiameter=%.1f, isHorizonScan=%s\n",
xmlParams.screwParam.rodDiameter,
xmlParams.screwParam.isHorizonScan ? "true" : "false");
LOG_INFO("Loaded XML params - Filter: continuityTh=%.1f, outlierTh=%.1f\n",
xmlParams.filterParam.continuityTh, xmlParams.filterParam.outlierTh);
LOG_INFO("Algorithm parameters initialized successfully\n");
return SUCCESS;
}
CalibMatrix ScrewPositionPresenter::GetClibMatrix(int index) const
{
CalibMatrix clibMatrix;
const double initClibMatrix[16] = {
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
};
std::memcpy(clibMatrix.clibMatrix, initClibMatrix, sizeof(initClibMatrix));
if (index >= 0 && index < static_cast<int>(m_clibMatrixList.size())) {
std::memcpy(clibMatrix.clibMatrix, m_clibMatrixList[index].clibMatrix, sizeof(initClibMatrix));
} else {
LOG_WARNING("Invalid hand-eye calibration matrix\n");
}
return clibMatrix;
}
void ScrewPositionPresenter::CheckAndUpdateWorkStatus()
{
SetWorkStatus(m_bCameraConnected ? WorkStatus::Ready : WorkStatus::Error);
}
int ScrewPositionPresenter::ProcessAlgoDetection(std::vector<std::pair<EVzResultDataType, SVzLaserLineData>>& detectionDataCache)
{
LOG_INFO("[Algo Thread] Start real detection task using algorithm\n");
const unsigned int lineNum = detectionDataCache.size();
if (auto pStatus = GetStatusCallback<IYScrewPositionStatus>()) {
pStatus->OnStatusUpdate(QString("扫描线数:%1正在算法检测...").arg(lineNum).toStdString());
}
if (!m_pDetectPresenter) {
LOG_ERROR("DetectPresenter is null, cannot proceed with detection\n");
if (auto pStatus = GetStatusCallback<IYScrewPositionStatus>()) {
pStatus->OnStatusUpdate("检测处理器未初始化");
}
return ERR_CODE(DEV_NOT_FIND);
}
CVrTimeUtils oTimeUtils;
const CalibMatrix currentClibMatrix = GetClibMatrix(m_currentCameraIndex - 1);
const VrAlgorithmParams algorithmParams = m_pConfigManager->GetAlgorithmParams();
const ConfigResult configResult = m_pConfigManager->GetConfigResult();
const VrDebugParam debugParam = configResult.debugParam;
const int eulerOrder = configResult.eulerOrder;
const int outputEulerOrder = configResult.outputEulerOrder;
const int poseOutputOrder = configResult.poseOutputOrder;
const int dirVectorInvert = configResult.dirVectorInvert;
const int longAxisDir = configResult.longAxisDir;
LOG_INFO("[Algo Thread] Using euler order: %d, output euler order: %d, pose output order: %d, dir vector invert: %d, long axis dir: %d\n",
eulerOrder, outputEulerOrder, poseOutputOrder, dirVectorInvert, longAxisDir);
DetectionResult detectionResult;
detectionResult.cameraIndex = m_currentCameraIndex;
int nRet = SUCCESS;
if (m_currentDetectionType == DETECTION_TYPE_TOOL_DISK) {
nRet = m_pDetectPresenter->DetectToolDisk(
m_currentCameraIndex,
detectionDataCache,
algorithmParams,
debugParam,
m_dataLoader,
currentClibMatrix.clibMatrix,
m_currentRobotPose,
eulerOrder,
outputEulerOrder,
poseOutputOrder,
dirVectorInvert,
longAxisDir,
detectionResult);
} else {
nRet = m_pDetectPresenter->DetectScrew(
m_currentCameraIndex,
detectionDataCache,
algorithmParams,
debugParam,
m_dataLoader,
currentClibMatrix.clibMatrix,
m_currentRobotPose,
eulerOrder,
outputEulerOrder,
poseOutputOrder,
dirVectorInvert,
longAxisDir,
detectionResult);
}
if (nRet != SUCCESS) {
detectionResult.success = false;
if (detectionResult.errorCode == 0) {
detectionResult.errorCode = nRet;
}
if (detectionResult.message.isEmpty() || detectionResult.message == QStringLiteral("检测成功")) {
detectionResult.message = QString("检测失败:%1").arg(nRet);
}
}
LOG_INFO("[Algo Thread] detection type=%d objects=%zu time : %.2f ms\n",
static_cast<int>(m_currentDetectionType),
detectionResult.positions.size(),
oTimeUtils.GetElapsedTimeInMilliSec());
if (auto pStatus = GetStatusCallback<IYScrewPositionStatus>()) {
pStatus->OnDetectionResult(detectionResult);
}
QString statusMsg;
if (!detectionResult.success) {
statusMsg = detectionResult.message;
} else if (m_currentDetectionType == DETECTION_TYPE_TOOL_DISK) {
statusMsg = QString("工具盘检测完成,定位点数:%1").arg(detectionResult.positions.size());
} else {
statusMsg = QString("检测完成,发现%1个螺杆").arg(detectionResult.positions.size());
}
if (auto pStatus = GetStatusCallback<IYScrewPositionStatus>()) {
pStatus->OnStatusUpdate(statusMsg.toStdString());
}
_SendDetectionResultToTCP(detectionResult, m_currentCameraIndex);
_PublishDetectionResultToModbus(detectionResult);
return nRet;
}
void ScrewPositionPresenter::OnConfigChanged(const ConfigResult& configResult)
{
LOG_INFO("Configuration changed notification received, reloading algorithm parameters\n");
SetDebugParam(configResult.debugParam);
int result = InitAlgoParams();
stopServer();
const int tcpResult = InitTCPServer();
if (result == SUCCESS) {
LOG_INFO("Algorithm parameters reloaded successfully after config change\n");
if (auto pStatus = GetStatusCallback<IYScrewPositionStatus>()) {
pStatus->OnStatusUpdate("配置已更新,算法参数重新加载成功");
}
} else {
LOG_ERROR("Failed to reload algorithm parameters after config change, error: %d\n", result);
if (auto pStatus = GetStatusCallback<IYScrewPositionStatus>()) {
pStatus->OnStatusUpdate("配置更新后算法参数重新加载失败");
}
}
if (tcpResult != SUCCESS) {
LOG_ERROR("Failed to restart TCP server after config change, error: %d\n", tcpResult);
if (auto pStatus = GetStatusCallback<IYScrewPositionStatus>()) {
pStatus->OnStatusUpdate("TCP server restart failed");
}
}
}
SSG_planeCalibPara ScrewPositionPresenter::_GetCameraCalibParam(int cameraIndex)
{
SSG_planeCalibPara calibParam;
const double identityMatrix[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
for (int i = 0; i < 9; ++i) {
calibParam.planeCalib[i] = identityMatrix[i];
calibParam.invRMatrix[i] = identityMatrix[i];
}
calibParam.planeHeight = -1.0;
const VrAlgorithmParams algorithmParams = m_pConfigManager->GetAlgorithmParams();
for (const auto& cameraParam : algorithmParams.planeCalibParam.cameraCalibParams) {
if (cameraParam.cameraIndex == cameraIndex && cameraParam.isCalibrated) {
for (int i = 0; i < 9; ++i) {
calibParam.planeCalib[i] = cameraParam.planeCalib[i];
calibParam.invRMatrix[i] = cameraParam.invRMatrix[i];
}
calibParam.planeHeight = cameraParam.planeHeight;
}
}
return calibParam;
}
void ScrewPositionPresenter::OnCameraStatusChanged(int cameraIndex, bool isConnected)
{
LOG_INFO("Camera %d status changed: %s\n", cameraIndex, isConnected ? "connected" : "disconnected");
if (auto pStatus = GetStatusCallback<IYScrewPositionStatus>()) {
if (cameraIndex == 1) {
pStatus->OnCamera1StatusChanged(isConnected);
} else if (cameraIndex == 2) {
pStatus->OnCamera2StatusChanged(isConnected);
}
QString cameraName;
const int arrayIndex = cameraIndex - 1;
if (arrayIndex >= 0 && arrayIndex < static_cast<int>(m_vrEyeDeviceList.size())) {
cameraName = QString::fromStdString(m_vrEyeDeviceList[arrayIndex].first);
} else {
cameraName = QString("相机%1").arg(cameraIndex);
}
const QString statusMsg = QString("%1%2").arg(cameraName).arg(isConnected ? "已连接" : "已断开");
pStatus->OnStatusUpdate(statusMsg.toStdString());
}
CheckAndUpdateWorkStatus();
}
void ScrewPositionPresenter::OnWorkStatusChanged(WorkStatus status)
{
if (auto pStatus = GetStatusCallback<IYScrewPositionStatus>()) {
pStatus->OnWorkStatusChanged(status);
}
if (!m_modbusRegistersInitialized && status == WorkStatus::Ready) {
_InitializeModbusRegisters();
}
if (status == WorkStatus::Working) {
_UpdateModbusWorkStatus(1);
} else if (status == WorkStatus::Error) {
_UpdateModbusWorkStatus(3);
}
}
void ScrewPositionPresenter::OnCameraCountChanged(int count)
{
if (auto pStatus = GetStatusCallback<IYScrewPositionStatus>()) {
pStatus->OnCameraCountChanged(count);
}
}
void ScrewPositionPresenter::OnStatusUpdate(const std::string& statusMessage)
{
if (auto pStatus = GetStatusCallback<IYScrewPositionStatus>()) {
pStatus->OnStatusUpdate(statusMessage);
}
}
void ScrewPositionPresenter::OnModbusServerStatusChanged(bool isConnected)
{
if (auto pStatus = GetStatusCallback<IYScrewPositionStatus>()) {
pStatus->OnRobotConnectionChanged(isConnected);
}
}
void ScrewPositionPresenter::OnModbusWriteCallback(uint16_t startAddress, const uint16_t* data, uint16_t count)
{
if (!data || count == 0) {
return;
}
constexpr uint16_t kTriggerAddress = 0;
constexpr uint16_t kRobotPoseAddress = 2;
constexpr uint16_t kRobotPoseRegCount = 12;
// 缓存机械臂位姿写入地址2~136个float32
for (uint16_t i = 0; i < count; ++i) {
uint16_t addr = startAddress + i;
if (addr >= kRobotPoseAddress && addr < kRobotPoseAddress + kRobotPoseRegCount) {
m_modbusRobotPoseRegs[addr - kRobotPoseAddress] = data[i];
}
}
// 检查触发
uint16_t triggerValue = 0;
bool hasTrigger = false;
for (uint16_t i = 0; i < count; ++i) {
if (startAddress + i == kTriggerAddress) {
triggerValue = data[i];
hasTrigger = true;
break;
}
}
if (!hasTrigger) {
return;
}
const uint16_t resetValue = 0;
WriteModbusRegisters(kTriggerAddress, &resetValue, 1);
if (triggerValue == static_cast<uint16_t>(DETECTION_TYPE_SCREW) ||
triggerValue == static_cast<uint16_t>(DETECTION_TYPE_TOOL_DISK)) {
// 从缓存的寄存器中解析机械臂位姿
RobotPose6D robotPose;
auto regToFloat = [this](int offset) -> float {
uint32_t raw = (static_cast<uint32_t>(m_modbusRobotPoseRegs[offset]) << 16) | static_cast<uint32_t>(m_modbusRobotPoseRegs[offset + 1]);
float val = 0;
std::memcpy(&val, &raw, sizeof(val));
return val;
};
robotPose.x = regToFloat(0);
robotPose.y = regToFloat(2);
robotPose.z = regToFloat(4);
robotPose.a = regToFloat(6);
robotPose.b = regToFloat(8);
robotPose.c = regToFloat(10);
LOG_INFO("Modbus trigger: type=%u, robotPose=(%.3f, %.3f, %.3f, %.3f, %.3f, %.3f)\n",
triggerValue, robotPose.x, robotPose.y, robotPose.z, robotPose.a, robotPose.b, robotPose.c);
TriggerDetection(-1, static_cast<DetectionType>(triggerValue), robotPose);
return;
}
LOG_WARNING("Unsupported Modbus trigger value: %u\n", triggerValue);
_UpdateModbusWorkStatus(3);
if (auto pStatus = GetStatusCallback<IYScrewPositionStatus>()) {
pStatus->OnStatusUpdate(QString("Modbus触发值无效:%1").arg(triggerValue).toStdString());
}
}
bool ScrewPositionPresenter::CalculatePlaneCalibration(
const std::vector<std::pair<EVzResultDataType, SVzLaserLineData>>& scanData,
double planeCalib[9],
double& planeHeight,
double invRMatrix[9])
{
try {
if (scanData.empty()) {
LOG_ERROR("No scan data available for plane calibration\n");
return false;
}
LaserDataLoader dataLoader;
std::vector<std::vector<SVzNL3DPosition>> xyzData;
int convertResult = dataLoader.ConvertToSVzNL3DPosition(scanData, xyzData);
if (convertResult != SUCCESS || xyzData.empty()) {
LOG_WARNING("Failed to convert data to XYZ format or no XYZ data available\n");
return false;
}
const double identity[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
std::memcpy(planeCalib, identity, sizeof(double) * 9);
std::memcpy(invRMatrix, identity, sizeof(double) * 9);
planeHeight = -1.0;
LOG_INFO("Plane calibration calculated successfully: height=%.3f\n", planeHeight);
return true;
} catch (const std::exception& e) {
LOG_ERROR("Exception in CalculatePlaneCalibration: %s\n", e.what());
return false;
} catch (...) {
LOG_ERROR("Unknown exception in CalculatePlaneCalibration\n");
return false;
}
}
bool ScrewPositionPresenter::SaveLevelingResults(double planeCalib[9], double planeHeight, double invRMatrix[9],
int cameraIndex, const QString& cameraName)
{
try {
if (!m_pConfigManager) {
LOG_ERROR("ConfigManager is null, cannot save leveling results\n");
return false;
}
if (cameraIndex <= 0 || cameraName.isEmpty()) {
LOG_ERROR("Invalid camera info when saving leveling results\n");
return false;
}
const QString configPath = PathManager::GetInstance().GetConfigFilePath();
SystemConfig systemConfig = m_pConfigManager->GetConfig();
VrCameraPlaneCalibParam cameraParam;
cameraParam.cameraIndex = cameraIndex;
cameraParam.cameraName = cameraName.toStdString();
cameraParam.planeHeight = planeHeight;
cameraParam.isCalibrated = true;
for (int i = 0; i < 9; ++i) {
cameraParam.planeCalib[i] = planeCalib[i];
cameraParam.invRMatrix[i] = invRMatrix[i];
}
systemConfig.configResult.algorithmParams.planeCalibParam.SetCameraCalibParam(cameraParam);
if (!m_pConfigManager->UpdateFullConfig(systemConfig)) {
LOG_ERROR("Failed to update config with leveling results\n");
return false;
}
if (!m_pConfigManager->SaveConfigToFile(configPath.toStdString())) {
LOG_ERROR("Failed to save config file with leveling results\n");
return false;
}
LOG_INFO("Leveling results saved successfully for camera %d (%s)\n",
cameraIndex, cameraName.toUtf8().constData());
return true;
} catch (const std::exception& e) {
LOG_ERROR("Exception in SaveLevelingResults: %s\n", e.what());
return false;
}
}
bool ScrewPositionPresenter::LoadLevelingResults(int cameraIndex, const QString& cameraName,
double planeCalib[9], double& planeHeight, double invRMatrix[9])
{
try {
if (!m_pConfigManager) {
LOG_ERROR("ConfigManager is null, cannot load calibration data\n");
return false;
}
const ConfigResult configResult = m_pConfigManager->GetConfigResult();
VrCameraPlaneCalibParam cameraParamValue;
if (!configResult.algorithmParams.planeCalibParam.GetCameraCalibParam(cameraIndex, cameraParamValue) ||
!cameraParamValue.isCalibrated) {
LOG_INFO("No calibration data found for camera %d (%s)\n",
cameraIndex, cameraName.toUtf8().constData());
return false;
}
for (int i = 0; i < 9; ++i) {
planeCalib[i] = cameraParamValue.planeCalib[i];
invRMatrix[i] = cameraParamValue.invRMatrix[i];
}
planeHeight = cameraParamValue.planeHeight;
return true;
} catch (const std::exception& e) {
LOG_ERROR("Exception in LoadLevelingResults: %s\n", e.what());
return false;
}
}
void ScrewPositionPresenter::DeinitApp()
{
LOG_DEBUG("Deinitializing ScrewPositionPresenter\n");
StopDetection();
if (m_pTCPServer) {
m_pTCPServer->Deinitialize();
delete m_pTCPServer;
m_pTCPServer = nullptr;
}
if (m_pConfigManager) {
delete m_pConfigManager;
m_pConfigManager = nullptr;
}
if (m_pDetectPresenter) {
delete m_pDetectPresenter;
m_pDetectPresenter = nullptr;
}
}
bool ScrewPositionPresenter::TriggerDetection(int cameraIndex, DetectionType detectionType, const RobotPose6D& robotPose)
{
if (cameraIndex > 0) {
SetDefaultCameraIndex(cameraIndex);
}
m_currentDetectionType = detectionType;
m_currentRobotPose = robotPose;
m_requestTimestamp = QDateTime::currentMSecsSinceEpoch();
if (!m_bCameraConnected) {
LOG_WARNING("Camera not connected, cannot trigger detection\n");
_UpdateModbusWorkStatus(3);
return false;
}
if (GetCurrentWorkStatus() == WorkStatus::Working) {
LOG_WARNING("Detection is already running, skip duplicated trigger\n");
_UpdateModbusWorkStatus(1);
return false;
}
_InitializeModbusRegisters();
_ResetModbusResultRegisters();
_UpdateModbusWorkStatus(1);
int ret = StartDetection(cameraIndex, false);
if (ret != SUCCESS) {
LOG_ERROR("Failed to trigger detection, error: %d\n", ret);
_UpdateModbusWorkStatus(3);
return false;
}
return true;
}
int ScrewPositionPresenter::LoadAndDetect(const QString& fileName, DetectionType detectionType)
{
LOG_INFO("Loading data from file: %s, detectionType: %d\n",
fileName.toStdString().c_str(), static_cast<int>(detectionType));
m_currentDetectionType = detectionType;
return LoadDebugDataAndDetect(fileName.toStdString());
}
void ScrewPositionPresenter::ReconnectCamera()
{
LOG_INFO("Attempting to reconnect cameras\n");
TryReconnectCameras();
}
ScrewPositionPresenter::AlgoParams ScrewPositionPresenter::GetAlgoParams() const
{
AlgoParams params;
if (m_pConfigManager) {
const VrAlgorithmParams algorithmParams = m_pConfigManager->GetAlgorithmParams();
params.screwParam = algorithmParams.screwParam;
params.cornerParam = algorithmParams.cornerParam;
params.filterParam = algorithmParams.filterParam;
params.growParam = algorithmParams.growParam;
} else {
params.screwParam.rodDiameter = 10.0;
params.screwParam.isHorizonScan = true;
}
return params;
}
QString ScrewPositionPresenter::GetAlgoVersion() const
{
return DetectPresenter::GetAlgoVersion();
}
void ScrewPositionPresenter::SetAlgoParams(const AlgoParams& params)
{
if (!m_pConfigManager) {
LOG_WARNING("ConfigManager not initialized, cannot set algorithm params\n");
return;
}
VrAlgorithmParams algorithmParams = m_pConfigManager->GetAlgorithmParams();
algorithmParams.screwParam = params.screwParam;
algorithmParams.cornerParam = params.cornerParam;
algorithmParams.filterParam = params.filterParam;
algorithmParams.growParam = params.growParam;
m_pConfigManager->UpdateAlgorithmParams(algorithmParams);
LOG_INFO("Algorithm parameters updated\n");
}