662 lines
23 KiB
C++
Raw Normal View History

#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>
#include <QSettings>
#include <QFileDialog>
#include "PathManager.h"
#include "StyledMessageBox.h"
#include "HandEyeCalibWidget.h"
#include "ToolExtrinsicWidget.h"
2026-07-14 17:14:55 +08:00
#include "WorkpieceProduct.h"
#include "VrLog.h"
DialogAlgoarg::DialogAlgoarg(ConfigManager* configManager, QWidget *parent)
: QDialog(parent)
, ui(new Ui::DialogAlgoarg)
, m_pConfigManager(configManager)
2026-07-14 17:14:55 +08:00
, m_currentWorkpieceNumber(1)
, m_isSwitchingWorkpieceProfile(true)
, m_handEyeCalibWidget(nullptr)
, m_toolExtrinsicWidget(nullptr)
{
try {
ui->setupUi(this);
// 获取配置文件路径
m_configFilePath = PathManager::GetInstance().GetConfigFilePath();
// 检查配置文件路径是否有效
if (m_configFilePath.isEmpty()) {
StyledMessageBox::critical(this, "错误", "无法获取配置文件路径!");
return;
}
// 初始化旋转顺序下拉框
InitEulerOrderComboBox();
// 初始化姿态输出顺序下拉框
InitPoseOutputOrderComboBox();
// 初始化方向向量反向下拉框
InitDirVectorInvertComboBox();
// 初始化数据字节序下拉框
InitByteOrderComboBox();
2026-07-14 17:14:55 +08:00
// 初始化工件参数组下拉框
InitWorkpieceProfileComboBox();
// 初始化工具参数 tab工具参数由顶部工件选择器驱动
InitToolExtrinsicTab();
// 从配置文件加载数据到界面
LoadConfigToUI();
2026-07-14 17:14:55 +08:00
m_isSwitchingWorkpieceProfile = false;
// 初始化手眼标定 tab在 LoadConfigToUI 之后,因为需要配置数据)
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");
}
2026-07-14 17:14:55 +08:00
// 算法参数在窗口内暂存,切换工件时不会立即写配置文件。
m_algorithmParams = configData.algorithmParams;
m_currentWorkpieceNumber = ui->comboBox_workpieceProfile->currentData().toInt();
if (m_currentWorkpieceNumber <= 0) {
m_currentWorkpieceNumber = 1;
}
LoadCurrentWorkpieceProfileToUI();
// 加载网络配置PLC和机械臂服务端
LoadPlcRobotServerConfigToUI(configData.plcRobotServerConfig);
// 加载旋转顺序(从第一个手眼标定矩阵获取)
if (!configData.handEyeCalibMatrixList.empty()) {
int eulerOrder = configData.handEyeCalibMatrixList[0].eulerOrder;
int index = ui->comboBox_eulerOrder->findData(eulerOrder);
if (index >= 0) {
ui->comboBox_eulerOrder->setCurrentIndex(index);
}
}
} catch (const std::exception& e) {
LOG_ERROR("Exception in LoadConfigToUI: %s\n", e.what());
StyledMessageBox::warning(this, "警告",
QString("加载配置时发生异常: %1\n将使用默认参数显示").arg(e.what()));
// 发生异常时使用默认参数
2026-07-14 17:14:55 +08:00
m_algorithmParams = VrAlgorithmParams();
m_currentWorkpieceNumber = 1;
LoadCurrentWorkpieceProfileToUI();
} catch (...) {
LOG_ERROR("Unknown exception in LoadConfigToUI\n");
StyledMessageBox::warning(this, "警告", "加载配置文件失败(未知错误),将使用默认参数显示");
// 发生未知异常时使用默认参数
2026-07-14 17:14:55 +08:00
m_algorithmParams = VrAlgorithmParams();
m_currentWorkpieceNumber = 1;
LoadCurrentWorkpieceProfileToUI();
}
}
void DialogAlgoarg::InitWorkpieceProfileComboBox()
{
if (!ui) return;
ui->comboBox_workpieceProfile->clear();
const WorkpieceProduct::ProductInfo* products = WorkpieceProduct::Products();
for (int i = 0; i < WorkpieceProduct::ProductCount(); ++i) {
QString displayText = QString("%1 - %2")
.arg(products[i].number)
.arg(QString::fromUtf8(products[i].model));
if (!products[i].detectionSupported) {
displayText += QString::fromUtf8("(预留)");
}
ui->comboBox_workpieceProfile->addItem(displayText, products[i].number);
}
const int defaultIndex = ui->comboBox_workpieceProfile->findData(1);
ui->comboBox_workpieceProfile->setCurrentIndex(defaultIndex >= 0 ? defaultIndex : 0);
}
void DialogAlgoarg::LoadCurrentWorkpieceProfileToUI()
{
VrWorkpieceAlgorithmProfile& profile =
m_algorithmParams.GetOrCreateWorkpieceProfile(m_currentWorkpieceNumber);
LoadWorkpieceHoleParamToUI(profile.workpieceHoleParam);
LoadLineSegParamToUI(profile.lineSegParam);
LoadFilterParamToUI(profile.filterParam);
LoadGrowParamToUI(profile.growParam);
if (m_toolExtrinsicWidget) {
m_toolExtrinsicWidget->setData(
profile.toolParam.eulerOrder,
profile.toolParam.rotX, profile.toolParam.rotY, profile.toolParam.rotZ,
profile.toolParam.offsetX, profile.toolParam.offsetY, profile.toolParam.offsetZ);
}
2026-07-14 17:14:55 +08:00
}
bool DialogAlgoarg::SaveCurrentWorkpieceProfileFromUI()
{
if (m_toolExtrinsicWidget && !m_toolExtrinsicWidget->hasAcceptableInput()) {
return false;
}
2026-07-14 17:14:55 +08:00
VrWorkpieceAlgorithmProfile& profile =
m_algorithmParams.GetOrCreateWorkpieceProfile(m_currentWorkpieceNumber);
if (!SaveWorkpieceHoleParamFromUI(profile.workpieceHoleParam) ||
!SaveLineSegParamFromUI(profile.lineSegParam) ||
!SaveFilterParamFromUI(profile.filterParam) ||
!SaveGrowParamFromUI(profile.growParam)) {
return false;
}
if (m_toolExtrinsicWidget) {
m_toolExtrinsicWidget->getData(
profile.toolParam.eulerOrder,
profile.toolParam.rotX, profile.toolParam.rotY, profile.toolParam.rotZ,
profile.toolParam.offsetX, profile.toolParam.offsetY, profile.toolParam.offsetZ);
}
return true;
2026-07-14 17:14:55 +08:00
}
void DialogAlgoarg::on_comboBox_workpieceProfile_currentIndexChanged(int index)
{
if (m_isSwitchingWorkpieceProfile || index < 0) {
return;
}
const int newWorkpieceNumber = ui->comboBox_workpieceProfile->itemData(index).toInt();
if (newWorkpieceNumber <= 0 || newWorkpieceNumber == m_currentWorkpieceNumber) {
return;
}
2026-07-14 17:14:55 +08:00
if (!SaveCurrentWorkpieceProfileFromUI()) {
StyledMessageBox::warning(this, "错误", "当前工件参数输入有误,请检查后再切换!");
m_isSwitchingWorkpieceProfile = true;
const int oldIndex = ui->comboBox_workpieceProfile->findData(m_currentWorkpieceNumber);
ui->comboBox_workpieceProfile->setCurrentIndex(oldIndex);
m_isSwitchingWorkpieceProfile = false;
return;
}
m_currentWorkpieceNumber = newWorkpieceNumber;
LoadCurrentWorkpieceProfileToUI();
}
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));
2026-07-14 17:14:55 +08:00
ui->lineEdit_bigHoleDiameter->setText(QString::number(param.bigHoleDiameter));
ui->lineEdit_holeDist_L->setText(QString::number(param.holeDist_L));
ui->lineEdit_holeDist_W->setText(QString::number(param.holeDist_W));
ui->lineEdit_xLen->setText(QString::number(param.xLen));
ui->lineEdit_yLen->setText(QString::number(param.yLen));
ui->lineEdit_H->setText(QString::number(param.H));
}
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 {
// 基于当前配置构造候选值;落盘失败时恢复运行时配置。
const SystemConfig previousSystemConfig = m_pConfigManager->GetConfig();
SystemConfig systemConfig = previousSystemConfig;
VrAlgorithmParams& algoParams = systemConfig.configResult.algorithmParams;
2026-07-14 17:14:55 +08:00
// 先暂存当前工件,再一次性保存所有工件参数组。
if (!SaveCurrentWorkpieceProfileFromUI()) {
StyledMessageBox::warning(this, "错误", "当前工件算法参数输入有误,请检查!");
return false;
}
2026-07-14 17:14:55 +08:00
algoParams.workpieceProfiles = m_algorithmParams.workpieceProfiles;
// 保存网络配置PLC和机械臂服务端
if (!SavePlcRobotServerConfigFromUI(systemConfig.configResult.plcRobotServerConfig)) {
StyledMessageBox::warning(this, "错误", "网络配置输入有误,请检查!");
return false;
}
// 保存手眼标定矩阵:从共享控件读取所有相机的矩阵
int eulerOrder = ui->comboBox_eulerOrder->currentData().toInt();
if (m_handEyeCalibWidget) {
const auto& oldMatrixList = systemConfig.configResult.handEyeCalibMatrixList;
std::vector<VrHandEyeCalibMatrix> newMatrixList;
ConfigResult configData = m_pConfigManager->GetConfigResult();
int cameraCount = std::max(1, static_cast<int>(configData.cameraList.size()));
for (int i = 0; i < cameraCount; ++i) {
int camIdx = i + 1; // 1-based
// 先从已有配置中获取该相机的矩阵作为基础
VrHandEyeCalibMatrix calibMatrix;
calibMatrix.cameraIndex = camIdx;
calibMatrix.eulerOrder = eulerOrder;
for (const auto& old : oldMatrixList) {
if (old.cameraIndex == camIdx) {
calibMatrix = old;
calibMatrix.eulerOrder = eulerOrder; // 更新旋转顺序
break;
}
}
// 如果控件中有更新的数据则覆盖
bool isCalibrated = false;
double matrix[16];
if (m_handEyeCalibWidget->getCalibData(camIdx, matrix, isCalibrated) && isCalibrated) {
memcpy(calibMatrix.matrix, matrix, sizeof(double) * 16);
}
newMatrixList.push_back(calibMatrix);
}
systemConfig.configResult.handEyeCalibMatrixList = newMatrixList;
}
// 更新并保存配置到文件
if (!m_pConfigManager->UpdateFullConfig(systemConfig)) {
return false;
}
if (!m_pConfigManager->SaveConfigToFile(m_configFilePath.toStdString())) {
m_pConfigManager->UpdateFullConfig(previousSystemConfig);
return false;
}
return true;
} 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;
2026-07-14 17:14:55 +08:00
param.bigHoleDiameter = ui->lineEdit_bigHoleDiameter->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;
param.xLen = ui->lineEdit_xLen->text().toDouble(&ok);
if (!ok) return false;
param.yLen = ui->lineEdit_yLen->text().toDouble(&ok);
if (!ok) return false;
param.H = ui->lineEdit_H->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();
}
// ========== 工具参数相关实现 ==========
void DialogAlgoarg::InitToolExtrinsicTab()
{
if (!ui || !ui->verticalLayout_toolExtrinsicHost || m_toolExtrinsicWidget) {
return;
}
m_toolExtrinsicWidget = new ToolExtrinsicWidget(this);
m_toolExtrinsicWidget->setCameraSelectorVisible(false);
m_toolExtrinsicWidget->setTargetOffsetVisible(true);
m_toolExtrinsicWidget->setAxialAngleRangeVisible(false);
ui->verticalLayout_toolExtrinsicHost->addWidget(m_toolExtrinsicWidget);
}
// ========== 手眼标定相关实现 ==========
void DialogAlgoarg::InitHandEyeCalibTab()
{
if (!ui || !m_pConfigManager) return;
// 创建共享控件并嵌入 tab 的 layout
m_handEyeCalibWidget = new HandEyeCalibWidget(this);
m_handEyeCalibWidget->setMatrixEditable(true); // WorkpieceHoleApp 矩阵可编辑
ui->verticalLayout_handEyeCalibHost->addWidget(m_handEyeCalibWidget);
// 设置默认文件路径
m_handEyeCalibWidget->setDefaultFilePath(
PathManager::GetInstance().GetAppConfigDirectory());
// 从配置中获取相机列表填充控件
ConfigResult configData = m_pConfigManager->GetConfigResult();
QVector<HandEyeCalibCameraInfo> cameraList;
if (configData.cameraList.empty()) {
// 如果没有配置相机列表,提供默认项
HandEyeCalibCameraInfo defaultCam;
defaultCam.cameraIndex = 1;
defaultCam.displayName = QString::fromUtf8("相机 1");
cameraList.append(defaultCam);
} else {
for (size_t i = 0; i < configData.cameraList.size(); ++i) {
const DeviceInfo& camera = configData.cameraList[i];
HandEyeCalibCameraInfo info;
info.cameraIndex = static_cast<int>(i + 1); // 1-based
info.displayName = QString::fromStdString(camera.name);
cameraList.append(info);
}
}
m_handEyeCalibWidget->setCameraList(cameraList);
// 加载已有的手眼标定矩阵数据到控件(支持多相机)
for (const auto& calibMatrix : configData.handEyeCalibMatrixList) {
// 检查矩阵是否不是单位矩阵(即已标定)
bool hasCalibData = false;
for (int i = 0; i < 16; ++i) {
double identity = (i / 4 == i % 4) ? 1.0 : 0.0;
if (qAbs(calibMatrix.matrix[i] - identity) > 1e-9) {
hasCalibData = true;
break;
}
}
m_handEyeCalibWidget->setCalibData(calibMatrix.cameraIndex, calibMatrix.matrix, hasCalibData);
}
// 连接信号
connect(m_handEyeCalibWidget, &HandEyeCalibWidget::calibMatrixLoaded,
this, &DialogAlgoarg::onCalibMatrixLoaded);
connect(m_handEyeCalibWidget, &HandEyeCalibWidget::saveCalibRequested,
this, &DialogAlgoarg::onSaveCalibRequested);
}
void DialogAlgoarg::onCalibMatrixLoaded(int cameraIndex, const double* matrix)
{
Q_UNUSED(cameraIndex);
Q_UNUSED(matrix);
StyledMessageBox::information(this, "提示", "已从文件导入标定矩阵");
}
void DialogAlgoarg::onSaveCalibRequested(int cameraIndex, const double* matrix)
{
Q_UNUSED(cameraIndex);
Q_UNUSED(matrix);
// 直接调用保存全部配置
if (SaveConfigFromUI()) {
StyledMessageBox::information(this, "成功", "手眼标定参数已保存到配置文件!");
} else {
StyledMessageBox::warning(this, "失败", "保存手眼标定参数失败!");
}
}
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);
}
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);
}
void DialogAlgoarg::InitByteOrderComboBox()
{
// 添加数据字节序选项
ui->comboBox_byteOrder->addItem("大端序 (ABCD)", BYTE_ORDER_BIG_ENDIAN);
ui->comboBox_byteOrder->addItem("小端序 (DCBA)", BYTE_ORDER_LITTLE_ENDIAN);
// 默认选择大端序
ui->comboBox_byteOrder->setCurrentIndex(0);
}
void DialogAlgoarg::LoadPlcRobotServerConfigToUI(const VrPlcRobotServerConfig& config)
{
if (!ui) return;
// 加载PLC服务端配置
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));
// 加载姿态输出顺序
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);
}
// 加载数据字节序配置
int byteOrderIndex = ui->comboBox_byteOrder->findData(config.byteOrder);
if (byteOrderIndex >= 0) {
ui->comboBox_byteOrder->setCurrentIndex(byteOrderIndex);
}
}
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;
}
// 获取姿态输出顺序
config.poseOutputOrder = ui->comboBox_poseOutputOrder->currentData().toInt();
// 获取方向向量反向配置
config.dirVectorInvert = ui->comboBox_dirVectorInvert->currentData().toInt();
// 获取数据字节序配置
config.byteOrder = ui->comboBox_byteOrder->currentData().toInt();
return true;
}