2026-07-03 19:21:24 +08:00

680 lines
23 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 "JiuruiWorkpiecePosePresenter.h"
#include "DetectPresenter.h"
#include "PathManager.h"
#include "JiuruiWorkpiecePoseTCPProtocol.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>
JiuruiWorkpiecePosePresenter::JiuruiWorkpiecePosePresenter(QObject *parent)
: BasePresenter(parent)
{
}
JiuruiWorkpiecePosePresenter::~JiuruiWorkpiecePosePresenter()
{
if (m_pConfigManager) {
delete m_pConfigManager;
m_pConfigManager = nullptr;
}
if (m_pTCPServer) {
m_pTCPServer->StopServer();
delete m_pTCPServer;
m_pTCPServer = nullptr;
}
if (m_pDetectPresenter) {
delete m_pDetectPresenter;
m_pDetectPresenter = nullptr;
}
}
int JiuruiWorkpiecePosePresenter::InitApp()
{
LOG_DEBUG("Start APP Version: %s\n", JIURUIWORKPIECEPOSE_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<IYJiuruiWorkpiecePoseStatus>()) {
pStatus->OnStatusUpdate("配置管理器创建失败");
}
return ERR_CODE(DEV_CONFIG_ERR);
}
if (!m_pConfigManager->Initialize()) {
LOG_ERROR("Failed to initialize ConfigManager\n");
if (auto pStatus = GetStatusCallback<IYJiuruiWorkpiecePoseStatus>()) {
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<IYJiuruiWorkpiecePoseStatus>()) {
pStatus->OnStatusUpdate("TCP服务器初始化失败");
}
m_bTCPConnected = false;
} else {
if (auto pStatus = GetStatusCallback<IYJiuruiWorkpiecePoseStatus>()) {
pStatus->OnStatusUpdate("TCP服务器初始化成功");
}
}
if (auto pStatus = GetStatusCallback<IYJiuruiWorkpiecePoseStatus>()) {
pStatus->OnStatusUpdate("设备初始化完成");
}
CheckAndUpdateWorkStatus();
if (auto pStatus = GetStatusCallback<IYJiuruiWorkpiecePoseStatus>()) {
pStatus->OnStatusUpdate("配置初始化成功");
}
return SUCCESS;
}
int JiuruiWorkpiecePosePresenter::InitAlgoParams()
{
LOG_DEBUG("initializing algorithm parameters\n");
const ConfigResult configResult = m_pConfigManager->GetConfigResult();
SetDebugParam(configResult.debugParam);
LOG_INFO("Algorithm parameters: cornerTh=%.1f scale=%.1f, wpLen=%.1f wpWidth=%.1f wpThick=%.1f\n",
configResult.algorithmParams.cornerParam.cornerTh,
configResult.algorithmParams.cornerParam.scale,
configResult.algorithmParams.workpieceParam.len,
configResult.algorithmParams.workpieceParam.width,
configResult.algorithmParams.workpieceParam.thickness);
LOG_INFO("Algorithm parameters initialized successfully\n");
return SUCCESS;
}
CalibMatrix JiuruiWorkpiecePosePresenter::GetClibMatrix(int cameraIndex) const
{
CalibMatrix clibMatrix;
const double identity[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, identity, sizeof(identity));
if (!m_pConfigManager) {
LOG_WARNING("ConfigManager not initialized while requesting clib matrix\n");
return clibMatrix;
}
const ConfigResult configResult = m_pConfigManager->GetConfigResult();
if (const auto* item = configResult.FindHandEyeMatrix(cameraIndex)) {
std::memcpy(clibMatrix.clibMatrix, item->matrix, sizeof(identity));
} else {
LOG_WARNING("No clib matrix configured for camera=%d, using identity\n", cameraIndex);
}
return clibMatrix;
}
void JiuruiWorkpiecePosePresenter::CheckAndUpdateWorkStatus()
{
SetWorkStatus(m_bCameraConnected ? WorkStatus::Ready : WorkStatus::Error);
}
int JiuruiWorkpiecePosePresenter::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<IYJiuruiWorkpiecePoseStatus>()) {
pStatus->OnStatusUpdate(QString("扫描线数:%1正在算法检测...").arg(lineNum).toStdString());
}
if (!m_pDetectPresenter) {
LOG_ERROR("DetectPresenter is null, cannot proceed with detection\n");
if (auto pStatus = GetStatusCallback<IYJiuruiWorkpiecePoseStatus>()) {
pStatus->OnStatusUpdate("检测处理器未初始化");
}
return ERR_CODE(DEV_NOT_FIND);
}
CVrTimeUtils oTimeUtils;
const CalibMatrix currentClibMatrix = GetClibMatrix(m_currentCameraIndex);
const SSG_planeCalibPara groundCalibParam = _GetCameraCalibParam(m_currentCameraIndex);
const ConfigResult configResult = m_pConfigManager->GetConfigResult();
const VrDebugParam debugParam = configResult.debugParam;
const int poseOutputOrder = configResult.poseOutputOrder;
// 使用共享算法参数(类比 WorkpieceHole 风格)
VrAlgorithmParams algorithmParams = configResult.algorithmParams;
// 从全局配置获取欧拉角输入/输出顺序(网络配置页设置)
HandEyeExtrinsic extrinsic;
extrinsic.eulerOrder = configResult.eulerOrder;
// 从手眼标定矩阵列表获取当前相机的外参补偿值
if (const auto* heItem = configResult.FindHandEyeMatrix(m_currentCameraIndex)) {
extrinsic.rotX = heItem->rotX;
extrinsic.rotY = heItem->rotY;
extrinsic.rotZ = heItem->rotZ;
extrinsic.offsetX = heItem->offsetX;
extrinsic.offsetY = heItem->offsetY;
extrinsic.offsetZ = heItem->offsetZ;
extrinsic.outRotX = heItem->outRotX;
extrinsic.outRotY = heItem->outRotY;
extrinsic.outRotZ = heItem->outRotZ;
}
LOG_INFO("[Algo Thread] camera=%d eulerOrder=%d(outputEuler=%d) poseOutputOrder=%d rot=(%.3f, %.3f, %.3f) outRot=(%.3f, %.3f, %.3f) offset=(%.3f, %.3f, %.3f)\n",
m_currentCameraIndex,
extrinsic.eulerOrder, configResult.outputEulerOrder, poseOutputOrder,
extrinsic.rotX, extrinsic.rotY, extrinsic.rotZ,
extrinsic.outRotX, extrinsic.outRotY, extrinsic.outRotZ,
extrinsic.offsetX, extrinsic.offsetY, extrinsic.offsetZ);
DetectionResult detectionResult;
detectionResult.cameraIndex = m_currentCameraIndex;
int nRet = m_pDetectPresenter->DetectWorkpiece(
m_currentCameraIndex,
detectionDataCache,
algorithmParams,
groundCalibParam,
debugParam,
m_dataLoader,
currentClibMatrix.clibMatrix,
m_currentRobotPose,
extrinsic,
poseOutputOrder,
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] objects=%zu time : %.2f ms\n",
detectionResult.positions.size(),
oTimeUtils.GetElapsedTimeInMilliSec());
if (auto pStatus = GetStatusCallback<IYJiuruiWorkpiecePoseStatus>()) {
pStatus->OnDetectionResult(detectionResult);
}
QString statusMsg;
if (!detectionResult.success) {
statusMsg = detectionResult.message;
} else {
statusMsg = QString("工件检测完成,发现%1个工件").arg(detectionResult.positions.size());
}
if (auto pStatus = GetStatusCallback<IYJiuruiWorkpiecePoseStatus>()) {
pStatus->OnStatusUpdate(statusMsg.toStdString());
}
_SendDetectionResultToTCP(detectionResult, m_currentCameraIndex);
_PublishDetectionResultToModbus(detectionResult);
return nRet;
}
void JiuruiWorkpiecePosePresenter::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<IYJiuruiWorkpiecePoseStatus>()) {
pStatus->OnStatusUpdate("配置已更新,算法参数重新加载成功");
}
} else {
LOG_ERROR("Failed to reload algorithm parameters after config change, error: %d\n", result);
if (auto pStatus = GetStatusCallback<IYJiuruiWorkpiecePoseStatus>()) {
pStatus->OnStatusUpdate("配置更新后算法参数重新加载失败");
}
}
if (tcpResult != SUCCESS) {
LOG_ERROR("Failed to restart TCP server after config change, error: %d\n", tcpResult);
if (auto pStatus = GetStatusCallback<IYJiuruiWorkpiecePoseStatus>()) {
pStatus->OnStatusUpdate("TCP server restart failed");
}
}
}
SSG_planeCalibPara JiuruiWorkpiecePosePresenter::_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 JiuruiWorkpiecePosePresenter::OnCameraStatusChanged(int cameraIndex, bool isConnected)
{
LOG_INFO("Camera %d status changed: %s\n", cameraIndex, isConnected ? "connected" : "disconnected");
if (auto pStatus = GetStatusCallback<IYJiuruiWorkpiecePoseStatus>()) {
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 JiuruiWorkpiecePosePresenter::OnWorkStatusChanged(WorkStatus status)
{
if (auto pStatus = GetStatusCallback<IYJiuruiWorkpiecePoseStatus>()) {
pStatus->OnWorkStatusChanged(status);
}
if (!m_modbusRegistersInitialized && status == WorkStatus::Ready) {
_InitializeModbusRegisters();
}
if (status == WorkStatus::Working) {
_UpdateModbusWorkStatus(1);
} else if (status == WorkStatus::Error) {
_UpdateModbusWorkStatus(3);
}
}
void JiuruiWorkpiecePosePresenter::OnCameraCountChanged(int count)
{
if (auto pStatus = GetStatusCallback<IYJiuruiWorkpiecePoseStatus>()) {
pStatus->OnCameraCountChanged(count);
}
}
void JiuruiWorkpiecePosePresenter::OnStatusUpdate(const std::string& statusMessage)
{
if (auto pStatus = GetStatusCallback<IYJiuruiWorkpiecePoseStatus>()) {
pStatus->OnStatusUpdate(statusMessage);
}
}
void JiuruiWorkpiecePosePresenter::OnModbusServerStatusChanged(bool isConnected)
{
if (auto pStatus = GetStatusCallback<IYJiuruiWorkpiecePoseStatus>()) {
pStatus->OnRobotConnectionChanged(isConnected);
}
}
void JiuruiWorkpiecePosePresenter::OnModbusWriteCallback(uint16_t startAddress, const uint16_t* data, uint16_t count)
{
if (!data || count == 0) {
return;
}
// Modbus 地址分配(与 TCPServerMethods.cpp 一致):
// 地址 0 : 触发寄存器
// 地址 2~13 : 机械臂位姿6 个 float32 = 12 个 uint16
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 == 1) { // JiuruiWorkpiece detection type
// 从缓存的寄存器中解析机械臂位姿
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, robotPose);
return;
}
LOG_WARNING("Unsupported Modbus trigger value: %u\n", triggerValue);
_UpdateModbusWorkStatus(3);
if (auto pStatus = GetStatusCallback<IYJiuruiWorkpiecePoseStatus>()) {
pStatus->OnStatusUpdate(QString("Modbus触发值无效:%1").arg(triggerValue).toStdString());
}
}
bool JiuruiWorkpiecePosePresenter::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;
}
// 调用算法库计算地面标定参数
SSG_planeCalibPara calibResult = wd_getGroundCalibPara(xyzData);
for (int i = 0; i < 9; ++i) {
planeCalib[i] = calibResult.planeCalib[i];
invRMatrix[i] = calibResult.invRMatrix[i];
}
planeHeight = calibResult.planeHeight;
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 JiuruiWorkpiecePosePresenter::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 JiuruiWorkpiecePosePresenter::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 JiuruiWorkpiecePosePresenter::DeinitApp()
{
LOG_DEBUG("Deinitializing JiuruiWorkpiecePosePresenter\n");
StopDetection();
if (m_pTCPServer) {
m_pTCPServer->StopServer();
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 JiuruiWorkpiecePosePresenter::TriggerDetection(int cameraIndex, const RobotPose6D& robotPose)
{
if (cameraIndex > 0) {
SetDefaultCameraIndex(cameraIndex);
}
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 JiuruiWorkpiecePosePresenter::LoadAndDetect(const QString& fileName)
{
LOG_INFO("Loading data from file: %s\n", fileName.toStdString().c_str());
return LoadDebugDataAndDetect(fileName.toStdString());
}
void JiuruiWorkpiecePosePresenter::ReconnectCamera()
{
LOG_INFO("Attempting to reconnect cameras\n");
TryReconnectCameras();
}
VrCornerParam JiuruiWorkpiecePosePresenter::GetCornerParams() const
{
VrCornerParam params;
if (m_pConfigManager) {
const ConfigResult configResult = m_pConfigManager->GetConfigResult();
params = configResult.algorithmParams.cornerParam;
return params;
}
// 默认值由 VrCornerParam 结构体默认初始化提供
return params;
}
QString JiuruiWorkpiecePosePresenter::GetAlgoVersion() const
{
return DetectPresenter::GetAlgoVersion();
}
void JiuruiWorkpiecePosePresenter::SetCornerParams(const VrCornerParam& params)
{
if (!m_pConfigManager) {
LOG_WARNING("ConfigManager not initialized, cannot set algorithm params\n");
return;
}
// 将角点参数写入共享算法参数(类比 WorkpieceHole 风格)
SystemConfig systemConfig = m_pConfigManager->GetConfig();
systemConfig.configResult.algorithmParams.cornerParam = params;
m_pConfigManager->UpdateFullConfig(systemConfig);
LOG_INFO("Corner parameters updated\n");
}
VrJiuruiWorkpieceParam JiuruiWorkpiecePosePresenter::GetWorkpieceParams() const
{
VrJiuruiWorkpieceParam params;
if (m_pConfigManager) {
const ConfigResult configResult = m_pConfigManager->GetConfigResult();
params = configResult.algorithmParams.workpieceParam;
return params;
}
return params;
}
void JiuruiWorkpiecePosePresenter::SetWorkpieceParams(const VrJiuruiWorkpieceParam& params)
{
if (!m_pConfigManager) {
LOG_WARNING("ConfigManager not initialized, cannot set workpiece params\n");
return;
}
SystemConfig systemConfig = m_pConfigManager->GetConfig();
systemConfig.configResult.algorithmParams.workpieceParam = params;
m_pConfigManager->UpdateFullConfig(systemConfig);
LOG_INFO("Workpiece parameters updated: len=%.1f width=%.1f thickness=%.1f\n",
params.len, params.width, params.thickness);
}