2026-01-27 20:43:12 +08:00
|
|
|
|
#include "dialogalgoarg.h"
|
|
|
|
|
|
#include "ui_dialogalgoarg.h"
|
|
|
|
|
|
#include <QMessageBox>
|
|
|
|
|
|
#include <QPushButton>
|
|
|
|
|
|
#include <QtCore/QCoreApplication>
|
|
|
|
|
|
#include <QtCore/QFileInfo>
|
|
|
|
|
|
#include <QtCore/QDir>
|
|
|
|
|
|
#include <QtCore/QStandardPaths>
|
|
|
|
|
|
#include <QtCore/QFile>
|
|
|
|
|
|
#include <cstring>
|
2026-02-01 14:51:16 +08:00
|
|
|
|
#include <QSettings>
|
|
|
|
|
|
#include <QFileDialog>
|
2026-01-27 20:43:12 +08:00
|
|
|
|
#include "PathManager.h"
|
|
|
|
|
|
#include "StyledMessageBox.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "VrLog.h"
|
|
|
|
|
|
|
|
|
|
|
|
DialogAlgoarg::DialogAlgoarg(ConfigManager* configManager, QWidget *parent)
|
|
|
|
|
|
: QDialog(parent)
|
|
|
|
|
|
, ui(new Ui::DialogAlgoarg)
|
|
|
|
|
|
, m_pConfigManager(configManager)
|
|
|
|
|
|
{
|
|
|
|
|
|
try {
|
|
|
|
|
|
ui->setupUi(this);
|
|
|
|
|
|
|
|
|
|
|
|
// 隐藏标题栏
|
|
|
|
|
|
// setWindowFlags(Qt::FramelessWindowHint);
|
|
|
|
|
|
|
|
|
|
|
|
// 获取配置文件路径
|
|
|
|
|
|
m_configFilePath = PathManager::GetInstance().GetConfigFilePath();
|
|
|
|
|
|
|
|
|
|
|
|
// 检查配置文件路径是否有效
|
|
|
|
|
|
if (m_configFilePath.isEmpty()) {
|
|
|
|
|
|
StyledMessageBox::critical(this, "错误", "无法获取配置文件路径!");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-01 14:51:16 +08:00
|
|
|
|
// 初始化旋转顺序下拉框
|
|
|
|
|
|
InitEulerOrderComboBox();
|
|
|
|
|
|
|
2026-02-02 23:24:24 +08:00
|
|
|
|
// 初始化姿态输出顺序下拉框
|
|
|
|
|
|
InitPoseOutputOrderComboBox();
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化方向向量反向下拉框
|
|
|
|
|
|
InitDirVectorInvertComboBox();
|
|
|
|
|
|
|
2026-01-27 20:43:12 +08:00
|
|
|
|
// 从配置文件加载数据到界面
|
|
|
|
|
|
LoadConfigToUI();
|
|
|
|
|
|
|
|
|
|
|
|
} 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;
|
|
|
|
|
|
|
|
|
|
|
|
// 加载各个参数组
|
|
|
|
|
|
LoadWorkpieceHoleParamToUI(algoParams.workpieceHoleParam);
|
|
|
|
|
|
LoadLineSegParamToUI(algoParams.lineSegParam);
|
|
|
|
|
|
LoadFilterParamToUI(algoParams.filterParam);
|
|
|
|
|
|
LoadGrowParamToUI(algoParams.growParam);
|
|
|
|
|
|
|
2026-02-01 14:51:16 +08:00
|
|
|
|
// 加载网络配置(PLC和机械臂服务端)
|
|
|
|
|
|
LoadPlcRobotServerConfigToUI(configData.plcRobotServerConfig);
|
|
|
|
|
|
|
|
|
|
|
|
// 加载手眼标定矩阵
|
|
|
|
|
|
LoadCalibMatrixToUI();
|
|
|
|
|
|
|
2026-01-27 20:43:12 +08:00
|
|
|
|
} 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;
|
|
|
|
|
|
LoadWorkpieceHoleParamToUI(algoParams.workpieceHoleParam);
|
|
|
|
|
|
LoadLineSegParamToUI(algoParams.lineSegParam);
|
|
|
|
|
|
LoadFilterParamToUI(algoParams.filterParam);
|
|
|
|
|
|
LoadGrowParamToUI(algoParams.growParam);
|
|
|
|
|
|
} catch (...) {
|
|
|
|
|
|
LOG_ERROR("Unknown exception in LoadConfigToUI\n");
|
|
|
|
|
|
StyledMessageBox::warning(this, "警告", "加载配置文件失败(未知错误),将使用默认参数显示");
|
|
|
|
|
|
|
|
|
|
|
|
// 发生未知异常时使用默认参数
|
|
|
|
|
|
ConfigResult configData;
|
|
|
|
|
|
const VrAlgorithmParams& algoParams = configData.algorithmParams;
|
|
|
|
|
|
LoadWorkpieceHoleParamToUI(algoParams.workpieceHoleParam);
|
|
|
|
|
|
LoadLineSegParamToUI(algoParams.lineSegParam);
|
|
|
|
|
|
LoadFilterParamToUI(algoParams.filterParam);
|
|
|
|
|
|
LoadGrowParamToUI(algoParams.growParam);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DialogAlgoarg::LoadWorkpieceHoleParamToUI(const VrWorkpieceHoleParam& param)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!ui) return;
|
|
|
|
|
|
|
|
|
|
|
|
ui->lineEdit_workpieceType->setText(QString::number(param.workpieceType));
|
|
|
|
|
|
ui->lineEdit_holeDiameter->setText(QString::number(param.holeDiameter));
|
|
|
|
|
|
ui->lineEdit_holeDist_L->setText(QString::number(param.holeDist_L));
|
|
|
|
|
|
ui->lineEdit_holeDist_W->setText(QString::number(param.holeDist_W));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DialogAlgoarg::LoadLineSegParamToUI(const VrLineSegParam& param)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!ui) return;
|
|
|
|
|
|
|
|
|
|
|
|
ui->lineEdit_distScale->setText(QString::number(param.distScale));
|
|
|
|
|
|
ui->lineEdit_segGapTh_y->setText(QString::number(param.segGapTh_y));
|
|
|
|
|
|
ui->lineEdit_segGapTh_z->setText(QString::number(param.segGapTh_z));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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::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 (!SaveWorkpieceHoleParamFromUI(algoParams.workpieceHoleParam)) {
|
|
|
|
|
|
StyledMessageBox::warning(this, "错误", "工件孔参数输入有误,请检查!");
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!SaveLineSegParamFromUI(algoParams.lineSegParam)) {
|
|
|
|
|
|
StyledMessageBox::warning(this, "错误", "线段分割参数输入有误,请检查!");
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!SaveFilterParamFromUI(algoParams.filterParam)) {
|
|
|
|
|
|
StyledMessageBox::warning(this, "错误", "滤波参数输入有误,请检查!");
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!SaveGrowParamFromUI(algoParams.growParam)) {
|
|
|
|
|
|
StyledMessageBox::warning(this, "错误", "生长参数输入有误,请检查!");
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-01 14:51:16 +08:00
|
|
|
|
// 保存网络配置(PLC和机械臂服务端)
|
|
|
|
|
|
if (!SavePlcRobotServerConfigFromUI(systemConfig.configResult.plcRobotServerConfig)) {
|
|
|
|
|
|
StyledMessageBox::warning(this, "错误", "网络配置输入有误,请检查!");
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 保存手眼标定矩阵到配置
|
|
|
|
|
|
if (!SaveCalibMatrixToConfig(systemConfig.configResult.handEyeCalibMatrix)) {
|
|
|
|
|
|
StyledMessageBox::warning(this, "错误", "手眼标定矩阵输入有误,请检查!");
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-27 20:43:12 +08:00
|
|
|
|
// 更新并保存配置到文件
|
|
|
|
|
|
if (!m_pConfigManager->UpdateFullConfig(systemConfig)) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return m_pConfigManager->SaveConfigToFile(m_configFilePath.toStdString());
|
|
|
|
|
|
|
|
|
|
|
|
} catch (const std::exception& e) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool DialogAlgoarg::SaveWorkpieceHoleParamFromUI(VrWorkpieceHoleParam& param)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool ok = true;
|
|
|
|
|
|
|
|
|
|
|
|
param.workpieceType = ui->lineEdit_workpieceType->text().toInt(&ok);
|
|
|
|
|
|
if (!ok) return false;
|
|
|
|
|
|
|
|
|
|
|
|
param.holeDiameter = ui->lineEdit_holeDiameter->text().toDouble(&ok);
|
|
|
|
|
|
if (!ok) return false;
|
|
|
|
|
|
|
|
|
|
|
|
param.holeDist_L = ui->lineEdit_holeDist_L->text().toDouble(&ok);
|
|
|
|
|
|
if (!ok) return false;
|
|
|
|
|
|
|
|
|
|
|
|
param.holeDist_W = ui->lineEdit_holeDist_W->text().toDouble(&ok);
|
|
|
|
|
|
if (!ok) return false;
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool DialogAlgoarg::SaveLineSegParamFromUI(VrLineSegParam& param)
|
|
|
|
|
|
{
|
|
|
|
|
|
bool ok = true;
|
|
|
|
|
|
|
|
|
|
|
|
param.distScale = ui->lineEdit_distScale->text().toDouble(&ok);
|
|
|
|
|
|
if (!ok) return false;
|
|
|
|
|
|
|
|
|
|
|
|
param.segGapTh_y = ui->lineEdit_segGapTh_y->text().toDouble(&ok);
|
|
|
|
|
|
if (!ok) return false;
|
|
|
|
|
|
|
|
|
|
|
|
param.segGapTh_z = ui->lineEdit_segGapTh_z->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::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();
|
|
|
|
|
|
}
|
2026-02-01 14:51:16 +08:00
|
|
|
|
|
|
|
|
|
|
void DialogAlgoarg::on_btn_loadCalibMatrix_clicked()
|
|
|
|
|
|
{
|
|
|
|
|
|
QString filePath = QFileDialog::getOpenFileName(
|
|
|
|
|
|
this,
|
|
|
|
|
|
"选择手眼标定文件",
|
|
|
|
|
|
QString(),
|
|
|
|
|
|
"INI文件 (*.ini);;所有文件 (*.*)"
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
if (filePath.isEmpty()) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
LoadCalibMatrixFromFile(filePath);
|
|
|
|
|
|
StyledMessageBox::information(this, "提示", "已从文件导入标定矩阵");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QLineEdit* DialogAlgoarg::GetCalibLineEdit(int row, int col)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 通过名称查找对应的QLineEdit
|
|
|
|
|
|
QString name = QString("lineEdit_calib_%1_%2").arg(row).arg(col);
|
|
|
|
|
|
return findChild<QLineEdit*>(name);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DialogAlgoarg::LoadCalibMatrixToUI()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!m_pConfigManager) return;
|
|
|
|
|
|
|
|
|
|
|
|
ConfigResult configData = m_pConfigManager->GetConfigResult();
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 16; i++) {
|
|
|
|
|
|
QLineEdit* edit = GetCalibLineEdit(i / 4, i % 4);
|
|
|
|
|
|
if (edit) {
|
|
|
|
|
|
edit->setText(QString::number(configData.handEyeCalibMatrix.matrix[i], 'f', 6));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 加载旋转顺序
|
|
|
|
|
|
int eulerOrder = configData.handEyeCalibMatrix.eulerOrder;
|
|
|
|
|
|
int index = ui->comboBox_eulerOrder->findData(eulerOrder);
|
|
|
|
|
|
if (index >= 0) {
|
|
|
|
|
|
ui->comboBox_eulerOrder->setCurrentIndex(index);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DialogAlgoarg::LoadCalibMatrixFromFile(const QString& filePath)
|
|
|
|
|
|
{
|
|
|
|
|
|
QSettings settings(filePath, QSettings::IniFormat);
|
|
|
|
|
|
settings.beginGroup("CalibMatrixInfo_0");
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 16; i++) {
|
|
|
|
|
|
int row = i / 4;
|
|
|
|
|
|
int col = i % 4;
|
|
|
|
|
|
QString key = QString("dCalibMatrix_%1").arg(i);
|
|
|
|
|
|
double val = settings.value(key, (row == col) ? 1.0 : 0.0).toDouble();
|
|
|
|
|
|
|
|
|
|
|
|
QLineEdit* edit = GetCalibLineEdit(row, col);
|
|
|
|
|
|
if (edit) {
|
|
|
|
|
|
edit->setText(QString::number(val, 'f', 6));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
settings.endGroup();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool DialogAlgoarg::SaveCalibMatrixToConfig(VrHandEyeCalibMatrix& calibMatrix)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (int i = 0; i < 16; i++) {
|
|
|
|
|
|
QLineEdit* edit = GetCalibLineEdit(i / 4, i % 4);
|
|
|
|
|
|
if (!edit) return false;
|
|
|
|
|
|
|
|
|
|
|
|
bool ok = false;
|
|
|
|
|
|
calibMatrix.matrix[i] = edit->text().toDouble(&ok);
|
|
|
|
|
|
if (!ok) return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 保存旋转顺序
|
|
|
|
|
|
calibMatrix.eulerOrder = ui->comboBox_eulerOrder->currentData().toInt();
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DialogAlgoarg::InitEulerOrderComboBox()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 添加外旋旋转顺序选项(工业机械臂常用)
|
|
|
|
|
|
ui->comboBox_eulerOrder->addItem("RZ-RY-RX (外旋ZYX)", 11); // ABB、KUKA、发那科等常用
|
|
|
|
|
|
ui->comboBox_eulerOrder->addItem("RX-RY-RZ (外旋XYZ)", 10);
|
|
|
|
|
|
ui->comboBox_eulerOrder->addItem("RZ-RX-RY (外旋ZXY)", 12);
|
|
|
|
|
|
ui->comboBox_eulerOrder->addItem("RY-RX-RZ (外旋YXZ)", 13);
|
|
|
|
|
|
ui->comboBox_eulerOrder->addItem("RY-RZ-RX (外旋YZX)", 14);
|
|
|
|
|
|
ui->comboBox_eulerOrder->addItem("RX-RZ-RY (外旋XZY)", 15);
|
|
|
|
|
|
|
|
|
|
|
|
// 默认选择外旋 ZYX
|
|
|
|
|
|
ui->comboBox_eulerOrder->setCurrentIndex(0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-02 23:24:24 +08:00
|
|
|
|
void DialogAlgoarg::InitPoseOutputOrderComboBox()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 添加姿态输出顺序选项
|
|
|
|
|
|
ui->comboBox_poseOutputOrder->addItem("RPY (Roll, Pitch, Yaw)", POSE_ORDER_RPY); // 默认
|
|
|
|
|
|
ui->comboBox_poseOutputOrder->addItem("RYP (Roll, Yaw, Pitch)", POSE_ORDER_RYP);
|
|
|
|
|
|
ui->comboBox_poseOutputOrder->addItem("PRY (Pitch, Roll, Yaw)", POSE_ORDER_PRY);
|
|
|
|
|
|
ui->comboBox_poseOutputOrder->addItem("PYR (Pitch, Yaw, Roll)", POSE_ORDER_PYR);
|
|
|
|
|
|
ui->comboBox_poseOutputOrder->addItem("YRP (Yaw, Roll, Pitch)", POSE_ORDER_YRP);
|
|
|
|
|
|
ui->comboBox_poseOutputOrder->addItem("YPR (Yaw, Pitch, Roll)", POSE_ORDER_YPR);
|
|
|
|
|
|
|
|
|
|
|
|
// 默认选择 RPY
|
|
|
|
|
|
ui->comboBox_poseOutputOrder->setCurrentIndex(0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void DialogAlgoarg::InitDirVectorInvertComboBox()
|
|
|
|
|
|
{
|
|
|
|
|
|
// 添加方向向量反向选项
|
|
|
|
|
|
ui->comboBox_dirVectorInvert->addItem("不反向", DIR_INVERT_NONE);
|
|
|
|
|
|
ui->comboBox_dirVectorInvert->addItem("XY反向", DIR_INVERT_XY);
|
|
|
|
|
|
ui->comboBox_dirVectorInvert->addItem("XZ反向", DIR_INVERT_XZ);
|
|
|
|
|
|
ui->comboBox_dirVectorInvert->addItem("YZ反向(默认)", DIR_INVERT_YZ);
|
|
|
|
|
|
|
|
|
|
|
|
// 默认选择 YZ反向(兼容原有行为)
|
|
|
|
|
|
ui->comboBox_dirVectorInvert->setCurrentIndex(3);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-01 14:51:16 +08:00
|
|
|
|
void DialogAlgoarg::LoadPlcRobotServerConfigToUI(const VrPlcRobotServerConfig& config)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!ui) return;
|
|
|
|
|
|
|
2026-02-02 23:24:24 +08:00
|
|
|
|
// 加载PLC服务端配置
|
2026-02-01 14:51:16 +08:00
|
|
|
|
ui->lineEdit_plcServerIp->setText(QString::fromStdString(config.plcServerIp));
|
|
|
|
|
|
ui->lineEdit_plcServerPort->setText(QString::number(config.plcServerPort));
|
|
|
|
|
|
|
|
|
|
|
|
// 加载PLC寄存器地址配置
|
|
|
|
|
|
ui->lineEdit_addrPhotoRequest->setText(QString::number(config.registerConfig.addrPhotoRequest));
|
|
|
|
|
|
ui->lineEdit_addrDataComplete->setText(QString::number(config.registerConfig.addrDataComplete));
|
|
|
|
|
|
ui->lineEdit_addrCoordDataStart->setText(QString::number(config.registerConfig.addrCoordDataStart));
|
2026-02-02 23:24:24 +08:00
|
|
|
|
|
|
|
|
|
|
// 加载姿态输出顺序
|
|
|
|
|
|
int poseOrderIndex = ui->comboBox_poseOutputOrder->findData(config.poseOutputOrder);
|
|
|
|
|
|
if (poseOrderIndex >= 0) {
|
|
|
|
|
|
ui->comboBox_poseOutputOrder->setCurrentIndex(poseOrderIndex);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 加载方向向量反向配置
|
|
|
|
|
|
int dirInvertIndex = ui->comboBox_dirVectorInvert->findData(config.dirVectorInvert);
|
|
|
|
|
|
if (dirInvertIndex >= 0) {
|
|
|
|
|
|
ui->comboBox_dirVectorInvert->setCurrentIndex(dirInvertIndex);
|
|
|
|
|
|
}
|
2026-02-01 14:51:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool DialogAlgoarg::SavePlcRobotServerConfigFromUI(VrPlcRobotServerConfig& config)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!ui) return false;
|
|
|
|
|
|
|
|
|
|
|
|
// 获取PLC服务端IP
|
|
|
|
|
|
QString plcIp = ui->lineEdit_plcServerIp->text().trimmed();
|
|
|
|
|
|
if (plcIp.isEmpty()) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
config.plcServerIp = plcIp.toStdString();
|
|
|
|
|
|
|
|
|
|
|
|
// 获取PLC服务端端口
|
|
|
|
|
|
bool ok = false;
|
|
|
|
|
|
config.plcServerPort = ui->lineEdit_plcServerPort->text().toInt(&ok);
|
|
|
|
|
|
if (!ok || config.plcServerPort <= 0 || config.plcServerPort > 65535) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取PLC寄存器地址配置
|
|
|
|
|
|
config.registerConfig.addrPhotoRequest = ui->lineEdit_addrPhotoRequest->text().toInt(&ok);
|
|
|
|
|
|
if (!ok || config.registerConfig.addrPhotoRequest < 0) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
config.registerConfig.addrDataComplete = ui->lineEdit_addrDataComplete->text().toInt(&ok);
|
|
|
|
|
|
if (!ok || config.registerConfig.addrDataComplete < 0) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
config.registerConfig.addrCoordDataStart = ui->lineEdit_addrCoordDataStart->text().toInt(&ok);
|
|
|
|
|
|
if (!ok || config.registerConfig.addrCoordDataStart < 0) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-02 23:24:24 +08:00
|
|
|
|
// 获取姿态输出顺序
|
|
|
|
|
|
config.poseOutputOrder = ui->comboBox_poseOutputOrder->currentData().toInt();
|
|
|
|
|
|
|
|
|
|
|
|
// 获取方向向量反向配置
|
|
|
|
|
|
config.dirVectorInvert = ui->comboBox_dirVectorInvert->currentData().toInt();
|
|
|
|
|
|
|
2026-02-01 14:51:16 +08:00
|
|
|
|
return true;
|
|
|
|
|
|
}
|