618 lines
30 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 "dialogalgoarg.h"
#include "ui_dialogalgoarg.h"
#include <QCheckBox>
#include <QDoubleValidator>
#include <QFormLayout>
#include <QFont>
#include <QIntValidator>
#include <QLineEdit>
#include <QList>
#include <QScrollArea>
#include <QTabWidget>
#include <cmath>
#include "ParkingSpaceGuidePresenter.h"
#include "PathManager.h"
#include "StyledMessageBox.h"
DialogAlgoArg::DialogAlgoArg(QWidget* parent)
: QDialog(parent)
, ui(new Ui::DialogAlgoArg)
{
ui->setupUi(this);
setWindowTitle(QStringLiteral("停机引导参数设置"));
if (ui->label_title) {
ui->label_title->setText(QStringLiteral("停机引导参数设置"));
}
BuildUi();
connect(ui->tabWidget, &QTabWidget::currentChanged, this, [this](int index) {
if (index >= 0 && index < m_visiblePages.size()) {
UpdateTitle(m_visiblePages[index]);
}
});
ApplyUiFont();
}
DialogAlgoArg::~DialogAlgoArg()
{
delete ui;
}
void DialogAlgoArg::SetPresenter(ParkingSpaceGuidePresenter* presenter)
{
m_presenter = presenter;
LoadParams();
}
void DialogAlgoArg::SetCurrentPage(ConfigPage page)
{
if (ui && ui->tabWidget) {
ShowTabGroup(page);
}
}
void DialogAlgoArg::ShowTabGroup(ConfigPage page)
{
if (!ui || !ui->tabWidget) {
return;
}
const bool oldBlocked = ui->tabWidget->blockSignals(true);
ui->tabWidget->clear();
HideDetachedTabs();
m_visiblePages.clear();
auto addTab = [this](QWidget* tab, const QString& title, ConfigPage tabPage) {
if (tab) {
ui->tabWidget->addTab(tab, title);
m_visiblePages.push_back(tabPage);
}
};
int selectedIndex = 0;
if (page == ConfigPage::Camera || page == ConfigPage::Lidar) {
addTab(m_cameraTab, QStringLiteral("相机参数"), ConfigPage::Camera);
addTab(m_lidarTab, QStringLiteral("雷达参数"), ConfigPage::Lidar);
selectedIndex = page == ConfigPage::Lidar ? 1 : 0;
} else if (page == ConfigPage::Calibration) {
addTab(m_groundCalibrationTab, QStringLiteral("地面调平"), ConfigPage::Calibration);
} else if (page == ConfigPage::Multicast) {
addTab(m_multicastTab, QStringLiteral("组播参数"), ConfigPage::Multicast);
} else {
addTab(m_planeParkingTab, QStringLiteral("停机几何"), ConfigPage::Detection);
addTab(m_groundCalibrationTab, QStringLiteral("地面调平"), ConfigPage::Detection);
addTab(m_treeGrowTab, QStringLiteral("聚类生长"), ConfigPage::Detection);
addTab(m_guideDecisionTab, QStringLiteral("引导判定"), ConfigPage::Detection);
addTab(m_processTab, QStringLiteral("流程判定"), ConfigPage::Detection);
addTab(m_modelRecognitionTab, QStringLiteral("机型识别"), ConfigPage::Detection);
}
if (selectedIndex >= 0 && selectedIndex < ui->tabWidget->count()) {
ui->tabWidget->setCurrentIndex(selectedIndex);
}
if (ui->tabWidget->currentWidget()) {
ui->tabWidget->currentWidget()->show();
}
ui->tabWidget->blockSignals(oldBlocked);
UpdateTitle(page);
}
void DialogAlgoArg::UpdateTitle(ConfigPage page)
{
QString title = QStringLiteral("停机引导参数设置");
switch (page) {
case ConfigPage::Detection:
title = QStringLiteral("检测参数设置");
break;
case ConfigPage::Camera:
title = QStringLiteral("相机参数设置");
break;
case ConfigPage::Lidar:
title = QStringLiteral("雷达参数设置");
break;
case ConfigPage::Multicast:
title = QStringLiteral("组播参数设置");
break;
case ConfigPage::Calibration:
title = QStringLiteral("雷达地面调平参数");
break;
}
setWindowTitle(title);
if (ui && ui->label_title) {
ui->label_title->setText(title);
}
}
void DialogAlgoArg::HideDetachedTabs()
{
const QList<QWidget*> tabs = {
m_planeParkingTab,
m_groundCalibrationTab,
m_treeGrowTab,
m_guideDecisionTab,
m_processTab,
m_modelRecognitionTab,
m_cameraTab,
m_lidarTab,
m_multicastTab
};
for (QWidget* tab : tabs) {
if (tab) {
tab->hide();
}
}
}
void DialogAlgoArg::BuildUi()
{
ui->tabWidget->clear();
auto makeTab = [this](QWidget** tabWidget, const QString& title) -> QWidget* {
auto* scroll = new QScrollArea(ui->tabWidget);
scroll->setWidgetResizable(true);
auto* page = new QWidget(scroll);
page->setObjectName(title);
auto* layout = new QFormLayout(page);
layout->setContentsMargins(24, 24, 24, 24);
layout->setSpacing(14);
scroll->setWidget(page);
*tabWidget = scroll;
scroll->hide();
return page;
};
QWidget* planeParking = makeTab(&m_planeParkingTab, QStringLiteral("停机几何"));
m_parkingPointX = AddDoubleEditor(planeParking, QStringLiteral("停机点X(毫米)"), 0, -1000000.0, 1000000.0);
m_parkingPointY = AddDoubleEditor(planeParking, QStringLiteral("停机点Y(毫米)"), 1, -1000000.0, 1000000.0);
m_parkingPointZ = AddDoubleEditor(planeParking, QStringLiteral("停机点Z(毫米)"), 2, -1000000.0, 1000000.0);
m_guideLinePointX = AddDoubleEditor(planeParking, QStringLiteral("引导线远点X(毫米)"), 3, -1000000.0, 1000000.0);
m_guideLinePointY = AddDoubleEditor(planeParking, QStringLiteral("引导线远点Y(毫米)"), 4, -1000000.0, 1000000.0);
m_guideLinePointZ = AddDoubleEditor(planeParking, QStringLiteral("引导线远点Z(毫米)"), 5, -1000000.0, 1000000.0);
m_guidingRange = AddDoubleEditor(planeParking, QStringLiteral("飞机引导范围(毫米)"), 6, 0.0, 10000000.0);
m_parkingRange = AddDoubleEditor(planeParking, QStringLiteral("引导线过滤范围(毫米)"), 7, 0.0, 10000000.0);
m_distFromNoseToWheel = AddDoubleEditor(planeParking, QStringLiteral("机鼻到前轮距离(毫米)"), 8, 0.0, 100000.0);
QWidget* ground = makeTab(&m_groundCalibrationTab, QStringLiteral("地面调平"));
for (int i = 0; i < 9; ++i) {
m_planeCalib[i] = AddDoubleEditor(ground,
QStringLiteral("调平矩阵 R%1%2").arg(i / 3).arg(i % 3), i, -1000.0, 1000.0);
}
m_planeHeight = AddDoubleEditor(ground, QStringLiteral("地面高度(毫米)"), 9, -1000000.0, 1000000.0);
for (int i = 0; i < 9; ++i) {
m_invRMatrix[i] = AddDoubleEditor(ground,
QStringLiteral("逆矩阵 R%1%2").arg(i / 3).arg(i % 3), 10 + i, -1000.0, 1000.0);
}
QWidget* treeGrow = makeTab(&m_treeGrowTab, QStringLiteral("聚类生长"));
m_yDeviationMax = AddDoubleEditor(treeGrow, QStringLiteral("Y方向最大偏差(毫米)"), 0, 0.0, 1000000.0);
m_zDeviationMax = AddDoubleEditor(treeGrow, QStringLiteral("Z方向最大偏差(毫米)"), 1, 0.0, 1000000.0);
m_maxLineSkipNum = AddIntEditor(treeGrow, QStringLiteral("最大跳线数(-1按距离)"), 2, -1, 1000000);
m_maxSkipDistance = AddDoubleEditor(treeGrow, QStringLiteral("最大跳过距离(毫米,-1禁用)"), 3, -1.0, 1000000.0);
m_minLTypeTreeLen = AddDoubleEditor(treeGrow, QStringLiteral("L型树最小长度(毫米)"), 4, 0.0, 1000000.0);
m_minVTypeTreeLen = AddDoubleEditor(treeGrow, QStringLiteral("V型树最小长度(毫米)"), 5, 0.0, 1000000.0);
QWidget* guideDecision = makeTab(&m_guideDecisionTab, QStringLiteral("引导判定"));
m_lateralTolerance = AddDoubleEditor(guideDecision, QStringLiteral("横向对中容差(毫米)"), 0, 0.0, 100000.0);
m_angleTolerance = AddDoubleEditor(guideDecision, QStringLiteral("航向角容差(度)"), 1, 0.0, 180.0);
QWidget* process = makeTab(&m_processTab, QStringLiteral("流程判定"));
m_approachStartDistance = AddDoubleEditor(process, QStringLiteral("进场开始距离(毫米)"), 0, 0.0, 1000000.0);
m_slowDistance = AddDoubleEditor(process, QStringLiteral("减速触发距离(毫米)"), 1, 0.0, 1000000.0);
m_stopDistanceTolerance = AddDoubleEditor(process, QStringLiteral("到位距离容差(毫米)"), 2, 0.0, 100000.0);
m_stoppedShortMinDistance = AddDoubleEditor(process, QStringLiteral("提前停止最小距离(毫米)"), 3, 0.0, 1000000.0);
m_maxApproachSpeed = AddDoubleEditor(process, QStringLiteral("最大接近速度(毫米/秒)"), 4, 0.0, 100000.0);
m_stoppedSpeedThreshold = AddDoubleEditor(process, QStringLiteral("静止速度阈值(毫米/秒)"), 5, 0.0, 100000.0);
m_speedFilterAlpha = AddDoubleEditor(process, QStringLiteral("速度滤波系数"), 6, 0.0, 1.0);
m_stopStableFrames = AddIntEditor(process, QStringLiteral("到位稳定帧数"), 7, 1, 1000000);
m_stoppedShortStableFrames = AddIntEditor(process, QStringLiteral("提前停止稳定帧数"), 8, 1, 1000000);
m_lostFrameThreshold = AddIntEditor(process, QStringLiteral("目标丢失帧阈值"), 9, 1, 1000000);
m_completedHoldFrames = AddIntEditor(process, QStringLiteral("完成状态保持帧数"), 10, 1, 1000000);
QWidget* model = makeTab(&m_modelRecognitionTab, QStringLiteral("机型识别"));
m_modelVerifyDistance = AddDoubleEditor(model, QStringLiteral("机型验证距离(毫米)"), 0, 0.0, 1000000.0);
m_confidenceThreshold = AddDoubleEditor(model, QStringLiteral("识别置信度阈值"), 1, 0.0, 1.0);
m_maxRecognitionAttempts = AddIntEditor(model, QStringLiteral("最大识别次数"), 2, 1, 1000);
QWidget* camera = makeTab(&m_cameraTab, QStringLiteral("相机参数"));
m_mvsSerialNumber = AddTextEditor(camera, QStringLiteral("设备序列号"), 0);
m_mvsDeviceIndex = AddIntEditor(camera, QStringLiteral("设备序号"), 1, 0, 64);
m_mvsEnabled = AddCheckBox(camera, QStringLiteral("启用"), 2);
QWidget* lidar = makeTab(&m_lidarTab, QStringLiteral("雷达参数"));
m_lidarType = AddTextEditor(lidar, QStringLiteral("雷达型号"), 0);
m_lidarHost = AddTextEditor(lidar, QStringLiteral("监听地址"), 1);
m_lidarMsopPort = AddIntEditor(lidar, QStringLiteral("数据端口"), 2, 1, 65535);
m_lidarDifopPort = AddIntEditor(lidar, QStringLiteral("设备端口"), 3, 1, 65535);
m_lidarMinDistance = AddDoubleEditor(lidar, QStringLiteral("最小距离(米)"), 4, 0.0, 1000.0);
m_lidarMaxDistance = AddDoubleEditor(lidar, QStringLiteral("最大距离(米)"), 5, 0.0, 1000.0);
m_lidarStartAngle = AddDoubleEditor(lidar, QStringLiteral("起始角度(度)"), 6, 0.0, 360.0);
m_lidarEndAngle = AddDoubleEditor(lidar, QStringLiteral("结束角度(度)"), 7, 0.0, 360.0);
QWidget* udp = makeTab(&m_multicastTab, QStringLiteral("组播参数"));
m_udpAddress = AddTextEditor(udp, QStringLiteral("组播地址"), 0);
m_udpPort = AddIntEditor(udp, QStringLiteral("组播端口"), 1, 1, 65535);
m_udpTargetId = AddTextEditor(udp, QStringLiteral("目标编号"), 2);
m_udpParkId = AddTextEditor(udp, QStringLiteral("车位编号"), 3);
m_udpEnabled = AddCheckBox(udp, QStringLiteral("启用"), 4);
ShowTabGroup(ConfigPage::Detection);
}
void DialogAlgoArg::ApplyUiFont()
{
QFont font;
font.setPointSize(16);
setFont(font);
const QList<QWidget*> widgets = findChildren<QWidget*>();
for (QWidget* widget : widgets) {
widget->setFont(font);
}
}
QLineEdit* DialogAlgoArg::AddDoubleEditor(QWidget* parent, const QString& label, int row, double min, double max)
{
Q_UNUSED(row);
auto* edit = new QLineEdit(parent);
auto* validator = new QDoubleValidator(min, max, 12, edit);
validator->setNotation(QDoubleValidator::ScientificNotation);
edit->setValidator(validator);
static_cast<QFormLayout*>(parent->layout())->addRow(label, edit);
return edit;
}
QLineEdit* DialogAlgoArg::AddIntEditor(QWidget* parent, const QString& label, int row, int min, int max)
{
Q_UNUSED(row);
auto* edit = new QLineEdit(parent);
edit->setValidator(new QIntValidator(min, max, edit));
static_cast<QFormLayout*>(parent->layout())->addRow(label, edit);
return edit;
}
QLineEdit* DialogAlgoArg::AddTextEditor(QWidget* parent, const QString& label, int row, bool password)
{
Q_UNUSED(row);
auto* edit = new QLineEdit(parent);
if (password) {
edit->setEchoMode(QLineEdit::Password);
}
static_cast<QFormLayout*>(parent->layout())->addRow(label, edit);
return edit;
}
QCheckBox* DialogAlgoArg::AddCheckBox(QWidget* parent, const QString& label, int row)
{
Q_UNUSED(row);
auto* check = new QCheckBox(parent);
static_cast<QFormLayout*>(parent->layout())->addRow(label, check);
return check;
}
void DialogAlgoArg::LoadParams()
{
if (!m_presenter || !m_presenter->GetConfigManager()) {
return;
}
const ConfigResult config = m_presenter->GetConfigManager()->GetConfigResult();
const VrAlgorithmParams& params = config.algorithmParams;
const VrPlaneParkingParam& parking = params.planeParkingParam;
SetDouble(m_parkingPointX, parking.parkingPointX);
SetDouble(m_parkingPointY, parking.parkingPointY);
SetDouble(m_parkingPointZ, parking.parkingPointZ);
SetDouble(m_guideLinePointX, parking.guideLinePointX);
SetDouble(m_guideLinePointY, parking.guideLinePointY);
SetDouble(m_guideLinePointZ, parking.guideLinePointZ);
SetDouble(m_guidingRange, parking.guidingRange);
SetDouble(m_parkingRange, parking.parkingRange);
SetDouble(m_distFromNoseToWheel, parking.distFromNoseToWheel);
const VrPlaneGroundCalibrationParam& ground = params.groundCalibrationParam;
SetMatrix(m_planeCalib, ground.planeCalib);
SetDouble(m_planeHeight, ground.planeHeight);
SetMatrix(m_invRMatrix, ground.invRMatrix);
const VrPlaneTreeGrowParam& tree = params.treeGrowParam;
SetDouble(m_yDeviationMax, tree.yDeviationMax);
SetDouble(m_zDeviationMax, tree.zDeviationMax);
SetInt(m_maxLineSkipNum, tree.maxLineSkipNum);
SetDouble(m_maxSkipDistance, tree.maxSkipDistance);
SetDouble(m_minLTypeTreeLen, tree.minLTypeTreeLen);
SetDouble(m_minVTypeTreeLen, tree.minVTypeTreeLen);
const VrGuideDecisionParam& guide = params.guideDecisionParam;
SetDouble(m_lateralTolerance, guide.lateralTolerance);
SetDouble(m_angleTolerance, guide.angleTolerance);
const VrParkingProcessParam& process = params.processParam;
SetDouble(m_approachStartDistance, process.approachStartDistance);
SetDouble(m_slowDistance, process.slowDistance);
SetDouble(m_stopDistanceTolerance, process.stopDistanceTolerance);
SetDouble(m_stoppedShortMinDistance, process.stoppedShortMinDistance);
SetDouble(m_maxApproachSpeed, process.maxApproachSpeed);
SetDouble(m_stoppedSpeedThreshold, process.stoppedSpeedThreshold);
SetDouble(m_speedFilterAlpha, process.speedFilterAlpha);
SetInt(m_stopStableFrames, process.stopStableFrames);
SetInt(m_stoppedShortStableFrames, process.stoppedShortStableFrames);
SetInt(m_lostFrameThreshold, process.lostFrameThreshold);
SetInt(m_completedHoldFrames, process.completedHoldFrames);
const VrModelRecognitionParam& model = params.modelRecognitionParam;
SetDouble(m_modelVerifyDistance, model.modelVerifyDistance);
SetDouble(m_confidenceThreshold, model.confidenceThreshold);
SetInt(m_maxRecognitionAttempts, model.maxRecognitionAttempts);
m_mvsSerialNumber->setText(QString::fromStdString(config.mvsCamera.serialNumber));
SetInt(m_mvsDeviceIndex, config.mvsCamera.deviceIndex);
m_mvsEnabled->setChecked(config.mvsCamera.enabled);
m_lidarType->setText(QString::fromStdString(config.lidarConfig.lidarType));
m_lidarHost->setText(QString::fromStdString(config.lidarConfig.hostAddress));
SetInt(m_lidarMsopPort, config.lidarConfig.msopPort);
SetInt(m_lidarDifopPort, config.lidarConfig.difopPort);
SetDouble(m_lidarMinDistance, config.lidarConfig.minDistance);
SetDouble(m_lidarMaxDistance, config.lidarConfig.maxDistance);
SetDouble(m_lidarStartAngle, config.lidarConfig.startAngle);
SetDouble(m_lidarEndAngle, config.lidarConfig.endAngle);
m_udpAddress->setText(QString::fromStdString(config.udpBroadcastConfig.address));
SetInt(m_udpPort, config.udpBroadcastConfig.port);
m_udpTargetId->setText(QString::fromStdString(config.udpBroadcastConfig.targetId));
m_udpParkId->setText(QString::fromStdString(config.udpBroadcastConfig.parkId));
m_udpEnabled->setChecked(config.udpBroadcastConfig.enabled);
}
bool DialogAlgoArg::SaveParams()
{
if (!m_presenter || !m_presenter->GetConfigManager()) {
return false;
}
SystemConfig systemConfig = m_presenter->GetConfigManager()->GetConfig();
ConfigResult& config = systemConfig.configResult;
VrAlgorithmParams& params = config.algorithmParams;
VrPlaneParkingParam& parking = params.planeParkingParam;
if (!GetDouble(m_parkingPointX, QStringLiteral("停机点X"), parking.parkingPointX)) return false;
if (!GetDouble(m_parkingPointY, QStringLiteral("停机点Y"), parking.parkingPointY)) return false;
if (!GetDouble(m_parkingPointZ, QStringLiteral("停机点Z"), parking.parkingPointZ)) return false;
if (!GetDouble(m_guideLinePointX, QStringLiteral("引导线远点X"), parking.guideLinePointX)) return false;
if (!GetDouble(m_guideLinePointY, QStringLiteral("引导线远点Y"), parking.guideLinePointY)) return false;
if (!GetDouble(m_guideLinePointZ, QStringLiteral("引导线远点Z"), parking.guideLinePointZ)) return false;
if (!GetDouble(m_guidingRange, QStringLiteral("飞机引导范围"), parking.guidingRange)) return false;
if (!GetDouble(m_parkingRange, QStringLiteral("引导线过滤范围"), parking.parkingRange)) return false;
if (!GetDouble(m_distFromNoseToWheel, QStringLiteral("机鼻到前轮距离"), parking.distFromNoseToWheel)) return false;
const double dx = parking.guideLinePointX - parking.parkingPointX;
const double dy = parking.guideLinePointY - parking.parkingPointY;
const double dz = parking.guideLinePointZ - parking.parkingPointZ;
if (parking.guidingRange <= 0.0 || parking.parkingRange <= 0.0 ||
std::sqrt(dx * dx + dy * dy + dz * dz) < 20000.0) {
StyledMessageBox::warning(this, QStringLiteral("参数错误"),
QStringLiteral("引导范围必须大于0且引导线远点距离停机点至少20米"));
return false;
}
VrPlaneGroundCalibrationParam& ground = params.groundCalibrationParam;
if (!GetMatrix(m_planeCalib, QStringLiteral("调平矩阵"), ground.planeCalib)) return false;
if (!GetDouble(m_planeHeight, QStringLiteral("地面高度"), ground.planeHeight)) return false;
if (!GetMatrix(m_invRMatrix, QStringLiteral("逆矩阵"), ground.invRMatrix)) return false;
VrPlaneTreeGrowParam& tree = params.treeGrowParam;
if (!GetDouble(m_yDeviationMax, QStringLiteral("Y方向最大偏差"), tree.yDeviationMax)) return false;
if (!GetDouble(m_zDeviationMax, QStringLiteral("Z方向最大偏差"), tree.zDeviationMax)) return false;
if (!GetInt(m_maxLineSkipNum, QStringLiteral("最大跳线数"), tree.maxLineSkipNum)) return false;
if (!GetDouble(m_maxSkipDistance, QStringLiteral("最大跳过距离"), tree.maxSkipDistance)) return false;
if (!GetDouble(m_minLTypeTreeLen, QStringLiteral("L型树最小长度"), tree.minLTypeTreeLen)) return false;
if (!GetDouble(m_minVTypeTreeLen, QStringLiteral("V型树最小长度"), tree.minVTypeTreeLen)) return false;
if (tree.yDeviationMax <= 0.0 || tree.zDeviationMax <= 0.0 ||
(tree.maxLineSkipNum == -1 && tree.maxSkipDistance < 0.0)) {
StyledMessageBox::warning(this, QStringLiteral("参数错误"), QStringLiteral("聚类生长参数组合无效"));
return false;
}
VrGuideDecisionParam& guide = params.guideDecisionParam;
if (!GetDouble(m_lateralTolerance, QStringLiteral("横向对中容差"), guide.lateralTolerance)) return false;
if (!GetDouble(m_angleTolerance, QStringLiteral("航向角容差"), guide.angleTolerance)) return false;
VrParkingProcessParam& process = params.processParam;
if (!GetDouble(m_approachStartDistance, QStringLiteral("进场开始距离"), process.approachStartDistance)) return false;
if (!GetDouble(m_slowDistance, QStringLiteral("减速触发距离"), process.slowDistance)) return false;
if (!GetDouble(m_stopDistanceTolerance, QStringLiteral("到位距离容差"), process.stopDistanceTolerance)) return false;
if (!GetDouble(m_stoppedShortMinDistance, QStringLiteral("提前停止最小距离"), process.stoppedShortMinDistance)) return false;
if (!GetDouble(m_maxApproachSpeed, QStringLiteral("最大接近速度"), process.maxApproachSpeed)) return false;
if (!GetDouble(m_stoppedSpeedThreshold, QStringLiteral("静止速度阈值"), process.stoppedSpeedThreshold)) return false;
if (!GetDouble(m_speedFilterAlpha, QStringLiteral("速度滤波系数"), process.speedFilterAlpha)) return false;
if (!GetInt(m_stopStableFrames, QStringLiteral("到位稳定帧数"), process.stopStableFrames)) return false;
if (!GetInt(m_stoppedShortStableFrames, QStringLiteral("提前停止稳定帧数"), process.stoppedShortStableFrames)) return false;
if (!GetInt(m_lostFrameThreshold, QStringLiteral("目标丢失帧阈值"), process.lostFrameThreshold)) return false;
if (!GetInt(m_completedHoldFrames, QStringLiteral("完成状态保持帧数"), process.completedHoldFrames)) return false;
if (process.approachStartDistance < process.slowDistance ||
process.slowDistance < process.stopDistanceTolerance ||
process.stoppedShortMinDistance < process.stopDistanceTolerance ||
process.maxApproachSpeed < process.stoppedSpeedThreshold) {
StyledMessageBox::warning(this, QStringLiteral("参数错误"),
QStringLiteral("流程距离或速度阈值的大小关系无效"));
return false;
}
VrModelRecognitionParam& model = params.modelRecognitionParam;
if (!GetDouble(m_modelVerifyDistance, QStringLiteral("机型验证距离"), model.modelVerifyDistance)) return false;
if (!GetDouble(m_confidenceThreshold, QStringLiteral("识别置信度阈值"), model.confidenceThreshold)) return false;
if (!GetInt(m_maxRecognitionAttempts, QStringLiteral("最大识别次数"), model.maxRecognitionAttempts)) return false;
config.mvsCamera.serialNumber = m_mvsSerialNumber->text().trimmed().toStdString();
if (!GetInt(m_mvsDeviceIndex, QStringLiteral("相机设备序号"), config.mvsCamera.deviceIndex)) return false;
config.mvsCamera.enabled = m_mvsEnabled->isChecked();
config.lidarConfig.lidarType = m_lidarType->text().trimmed().toStdString();
config.lidarConfig.hostAddress = m_lidarHost->text().trimmed().toStdString();
int intValue = 0;
if (!GetInt(m_lidarMsopPort, QStringLiteral("雷达数据端口"), intValue)) return false;
config.lidarConfig.msopPort = static_cast<unsigned short>(intValue);
if (!GetInt(m_lidarDifopPort, QStringLiteral("雷达设备端口"), intValue)) return false;
config.lidarConfig.difopPort = static_cast<unsigned short>(intValue);
if (!GetFloat(m_lidarMinDistance, QStringLiteral("雷达最小距离"), config.lidarConfig.minDistance)) return false;
if (!GetFloat(m_lidarMaxDistance, QStringLiteral("雷达最大距离"), config.lidarConfig.maxDistance)) return false;
if (!GetFloat(m_lidarStartAngle, QStringLiteral("雷达起始角度"), config.lidarConfig.startAngle)) return false;
if (!GetFloat(m_lidarEndAngle, QStringLiteral("雷达结束角度"), config.lidarConfig.endAngle)) return false;
config.udpBroadcastConfig.address = m_udpAddress->text().trimmed().toStdString();
if (!GetInt(m_udpPort, QStringLiteral("组播端口"), config.udpBroadcastConfig.port)) return false;
config.udpBroadcastConfig.targetId = m_udpTargetId->text().trimmed().toStdString();
config.udpBroadcastConfig.parkId = m_udpParkId->text().trimmed().toStdString();
config.udpBroadcastConfig.enabled = m_udpEnabled->isChecked();
config.Normalize();
if (!m_presenter->GetConfigManager()->UpdateFullConfig(systemConfig)) {
StyledMessageBox::warning(this, QStringLiteral("失败"), QStringLiteral("更新配置缓存失败"));
return false;
}
const QString configPath = PathManager::GetInstance().GetConfigFilePath();
if (!m_presenter->GetConfigManager()->SaveConfigToFile(configPath.toStdString())) {
StyledMessageBox::warning(this, QStringLiteral("失败"), QStringLiteral("保存配置文件失败"));
return false;
}
m_presenter->OnConfigChanged(config);
return true;
}
void DialogAlgoArg::ResetParams()
{
ConfigResult config;
config.Normalize();
const VrAlgorithmParams& params = config.algorithmParams;
const VrPlaneParkingParam& parking = params.planeParkingParam;
SetDouble(m_parkingPointX, parking.parkingPointX);
SetDouble(m_parkingPointY, parking.parkingPointY);
SetDouble(m_parkingPointZ, parking.parkingPointZ);
SetDouble(m_guideLinePointX, parking.guideLinePointX);
SetDouble(m_guideLinePointY, parking.guideLinePointY);
SetDouble(m_guideLinePointZ, parking.guideLinePointZ);
SetDouble(m_guidingRange, parking.guidingRange);
SetDouble(m_parkingRange, parking.parkingRange);
SetDouble(m_distFromNoseToWheel, parking.distFromNoseToWheel);
const VrPlaneGroundCalibrationParam& ground = params.groundCalibrationParam;
SetMatrix(m_planeCalib, ground.planeCalib);
SetDouble(m_planeHeight, ground.planeHeight);
SetMatrix(m_invRMatrix, ground.invRMatrix);
const VrPlaneTreeGrowParam& tree = params.treeGrowParam;
SetDouble(m_yDeviationMax, tree.yDeviationMax);
SetDouble(m_zDeviationMax, tree.zDeviationMax);
SetInt(m_maxLineSkipNum, tree.maxLineSkipNum);
SetDouble(m_maxSkipDistance, tree.maxSkipDistance);
SetDouble(m_minLTypeTreeLen, tree.minLTypeTreeLen);
SetDouble(m_minVTypeTreeLen, tree.minVTypeTreeLen);
const VrGuideDecisionParam& guide = params.guideDecisionParam;
SetDouble(m_lateralTolerance, guide.lateralTolerance);
SetDouble(m_angleTolerance, guide.angleTolerance);
const VrParkingProcessParam& process = params.processParam;
SetDouble(m_approachStartDistance, process.approachStartDistance);
SetDouble(m_slowDistance, process.slowDistance);
SetDouble(m_stopDistanceTolerance, process.stopDistanceTolerance);
SetDouble(m_stoppedShortMinDistance, process.stoppedShortMinDistance);
SetDouble(m_maxApproachSpeed, process.maxApproachSpeed);
SetDouble(m_stoppedSpeedThreshold, process.stoppedSpeedThreshold);
SetDouble(m_speedFilterAlpha, process.speedFilterAlpha);
SetInt(m_stopStableFrames, process.stopStableFrames);
SetInt(m_stoppedShortStableFrames, process.stoppedShortStableFrames);
SetInt(m_lostFrameThreshold, process.lostFrameThreshold);
SetInt(m_completedHoldFrames, process.completedHoldFrames);
const VrModelRecognitionParam& model = params.modelRecognitionParam;
SetDouble(m_modelVerifyDistance, model.modelVerifyDistance);
SetDouble(m_confidenceThreshold, model.confidenceThreshold);
SetInt(m_maxRecognitionAttempts, model.maxRecognitionAttempts);
m_mvsSerialNumber->setText(QString::fromStdString(config.mvsCamera.serialNumber));
SetInt(m_mvsDeviceIndex, config.mvsCamera.deviceIndex);
m_mvsEnabled->setChecked(config.mvsCamera.enabled);
m_lidarType->setText(QString::fromStdString(config.lidarConfig.lidarType));
m_lidarHost->setText(QString::fromStdString(config.lidarConfig.hostAddress));
SetInt(m_lidarMsopPort, config.lidarConfig.msopPort);
SetInt(m_lidarDifopPort, config.lidarConfig.difopPort);
SetDouble(m_lidarMinDistance, config.lidarConfig.minDistance);
SetDouble(m_lidarMaxDistance, config.lidarConfig.maxDistance);
SetDouble(m_lidarStartAngle, config.lidarConfig.startAngle);
SetDouble(m_lidarEndAngle, config.lidarConfig.endAngle);
m_udpAddress->setText(QString::fromStdString(config.udpBroadcastConfig.address));
SetInt(m_udpPort, config.udpBroadcastConfig.port);
m_udpTargetId->setText(QString::fromStdString(config.udpBroadcastConfig.targetId));
m_udpParkId->setText(QString::fromStdString(config.udpBroadcastConfig.parkId));
m_udpEnabled->setChecked(config.udpBroadcastConfig.enabled);
}
void DialogAlgoArg::SetDouble(QLineEdit* edit, double value)
{
if (edit) edit->setText(QString::number(value, 'g', 12));
}
void DialogAlgoArg::SetInt(QLineEdit* edit, int value)
{
if (edit) edit->setText(QString::number(value));
}
bool DialogAlgoArg::GetDouble(QLineEdit* edit, const QString& label, double& value)
{
bool ok = false;
value = edit ? edit->text().trimmed().toDouble(&ok) : 0.0;
if (!edit || !edit->hasAcceptableInput() || !ok || !std::isfinite(value)) {
StyledMessageBox::warning(this, QStringLiteral("参数错误"), QStringLiteral("%1无效").arg(label));
if (edit) edit->setFocus();
return false;
}
return true;
}
bool DialogAlgoArg::GetFloat(QLineEdit* edit, const QString& label, float& value)
{
double doubleValue = 0.0;
if (!GetDouble(edit, label, doubleValue)) return false;
value = static_cast<float>(doubleValue);
return true;
}
bool DialogAlgoArg::GetInt(QLineEdit* edit, const QString& label, int& value)
{
bool ok = false;
value = edit ? edit->text().trimmed().toInt(&ok) : 0;
if (!edit || !edit->hasAcceptableInput() || !ok) {
StyledMessageBox::warning(this, QStringLiteral("参数错误"), QStringLiteral("%1无效").arg(label));
if (edit) edit->setFocus();
return false;
}
return true;
}
void DialogAlgoArg::SetMatrix(QLineEdit* const edits[9], const double values[9])
{
for (int i = 0; i < 9; ++i) SetDouble(edits[i], values[i]);
}
bool DialogAlgoArg::GetMatrix(QLineEdit* const edits[9], const QString& label, double values[9])
{
for (int i = 0; i < 9; ++i) {
if (!GetDouble(edits[i], QStringLiteral("%1 R%2%3").arg(label).arg(i / 3).arg(i % 3), values[i])) {
return false;
}
}
return true;
}
void DialogAlgoArg::on_btnOK_clicked()
{
if (SaveParams()) accept();
}
void DialogAlgoArg::on_btnCancel_clicked()
{
reject();
}
void DialogAlgoArg::on_btnApply_clicked()
{
if (SaveParams()) {
StyledMessageBox::information(this, QStringLiteral("提示"), QStringLiteral("参数已应用"));
}
}
void DialogAlgoArg::on_btnReset_clicked()
{
ResetParams();
}