2025-06-20T17:28:44

This commit is contained in:
yuntang 2025-06-20 17:28:45 +08:00
parent ede02dfbfa
commit 0a359b4645
36 changed files with 292 additions and 35 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -30,6 +30,7 @@ SOURCES += \
data/confighandler.cpp \
data/filemanager.cpp \
data/lowesssmoother.cpp \
data/oitautoanalysis.cpp \
data/pointcalculate.cpp \
data/txthandler.cpp \
global.cpp \
@ -66,6 +67,7 @@ SOURCES += \
HEADERS += \
data/confighandler.h \
data/lowesssmoother.h \
data/oitautoanalysis.h \
data/txthandler.h \
global.h \
data/filemanager.h \

View File

@ -0,0 +1,70 @@
#include "oitautoanalysis.h"
#include "global.h"
#include "logger.h"
OITAutoAnalysis::OITAutoAnalysis(QObject *parent) : QObject(parent)
{
}
void OITAutoAnalysis::analysis()
{
if(!Global::_OITAutoAnalysisModeFlag){
return;
}
//
if(!Global::_currentCurveExperimentDataPtr){
return;
}
if(Global::_currentCurveExperimentDataPtr->phaseIndex != 2){
return;
}
#if 0
static Global::ExperimentData reachCoefficientData;
static bool runTimeReachTheCoefficientFirstFlag = false;
if(!runTimeReachTheCoefficientFirstFlag &&
(Global::_currentCurveExperimentDataPtr->dataVtr.last().runTime
> Global::_OITAutoAnalysisCoefficient)){
runTimeReachTheCoefficientFirstFlag = true;
reachCoefficientData = Global::_currentCurveExperimentDataPtr->dataVtr.last();
}
if(runTimeReachTheCoefficientFirstFlag){
logde<<"phase index 1:"<<Global::_currentCurveExperimentDataPtr->phaseIndex;
logde<<"phase index:"<<Global::_currentCurveExperimentDataPtr->dataVtr.last().phaseIndex;
if(Global::_currentCurveExperimentDataPtr->dataVtr.last().dsc
- reachCoefficientData.dsc > Global::_OITAutoAnalysisThreshold){
double x1 = reachCoefficientData.runTime;
double x2 = Global::_currentCurveExperimentDataPtr->dataVtr.last().runTime;
emit sigExperimentStop(x1,x2);
}
}
#endif
if(Global::_mode != Global::Mode::Experiment){
return;
}
static Global::ExperimentData phase2FirstData;
static bool phase2FirstDataRecordFlag = false;
if(!phase2FirstDataRecordFlag){
phase2FirstDataRecordFlag = true;
phase2FirstData = Global::_currentCurveExperimentDataPtr->dataVtr.last();
}else{
Global::ExperimentData& ed = Global::_currentCurveExperimentDataPtr->dataVtr.last();
if((ed.runTime > Global::_OITAutoAnalysisCoefficient)
&& (ed.dsc - phase2FirstData.dsc > Global::_OITAutoAnalysisThreshold)){
//
double x1 = phase2FirstData.runTime;
double x2 = ed.runTime;
emit sigExperimentStop(x1,x2);
phase2FirstDataRecordFlag = false;
}
}
}

View File

@ -0,0 +1,23 @@
#ifndef OITAUTOANALYSIS_H
#define OITAUTOANALYSIS_H
#include <QObject>
class OITAutoAnalysis : public QObject
{
Q_OBJECT
public:
explicit OITAutoAnalysis(QObject *parent = nullptr);
static OITAutoAnalysis* getInstance()
{
static OITAutoAnalysis instance;
return &instance;
}
void analysis();
signals:
void sigExperimentStop(const double x1,const double x2);
};
#endif // OITAUTOANALYSIS_H

View File

@ -28,6 +28,11 @@ LanguageType _languageType = LanguageType::Chinese;
bool _experimentOITFlag = false;
// OIT auto mode.
bool _OITAutoAnalysisModeFlag = false;
double _OITAutoAnalysisCoefficient = OITAutoAnalysisDefaultCoefficient;
double _OITAutoAnalysisThreshold = OITAutoAnalysisDefaultThreshold;
QString converDoubleToStr(const double num)
{
return QString::number(num,'f',3);

View File

@ -98,6 +98,13 @@ struct ExperimentInfo{
int phaseSize;
QVector<Phase> phaseVtr;
ExperimentInfo()
:sampleName("new")
,sampleWeight("0")
,date("20250101")
,experimentor("experimentor")
{}
};
struct PhaseTotalInfo{
@ -160,6 +167,14 @@ extern AxisMode _axisMode;
extern bool _experimentOITFlag;
// OIT auto mode.
const double OITAutoAnalysisDefaultCoefficient = 10.0;
const double OITAutoAnalysisDefaultThreshold = 2.0;
extern bool _OITAutoAnalysisModeFlag;
extern double _OITAutoAnalysisCoefficient;
extern double _OITAutoAnalysisThreshold;
// common func
QString converDoubleToStr(const double);
void quadraticLeastSquaresFit(double x[], double y[], int n, double coeff[]);

View File

@ -33,6 +33,7 @@ MainWindow::MainWindow(QWidget *parent)
,_manuallyStopTheExperimentFlag(false)
{
ui->setupUi(this);
ui->actionOITAutoAnalysisMode->setVisible(false);
this->setToolTip(".....");
ui->actionSaveas->setVisible(false);
@ -93,6 +94,13 @@ void MainWindow::slotUpdateStatusbarMsg(const QString msg)
ui->statusbar->showMessage(msg);
}
void MainWindow::slotOITAutoAnalysis(const double x1,const double x2)
{
on_actionStop_triggered();
_centralWidget->setAnalysisMode(CentralWidget::AnalysisMode::OIT);
_centralWidget->setVerticalLineRange(x1,x2);
}
void MainWindow::closeEvent(QCloseEvent *event)
{
// 弹出确认对话框
@ -174,6 +182,9 @@ void MainWindow::connections()
_axisSettingForm,&AxisSettingForm::slotGetAxisInfoWithData);
connect(_axisSettingForm,&AxisSettingForm::sigSetAxisSettings,
_centralWidget,&CentralWidget::slotSetAxisSettings);
// OIT
connect(OITAutoAnalysis::getInstance(),&OITAutoAnalysis::sigExperimentStop,
this,&MainWindow::slotOITAutoAnalysis);
}
void MainWindow::setActionEnable(const bool flag)
@ -244,7 +255,8 @@ bool MainWindow::saveAnalysisFile(const QString fileName)
}
#endif
bool MainWindow::saveFile(const QString fileName,const Global::Mode mode)
bool MainWindow::saveFile(const QString fileName,const Global::Mode mode,
QString& finalFileName,const bool autoSaveFlag)
{
QString localFileName = fileName;
if(fileName.isEmpty()){
@ -260,9 +272,18 @@ bool MainWindow::saveFile(const QString fileName,const Global::Mode mode)
folder = Global::SampleDataFloder;
}
QString xlsxfilePath = folder + "/" + localFileName + ".xlsx";
QString filePath = QFileDialog::getSaveFileName(nullptr, "Save experiment file",
xlsxfilePath, "Excel Files (*.xlsx)");
QString filePath;
if(autoSaveFlag){
localFileName = _leftWidget->filePathCheck(fileName,folder);
filePath = folder + "/" + localFileName + ".xlsx";
}else{
QString xlsxfilePath = folder + "/" + localFileName + ".xlsx";
filePath = QFileDialog::getSaveFileName(nullptr, "Save experiment file",
xlsxfilePath, "Excel Files (*.xlsx)");
}
//
finalFileName = localFileName + ".xlsx";
logde<<"filePath:"<<filePath.toStdString();
if (filePath.isEmpty()) {
@ -445,8 +466,12 @@ void MainWindow::on_actionStop_triggered()
// _leftWidget->reloadFileName();
// }
if(saveFile(Global::_experimentInfo.sampleName,Global::Mode::Experiment)){
QString finalFileName;
if(saveFile(Global::_experimentInfo.sampleName,Global::Mode::Experiment,finalFileName,true)){
_leftWidget->reloadFileName();
QString str = QString("%1 文件保存成功。").arg(finalFileName);
QMessageBox::information(this, "文件保存", str,QMessageBox::Yes );
}
#endif
@ -500,20 +525,26 @@ void MainWindow::slotSaveExperimentalDataMsgBox()
return;
}
// auto save file.
QString finalFileName;
if(saveFile(Global::_experimentInfo.sampleName,Global::Mode::Experiment,finalFileName,true)){
_leftWidget->reloadFileName();
QString str = QString("%1 文件保存成功。").arg(finalFileName);
QMessageBox::information(this, "文件保存", str,QMessageBox::Yes );
}
#if 0
QMessageBox::StandardButton reply;
reply = QMessageBox::question(this, "数据保存提示", "是否保存实验数据?",
QMessageBox::Yes | QMessageBox::No);
if (reply == QMessageBox::Yes) {
saveFile(Global::_experimentInfo.sampleName,Global::Mode::Experiment);
QString finaleFileName;
saveFile(Global::_experimentInfo.sampleName,Global::Mode::Experiment,finaleFileName);
_leftWidget->reloadFileName();
} else {
on_actionClearAllData_triggered();
}
#if 0
// Clear data.
logde<<"save mesg box.clearExperimentData...";
Global::clearExperimentData();
#endif
}
@ -614,7 +645,7 @@ void MainWindow::on_actionOITAutoAnalysisParam_triggered()
void MainWindow::on_actionOITAutoAnalysisMode_triggered()
{
//
}
void MainWindow::on_actionTimeAxisAnalysisPCTMode_triggered()
@ -675,13 +706,15 @@ void MainWindow::on_actionAxisSetting_triggered()
void MainWindow::on_actionSaveData_triggered()
{
saveFile(Global::_experimentInfo.sampleName,Global::_mode);
QString finaleFileName;
saveFile(Global::_experimentInfo.sampleName,Global::_mode,finaleFileName);
_leftWidget->reloadFileName();
}
void MainWindow::on_actionSaveas_triggered()
{
saveFile(Global::_experimentInfo.sampleName,Global::Mode::None);
QString finaleFileName;
saveFile(Global::_experimentInfo.sampleName,Global::Mode::None,finaleFileName);
_leftWidget->reloadFileName();
}

View File

@ -5,6 +5,7 @@
#include <QStatusBar>
#include <QDockWidget>
#include "oitautoanalysis.h"
#include "axissettingform.h"
#include "printpreviewform.h"
#include "centralwidget.h"
@ -38,6 +39,9 @@ public:
public slots:
void slotContextMenuShow(const QPoint);
void slotUpdateStatusbarMsg(const QString);
void slotOITAutoAnalysis(const double,const double);
protected:
void closeEvent(QCloseEvent *event) override;
private slots:
@ -117,7 +121,8 @@ private:
void setActionEnable(const bool);
void setSubWidgetAttribute(QWidget *);
bool saveFile(const QString fileName,const Global::Mode);
bool saveFile(const QString fileName,const Global::Mode,
QString& finalFileName,const bool autoSaveFlag = false);
void smoothness(const int level);
QVector<Global::ExperimentData> smoothnessDetail(const int level,const QVector<Global::ExperimentData>&);

View File

@ -62,10 +62,11 @@
<addaction name="actionInstrumentParameter"/>
<addaction name="actionOnsetTemperaturePoint"/>
<addaction name="actionEndsetTemperaturePoint"/>
<addaction name="actionOITAutoAnalysisParam"/>
<addaction name="actionOITAutoAnalysisMode"/>
<addaction name="actionTimeAxisAnalysisPCTMode"/>
<addaction name="actionDegreeOfCuring"/>
<addaction name="separator"/>
<addaction name="actionOITAutoAnalysisParam"/>
<addaction name="actionOITAutoAnalysisMode"/>
</widget>
<widget class="QMenu" name="menu_5">
<property name="title">
@ -288,10 +289,13 @@
</action>
<action name="actionOITAutoAnalysisParam">
<property name="text">
<string>OIT自动分析参数</string>
<string>OIT自动分析设置</string>
</property>
</action>
<action name="actionOITAutoAnalysisMode">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>OIT自动分析模式</string>
</property>

View File

@ -220,7 +220,7 @@ void SerialPort::updateStatus(const CommonData &cd)
preMode = Global::_mode;
}
if(sendSignalFlag){
if(sendSignalFlag && !Global::_OITAutoAnalysisModeFlag){
emit sigSaveExperimentalDataMsgBox();
}
}

View File

@ -5,6 +5,7 @@
#include <qcustomplot.h>
#include <QMessageBox>
#include "oitautoanalysis.h"
#include "analysisoperationrecorder.h"
#include "centralwidget.h"
#include "filemanager.h"
@ -215,6 +216,17 @@ void CentralWidget::startExperiment()
_customPlot->replot();
}
void CentralWidget::setVerticalLineRange(const double x1, const double x2)
{
_line1->point1->setCoords(x1,_line1->point1->coords().y());
_line1->point2->setCoords(x1,_line1->point2->coords().y());
_line2->point1->setCoords(x2,_line2->point1->coords().y());
_line2->point2->setCoords(x2,_line2->point2->coords().y());
slotAnalysisSettingConfirm();
}
void CentralWidget::setAnalysisMode(const AnalysisMode mode)
{
_analysisMode = mode;
@ -290,12 +302,15 @@ void CentralWidget::slotRecvCommonData(const CommonData &cd)
ed.constantTempTime = cd.add_constan_temp_time;
if(Global::_currentCurveExperimentDataPtr->dataVtr.empty()){
ed.phaseIndex = Global::_currentCurveExperimentDataPtr->phaseIndex;
logde<<"change phase, index:"<<Global::_currentCurveExperimentDataPtr->phaseIndex;
_currentCurve = nullptr;
}
ed.phaseIndex = Global::_currentCurveExperimentDataPtr->phaseIndex;
Global::_currentCurveExperimentDataPtr->dataVtr.push_back(ed);
OITAutoAnalysis::getInstance()->analysis();
}
// Update ui.
@ -331,7 +346,7 @@ void CentralWidget::slotRecvCommonData(const CommonData &cd)
_currentCurve->addData(index++,cd.add_run_time, cd.dsc);
}
// _customPlot->rescaleAxes();
//
_customPlot->replot();
}
@ -1542,6 +1557,8 @@ void CentralWidget::calculateAnalysisResult(
endData.runTime = startEndPointPair.second.x();
endData.dsc = startEndPointPair.second.y();
logde<<"start runtime:"<<startData.runTime;
logde<<"end runtime:"<<endData.runTime;
drawOITLine(startData,endData,step,objectName);

View File

@ -53,6 +53,8 @@ public:
QCPCurve * getCurrentCurve(){return _currentCurve;}
void startExperiment();
void setVerticalLineRange(const double,const double);
signals:
void sigContextMenuShow(const QPoint);
void sigSendLineXCoord(const int,const double);

View File

@ -21,6 +21,11 @@ ExperimentSettingForm::ExperimentSettingForm(QWidget *parent) : QWidget(parent),
ui(new Ui::ExperimentSettingForm)
{
ui->setupUi(this);
ui->sampleNameLineEdit->setText("new");
ui->sampleWeightLineEdit->setText("0");
ui->userLineEdit->setText("user");
uiReset();
ui->checkBox_phase_1->setTristate(false);

View File

@ -53,6 +53,26 @@ void LeftWidget::reloadFileName()
initFileName(_analysisStateItem,Global::AnalysisStateFolder);
}
QString LeftWidget::filePathCheck(const QString fileName,const QString folderPath)
{
QString resultFileName = fileName;
QDir dir(folderPath);
QStringList files = dir.entryList(QDir::Files);
for(const QString &existedFileName:files){
QFileInfo fileInfo(existedFileName);
if(fileName == fileInfo.baseName()){
QDateTime currentDateTime = QDateTime::currentDateTime();
QString formattedTime = currentDateTime.toString("yyyy_MM_dd_HH_mm_ss");
resultFileName = fileName + QString("_") + formattedTime;
break;
}
}
return resultFileName;
}
void LeftWidget::initData()
{
// const QString folderPath = QDir::currentPath()+"/../experiment_data";

View File

@ -6,6 +6,8 @@
#include <qtreewidget.h>
#include <QTreeWidgetItem>
#include "global.h"
class LeftWidget:public QDockWidget
{
Q_OBJECT
@ -13,6 +15,8 @@ public:
LeftWidget(QWidget *parent = nullptr);
void reloadFileName();
QString filePathCheck(const QString fileName,const QString folderPath);
signals:
void sigSendAnalysisFileName(const QString&);
private:

View File

@ -1,11 +1,22 @@
#include "oitautoanalysisparamform.h"
#include "ui_oitautoanalysisparamform.h"
#include "global.h"
#include "logger.h"
OITAutoAnalysisParamForm::OITAutoAnalysisParamForm(QWidget *parent) :
QWidget(parent),
ui(new Ui::OITAutoAnalysisParamForm)
{
ui->setupUi(this);
ui->LineEditCoefficient->setEnabled(false);
ui->LineEditThreshold->setEnabled(false);
ui->LineEditCoefficient->setText(
Global::converDoubleToStr(Global::_OITAutoAnalysisCoefficient));
ui->LineEditThreshold->setText(
Global::converDoubleToStr(Global::_OITAutoAnalysisThreshold));
}
OITAutoAnalysisParamForm::~OITAutoAnalysisParamForm()
@ -16,4 +27,30 @@ OITAutoAnalysisParamForm::~OITAutoAnalysisParamForm()
void OITAutoAnalysisParamForm::on_pushButtonOk_clicked()
{
hide();
if(ui->checkBoxAutoAnalysisEnable->checkState() == Qt::Checked){
Global::_OITAutoAnalysisModeFlag = true;
}else if(ui->checkBoxAutoAnalysisEnable->checkState() == Qt::Unchecked){
Global::_OITAutoAnalysisModeFlag = false;
}
Global::_OITAutoAnalysisCoefficient =
ui->LineEditCoefficient->text().toDouble();
Global::_OITAutoAnalysisThreshold =
ui->LineEditThreshold->text().toDouble();
logde<<"flag:"<<Global::_OITAutoAnalysisModeFlag;
logde<<"coefficient:"<<Global::_OITAutoAnalysisCoefficient;
logde<<"threshold:"<<Global::_OITAutoAnalysisThreshold;
}
void OITAutoAnalysisParamForm::on_checkBoxAutoAnalysisEnable_stateChanged(int arg1)
{
if(arg1 == Qt::Checked){
ui->LineEditCoefficient->setEnabled(true);
ui->LineEditThreshold->setEnabled(true);
}else if(arg1 == Qt::Unchecked){
ui->LineEditCoefficient->setEnabled(false);
ui->LineEditThreshold->setEnabled(false);
}
}

View File

@ -18,6 +18,8 @@ public:
private slots:
void on_pushButtonOk_clicked();
void on_checkBoxAutoAnalysisEnable_stateChanged(int arg1);
private:
Ui::OITAutoAnalysisParamForm *ui;
};

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>233</width>
<height>156</height>
<width>269</width>
<height>235</height>
</rect>
</property>
<property name="windowTitle">
@ -16,8 +16,8 @@
<widget class="QPushButton" name="pushButtonOk">
<property name="geometry">
<rect>
<x>130</x>
<y>120</y>
<x>170</x>
<y>170</y>
<width>80</width>
<height>20</height>
</rect>
@ -29,8 +29,8 @@
<widget class="QGroupBox" name="groupBox">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<x>30</x>
<y>60</y>
<width>191</width>
<height>91</height>
</rect>
@ -44,17 +44,10 @@
<x>10</x>
<y>20</y>
<width>171</width>
<height>61</height>
<height>70</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="Label">
<property name="text">
<string>系数:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="LineEditCoefficient"/>
</item>
@ -68,9 +61,29 @@
<item row="1" column="1">
<widget class="QLineEdit" name="LineEditThreshold"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="Label">
<property name="text">
<string>系数:</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QCheckBox" name="checkBoxAutoAnalysisEnable">
<property name="geometry">
<rect>
<x>30</x>
<y>30</y>
<width>181</width>
<height>18</height>
</rect>
</property>
<property name="text">
<string>OIT自动分析模式</string>
</property>
</widget>
</widget>
<resources/>
<connections/>