#include "dialogalgoarg.h" #include "ui_dialogalgoarg.h" #include #include #include #include #include #include #include #include #include #include #include "PathManager.h" #include "StyledMessageBox.h" #include "HandEyeCalibWidget.h" #include "VrLog.h" DialogAlgoarg::DialogAlgoarg(ConfigManager* configManager, QWidget *parent) : QDialog(parent) , ui(new Ui::DialogAlgoarg) , m_pConfigManager(configManager) , m_handEyeCalibWidget(nullptr) { try { ui->setupUi(this); // 获取配置文件路径 m_configFilePath = PathManager::GetInstance().GetConfigFilePath(); // 检查配置文件路径是否有效 if (m_configFilePath.isEmpty()) { StyledMessageBox::critical(this, "错误", "无法获取配置文件路径!"); return; } // 从配置文件加载数据到界面 LoadConfigToUI(); // 初始化手眼标定 tab InitHandEyeCalibTab(); } catch (const std::exception& e) { StyledMessageBox::critical(this, "初始化错误", QString("对话框初始化失败: %1").arg(e.what())); } catch (...) { StyledMessageBox::critical(this, "初始化错误", "对话框初始化失败!(未知错误)"); } } DialogAlgoarg::~DialogAlgoarg() { delete ui; } void DialogAlgoarg::LoadConfigToUI() { if (!m_pConfigManager) { StyledMessageBox::critical(this, "错误", "配置对象未初始化!"); return; } try { // 从ConfigManager获取配置数据 ConfigResult configData = m_pConfigManager->GetConfigResult(); // 检查配置文件路径是否有效 if (m_configFilePath.isEmpty()) { LOG_WARNING("Config file path is empty\n"); } // 加载算法参数到UI const VrAlgorithmParams& algoParams = configData.algorithmParams; // 加载各个参数组 LoadWorkpieceParamToUI(algoParams.workpieceParam); LoadFilterParamToUI(algoParams.filterParam); LoadCornerParamToUI(algoParams.cornerParam); LoadGrowParamToUI(algoParams.growParam); } catch (const std::exception& e) { LOG_ERROR("Exception in LoadConfigToUI: %s\n", e.what()); StyledMessageBox::warning(this, "警告", QString("加载配置时发生异常: %1\n将使用默认参数显示").arg(e.what())); // 发生异常时使用默认参数 ConfigResult configData; const VrAlgorithmParams& algoParams = configData.algorithmParams; LoadWorkpieceParamToUI(algoParams.workpieceParam); LoadFilterParamToUI(algoParams.filterParam); LoadCornerParamToUI(algoParams.cornerParam); LoadGrowParamToUI(algoParams.growParam); } catch (...) { LOG_ERROR("Unknown exception in LoadConfigToUI\n"); StyledMessageBox::warning(this, "警告", "加载配置文件失败(未知错误),将使用默认参数显示"); // 发生未知异常时使用默认参数 ConfigResult configData; const VrAlgorithmParams& algoParams = configData.algorithmParams; LoadWorkpieceParamToUI(algoParams.workpieceParam); LoadFilterParamToUI(algoParams.filterParam); LoadCornerParamToUI(algoParams.cornerParam); LoadGrowParamToUI(algoParams.growParam); } } void DialogAlgoarg::LoadWorkpieceParamToUI(const VrWorkpieceParam& param) { if (!ui) return; ui->lineEdit_lineLen->setText(QString::number(param.lineLen)); ui->lineEdit_dirAngleScale->setText(QString::number(param.dirAngleScale)); ui->lineEdit_lineDeviation->setText(QString::number(param.lineDeviation)); ui->lineEdit_minCutAngleTh->setText(QString::number(param.minCutAngleTh)); } void DialogAlgoarg::LoadFilterParamToUI(const VrOutlierFilterParam& param) { if (!ui) return; ui->lineEdit_continuityTh->setText(QString::number(param.continuityTh)); ui->lineEdit_outlierTh->setText(QString::number(param.outlierTh)); } void DialogAlgoarg::LoadCornerParamToUI(const VrCornerParam& param) { if (!ui) return; ui->lineEdit_cornerTh->setText(QString::number(param.cornerTh)); ui->lineEdit_scale->setText(QString::number(param.scale)); ui->lineEdit_minEndingGap->setText(QString::number(param.minEndingGap)); ui->lineEdit_minEndingGap_z->setText(QString::number(param.minEndingGap_z)); ui->lineEdit_jumpCornerTh_1->setText(QString::number(param.jumpCornerTh_1)); ui->lineEdit_jumpCornerTh_2->setText(QString::number(param.jumpCornerTh_2)); } void DialogAlgoarg::LoadGrowParamToUI(const VrTreeGrowParam& param) { if (!ui) return; ui->lineEdit_maxLineSkipNum->setText(QString::number(param.maxLineSkipNum)); ui->lineEdit_yDeviation_max->setText(QString::number(param.yDeviation_max)); ui->lineEdit_maxSkipDistance->setText(QString::number(param.maxSkipDistance)); ui->lineEdit_zDeviation_max->setText(QString::number(param.zDeviation_max)); ui->lineEdit_minLTypeTreeLen->setText(QString::number(param.minLTypeTreeLen)); ui->lineEdit_minVTypeTreeLen->setText(QString::number(param.minVTypeTreeLen)); } bool DialogAlgoarg::SaveConfigFromUI() { if (!m_pConfigManager) { return false; } try { // 获取当前配置 SystemConfig systemConfig = m_pConfigManager->GetConfig(); VrAlgorithmParams& algoParams = systemConfig.configResult.algorithmParams; // 保存各个参数组 if (!SaveWorkpieceParamFromUI(algoParams.workpieceParam)) { StyledMessageBox::warning(this, "错误", "工件参数输入有误,请检查!"); return false; } if (!SaveFilterParamFromUI(algoParams.filterParam)) { StyledMessageBox::warning(this, "错误", "滤波参数输入有误,请检查!"); return false; } if (!SaveCornerParamFromUI(algoParams.cornerParam)) { StyledMessageBox::warning(this, "错误", "拐角参数输入有误,请检查!"); return false; } if (!SaveGrowParamFromUI(algoParams.growParam)) { StyledMessageBox::warning(this, "错误", "生长参数输入有误,请检查!"); return false; } // 保存手眼标定参数(从临时缓存更新到配置) algoParams.handEyeCalibParam = m_handEyeCalibParams; // 更新并保存配置到文件 if (!m_pConfigManager->UpdateFullConfig(systemConfig)) { return false; } return m_pConfigManager->SaveConfigToFile(m_configFilePath.toStdString()); } catch (const std::exception& e) { return false; } } bool DialogAlgoarg::SaveWorkpieceParamFromUI(VrWorkpieceParam& param) { bool ok = true; param.lineLen = ui->lineEdit_lineLen->text().toDouble(&ok); if (!ok) return false; param.dirAngleScale = ui->lineEdit_dirAngleScale->text().toDouble(&ok); if (!ok) return false; param.lineDeviation = ui->lineEdit_lineDeviation->text().toDouble(&ok); if (!ok) return false; param.minCutAngleTh = ui->lineEdit_minCutAngleTh->text().toDouble(&ok); if (!ok) return false; return true; } bool DialogAlgoarg::SaveFilterParamFromUI(VrOutlierFilterParam& param) { bool ok = true; param.continuityTh = ui->lineEdit_continuityTh->text().toDouble(&ok); if (!ok) return false; param.outlierTh = ui->lineEdit_outlierTh->text().toDouble(&ok); if (!ok) return false; return true; } bool DialogAlgoarg::SaveCornerParamFromUI(VrCornerParam& param) { bool ok = true; param.cornerTh = ui->lineEdit_cornerTh->text().toDouble(&ok); if (!ok) return false; param.scale = ui->lineEdit_scale->text().toDouble(&ok); if (!ok) return false; param.minEndingGap = ui->lineEdit_minEndingGap->text().toDouble(&ok); if (!ok) return false; param.minEndingGap_z = ui->lineEdit_minEndingGap_z->text().toDouble(&ok); if (!ok) return false; param.jumpCornerTh_1 = ui->lineEdit_jumpCornerTh_1->text().toDouble(&ok); if (!ok) return false; param.jumpCornerTh_2 = ui->lineEdit_jumpCornerTh_2->text().toDouble(&ok); if (!ok) return false; return true; } bool DialogAlgoarg::SaveGrowParamFromUI(VrTreeGrowParam& param) { bool ok = true; param.maxLineSkipNum = ui->lineEdit_maxLineSkipNum->text().toInt(&ok); if (!ok) return false; param.yDeviation_max = ui->lineEdit_yDeviation_max->text().toDouble(&ok); if (!ok) return false; param.maxSkipDistance = ui->lineEdit_maxSkipDistance->text().toDouble(&ok); if (!ok) return false; param.zDeviation_max = ui->lineEdit_zDeviation_max->text().toDouble(&ok); if (!ok) return false; param.minLTypeTreeLen = ui->lineEdit_minLTypeTreeLen->text().toDouble(&ok); if (!ok) return false; param.minVTypeTreeLen = ui->lineEdit_minVTypeTreeLen->text().toDouble(&ok); if (!ok) return false; return true; } void DialogAlgoarg::on_btn_camer_ok_clicked() { if (SaveConfigFromUI()) { StyledMessageBox::information(this, "成功", "配置保存成功!"); accept(); } else { StyledMessageBox::warning(this, "失败", "配置保存失败,请检查文件权限或参数输入!"); } } void DialogAlgoarg::on_btn_camer_cancel_clicked() { // 直接关闭窗口,不保存任何更改 reject(); } // ========== 手眼标定相关实现 ========== void DialogAlgoarg::InitHandEyeCalibTab() { if (!ui || !m_pConfigManager) return; // 创建共享控件并嵌入 tab 的 layout m_handEyeCalibWidget = new HandEyeCalibWidget(this); ui->verticalLayout_handeyecalib->addWidget(m_handEyeCalibWidget); // 设置默认文件路径 m_handEyeCalibWidget->setDefaultFilePath( PathManager::GetInstance().GetAppConfigDirectory()); // 从配置中获取相机列表填充控件 ConfigResult configData = m_pConfigManager->GetConfigResult(); QVector cameraList; for (size_t i = 0; i < configData.cameraList.size(); ++i) { const DeviceInfo& camera = configData.cameraList[i]; HandEyeCalibCameraInfo info; info.cameraIndex = static_cast(i + 1); // 1-based info.displayName = QString::fromStdString(camera.name); cameraList.append(info); } m_handEyeCalibWidget->setCameraList(cameraList); // 加载已有的手眼标定数据到缓存和控件 m_handEyeCalibParams = configData.algorithmParams.handEyeCalibParam; for (const VrHandEyeCalibParam& param : m_handEyeCalibParams.cameraHandEyeParams) { m_handEyeCalibWidget->setCalibData( param.cameraIndex, param.transformMatrix, param.isCalibrated); } // 连接信号 connect(m_handEyeCalibWidget, &HandEyeCalibWidget::calibMatrixLoaded, this, &DialogAlgoarg::onCalibMatrixLoaded); connect(m_handEyeCalibWidget, &HandEyeCalibWidget::saveCalibRequested, this, &DialogAlgoarg::onSaveCalibRequested); } void DialogAlgoarg::onCalibMatrixLoaded(int cameraIndex, const double* matrix) { // 更新临时缓存 VrHandEyeCalibParam param; param.cameraIndex = cameraIndex; param.isCalibrated = true; memcpy(param.transformMatrix, matrix, sizeof(double) * 16); m_handEyeCalibParams.SetCameraHandEyeParam(param); StyledMessageBox::information(this, "成功", "标定矩阵加载成功!"); } void DialogAlgoarg::onSaveCalibRequested(int cameraIndex, const double* matrix) { const VrHandEyeCalibParam* param = m_handEyeCalibParams.GetCameraHandEyeParam(cameraIndex); if (!param || !param->isCalibrated) { StyledMessageBox::warning(this, "提示", "当前相机尚未加载标定矩阵!请先加载标定矩阵文件。"); return; } // 将手眼标定数据保存到配置 try { SystemConfig systemConfig = m_pConfigManager->GetConfig(); systemConfig.configResult.algorithmParams.handEyeCalibParam = m_handEyeCalibParams; if (m_pConfigManager->UpdateFullConfig(systemConfig) && m_pConfigManager->SaveConfigToFile(m_configFilePath.toStdString())) { StyledMessageBox::information(this, "成功", "手眼标定参数已保存到配置文件!"); } else { StyledMessageBox::warning(this, "失败", "保存手眼标定参数失败!"); } } catch (const std::exception& e) { StyledMessageBox::warning(this, "错误", QString("保存手眼标定参数异常: %1").arg(e.what())); } }