2137 lines
62 KiB
C++
2137 lines
62 KiB
C++
#include "stdafx.h"
|
||
//#include <afx.h>
|
||
|
||
#include <exception>
|
||
#include <QMessageBox>
|
||
|
||
#include "HPPA.h"
|
||
#include "ImageReaderWriter.h"
|
||
|
||
|
||
|
||
|
||
HPPA::HPPA(QWidget *parent)
|
||
: QMainWindow(parent)
|
||
{
|
||
ui.setupUi(this);
|
||
|
||
//状态栏
|
||
xmotor_state_label1 = new QLabel();
|
||
ymotor_state_label1 = new QLabel();
|
||
xmotor_state_label1->setText("xMotor");
|
||
ymotor_state_label1->setText("yMotor");
|
||
ui.statusBar->addPermanentWidget(xmotor_state_label1);
|
||
ui.statusBar->addPermanentWidget(ymotor_state_label1);
|
||
|
||
|
||
|
||
|
||
|
||
connect(this->ui.action_exit, SIGNAL(triggered()), this, SLOT(onExit()));
|
||
|
||
//ui.cam_label->setScaledContents(true);
|
||
|
||
/*ui.splitter->setStretchFactor(0, 1);
|
||
ui.splitter->setStretchFactor(1, 1);
|
||
ui.splitter->setStretchFactor(2, 3);*/
|
||
|
||
|
||
|
||
//在工具栏上添加输入框QLineEdit
|
||
frame_number = new QLineEdit(ui.mainToolBar);
|
||
frame_number->setStyleSheet("QLineEdit{background-color:rgb(255,255,255);}");
|
||
frame_number->setMaximumWidth(100);
|
||
frame_number->setText("5000");
|
||
QAction *action = ui.mainToolBar->insertWidget(ui.action_start_recording, frame_number);
|
||
|
||
m_FilenameLineEdit = new QLineEdit(ui.mainToolBar);
|
||
m_FilenameLineEdit->setStyleSheet("QLineEdit{background-color:rgb(255,255,255);}");
|
||
m_FilenameLineEdit->setMaximumWidth(100);
|
||
m_FilenameLineEdit->setText("tmp_image");
|
||
QAction *action1 = ui.mainToolBar->insertWidget(ui.action_start_recording, m_FilenameLineEdit);
|
||
|
||
|
||
|
||
|
||
/*QToolBar *ptoolbar = ui.mainToolBar;
|
||
QAction *pAction = new QAction("tangchao");
|
||
ptoolbar->addAction(pAction);*/
|
||
|
||
|
||
//用于显示光谱
|
||
m_chartView = new QChartView();
|
||
m_chartView->setRenderHint(QPainter::Antialiasing);
|
||
ui.spectral_gridLayout->addWidget(m_chartView);
|
||
|
||
//QLineSeries *series = new QLineSeries();
|
||
//QChart *chart = new QChart();
|
||
|
||
|
||
//光谱仪操作
|
||
m_Imager = nullptr;
|
||
m_RecordState = 0;
|
||
connect(this->ui.action_connect_imager, SIGNAL(triggered()), this, SLOT(onconnect()));//信号与槽:连接相机,相机操作相关信号与槽绑定放在函数onconnect中
|
||
|
||
//rgb相机
|
||
m_RgbCameraThread = new QThread();
|
||
m_RgbCamera = new RgbCameraOperation();
|
||
m_RgbCamera->moveToThread(m_RgbCameraThread);
|
||
m_RgbCameraThread->start();
|
||
connect(this->ui.open_rgb_camera_btn, SIGNAL(clicked()), m_RgbCamera, SLOT(OpenCamera()));//使用信号通知主线程(ui线程)刷新视频 → 成功,但是界面卡顿
|
||
connect(m_RgbCamera, SIGNAL(PlotSignal()), this, SLOT(onPlotRgbImage()));
|
||
|
||
//m_RgbCamera->setCallback(onPlotRgbImage);
|
||
//connect(this->ui.open_rgb_camera_btn, SIGNAL(clicked()), m_RgbCamera, SLOT(OpenCamera_callback()));//使用回调函数来刷新主线程(ui线程)上的视频 → 失败
|
||
|
||
connect(this->ui.close_rgb_camera_btn, SIGNAL(clicked()), this, SLOT(onCloseRgbCamera()));//关闭相机
|
||
connect(m_RgbCamera, SIGNAL(CamClosed()), this, SLOT(onClearLabel()));
|
||
|
||
|
||
//设置相机可用帧率范围:这些设置必须在slider的信号和槽连接connect前,否则setMinimum会改变slider的值
|
||
ui.FramerateSlider->setMinimum(1);
|
||
ui.FramerateSlider->setMaximum(250);
|
||
ui.GainSlider->setMinimum(0);
|
||
ui.GainSlider->setMaximum(24);
|
||
//相机参数控件设置为不可用
|
||
frame_number->setEnabled(false);
|
||
|
||
ui.framerate_lineEdit->setEnabled(false);
|
||
ui.integratioin_time_lineEdit->setEnabled(false);
|
||
ui.gain_lineEdit->setEnabled(false);
|
||
|
||
ui.FramerateSlider->setEnabled(false);
|
||
ui.IntegratioinTimeSlider->setEnabled(false);
|
||
ui.GainSlider->setEnabled(false);
|
||
|
||
|
||
|
||
|
||
m_xMotor = nullptr;
|
||
m_yMotor = nullptr;
|
||
newMotor();
|
||
|
||
|
||
//m_TestXmotorStausThread = new MotorWorkerThread(m_xMotor);
|
||
//m_TestXmotorStausThread->start();
|
||
|
||
startTimer(1000);
|
||
|
||
|
||
m_lManualSpeedOfXMotor = 6000;
|
||
m_lManualSpeedOfYMotor = 6000*2;//上海农科院:20000
|
||
|
||
connect(this->ui.motor_reset_btn, SIGNAL(clicked()), this, SLOT(onMotorReset()));
|
||
|
||
connect(this->ui.xmotor_left_btn, SIGNAL(pressed()), this, SLOT(onxMotorLeft()));
|
||
connect(this->ui.xmotor_left_btn, SIGNAL(released()), this, SLOT(onxMotorStop()));
|
||
connect(this->ui.xmotor_right_btn, SIGNAL(pressed()), this, SLOT(onxMotorRight()));
|
||
connect(this->ui.xmotor_right_btn, SIGNAL(released()), this, SLOT(onxMotorStop()));
|
||
|
||
connect(this->ui.ymotor_forward_btn, SIGNAL(pressed()), this, SLOT(onyMotorForward()));
|
||
connect(this->ui.ymotor_forward_btn, SIGNAL(released()), this, SLOT(onyMotorStop()));
|
||
connect(this->ui.ymotor_backward_btn, SIGNAL(pressed()), this, SLOT(onyMotorBackward()));
|
||
connect(this->ui.ymotor_backward_btn, SIGNAL(released()), this, SLOT(onyMotorStop()));
|
||
|
||
//速度
|
||
QRegExp rx("\\d{0,3}[1-9]$");
|
||
ui.xmotor_speed_lineEdit->setValidator(new QRegExpValidator(rx));
|
||
|
||
ui.xmotor_speed_slider->setRange(0, 3);//5.2734375cm/s=10000脉冲
|
||
ui.xmotor_speed_slider->setValue(1);
|
||
connect(this->ui.xmotor_speed_lineEdit, SIGNAL(editingFinished()), this, SLOT(OnXmotorSpeedLineeditEditingFinished()));
|
||
//connect(this->ui.xmotor_speed_lineEdit, SIGNAL(editingFinished()), this, SLOT(OnXmotorSpeedEditingFinished()));//不通过此方式为马达设置速度,每次点击采集后,都会读取界面的速度,然后设置
|
||
connect(this->ui.xmotor_speed_slider, SIGNAL(valueChanged(double)), this, SLOT(OnXmotorSpeedSliderChanged(double)));
|
||
|
||
connect(this->ui.xmotor_location_lineEdit, SIGNAL(editingFinished()), this, SLOT(OnXmotorLocationLineeditEditingFinished()));
|
||
connect(this->ui.xmotor_location_slider, SIGNAL(valueChanged(double)), this, SLOT(OnXmotorLocationSliderChanged(double)));
|
||
connect(this->ui.xmotor_location_slider, SIGNAL(sliderReleased()), this, SLOT(OnXmotorLocationSliderReleased()));
|
||
ui.xmotor_location_slider->setValue(0);
|
||
|
||
|
||
|
||
|
||
connect(this->ui.ymotor_location_lineEdit, SIGNAL(editingFinished()), this, SLOT(OnYmotorLocationLineeditEditingFinished()));
|
||
connect(this->ui.ymotor_location_slider, SIGNAL(valueChanged(double)), this, SLOT(OnYmotorLocationSliderChanged(double)));
|
||
connect(this->ui.ymotor_location_slider, SIGNAL(sliderReleased()), this, SLOT(OnYmotorLocationSliderReleased()));
|
||
ui.ymotor_location_slider->setValue(0);
|
||
|
||
|
||
|
||
m_timerLocationFeedBackOfMotor_x_y = new QTimer();
|
||
connect(m_timerLocationFeedBackOfMotor_x_y, SIGNAL(timeout()), this, SLOT(ontimerLocationFeedBackOfMotor_x_y()));
|
||
|
||
m_timerYmotorLocationFeedBackAfterRecord = new QTimer();
|
||
connect(m_timerYmotorLocationFeedBackAfterRecord, SIGNAL(timeout()), this, SLOT(ontimerYmotorLocationFeedBackAfterRecord()));
|
||
|
||
//马达量程测量
|
||
connect(this->ui.test_range_btn, SIGNAL(clicked()), this, SLOT(ontestRangeOfMotor_x_y()));
|
||
m_timerTestRangeOfxMotor = new QTimer();
|
||
connect(m_timerTestRangeOfxMotor, SIGNAL(timeout()), this, SLOT(ontimerTestRangeOfxMotor()));
|
||
m_timerTestRangeOfyMotor = new QTimer();
|
||
connect(m_timerTestRangeOfyMotor, SIGNAL(timeout()), this, SLOT(ontimerTestRangeOfyMotor()));
|
||
|
||
widthScale = 1;
|
||
heightScale = 1;
|
||
|
||
//马达位置模拟
|
||
connect(ui.graphicsView->imager, SIGNAL(leftMouseButtonPressed(int, int)), this, SLOT(onimagerSimulatorMove(int, int)));
|
||
|
||
|
||
|
||
//规划采集线
|
||
ui.recordLine_tableWidget->setFocusPolicy(Qt::NoFocus);
|
||
ui.recordLine_tableWidget->setStyleSheet("selection-background-color:rgb(255,209,128)");//设置选择的行高亮
|
||
|
||
ui.recordLine_tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);//设置选择行为,以行为单位
|
||
//ui.recordLine_tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);//设置选择模式,选择单行
|
||
//QHeaderView* headerView = ui.recordLine_tableWidget->verticalHeader();
|
||
//headerView->setHidden(true);//去除左边默认自带序列号
|
||
|
||
|
||
ui.recordLine_tableWidget->setColumnCount(2);
|
||
ui.recordLine_tableWidget->setHorizontalHeaderLabels(QStringList() << "yPosition" << "xMaxPosition");
|
||
|
||
connect(ui.addRecordLine_btn, SIGNAL(clicked()), this, SLOT(onAddRecordLine_btn()));
|
||
connect(ui.removeRecordLine_btn, SIGNAL(clicked()), this, SLOT(onRemoveRecordLine_btn()));
|
||
connect(ui.generateRecordLine_btn, SIGNAL(clicked()), this, SLOT(onGenerateRecordLine_btn()));
|
||
connect(ui.deleteRecordLine_btn, SIGNAL(clicked()), this, SLOT(onDeleteRecordLine_btn()));
|
||
connect(ui.saveRecordLine2File_btn, SIGNAL(clicked()), this, SLOT(onSaveRecordLine2File_btn()));
|
||
connect(ui.readRecordLineFile_btn, SIGNAL(clicked()), this, SLOT(onReadRecordLineFile_btn()));
|
||
|
||
|
||
//
|
||
m_ForLoopControlThread = new QThread();
|
||
m_ForLoopControl = new ForLoopControl();
|
||
m_ForLoopControl->moveToThread(m_ForLoopControlThread);
|
||
m_ForLoopControlThread->start();
|
||
|
||
|
||
//connect(this->ui.action_start_recording, SIGNAL(triggered()), m_ForLoopControl, SLOT(startLoop()));//放在函数onconnect中
|
||
connect(m_ForLoopControl, SIGNAL(recordSignal(int)), this, SLOT(onStartRecordStep2(int)));
|
||
|
||
|
||
|
||
m_timerMoveXmotor = new QTimer();
|
||
connect(m_timerMoveXmotor, SIGNAL(timeout()), this, SLOT(ontimerMoveXmotor()));
|
||
m_timerMoveYmotor = new QTimer();
|
||
connect(m_timerMoveYmotor, SIGNAL(timeout()), this, SLOT(ontimerMoveYmotor()));
|
||
|
||
|
||
//
|
||
ui.ImageViewerTabWidget->clear();//必须放在最前面,首先删除所有的tab
|
||
//ui.ImageViewerTabWidget->setTabsClosable(true);//这样每页都会有关闭按钮
|
||
connect(m_ForLoopControl, SIGNAL(recordSignal(int)), this, SLOT(onCreateTab(int)));//在tabWidget中新建一个tab,用于显示图像
|
||
connect(ui.ImageViewerTabWidget, SIGNAL(currentChanged(int)), this, SLOT(onTabWidgetCurrentChanged(int)));
|
||
|
||
//电源控制
|
||
connect(ui.lamp_power_open_btn, SIGNAL(clicked()), this, SLOT(onLampPowerOpen_btn()));
|
||
connect(ui.lamp_power_close_btn, SIGNAL(clicked()), this, SLOT(onLampPowerClose_btn()));
|
||
|
||
connect(ui.motor_power_open_btn, SIGNAL(clicked()), this, SLOT(onMotorPowerOpen_btn()));
|
||
connect(ui.motor_power_close_btn, SIGNAL(clicked()), this, SLOT(onMotorPowerClose_btn()));
|
||
|
||
//
|
||
connect(this->ui.action_about, SIGNAL(triggered()), this, SLOT(onAbout()));
|
||
|
||
//配置文件:如果没有,就创建配置文件
|
||
string HPPACfgFile = getPathofEXE() + "\\HPPA.cfg";
|
||
|
||
Configfile configfile;
|
||
configfile.setConfigfilePath(HPPACfgFile);
|
||
if (!configfile.isConfigfileExist())
|
||
{
|
||
configfile.createConfigFile();
|
||
qDebug() << "create: " << QString::fromStdString(HPPACfgFile);
|
||
}
|
||
configfile.parseConfigfile();
|
||
qDebug() << "exist: " << QString::fromStdString(HPPACfgFile);
|
||
|
||
/*int max, min;
|
||
configfile.getPositionRestriction(max, min);
|
||
|
||
string sn;
|
||
configfile.getSN(sn);
|
||
|
||
int coarse, fine;
|
||
configfile.getTuningStepSize(coarse, fine);
|
||
float fa, fb;
|
||
configfile.getFitParams(fa, fb);
|
||
int max_FocusRange, min_FocusRange;
|
||
configfile.getAutoFocusRange(max_FocusRange, min_FocusRange);
|
||
|
||
float StepAnglemar_x, Lead_x, ScaleFactor_x;
|
||
int SubdivisionMultiples_x;
|
||
configfile.getXMotorParm(StepAnglemar_x, Lead_x, SubdivisionMultiples_x, ScaleFactor_x);
|
||
float StepAnglemar_y, Lead_y, ScaleFactor_y;
|
||
int SubdivisionMultiples_y;
|
||
configfile.getYMotorParm(StepAnglemar_y, Lead_y, SubdivisionMultiples_y, ScaleFactor_y);*/
|
||
|
||
//
|
||
connect(ui.objective_table1_up_btn, SIGNAL(clicked()), this, SLOT(onObjectivTable1Up_btn()));
|
||
connect(ui.objective_table1_down_btn, SIGNAL(clicked()), this, SLOT(onObjectivTable1Down_btn()));
|
||
connect(ui.objective_table1_stop_btn, SIGNAL(clicked()), this, SLOT(onObjectivTable1Stop_btn()));
|
||
|
||
connect(ui.objective_table2_up_btn, SIGNAL(clicked()), this, SLOT(onObjectivTable2Up_btn()));
|
||
connect(ui.objective_table2_down_btn, SIGNAL(clicked()), this, SLOT(onObjectivTable2Down_btn()));
|
||
connect(ui.objective_table2_stop_btn, SIGNAL(clicked()), this, SLOT(onObjectivTable2Stop_btn()));
|
||
}
|
||
|
||
HPPA::~HPPA()
|
||
{
|
||
if (m_Imager != nullptr)
|
||
m_Imager->~ResononImager();//释放资源
|
||
|
||
if (m_xMotor != nullptr && m_yMotor != nullptr)
|
||
{
|
||
if (isMotorConnected(m_xMotor))
|
||
{
|
||
m_xMotor->StopMotormove();
|
||
}
|
||
if (isMotorConnected(m_yMotor))
|
||
{
|
||
m_yMotor->StopMotormove();
|
||
}
|
||
}
|
||
}
|
||
|
||
void HPPA::CalculateIntegratioinTimeRange()
|
||
{
|
||
double range = 1 / m_Imager->get_framerate() * 1000;//毫秒
|
||
|
||
ui.IntegratioinTimeSlider->blockSignals(true);//因为setMaximum会触发valueChanged信号,所以调用setMaximum前需要阻断信号
|
||
ui.IntegratioinTimeSlider->setMaximum(range);
|
||
ui.IntegratioinTimeSlider->blockSignals(false);
|
||
}
|
||
|
||
void HPPA::onStartRecordStep1()
|
||
{
|
||
////测试代码,用于没有马达时,仅采集光谱仪数据
|
||
//m_RecordState += 1;
|
||
|
||
//if (m_RecordState % 2 == 1)
|
||
//{
|
||
// onCreateTab(1);
|
||
// m_numberOfRecording = 0;
|
||
// m_Imager->setFileName2Save(m_FilenameLineEdit->text().toStdString());
|
||
// emit StartRecordSignal();//发射开始采集信号
|
||
//}
|
||
//else
|
||
//{
|
||
// m_Imager->setRecordControlState(false);//光谱仪停止采集
|
||
|
||
// ui.action_start_recording->setText(QString::fromLocal8Bit("采集"));
|
||
// ui.mainToolBar->widgetForAction(ui.action_start_recording)->setStyleSheet("QWidget{background-color:rgb(0,255,0);}");
|
||
//}
|
||
|
||
|
||
//确保x马达所在位置 小于 x马达最大采集限制位置
|
||
int validLineCount = 0;
|
||
for (size_t i = 0; i < ui.recordLine_tableWidget->rowCount(); i++)
|
||
{
|
||
//xx = xx + ui.xmotor_location_slider->value() < ui.recordLine_tableWidget->item(i, 1)->text().toDouble();
|
||
|
||
if (ui.xmotor_location_slider->value() < ui.recordLine_tableWidget->item(i, 1)->text().toDouble())
|
||
{
|
||
validLineCount++;
|
||
}
|
||
|
||
}
|
||
|
||
if (validLineCount < ui.recordLine_tableWidget->rowCount())
|
||
{
|
||
QMessageBox::information(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("轨迹x马达限位错误!"));
|
||
return;
|
||
}
|
||
|
||
//确保采集线存在
|
||
if (ui.recordLine_tableWidget->rowCount() <= 0)
|
||
{
|
||
QMessageBox::information(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("请先生成轨迹!"));
|
||
return;
|
||
}
|
||
|
||
|
||
//开始采集
|
||
m_RecordState += 1;
|
||
|
||
if (m_RecordState % 2 == 1)
|
||
{
|
||
//判断是否覆盖存在的文件
|
||
FileOperation * fileOperation = new FileOperation();
|
||
string directory = fileOperation->getDirectoryFromString();
|
||
//string imgPath = directory + "\\tmp_image";
|
||
string imgPath = directory + "\\" + m_FilenameLineEdit->text().toStdString() + "_" + std::to_string(1);
|
||
int x = _access(imgPath.c_str(), 0);
|
||
if (!x)//如果文件存在就执行此if的代码
|
||
{
|
||
enum QMessageBox::StandardButton response = QMessageBox::question(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("文件存在!是否覆盖?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);;
|
||
if (response == QMessageBox::Yes)//
|
||
{
|
||
//std::cout << "覆盖" << std::endl;
|
||
}
|
||
else
|
||
{
|
||
//std::cout << "不覆盖" << std::endl;
|
||
m_RecordState -= 1;//不覆盖的话就需要还原这个参数,并停止采集
|
||
return;
|
||
}
|
||
}
|
||
|
||
|
||
//
|
||
operateWidget = QObject::sender()->objectName();
|
||
|
||
//设置文件保存名
|
||
m_Imager->setFileName2Save(m_FilenameLineEdit->text().toStdString());
|
||
|
||
//删除所有tab
|
||
ui.ImageViewerTabWidget->clear();
|
||
|
||
//开始循环
|
||
m_ForLoopControl->setLoopCount(ui.recordLine_tableWidget->rowCount());//为循环控制线程设置循环次数
|
||
emit StartLoopSignal();
|
||
|
||
//所有行设置为灰色
|
||
for (size_t i = 0; i < ui.recordLine_tableWidget->rowCount(); i++)
|
||
{
|
||
for (size_t j = 0; j < ui.recordLine_tableWidget->columnCount(); j++)
|
||
{
|
||
ui.recordLine_tableWidget->item(i, j)->setBackgroundColor(QColor(240, 240, 240));
|
||
}
|
||
}
|
||
|
||
ui.action_start_recording->setText(QString::fromLocal8Bit("停止采集"));
|
||
ui.mainToolBar->widgetForAction(ui.action_start_recording)->setStyleSheet("QWidget{background-color:rgb(255,0,0);}");
|
||
}
|
||
else
|
||
{
|
||
m_Imager->setRecordControlState(false);//光谱仪停止采集
|
||
|
||
m_ForLoopControl->m_boolQuitLoop = true;//循环停止
|
||
|
||
ui.action_start_recording->setText(QString::fromLocal8Bit("采集"));
|
||
ui.mainToolBar->widgetForAction(ui.action_start_recording)->setStyleSheet("QWidget{background-color:rgb(0,255,0);}");
|
||
}
|
||
}
|
||
|
||
void HPPA::onStartRecordStep2(int lineNumber)
|
||
{
|
||
if (m_xMotor == nullptr && m_yMotor == nullptr)
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (lineNumber >= 0)
|
||
{
|
||
m_numberOfRecording = lineNumber;
|
||
}
|
||
|
||
if (lineNumber >= 0)
|
||
{
|
||
//开始移动y马达,控制x马达移动和光谱仪采集的代码也在这里面
|
||
double pos = ui.recordLine_tableWidget->item(lineNumber, 0)->text().toDouble();
|
||
m_yMotor->SettingSpeed(m_lManualSpeedOfYMotor);
|
||
m_yMotor->MoveToLocation(ui.ymotor_location_slider->getPositionPulse(pos));
|
||
m_timerMoveYmotor->start(500);
|
||
|
||
//将正在采集的行设置为红色
|
||
for (size_t i = 0; i < ui.recordLine_tableWidget->columnCount(); i++)
|
||
{
|
||
ui.recordLine_tableWidget->item(lineNumber, i)->setBackgroundColor(QColor(255, 0, 0));
|
||
}
|
||
}
|
||
else if (lineNumber == -1)
|
||
{
|
||
std::cout << "软件自动终止采集。" << std::endl;
|
||
m_RecordState++;
|
||
|
||
ui.action_start_recording->setText(QString::fromLocal8Bit("采集"));
|
||
ui.mainToolBar->widgetForAction(ui.action_start_recording)->setStyleSheet("QWidget{background-color:rgb(0,255,0);}");
|
||
|
||
//将y马达移动到第一条采集线的位置
|
||
double ymotorPositionOfLine1Tmp = ui.recordLine_tableWidget->item(0, 0)->text().toDouble();
|
||
long ymotorPositionOfLine1 = ui.ymotor_location_slider->getPositionPulse(ymotorPositionOfLine1Tmp);
|
||
m_yMotor->SettingSpeed(m_lManualSpeedOfYMotor);
|
||
m_yMotor->MoveToLocation(ymotorPositionOfLine1);
|
||
m_timerYmotorLocationFeedBackAfterRecord->start(500);
|
||
}
|
||
else if (lineNumber == -2)
|
||
{
|
||
std::cout << "手动终止采集。" << std::endl;
|
||
|
||
//停止y马达运动
|
||
m_yMotor->StopMotormove();
|
||
|
||
}
|
||
}
|
||
|
||
void HPPA::onCreateTab(int trackNumber)
|
||
{
|
||
if (trackNumber >= 0)
|
||
{
|
||
QWidget * tabTmp = new QWidget();
|
||
|
||
QGridLayout *GridLayout = new QGridLayout();
|
||
GridLayout->addWidget(new ImageViewer(tabTmp));
|
||
|
||
tabTmp->setLayout(GridLayout);
|
||
|
||
ui.ImageViewerTabWidget->addTab(tabTmp, QString::number(trackNumber + 1));
|
||
|
||
ui.ImageViewerTabWidget->setCurrentIndex(trackNumber);
|
||
}
|
||
|
||
}
|
||
|
||
void HPPA::onTabWidgetCurrentChanged(int index)//代码新建一个tab,会调用onTabWidgetCurrentChanged函数!
|
||
{
|
||
if (index < 0)//当删除所有tab时,index=-1
|
||
{
|
||
return;
|
||
}
|
||
|
||
|
||
//记录当前
|
||
m_TabWidgetCurrentIndex = index;
|
||
|
||
//获取绘图控件
|
||
QWidget* currentWidget = ui.ImageViewerTabWidget->widget(index);
|
||
QList<ImageViewer *> currentImageViewer = currentWidget->findChildren<ImageViewer *>();
|
||
|
||
//先disconnect然后再connect,否则每次切换一次都会connect一次,会累积connect很多次!
|
||
disconnect(currentImageViewer[0], SIGNAL(leftMouseButtonPressed(int, int)), this, SLOT(onLeftMouseButtonPressed(int, int)));
|
||
connect(currentImageViewer[0], SIGNAL(leftMouseButtonPressed(int, int)), this, SLOT(onLeftMouseButtonPressed(int, int)));
|
||
}
|
||
|
||
void HPPA::onActionOpenDirectory()
|
||
{
|
||
FileOperation * fileOperation = new FileOperation();
|
||
string directory = fileOperation->getDirectoryFromString();
|
||
|
||
QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdString(directory)));
|
||
|
||
//QDesktopServices::openUrl(QUrl("file:C:\ASD", QUrl::TolerantMode));
|
||
|
||
|
||
////std::cout << "保存影像文件!" << std::endl;
|
||
//
|
||
//FileOperation * fileOperation = new FileOperation();
|
||
//string directory = fileOperation->getDirectoryFromString();
|
||
|
||
//string sourceImg = directory + "\\tmp_image";
|
||
//string sourceHdr = sourceImg + ".hdr";
|
||
//
|
||
|
||
//QString FileName2Save = QFileDialog::getSaveFileName(this,tr("save image"));
|
||
|
||
//if (FileName2Save.length()>0)
|
||
//{
|
||
// string targetImg = FileName2Save.toStdString();
|
||
// string targetHdr = targetImg + ".hdr";
|
||
|
||
// emit CopyFileThreadSignal(QString::fromStdString(sourceHdr), QString::fromStdString(targetHdr));
|
||
// emit CopyFileThreadSignal(QString::fromStdString(sourceImg), QString::fromStdString(targetImg));
|
||
|
||
// this->setEnabled(false);
|
||
//}
|
||
//else
|
||
//{
|
||
// std::cout << "文件名长度:" << FileName2Save.length() << std::endl;
|
||
//}
|
||
|
||
}
|
||
|
||
void HPPA::OnFramerateLineeditEditingFinished()
|
||
{
|
||
std::cout << "Lineedit设置帧率------------------------------------------" << std::endl;
|
||
m_Imager->set_framerate(this->ui.framerate_lineEdit->text().toDouble());
|
||
ui.FramerateSlider->setValue(ui.framerate_lineEdit->text().toDouble());
|
||
|
||
CalculateIntegratioinTimeRange();
|
||
}
|
||
|
||
void HPPA::OnFramerateSliderChanged(double framerate)
|
||
{
|
||
std::cout << "Slider设置帧率------------------------------------------" << std::endl;
|
||
m_Imager->set_framerate(this->ui.framerate_lineEdit->text().toDouble());
|
||
ui.framerate_lineEdit->setText(QString::number(framerate));
|
||
|
||
CalculateIntegratioinTimeRange();
|
||
}
|
||
|
||
void HPPA::OnIntegratioinTimeEditingFinished()
|
||
{
|
||
std::cout << "Lineedit设置积分时间------------------------------------------" << std::endl;
|
||
m_Imager->set_integration_time(this->ui.integratioin_time_lineEdit->text().toDouble());
|
||
ui.IntegratioinTimeSlider->setValue(ui.integratioin_time_lineEdit->text().toDouble());
|
||
}
|
||
|
||
void HPPA::OnIntegratioinTimeSliderChanged(double IntegratioinTime)
|
||
{
|
||
std::cout << "Slider设置积分时间------------------------------------------" << std::endl;
|
||
m_Imager->set_integration_time(IntegratioinTime);
|
||
ui.integratioin_time_lineEdit->setText(QString::number(IntegratioinTime));
|
||
}
|
||
|
||
void HPPA::OnGainEditingFinished()
|
||
{
|
||
m_Imager->set_gain(this->ui.gain_lineEdit->text().toDouble());
|
||
ui.GainSlider->setValue(ui.gain_lineEdit->text().toDouble());
|
||
}
|
||
|
||
void HPPA::OnGainSliderChanged(double Gain)
|
||
{
|
||
m_Imager->set_gain(this->ui.gain_lineEdit->text().toDouble());
|
||
ui.gain_lineEdit->setText(QString::number(Gain));
|
||
}
|
||
|
||
void HPPA::onLeftMouseButtonPressed(int x, int y)
|
||
{
|
||
try
|
||
{
|
||
//正在采集时,不能显示光谱曲线
|
||
if (m_RecordState % 2 == 1)
|
||
{
|
||
return;
|
||
}
|
||
|
||
|
||
FileOperation * fileOperation = new FileOperation();
|
||
string directory = fileOperation->getDirectoryFromString();
|
||
string imgPath = directory + "\\" + m_FilenameLineEdit->text().toStdString() + "_" + std::to_string(m_TabWidgetCurrentIndex + 1);
|
||
|
||
ImageReaderWriter *ImageReader = new ImageReaderWriter(imgPath.c_str());
|
||
|
||
|
||
if (x < 0 || x>899 || y<0 || y>ImageReader->getyCount() - 1)
|
||
{
|
||
return;
|
||
}
|
||
|
||
|
||
float *data = ImageReader->ReadImage(x, y, 1, 1);
|
||
|
||
|
||
QLineSeries *series = new QLineSeries();
|
||
//series->clear();//////////////////////////////
|
||
|
||
for (size_t i = 0; i < m_Imager->getBandCount(); i++)
|
||
{
|
||
//malloc申请的内存用法1:可以当做数组用
|
||
series->append(m_Imager->getWavelengthAtBand(i), data[i]);
|
||
|
||
////malloc申请的内存用法2:指针存取
|
||
//series->append(m_Imager->getWavelengthAtBand(i), *data);
|
||
//data++;
|
||
}
|
||
|
||
QChart *chart = new QChart();
|
||
chart->legend()->hide();
|
||
chart->addSeries(series);
|
||
chart->createDefaultAxes();
|
||
//chart->setTitle("Simple line chart example");
|
||
|
||
m_chartView->setChart(chart);
|
||
//m_chartView->update();//////////////////////////////
|
||
|
||
|
||
/*std::cout << "x坐标:" << x << std::endl;
|
||
std::cout << "y坐标:" << y << std::endl;
|
||
std::cout << "文件名:" << imgPath << std::endl;*/
|
||
|
||
}
|
||
catch (const std::exception&)
|
||
{
|
||
std::cout << "显示光谱有错误!" << std::endl;
|
||
}
|
||
|
||
}
|
||
|
||
void HPPA::timerEvent(QTimerEvent *event)
|
||
{
|
||
try
|
||
{
|
||
if (m_xMotor == nullptr || m_yMotor == nullptr)
|
||
{
|
||
qDebug() << "Motor pointer is null!!!!!";
|
||
return;
|
||
}
|
||
|
||
if (!m_xMotor->IsMotorInit)
|
||
{
|
||
//return;
|
||
|
||
}
|
||
ByteBack xMotorState = m_xMotor->GetState();//执行有问题
|
||
|
||
std::cout << "------------------------------------------x马达速度:" << xMotorState.Speed << std::endl;
|
||
|
||
if (xMotorState.Speed == -1000000)
|
||
{
|
||
xmotor_state_label1->setStyleSheet("QLabel{background-color:rgb(255,0,0);}");
|
||
SetXMotorWidgetEnable(false);
|
||
//std::cout << "xMotor: false!" << std::endl;
|
||
}
|
||
else
|
||
{
|
||
m_xConnectCount++;
|
||
if (m_xConnectCount == 1)//第一次连接马达,设置电流
|
||
{
|
||
m_xMotor->SendCommandtoMotor("cfg crn=3\n");
|
||
}
|
||
|
||
xmotor_state_label1->setStyleSheet("QLabel{background-color:rgb(0,255,0);}");
|
||
SetXMotorWidgetEnable(true);
|
||
//std::cout << "xMotor: ok!" << std::endl;
|
||
}
|
||
|
||
|
||
ByteBack yMotorState = m_yMotor->GetState();
|
||
|
||
//std::cout << "------------------------------------------马达速度:" << x.Speed << std::endl;
|
||
|
||
if (yMotorState.Speed == -1000000)
|
||
{
|
||
ymotor_state_label1->setStyleSheet("QLabel{background-color:rgb(255,0,0);}");
|
||
SetYMotorWidgetEnable(false);
|
||
//std::cout << "yMotor: false!" << std::endl;
|
||
}
|
||
else
|
||
{
|
||
m_yConnectCount++;
|
||
if (m_yConnectCount == 1)//第一次连接马达,设置电流
|
||
{
|
||
m_yMotor->SendCommandtoMotor("cfg crn=2\n");
|
||
}
|
||
|
||
ymotor_state_label1->setStyleSheet("QLabel{background-color:rgb(0,255,0);}");
|
||
SetYMotorWidgetEnable(true);
|
||
//std::cout << "yMotor: ok!" << std::endl;
|
||
}
|
||
|
||
|
||
}
|
||
catch (...)
|
||
{
|
||
|
||
}
|
||
}
|
||
|
||
void HPPA::onxMotorLeft()
|
||
{
|
||
m_timerLocationFeedBackOfMotor_x_y->start(500);
|
||
if (isMotorConnected(m_xMotor))
|
||
{
|
||
return;
|
||
}
|
||
|
||
m_xMotor->EnableMotro();
|
||
m_xMotor->SettingSpeed(m_lManualSpeedOfXMotor);
|
||
m_xMotor->MoveMotar(false);
|
||
}
|
||
|
||
void HPPA::onxMotorRight()
|
||
{
|
||
m_timerLocationFeedBackOfMotor_x_y->start(500);
|
||
if (isMotorConnected(m_xMotor))
|
||
{
|
||
return;
|
||
}
|
||
|
||
m_xMotor->EnableMotro();
|
||
m_xMotor->SettingSpeed(m_lManualSpeedOfXMotor);
|
||
m_xMotor->MoveMotar(true);
|
||
}
|
||
|
||
void HPPA::onxMotorStop()
|
||
{
|
||
if (isMotorConnected(m_xMotor))
|
||
{
|
||
return;
|
||
}
|
||
|
||
m_timerLocationFeedBackOfMotor_x_y->stop();
|
||
m_xMotor->StopMotormove();
|
||
}
|
||
|
||
void HPPA::onyMotorForward()
|
||
{
|
||
operateWidget = QObject::sender()->objectName();
|
||
|
||
m_timerLocationFeedBackOfMotor_x_y->start(500);
|
||
if (isMotorConnected(m_yMotor))
|
||
{
|
||
return;
|
||
}
|
||
|
||
m_yMotor->EnableMotro();
|
||
m_yMotor->SettingSpeed(m_lManualSpeedOfYMotor);
|
||
m_yMotor->MoveMotar(true);
|
||
}
|
||
|
||
void HPPA::onyMotorBackward()
|
||
{
|
||
operateWidget = QObject::sender()->objectName();
|
||
|
||
m_timerLocationFeedBackOfMotor_x_y->start(500);
|
||
if (isMotorConnected(m_yMotor))
|
||
{
|
||
return;
|
||
}
|
||
|
||
m_yMotor->EnableMotro();
|
||
m_yMotor->SettingSpeed(m_lManualSpeedOfYMotor);
|
||
m_yMotor->MoveMotar(false);
|
||
}
|
||
|
||
void HPPA::onyMotorStop()
|
||
{
|
||
if (isMotorConnected(m_yMotor))
|
||
{
|
||
return;
|
||
}
|
||
|
||
m_timerLocationFeedBackOfMotor_x_y->stop();
|
||
m_yMotor->StopMotormove();
|
||
}
|
||
|
||
void HPPA::onMotorReset()
|
||
{
|
||
setMotorRange();
|
||
|
||
if (isMotorConnected(m_xMotor))
|
||
{
|
||
return;
|
||
}
|
||
if (isMotorConnected(m_yMotor))
|
||
{
|
||
return;
|
||
}
|
||
|
||
m_xMotor->SettingZeroLocation();
|
||
m_yMotor->SettingZeroLocation();
|
||
|
||
|
||
}
|
||
|
||
void HPPA::OnXmotorSpeedEditingFinished()
|
||
{
|
||
if (isMotorConnected(m_xMotor))
|
||
{
|
||
return;
|
||
}
|
||
|
||
m_xMotor->SettingSpeed(ui.xmotor_speed_lineEdit->text().toLong());
|
||
}
|
||
|
||
|
||
bool HPPA::isMotorConnected(VinceControl *motor)
|
||
{
|
||
ByteBack x = motor->GetState();
|
||
|
||
//std::cout << "------------------------------------------马达速度:" << x.Speed << std::endl;
|
||
|
||
if (x.Speed == -1000000)
|
||
{
|
||
return true;
|
||
}
|
||
else
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
void HPPA::SetXMotorWidgetEnable(bool enable)
|
||
{
|
||
ui.test_range_btn->setEnabled(enable);
|
||
ui.motor_reset_btn->setEnabled(enable);
|
||
|
||
//ui.xmotor_left_btn->setEnabled(enable);
|
||
//ui.xmotor_right_btn->setEnabled(enable);
|
||
ui.xmotor_speed_lineEdit->setEnabled(enable);
|
||
ui.xmotor_speed_slider->setEnabled(enable);
|
||
ui.xmotor_location_lineEdit->setEnabled(enable);
|
||
ui.xmotor_location_slider->setEnabled(enable);
|
||
}
|
||
|
||
void HPPA::SetYMotorWidgetEnable(bool enable)
|
||
{
|
||
ui.test_range_btn->setEnabled(enable);
|
||
ui.motor_reset_btn->setEnabled(enable);
|
||
|
||
//ui.ymotor_forward_btn->setEnabled(enable);
|
||
//ui.ymotor_backward_btn->setEnabled(enable);
|
||
ui.ymotor_location_lineEdit->setEnabled(enable);
|
||
ui.ymotor_location_slider->setEnabled(enable);
|
||
}
|
||
|
||
void HPPA::setMotorRange()
|
||
{
|
||
try
|
||
{
|
||
//将x马达量程记录到文件,以便后面使用 → 不用每次都测试量程,这样很浪费时间
|
||
|
||
FileOperation * fileOperation = new FileOperation();
|
||
string directory = fileOperation->getDirectoryOfExe();
|
||
string xMotorRangeFilePath = directory + "\\xMotorRange";
|
||
string yMotorRangeFilePath = directory + "\\yMotorRange";
|
||
|
||
|
||
FILE * xMotorRangeFile = fopen(xMotorRangeFilePath.c_str(), "r+b");
|
||
FILE * yMotorRangeFile = fopen(yMotorRangeFilePath.c_str(), "r+b");
|
||
|
||
|
||
//FILE * xMotorRangeFile = fopen("xMotorRange", "r+b");
|
||
//FILE * yMotorRangeFile = fopen("yMotorRange", "r+b");
|
||
|
||
double xMotorRange;
|
||
double yMotorRange;
|
||
|
||
fread(&xMotorRange, sizeof(double), 1, xMotorRangeFile);
|
||
fread(&yMotorRange, sizeof(double), 1, yMotorRangeFile);
|
||
|
||
fclose(xMotorRangeFile);
|
||
fclose(yMotorRangeFile);
|
||
|
||
//std::cout << "xMotorRange:" << xMotorRange << std::endl;
|
||
//std::cout << "yMotorRange:" << yMotorRange << std::endl;
|
||
|
||
|
||
//设置x马达范围
|
||
ui.xmotor_location_slider->setMaximum(xMotorRange);
|
||
ui.xmotor_max_location_label->setText(QString::number(ui.xmotor_location_slider->maximum()));
|
||
//设置y马达范围
|
||
ui.ymotor_location_slider->setMaximum(yMotorRange);
|
||
ui.ymotor_max_location_label->setText(QString::number(ui.ymotor_location_slider->maximum()));
|
||
|
||
|
||
QRectF rect = ui.graphicsView->viewport()->rect();
|
||
widthScale = rect.width() / xMotorRange;//重新设置sceneRect的宽度缩放系数(x)
|
||
heightScale = rect.height() / yMotorRange;//重新设置sceneRect的高度缩放系数(y)
|
||
|
||
|
||
ui.graphicsView->setSceneRect();
|
||
}
|
||
catch (...)
|
||
{
|
||
QMessageBox msgBox;
|
||
msgBox.setText(QString::fromLocal8Bit("请进行马达量程测量!"));
|
||
msgBox.exec();
|
||
}
|
||
}
|
||
|
||
void HPPA::setImagerSimulationPos(double x, double y)
|
||
{
|
||
x = widthScale * x;
|
||
y = heightScale * y;
|
||
ui.graphicsView->imager->setPos(x, y);
|
||
}
|
||
|
||
void HPPA::ontimerLocationFeedBackOfMotor_x_y()
|
||
{
|
||
//std::cout << "------------------------------------------" << std::endl;
|
||
if (isMotorConnected(m_xMotor))
|
||
{
|
||
return;
|
||
}
|
||
|
||
ByteBack xMotorState = m_xMotor->GetState();
|
||
|
||
//作用1:当手动控制/采集控制x马达运动时(左/右),将自动的调整马达位置slider
|
||
if (xMotorState.Speed != 0)
|
||
{
|
||
double newPos = ui.xmotor_location_slider->getDistanceFromPulse(xMotorState.Location);
|
||
|
||
ui.xmotor_location_slider->setValue(newPos, false);
|
||
setImagerSimulationPos(newPos, ui.ymotor_location_slider->value());
|
||
|
||
|
||
QApplication::processEvents();
|
||
}
|
||
|
||
|
||
|
||
if (isMotorConnected(m_yMotor))
|
||
{
|
||
return;
|
||
}
|
||
|
||
ByteBack yMotorState = m_yMotor->GetState();
|
||
|
||
//作用2:当手动控制y马达运动时(前/后),将自动的调整马达位置slider
|
||
if (yMotorState.Speed != 0)
|
||
{
|
||
double newPos = ui.ymotor_location_slider->getDistanceFromPulse(yMotorState.Location);
|
||
|
||
ui.ymotor_location_slider->setValue(newPos, false);
|
||
setImagerSimulationPos(ui.xmotor_location_slider->value(), newPos);
|
||
|
||
QApplication::processEvents();
|
||
}
|
||
|
||
}
|
||
|
||
void HPPA::ontimerYmotorLocationFeedBackAfterRecord()
|
||
{
|
||
if (isMotorConnected(m_yMotor))
|
||
{
|
||
return;
|
||
}
|
||
|
||
ByteBack yMotorState = m_yMotor->GetState();
|
||
|
||
//将马达位置反馈到slider
|
||
if (yMotorState.Speed != 0)
|
||
{
|
||
double newPos = ui.ymotor_location_slider->getDistanceFromPulse(yMotorState.Location);
|
||
|
||
ui.ymotor_location_slider->setValue(newPos, false);
|
||
setImagerSimulationPos(ui.xmotor_location_slider->value(), newPos);
|
||
|
||
QApplication::processEvents();
|
||
}
|
||
else//调用此函数不能精确的返回采集前的位置;需要通过采集前记录的精确位置来设置
|
||
{
|
||
m_timerYmotorLocationFeedBackAfterRecord->stop();
|
||
|
||
double ymotorPositionOfLine1Tmp = ui.recordLine_tableWidget->item(0, 0)->text().toDouble();//ymotorPositionOfLine1
|
||
|
||
ui.ymotor_location_slider->setValue(ymotorPositionOfLine1Tmp, false);
|
||
setImagerSimulationPos(ui.xmotor_location_slider->value(), ymotorPositionOfLine1Tmp);
|
||
}
|
||
}
|
||
|
||
void HPPA::OnXmotorSpeedLineeditEditingFinished()
|
||
{
|
||
ui.xmotor_speed_slider->setValue(ui.xmotor_speed_lineEdit->text().toDouble());
|
||
}
|
||
|
||
void HPPA::OnXmotorSpeedSliderChanged(double speed)
|
||
{
|
||
ui.xmotor_speed_lineEdit->setText(QString::number(speed));
|
||
}
|
||
|
||
void HPPA::OnXmotorLocationLineeditEditingFinished()
|
||
{
|
||
if (isMotorConnected(m_xMotor))
|
||
{
|
||
return;
|
||
}
|
||
|
||
ui.xmotor_location_slider->setValue(ui.xmotor_location_lineEdit->text().toDouble());
|
||
|
||
setImagerSimulationPos(ui.xmotor_location_slider->value(), ui.ymotor_location_slider->value());
|
||
|
||
m_xMotor->MoveToLocation(ui.xmotor_location_slider->OriginalValue());
|
||
}
|
||
|
||
void HPPA::OnXmotorLocationSliderChanged(double location)
|
||
{
|
||
ui.xmotor_location_lineEdit->setText(QString::number(location));
|
||
}
|
||
|
||
void HPPA::OnXmotorLocationSliderReleased()
|
||
{
|
||
if (isMotorConnected(m_xMotor))
|
||
{
|
||
return;
|
||
}
|
||
|
||
m_xMotor->SettingSpeed(m_lManualSpeedOfXMotor);
|
||
m_xMotor->MoveToLocation(ui.xmotor_location_slider->OriginalValue());
|
||
|
||
setImagerSimulationPos(ui.xmotor_location_slider->value(), ui.ymotor_location_slider->value());
|
||
}
|
||
|
||
void HPPA::OnYmotorLocationLineeditEditingFinished()
|
||
{
|
||
if (isMotorConnected(m_yMotor))
|
||
{
|
||
return;
|
||
}
|
||
|
||
ui.ymotor_location_slider->setValue(ui.ymotor_location_lineEdit->text().toDouble());
|
||
|
||
setImagerSimulationPos(ui.xmotor_location_slider->value(), ui.ymotor_location_slider->value());
|
||
|
||
m_yMotor->MoveToLocation(ui.ymotor_location_slider->OriginalValue());
|
||
}
|
||
|
||
void HPPA::OnYmotorLocationSliderChanged(double location)
|
||
{
|
||
ui.ymotor_location_lineEdit->setText(QString::number(location));
|
||
}
|
||
|
||
void HPPA::OnYmotorLocationSliderReleased()
|
||
{
|
||
if (isMotorConnected(m_yMotor))
|
||
{
|
||
return;
|
||
}
|
||
|
||
m_yMotor->SettingSpeed(m_lManualSpeedOfYMotor);
|
||
m_yMotor->MoveToLocation(ui.ymotor_location_slider->OriginalValue());
|
||
|
||
setImagerSimulationPos(ui.xmotor_location_slider->value(), ui.ymotor_location_slider->value());
|
||
}
|
||
|
||
void HPPA::ontestRangeOfMotor_x_y()
|
||
{
|
||
//测量x马达量程
|
||
if (isMotorConnected(m_xMotor))
|
||
{
|
||
return;
|
||
}
|
||
|
||
m_xMotor->SettingZeroLocation();//先移动到0位置的接近开关,并设置位置为0
|
||
m_timerTestRangeOfxMotor->start(500);
|
||
|
||
//测量y马达量程
|
||
if (isMotorConnected(m_yMotor))
|
||
{
|
||
return;
|
||
}
|
||
|
||
m_yMotor->SettingZeroLocation();
|
||
m_timerTestRangeOfyMotor->start(500);
|
||
}
|
||
|
||
void HPPA::ontimerTestRangeOfxMotor()
|
||
{
|
||
if (isMotorConnected(m_xMotor))
|
||
{
|
||
std::cout << "x马达有问题+++++++++++++++++++++++++++++++++++++++++++" << std::endl;
|
||
return;
|
||
}
|
||
|
||
|
||
ByteBack MotorState = m_xMotor->GetState();
|
||
//std::cout << "x马达速度:" << MotorState.Speed << std::endl;
|
||
|
||
|
||
if (MotorState.Speed == 0 && MotorState.Location == 0)//处于位置为0的地方
|
||
{
|
||
std::cout << "开始测量x马达量程+++++++++++++++++++++++++++++++++++++++++++" << std::endl;
|
||
|
||
m_xMotor->EnableMotro();
|
||
m_xMotor->SettingSpeed(m_lManualSpeedOfXMotor);
|
||
m_xMotor->MoveMotar(true);//向左移动
|
||
}
|
||
|
||
if (MotorState.Speed == 0 && MotorState.Location != 0)//处于位置最大的地方
|
||
{
|
||
m_xMotor->MoveToLocation(0);
|
||
m_timerTestRangeOfxMotor->stop();
|
||
|
||
double maxDistance = ui.xmotor_location_slider->getDistanceFromPulse(MotorState.Location);
|
||
|
||
//将x马达量程记录到文件,以便后面使用 → 不用每次都测试量程,这样很浪费时间
|
||
|
||
FileOperation * fileOperation = new FileOperation();
|
||
string directory = fileOperation->getDirectoryOfExe();
|
||
string xMotorRangeFile = directory + "\\xMotorRange";
|
||
|
||
FILE * motorRange = fopen(xMotorRangeFile.c_str(), "w+b");
|
||
|
||
fwrite(&maxDistance, sizeof(double), 1, motorRange);
|
||
fclose(motorRange);
|
||
|
||
ui.xmotor_location_slider->setMaximum(maxDistance);
|
||
ui.xmotor_max_location_label->setText(QString::number(ui.xmotor_location_slider->maximum()));
|
||
|
||
//重新设置sceneRect的宽度缩放系数(x)
|
||
QRectF rect = ui.graphicsView->viewport()->rect();
|
||
widthScale = rect.width() / maxDistance;
|
||
ui.graphicsView->setSceneRect();
|
||
}
|
||
}
|
||
|
||
void HPPA::ontimerTestRangeOfyMotor()
|
||
{
|
||
if (isMotorConnected(m_yMotor))
|
||
{
|
||
std::cout << "y马达有问题+++++++++++++++++++++++++++++++++++++++++++" << std::endl;
|
||
return;
|
||
}
|
||
|
||
ByteBack MotorState = m_yMotor->GetState();
|
||
|
||
if (MotorState.Speed == 0 && MotorState.Location == 0)//处于位置为0的地方
|
||
{
|
||
std::cout << "开始测量y马达量程+++++++++++++++++++++++++++++++++++++++++++" << std::endl;
|
||
|
||
m_yMotor->EnableMotro();
|
||
m_yMotor->SettingSpeed(m_lManualSpeedOfYMotor);
|
||
m_yMotor->MoveMotar(true);//向前移动
|
||
}
|
||
|
||
if (MotorState.Speed == 0 && MotorState.Location != 0)//处于位置最大的地方
|
||
{
|
||
m_yMotor->MoveToLocation(0);
|
||
m_timerTestRangeOfyMotor->stop();
|
||
|
||
double maxDistance = ui.ymotor_location_slider->getDistanceFromPulse(MotorState.Location);
|
||
|
||
//将y马达量程记录到文件,以便后面使用 → 不用每次都测试量程,这样很浪费时间
|
||
|
||
FileOperation * fileOperation = new FileOperation();
|
||
string directory = fileOperation->getDirectoryOfExe();
|
||
string yMotorRangeFile = directory + "\\yMotorRange";
|
||
|
||
FILE * motorRange = fopen(yMotorRangeFile.c_str(), "w+b");
|
||
fwrite(&maxDistance, sizeof(double), 1, motorRange);
|
||
fclose(motorRange);
|
||
|
||
ui.ymotor_location_slider->setMaximum(maxDistance);
|
||
ui.ymotor_max_location_label->setText(QString::number(ui.ymotor_location_slider->maximum()));
|
||
|
||
//重新设置sceneRect的高度缩放系数(y)
|
||
QRectF rect = ui.graphicsView->viewport()->rect();
|
||
heightScale = rect.height() / maxDistance;
|
||
ui.graphicsView->setSceneRect();
|
||
}
|
||
}
|
||
|
||
void HPPA::onAddRecordLine_btn()
|
||
{
|
||
//准备数据
|
||
ByteBack MotorState = m_yMotor->GetState();
|
||
double currentPosOfYmotor = ui.ymotor_location_slider->getDistanceFromPulse(MotorState.Location);
|
||
double maxRangeOfXmotro = ui.xmotor_location_slider->maximum();
|
||
|
||
//获取选中行的索引
|
||
int currentRow = ui.recordLine_tableWidget->currentRow();
|
||
std::cout << "currentRow:" << currentRow << std::endl;
|
||
|
||
if (currentRow == -1)//当没有选中行时
|
||
{
|
||
int RowCount = ui.recordLine_tableWidget->rowCount();//Returns the number of rows. 从1开始的
|
||
ui.recordLine_tableWidget->insertRow(RowCount);//增加一行,形参是从0开始的
|
||
|
||
ui.recordLine_tableWidget->setItem(RowCount, 0, new QTableWidgetItem(QString::number(currentPosOfYmotor, 10, 2)));
|
||
ui.recordLine_tableWidget->setItem(RowCount, 1, new QTableWidgetItem(QString::number(maxRangeOfXmotro, 10, 2)));
|
||
}
|
||
else
|
||
{
|
||
ui.recordLine_tableWidget->insertRow(currentRow + 1);//增加一行,形参是从0开始的
|
||
|
||
ui.recordLine_tableWidget->setItem(currentRow + 1, 0, new QTableWidgetItem(QString::number(currentPosOfYmotor, 10, 2)));
|
||
ui.recordLine_tableWidget->setItem(currentRow + 1, 1, new QTableWidgetItem(QString::number(maxRangeOfXmotro, 10, 2)));
|
||
}
|
||
}
|
||
|
||
void HPPA::onRemoveRecordLine_btn()
|
||
{
|
||
int rowIndex = ui.recordLine_tableWidget->currentRow();
|
||
if (rowIndex != -1)
|
||
ui.recordLine_tableWidget->removeRow(rowIndex);
|
||
}
|
||
|
||
void HPPA::onGenerateRecordLine_btn()
|
||
{
|
||
//求幅宽
|
||
double height = ui.height_lineEdit->text().toDouble();
|
||
double fov = ui.fov_lineEdit->text().toDouble();
|
||
double swath = (height * tan(fov / 2 * PI / 180)) * 2;//tan输入是弧度
|
||
ui.swath_lineEdit->setText(QString::number(swath));
|
||
|
||
|
||
//读取马达测量范围
|
||
double xMotorRange = ui.xmotor_location_slider->maximum();
|
||
double yMotorRange = ui.ymotor_location_slider->maximum();
|
||
|
||
|
||
//确定有多少条采集线,公式:numberOfRecordLine_tmp * swath - repetitiveLength(numberOfRecordLine_tmp - 1) = overallLength
|
||
double overallLength = yMotorRange + swath;
|
||
double repetitiveRate = ui.repetitiveRate_lineEdit->text().toDouble() / 100;
|
||
double repetitiveLength = repetitiveRate * swath;
|
||
double offset = ui.offset_lineEdit->text().toDouble();
|
||
|
||
double numberOfRecordLine_tmp = (overallLength - repetitiveLength - offset) / (swath - repetitiveLength);
|
||
double tmp = numberOfRecordLine_tmp - (int)numberOfRecordLine_tmp;
|
||
int numberOfRecordLine;
|
||
double threshold = ui.LastLineThreshold_lineEdit->text().toDouble();//当numberOfRecordLine_tmp为小数时,判断是否多加一条采集线
|
||
if (tmp > threshold)
|
||
{
|
||
numberOfRecordLine = (int)numberOfRecordLine_tmp + 1;
|
||
//std::cout << "大于:" << threshold << std::endl;
|
||
}
|
||
else
|
||
{
|
||
numberOfRecordLine = (int)numberOfRecordLine_tmp;
|
||
}
|
||
|
||
|
||
|
||
//去掉tableWidget中所有的行
|
||
int rowCount = ui.recordLine_tableWidget->rowCount();
|
||
for (size_t i = 0; i < rowCount; i++)
|
||
{
|
||
ui.recordLine_tableWidget->removeRow(0);
|
||
}
|
||
|
||
|
||
//向tableWidget添加行(采集线)
|
||
for (size_t i = 0; i < numberOfRecordLine; i++)
|
||
{
|
||
//增加一行
|
||
int RowCount = ui.recordLine_tableWidget->rowCount();
|
||
ui.recordLine_tableWidget->insertRow(RowCount);
|
||
|
||
//设置yPosition
|
||
if (tmp > threshold && i == numberOfRecordLine - 1)//设置最后一行的yPosition
|
||
{
|
||
ui.recordLine_tableWidget->setItem(i, 0, new QTableWidgetItem(QString::number(yMotorRange, 10, 2)));
|
||
}
|
||
else
|
||
{
|
||
double x = swath * i - i * repetitiveLength + offset;
|
||
ui.recordLine_tableWidget->setItem(i, 0, new QTableWidgetItem(QString::number(x, 10, 2)));
|
||
}
|
||
|
||
//设置x马达最大运动位置 → 值设置为x马达量程
|
||
ui.recordLine_tableWidget->setItem(i, 1, new QTableWidgetItem(QString::number(xMotorRange, 10, 2)));
|
||
|
||
}
|
||
|
||
}
|
||
|
||
void HPPA::onDeleteRecordLine_btn()
|
||
{
|
||
int rowCount = ui.recordLine_tableWidget->rowCount();
|
||
for (size_t i = 0; i < rowCount; i++)
|
||
{
|
||
ui.recordLine_tableWidget->removeRow(0);
|
||
}
|
||
}
|
||
|
||
void HPPA::onSaveRecordLine2File_btn()
|
||
{
|
||
//确保采集线存在
|
||
if (ui.recordLine_tableWidget->rowCount() <= 0)
|
||
{
|
||
QMessageBox::information(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("请先生成轨迹!"));
|
||
return;
|
||
}
|
||
|
||
double height = ui.height_lineEdit->text().toDouble();
|
||
double fov = ui.fov_lineEdit->text().toDouble();
|
||
double swath = ui.swath_lineEdit->text().toDouble();
|
||
double offset = ui.offset_lineEdit->text().toDouble();
|
||
double repetitiveRate = ui.repetitiveRate_lineEdit->text().toDouble();
|
||
double LastLineThreshold = ui.LastLineThreshold_lineEdit->text().toDouble();
|
||
|
||
FileOperation * fileOperation = new FileOperation();
|
||
string directory = fileOperation->getDirectoryOfExe();
|
||
|
||
QString RecordLineFilePath = QFileDialog::getSaveFileName(this, tr("Save RecordLine File"),
|
||
QString::fromStdString(directory),
|
||
tr("RecordLineFile (*.RecordLine)"));
|
||
|
||
if (RecordLineFilePath.isEmpty())
|
||
{
|
||
return;
|
||
}
|
||
|
||
FILE * RecordLineFileHandle = fopen(RecordLineFilePath.toStdString().c_str(), "wb+");
|
||
|
||
fwrite(&height, sizeof(double), 1, RecordLineFileHandle);
|
||
fwrite(&fov, sizeof(double), 1, RecordLineFileHandle);
|
||
fwrite(&swath, sizeof(double), 1, RecordLineFileHandle);
|
||
fwrite(&offset, sizeof(double), 1, RecordLineFileHandle);
|
||
fwrite(&repetitiveRate, sizeof(double), 1, RecordLineFileHandle);
|
||
fwrite(&LastLineThreshold, sizeof(double), 1, RecordLineFileHandle);
|
||
|
||
double number = ui.recordLine_tableWidget->rowCount()*ui.recordLine_tableWidget->columnCount();
|
||
fwrite(&number, sizeof(double), 1, RecordLineFileHandle);
|
||
|
||
double *data = new double[number];
|
||
//double data[number];
|
||
for (size_t i = 0; i < ui.recordLine_tableWidget->rowCount(); i++)
|
||
{
|
||
for (size_t j = 0; j < ui.recordLine_tableWidget->columnCount(); j++)
|
||
{
|
||
data[i*ui.recordLine_tableWidget->columnCount() + j] = ui.recordLine_tableWidget->item(i, j)->text().toDouble();
|
||
}
|
||
}
|
||
|
||
fwrite(data, sizeof(double), number, RecordLineFileHandle);
|
||
|
||
fclose(RecordLineFileHandle);
|
||
delete[] data;
|
||
|
||
QMessageBox::information(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("保存成功!"));
|
||
}
|
||
|
||
void HPPA::onReadRecordLineFile_btn()
|
||
{
|
||
//打开文件
|
||
FileOperation * fileOperation = new FileOperation();
|
||
string directory = fileOperation->getDirectoryOfExe();
|
||
//string RecordLineFilePath = directory + "\\test.RecordLine";
|
||
|
||
QString RecordLineFilePath = QFileDialog::getOpenFileName(this, tr("Open RecordLine File"),
|
||
QString::fromStdString(directory),
|
||
tr("RecordLineFile (*.RecordLine)"));
|
||
|
||
if (RecordLineFilePath.isEmpty())
|
||
{
|
||
return;
|
||
}
|
||
|
||
FILE * RecordLineFileHandle = fopen(RecordLineFilePath.toStdString().c_str(), "r");
|
||
double height, fov, swath, offset, repetitiveRate, LastLineThreshold, number;
|
||
|
||
//读取数据
|
||
fread(&height, sizeof(double), 1, RecordLineFileHandle);
|
||
fread(&fov, sizeof(double), 1, RecordLineFileHandle);
|
||
fread(&swath, sizeof(double), 1, RecordLineFileHandle);
|
||
fread(&offset, sizeof(double), 1, RecordLineFileHandle);
|
||
fread(&repetitiveRate, sizeof(double), 1, RecordLineFileHandle);
|
||
fread(&LastLineThreshold, sizeof(double), 1, RecordLineFileHandle);
|
||
fread(&number, sizeof(double), 1, RecordLineFileHandle);
|
||
|
||
double *data = new double[number];
|
||
for (size_t i = 0; i < number; i++)
|
||
{
|
||
fread(data + i, sizeof(double), 1, RecordLineFileHandle);
|
||
//std::cout << *(data + i) << std::endl;
|
||
}
|
||
|
||
//向界面中填写
|
||
ui.height_lineEdit->setText(QString::number(height));
|
||
ui.fov_lineEdit->setText(QString::number(fov));
|
||
ui.swath_lineEdit->setText(QString::number(swath));
|
||
ui.offset_lineEdit->setText(QString::number(offset));
|
||
ui.repetitiveRate_lineEdit->setText(QString::number(repetitiveRate));
|
||
ui.LastLineThreshold_lineEdit->setText(QString::number(LastLineThreshold));
|
||
|
||
|
||
//向tableWidget添加采集线
|
||
//(1)去掉tableWidget中所有的行
|
||
int rowCount = ui.recordLine_tableWidget->rowCount();
|
||
for (size_t i = 0; i < rowCount; i++)
|
||
{
|
||
ui.recordLine_tableWidget->removeRow(0);
|
||
}
|
||
//(2)添加行(采集线)
|
||
int RecordLineCount = number / ui.recordLine_tableWidget->columnCount();
|
||
for (size_t i = 0; i < RecordLineCount; i++)
|
||
{
|
||
ui.recordLine_tableWidget->insertRow(0);
|
||
|
||
}
|
||
//(3)向tableWidget填充数据
|
||
for (size_t i = 0; i < ui.recordLine_tableWidget->rowCount(); i++)
|
||
{
|
||
for (size_t j = 0; j < ui.recordLine_tableWidget->columnCount(); j++)
|
||
{
|
||
ui.recordLine_tableWidget->setItem(i, j, new QTableWidgetItem(QString::number(data[i*ui.recordLine_tableWidget->columnCount() + j], 10, 2)));
|
||
}
|
||
}
|
||
|
||
fclose(RecordLineFileHandle);
|
||
delete[] data;
|
||
|
||
QMessageBox::information(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("读取成功!"));
|
||
|
||
}
|
||
|
||
void HPPA::ontimerMoveXmotor()
|
||
{
|
||
//std::cout << "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" << std::endl;
|
||
if (isMotorConnected(m_xMotor))
|
||
{
|
||
return;
|
||
}
|
||
|
||
ByteBack MotorState = m_xMotor->GetState();
|
||
|
||
//将x马达的位置反馈到slider上
|
||
if (MotorState.Speed != 0)
|
||
{
|
||
double newPos = ui.xmotor_location_slider->getDistanceFromPulse(MotorState.Location);
|
||
|
||
ui.xmotor_location_slider->setValue(newPos, false);
|
||
setImagerSimulationPos(newPos, ui.ymotor_location_slider->value());
|
||
|
||
QApplication::processEvents();
|
||
}
|
||
|
||
//采集结束,x马达返回初始位置(开始采集前记录的位置:m_lXmotorLocationOfStartRecord)
|
||
if (MotorState.Speed == 0 && MotorState.Location != m_lXmotorLocationOfStartRecord //x马达位置处于最大值(接近开关),帧数没有采集完
|
||
|| !m_Imager->getRecordControlState())//当相机停止采集需要马达配合回到初始位置:(1)点击停止采集;(2)帧数采集完了,马达还在运动
|
||
{
|
||
//光谱仪停止采集
|
||
m_Imager->setRecordControlState(false);
|
||
|
||
//x马达返回采集前的位置
|
||
m_xMotor->SettingSpeed(m_lManualSpeedOfXMotor);
|
||
m_xMotor->MoveToLocation(m_lXmotorLocationOfStartRecord);
|
||
}
|
||
|
||
//进行下一条采集线的采集过程
|
||
if (MotorState.Speed == 0 && MotorState.Location == m_lXmotorLocationOfStartRecord//当x马达返回初始位置
|
||
|| MotorState.Location - m_lXmotorLocationOfStartRecord < 300)//当采集前位置为0时,就需要这个条件
|
||
{
|
||
//停止
|
||
m_timerMoveXmotor->stop();
|
||
|
||
//将采集完成的行设置为绿色
|
||
for (size_t j = 0; j < ui.recordLine_tableWidget->columnCount(); j++)
|
||
{
|
||
ui.recordLine_tableWidget->item(m_numberOfRecording, j)->setBackgroundColor(QColor(0, 255, 0));
|
||
}
|
||
|
||
//准确设置x马达slider的位置
|
||
double pos = ui.xmotor_location_slider->getDistanceFromPulse(m_lXmotorLocationOfStartRecord);
|
||
ui.xmotor_location_slider->setValue(pos, false);
|
||
setImagerSimulationPos(pos, ui.ymotor_location_slider->value());
|
||
|
||
//执行下一条航线
|
||
m_ForLoopControl->m_boolRecordNextLine = true;
|
||
}
|
||
|
||
//std::cout << "初始位置为:" << m_lXmotorLocationOfStartRecord << std::endl;
|
||
//std::cout << "差距为:" << MotorState.Location - m_lXmotorLocationOfStartRecord << std::endl;
|
||
}
|
||
|
||
void HPPA::ontimerMoveYmotor()
|
||
{
|
||
//std::cout << "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy" << std::endl;
|
||
if (isMotorConnected(m_yMotor))
|
||
{
|
||
return;
|
||
}
|
||
|
||
ByteBack MotorState = m_yMotor->GetState();
|
||
|
||
//将y马达的位置反馈到slider上
|
||
if (MotorState.Speed != 0)
|
||
{
|
||
double newPos = ui.ymotor_location_slider->getDistanceFromPulse(MotorState.Location);
|
||
//std::cout << "y马达位置:" << newPos << std::endl;
|
||
|
||
ui.ymotor_location_slider->setValue(newPos, false);
|
||
setImagerSimulationPos(ui.xmotor_location_slider->value(), newPos);
|
||
|
||
QApplication::processEvents();
|
||
}
|
||
else if (MotorState.Speed == 0)
|
||
{
|
||
//停止调用本函数
|
||
m_timerMoveYmotor->stop();
|
||
|
||
//准确设置y马达slider的位置
|
||
double pos = ui.recordLine_tableWidget->item(m_numberOfRecording, 0)->text().toDouble();
|
||
ui.ymotor_location_slider->setValue(pos, false);
|
||
setImagerSimulationPos(ui.xmotor_location_slider->value(), pos);
|
||
|
||
//当点击开始采集后,当y马达前往第一条采集线的途中,点击了停止采集
|
||
if (m_RecordState % 2 == 0)
|
||
{
|
||
//
|
||
for (size_t j = 0; j < ui.recordLine_tableWidget->columnCount(); j++)
|
||
{
|
||
ui.recordLine_tableWidget->item(m_numberOfRecording, j)->setBackgroundColor(QColor(240, 240, 240));
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
//移动x马达
|
||
if (isMotorConnected(m_xMotor))
|
||
{
|
||
return;
|
||
}
|
||
m_xMotor->EnableMotro();
|
||
m_lXmotorLocationOfStartRecord = m_xMotor->GetLocationNow();//记录当前马达位置
|
||
m_xMotor->SettingSpeed(ui.xmotor_speed_slider->OriginalValue());//开始采集时才设置光谱仪速度 → 优点:隔离了采集时速度和其他速度
|
||
|
||
|
||
double xMaxPositionTmp = ui.recordLine_tableWidget->item(m_numberOfRecording, 1)->text().toDouble();
|
||
long xMaxPosition = ui.xmotor_location_slider->getPositionPulse(xMaxPositionTmp);
|
||
m_xMotor->MoveToLocation(xMaxPosition);
|
||
m_timerMoveXmotor->start(500);
|
||
|
||
|
||
//开始采集影像
|
||
m_Imager->setFrameNumber(this->frame_number->text().toInt());
|
||
|
||
emit StartRecordSignal();//发射开始采集信号
|
||
}
|
||
}
|
||
|
||
void HPPA::onimagerSimulatorMove(int x, int y)
|
||
{
|
||
if (isMotorConnected(m_xMotor))
|
||
{
|
||
return;
|
||
}
|
||
|
||
//std::cout << "x马达断电后还能正常发送命令+++++++++++++++++++++++++++++++++++++++++++" << std::endl;
|
||
|
||
double xLocatioin = abs(x) / widthScale;//单位为cm的真实距离
|
||
ui.xmotor_location_slider->setValue(xLocatioin, false);
|
||
|
||
double xx = ui.xmotor_location_slider->OriginalValue();//单位为脉冲的真实距离
|
||
m_xMotor->MoveToLocation(xx);
|
||
|
||
|
||
if (isMotorConnected(m_yMotor))
|
||
{
|
||
return;
|
||
}
|
||
|
||
//std::cout << "y马达断电后还能正常发送命令+++++++++++++++++++++++++++++++++++++++++++" << std::endl;
|
||
|
||
double yLocatioin = abs(y) / heightScale;//单位为cm的真实距离
|
||
ui.ymotor_location_slider->setValue(yLocatioin, false);
|
||
|
||
double yy = ui.ymotor_location_slider->OriginalValue();//单位为脉冲的真实距离
|
||
|
||
//std::cout << "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" << std::endl;
|
||
m_yMotor->MoveToLocation(yy);
|
||
//std::cout << "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" << std::endl;
|
||
|
||
}
|
||
|
||
void HPPA::OnSendLogToCallClass(QString str)
|
||
{
|
||
qDebug() << str;
|
||
}
|
||
|
||
void HPPA::onPlotRgbImage()
|
||
{
|
||
//std::cout << "显示视频+++++++++++++++++++++++++++++++++++++++++++" << std::endl;
|
||
QPixmap pixmap = QPixmap::fromImage(m_RgbCamera->m_qImage);
|
||
|
||
int width = ui.cam_label->width();
|
||
int height = ui.cam_label->height();
|
||
QPixmap fitpixmap = pixmap.scaled(width, height, Qt::KeepAspectRatio, Qt::SmoothTransformation); //按比例缩放
|
||
|
||
|
||
ui.cam_label->setPixmap(fitpixmap);
|
||
}
|
||
|
||
void HPPA::onCloseRgbCamera()
|
||
{
|
||
//std::cout << "关闭视频+++++++++++++++++++++++++++++++++++++++++++" << std::endl;
|
||
m_RgbCamera->CloseCamera();
|
||
}
|
||
|
||
void HPPA::onClearLabel()
|
||
{
|
||
ui.cam_label->clear();
|
||
ui.cam_label->setText("closed");
|
||
}
|
||
|
||
void HPPA::onCopyFinished()
|
||
{
|
||
this->setEnabled(true);
|
||
}
|
||
|
||
void HPPA::getRequest(QString str)
|
||
{
|
||
QNetworkRequest request;
|
||
QNetworkAccessManager* naManager = new QNetworkAccessManager(this);
|
||
QMetaObject::Connection connRet = QObject::connect(naManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(requestFinished(QNetworkReply*)));
|
||
Q_ASSERT(connRet);
|
||
|
||
request.setUrl(QUrl(str));
|
||
QNetworkReply* reply = naManager->get(request);
|
||
}
|
||
|
||
void HPPA::onLampPowerOpen_btn()//onLampPowerOpen_btn
|
||
{
|
||
QString xx = "http://192.168.1.3/setshutter?Portname=3&Value=1";
|
||
getRequest(xx);
|
||
}
|
||
|
||
void HPPA::onLampPowerClose_btn()//onLampPowerClose_btn
|
||
{
|
||
QString xx = "http://192.168.1.3/setshutter?Portname=3&Value=0";
|
||
getRequest(xx);
|
||
}
|
||
|
||
void HPPA::onMotorPowerOpen_btn()
|
||
{
|
||
QString xx = "http://192.168.1.3/setshutter?Portname=1&Value=1";
|
||
getRequest(xx);
|
||
|
||
newMotor();
|
||
}
|
||
|
||
void HPPA::onMotorPowerClose_btn()
|
||
{
|
||
QString xx = "http://192.168.1.3/setshutter?Portname=1&Value=0";
|
||
getRequest(xx);
|
||
|
||
deleteMotor();
|
||
}
|
||
|
||
void HPPA::newMotor()
|
||
{
|
||
if (m_xMotor != nullptr && m_yMotor != nullptr)
|
||
{
|
||
return;
|
||
}
|
||
|
||
//马达
|
||
m_xMotor = new VinceControl(NETTCP, 6002);//相机轴
|
||
m_yMotor = new VinceControl(NETTCP, 6001);//原本:6001;韩工测试:6003
|
||
m_xConnectCount = 0;
|
||
m_yConnectCount = 0;
|
||
|
||
connect(m_xMotor, SIGNAL(SendLogToCallClass(QString)), this, SLOT(OnSendLogToCallClass(QString)));
|
||
connect(m_yMotor, SIGNAL(SendLogToCallClass(QString)), this, SLOT(OnSendLogToCallClass(QString)));
|
||
}
|
||
|
||
void HPPA::deleteMotor()
|
||
{
|
||
disconnect(m_xMotor, SIGNAL(SendLogToCallClass(QString)), this, SLOT(OnSendLogToCallClass(QString)));
|
||
disconnect(m_yMotor, SIGNAL(SendLogToCallClass(QString)), this, SLOT(OnSendLogToCallClass(QString)));
|
||
|
||
delete m_xMotor;
|
||
delete m_yMotor;
|
||
|
||
m_xMotor = nullptr;
|
||
m_yMotor = nullptr;
|
||
|
||
xmotor_state_label1->setStyleSheet("QLabel{background-color:rgb(255,0,0);}");
|
||
ymotor_state_label1->setStyleSheet("QLabel{background-color:rgb(255,0,0);}");
|
||
}
|
||
|
||
void HPPA::requestFinished(QNetworkReply* reply) {
|
||
// 获取http状态码
|
||
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
|
||
if (statusCode.isValid())
|
||
qDebug() << "status code=" << statusCode.toInt();
|
||
|
||
QVariant reason = reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
|
||
if (reason.isValid())
|
||
qDebug() << "reason=" << reason.toString();
|
||
|
||
QNetworkReply::NetworkError err = reply->error();
|
||
if (err != QNetworkReply::NoError) {
|
||
qDebug() << "Failed: " << reply->errorString();
|
||
}
|
||
else {
|
||
// 获取返回内容
|
||
qDebug() << reply->readAll();
|
||
}
|
||
}
|
||
|
||
void HPPA::onObjectivTable1Up_btn()
|
||
{
|
||
QString xx = "http://192.168.1.253/set_up";
|
||
getRequest(xx);
|
||
}
|
||
|
||
void HPPA::onObjectivTable1Down_btn()
|
||
{
|
||
QString xx = "http://192.168.1.253/set_down";
|
||
getRequest(xx);
|
||
}
|
||
|
||
void HPPA::onObjectivTable1Stop_btn()
|
||
{
|
||
QString xx = "http://192.168.1.253/stopnow";
|
||
getRequest(xx);
|
||
}
|
||
|
||
void HPPA::onObjectivTable2Up_btn()
|
||
{
|
||
QString xx = "http://192.168.1.254/set_up";
|
||
getRequest(xx);
|
||
}
|
||
|
||
void HPPA::onObjectivTable2Down_btn()
|
||
{
|
||
QString xx = "http://192.168.1.254/set_down";
|
||
getRequest(xx);
|
||
}
|
||
|
||
void HPPA::onObjectivTable2Stop_btn()
|
||
{
|
||
QString xx = "http://192.168.1.254/stopnow";
|
||
getRequest(xx);
|
||
}
|
||
|
||
void HPPA::onExit()
|
||
{
|
||
this->close();
|
||
}
|
||
|
||
void HPPA::onconnect()
|
||
{
|
||
if (m_Imager != nullptr)
|
||
{
|
||
//std::cout << "相机已经连接!" << std::endl;
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
//采集影像线程:放入新线程中采集以免在采集过程中界面卡死:https://www.cnblogs.com/xia-weiwen/p/10306089.html
|
||
m_RecordThread = new QThread();
|
||
m_Imager = new ResononImager();
|
||
m_Imager->moveToThread(m_RecordThread);
|
||
m_RecordThread->start();
|
||
|
||
m_Imager->connect_imager(frame_number->text().toInt());
|
||
m_Imager->setFileName2Save(m_FilenameLineEdit->text().toStdString());
|
||
connect(m_Imager, SIGNAL(PlotSignal()), this, SLOT(onPlotHyperspectralImageRgbImage()));
|
||
connect(m_Imager, SIGNAL(RecordFinishedSignal_WhenFrameNumberMeet()), this, SLOT(onRecordFinishedSignal_WhenFrameNumberMeet()));
|
||
connect(m_Imager, SIGNAL(RecordFinishedSignal_WhenFrameNumberNotMeet()), this, SLOT(onRecordFinishedSignal_WhenFrameNumberNotMeet()));
|
||
connect(m_Imager, SIGNAL(SpectralSignal(int)), this, SLOT(PlotSpectral(int)));
|
||
//connect(m_Imager, SIGNAL(testImagerStatus()), this, SLOT(testImagerStatus()));
|
||
|
||
|
||
//文件拷贝
|
||
m_CopyFileThread = new QThread();
|
||
m_FileOperation = new FileOperation();
|
||
m_FileOperation->moveToThread(m_CopyFileThread);
|
||
m_CopyFileThread->start();
|
||
connect(this, SIGNAL(CopyFileThreadSignal(QString, QString)), m_FileOperation, SLOT(copyFile(QString, QString)));
|
||
connect(m_FileOperation, SIGNAL(CopyFinishedSignal()), this, SLOT(onCopyFinished()));
|
||
|
||
//检测光谱仪连接状态
|
||
m_TestImagerStausThread = new WorkerThread(m_Imager);
|
||
|
||
|
||
|
||
connect(this->ui.action_auto_exposure, SIGNAL(triggered()), this, SLOT(onAutoExposure()));
|
||
connect(this->ui.action_focus, SIGNAL(triggered()), this, SLOT(onFocus1()));
|
||
connect(this, SIGNAL(StartFocusSignal()), m_Imager, SLOT(focus()));
|
||
connect(this->ui.action_dark, SIGNAL(triggered()), this, SLOT(onDark()));
|
||
connect(this->ui.action_reference, SIGNAL(triggered()), this, SLOT(onReference()));
|
||
|
||
connect(this->ui.action_start_recording, SIGNAL(triggered()), this, SLOT(onStartRecordStep1()));
|
||
connect(this, SIGNAL(StartLoopSignal()), m_ForLoopControl, SLOT(startLoop()));
|
||
connect(this, SIGNAL(StartRecordSignal()), m_Imager, SLOT(start_record()));
|
||
|
||
connect(this->ui.actionOpenDirectory, SIGNAL(triggered()), this, SLOT(onActionOpenDirectory()));
|
||
|
||
|
||
|
||
|
||
connect(this->ui.framerate_lineEdit, SIGNAL(editingFinished()), this, SLOT(OnFramerateLineeditEditingFinished()));
|
||
connect(this->ui.FramerateSlider, SIGNAL(valueChanged(double)), this, SLOT(OnFramerateSliderChanged(double)));
|
||
connect(this->ui.integratioin_time_lineEdit, SIGNAL(editingFinished()), this, SLOT(OnIntegratioinTimeEditingFinished()));
|
||
connect(this->ui.IntegratioinTimeSlider, SIGNAL(valueChanged(double)), this, SLOT(OnIntegratioinTimeSliderChanged(double)));
|
||
connect(this->ui.gain_lineEdit, SIGNAL(editingFinished()), this, SLOT(OnGainEditingFinished()));
|
||
connect(this->ui.GainSlider, SIGNAL(valueChanged(double)), this, SLOT(OnGainSliderChanged(double)));
|
||
|
||
|
||
//相机参数控件设置为可用 + 输入控制
|
||
frame_number->setEnabled(true);
|
||
|
||
ui.framerate_lineEdit->setEnabled(true);
|
||
ui.integratioin_time_lineEdit->setEnabled(true);
|
||
ui.gain_lineEdit->setEnabled(true);
|
||
|
||
ui.FramerateSlider->setEnabled(true);
|
||
ui.IntegratioinTimeSlider->setEnabled(true);
|
||
ui.GainSlider->setEnabled(true);
|
||
|
||
/*QRegExp rx("\\d{0,3}[1-9]$");
|
||
ui.framerate_lineEdit->setValidator(new QRegExpValidator(rx));
|
||
frame_number->setValidator(new QRegExpValidator(rx));
|
||
|
||
ui.integratioin_time_lineEdit->setValidator(new QRegExpValidator(rx));
|
||
ui.gain_lineEdit->setValidator(new QRegExpValidator(rx));*/
|
||
|
||
//获取相机参数并显示到界面中
|
||
ui.framerate_lineEdit->setText(QString::number(m_Imager->get_framerate(), 10, 2));
|
||
ui.FramerateSlider->setValue(m_Imager->get_framerate(), true);
|
||
CalculateIntegratioinTimeRange();
|
||
|
||
ui.integratioin_time_lineEdit->setText(QString::number(m_Imager->get_integration_time(), 10, 2));
|
||
ui.IntegratioinTimeSlider->setValue(m_Imager->get_integration_time());
|
||
|
||
ui.gain_lineEdit->setText(QString::number(m_Imager->get_gain(), 10, 2));
|
||
ui.GainSlider->setValue(m_Imager->get_gain());
|
||
}
|
||
catch (...)
|
||
{
|
||
delete m_Imager;
|
||
m_Imager = nullptr;
|
||
|
||
QMessageBox msgBox;
|
||
msgBox.setText(QString::fromLocal8Bit("请连接相机!"));
|
||
msgBox.exec();
|
||
}
|
||
|
||
|
||
|
||
}
|
||
|
||
void HPPA::testImagerStatus()
|
||
{
|
||
m_TestImagerStausThread->start();
|
||
}
|
||
|
||
void HPPA::onAutoExposure()
|
||
{
|
||
double ReturnedExposureTime = m_Imager->auto_exposure();
|
||
|
||
//将自动曝光所得的值显示到界面
|
||
ui.IntegratioinTimeSlider->setValue(ReturnedExposureTime, false);
|
||
|
||
|
||
ui.mainToolBar->widgetForAction(ui.action_auto_exposure)->setStyleSheet("QWidget{background-color:rgb(0,255,0);}");
|
||
//ui.mainToolBar->widgetForAction(ui.action_auto_exposure)->setStyleSheet("QLineEdit{background-color:rgb(255,255,255);}");
|
||
}
|
||
|
||
void HPPA::onFocus1()
|
||
{
|
||
focusWindow* w = new focusWindow(this, m_Imager);
|
||
connect(w, SIGNAL(StartManualFocusSignal(int)), this, SLOT(onFocus2(int)));
|
||
|
||
//w->setModal(true);//设置窗口为模态:只能操作当前窗口
|
||
w->show();
|
||
w->exec();
|
||
|
||
//disconnect(w, SIGNAL(StartManualFocusSignal(int)), this, SLOT(onFocus2(int)));
|
||
}
|
||
|
||
void HPPA::onFocus2(int command)
|
||
{
|
||
if (command == 1)
|
||
{
|
||
//创建影像显示窗口
|
||
QWidget * tabTmp = new QWidget();
|
||
|
||
QGridLayout *GridLayout = new QGridLayout();
|
||
GridLayout->addWidget(new ImageViewer(tabTmp));
|
||
|
||
tabTmp->setLayout(GridLayout);
|
||
|
||
ui.ImageViewerTabWidget->addTab(tabTmp, QString::fromLocal8Bit("调焦"));
|
||
|
||
//ui.ImageViewerTabWidget->setCurrentIndex(trackNumber);
|
||
ui.ImageViewerTabWidget->setCurrentWidget(tabTmp);
|
||
|
||
|
||
//开始调焦
|
||
emit StartFocusSignal();
|
||
}
|
||
else if (command == 0)
|
||
{
|
||
m_Imager->setFocusControlState(false);
|
||
}
|
||
}
|
||
|
||
void HPPA::onAbout()
|
||
{
|
||
aboutWindow about;
|
||
about.show();
|
||
about.exec();
|
||
}
|
||
|
||
void HPPA::onDark()
|
||
{
|
||
QMessageBox msgBox;
|
||
msgBox.setText(QString::fromLocal8Bit("请确保镜头盖盖上!"));
|
||
msgBox.exec();
|
||
m_Imager->record_dark();
|
||
|
||
ui.mainToolBar->widgetForAction(ui.action_dark)->setStyleSheet("QWidget{background-color:rgb(0,255,0);}");
|
||
}
|
||
|
||
void HPPA::onReference()
|
||
{
|
||
QMessageBox msgBox;
|
||
msgBox.setText(QString::fromLocal8Bit("请确保白板放置正确!"));
|
||
msgBox.exec();
|
||
m_Imager->record_white();
|
||
|
||
ui.mainToolBar->widgetForAction(ui.action_reference)->setStyleSheet("QWidget{background-color:rgb(0,255,0);}");
|
||
}
|
||
|
||
void HPPA::onPlotHyperspectralImageRgbImage()
|
||
{
|
||
//获取绘图控件
|
||
QWidget* currentWidget = ui.ImageViewerTabWidget->widget(m_numberOfRecording);
|
||
QList<ImageViewer *> currentImageViewer = currentWidget->findChildren<ImageViewer *>();
|
||
currentImageViewer[0]->DisplayFrameNumber(m_Imager->getFrameCounter());//界面中显示已经采集的帧数
|
||
|
||
//创建需要显示的图像--opencv版本
|
||
ImageProcessor imageProcessor;
|
||
//cv::Mat rgbImage(*m_Imager->getRgbImage()->m_matRgbImage, cv::Range(0, m_Imager->getFrameCounter()), cv::Range::all());//2022.3.18重构的
|
||
cv::Mat rgbImage(*m_Imager->getMatRgbImage(), cv::Range(0, m_Imager->getFrameCounter()), cv::Range::all());
|
||
cv::Mat rgbImageStretched = imageProcessor.CStretch(rgbImage, 0.02);
|
||
|
||
//在界面中显示图像
|
||
currentImageViewer[0]->SetImage(&QPixmap::fromImage(imageProcessor.Mat2QImage(rgbImageStretched)));//绘制图像
|
||
|
||
//创建需要显示的图像--qt版本
|
||
//QRect CuttedRect = m_Imager->getRgbImage()->m_QRgbImage->rect();//先获取image整个rect
|
||
//CuttedRect.setHeight(m_Imager->getFrameCounter() - 1);//裁剪rect
|
||
//QImage CuttedImage = m_Imager->getRgbImage()->m_QRgbImage->copy(CuttedRect);
|
||
|
||
//currentImageViewer[0]->SetImage(&QPixmap::fromImage(CuttedImage));//绘制图像
|
||
}
|
||
|
||
void HPPA::PlotSpectral(int state)
|
||
{
|
||
if (state == 1)
|
||
{
|
||
//显示影像
|
||
QWidget* currentWidget = ui.ImageViewerTabWidget->currentWidget();
|
||
QList<ImageViewer *> currentImageViewer = currentWidget->findChildren<ImageViewer *>();
|
||
currentImageViewer[0]->DisplayFrameNumber(m_Imager->getFocusFrameCounter());//界面中显示已经采集的帧数
|
||
|
||
ImageProcessor imageProcessor;
|
||
//cv::Mat grayImage(*m_Imager->getRgbImage()->m_matFocusGrayImage, cv::Range::all(), cv::Range::all());//2022.3.18重构的
|
||
cv::Mat grayImage(*m_Imager->getMatFocusGrayImage(), cv::Range::all(), cv::Range::all());
|
||
//currentImageViewer[0]->SetImage(&QPixmap::fromImage(imageProcessor.Mat2QImage(grayImage)));//绘制图像
|
||
|
||
currentImageViewer[0]->SetImage(&QPixmap::fromImage(m_Imager->getQImageFocusGrayImage()));//绘制图像
|
||
|
||
//绘制光谱
|
||
QLineSeries *series = new QLineSeries();
|
||
//series->clear();//////////////////////////////
|
||
int sampleCount = m_Imager->getSampleCount();
|
||
for (size_t i = 0; i < sampleCount; i++)
|
||
{
|
||
//malloc申请的内存用法1:可以当做数组用
|
||
//series->append(i, m_Imager->buffer[i + 5 * 900]);
|
||
series->append(i, m_Imager->buffer[900 * 150 + i]);
|
||
}
|
||
|
||
QChart *chart = new QChart();
|
||
chart->legend()->hide();
|
||
chart->addSeries(series);
|
||
chart->createDefaultAxes();
|
||
//chart->setTitle("Simple line chart example");
|
||
|
||
m_chartView->setChart(chart);
|
||
}
|
||
else
|
||
{
|
||
//改变界面上的按钮文字
|
||
}
|
||
|
||
|
||
|
||
////显示影像
|
||
//QWidget* currentWidget = ui.ImageViewerTabWidget->currentWidget();
|
||
//QList<ImageViewer *> currentImageViewer = currentWidget->findChildren<ImageViewer *>();
|
||
//
|
||
|
||
//ImageProcessor imageProcessor;
|
||
//
|
||
|
||
////绘制光谱
|
||
//QLineSeries *series = new QLineSeries();
|
||
////series->clear();//////////////////////////////
|
||
//int sampleCount = m_Imager->getSampleCount();
|
||
//
|
||
|
||
//QChart *chart = new QChart();
|
||
//chart->legend()->hide();
|
||
//chart->addSeries(series);
|
||
//chart->createDefaultAxes();
|
||
////chart->setTitle("Simple line chart example");
|
||
|
||
//m_chartView->setChart(chart);
|
||
|
||
//while (state)
|
||
//{
|
||
// currentImageViewer[0]->DisplayFrameNumber(m_Imager->getFocusFrameCounter());//界面中显示已经采集的帧数
|
||
// cv::Mat grayImage(*m_Imager->getMatFocusGrayImage(), cv::Range::all(), cv::Range::all());
|
||
// currentImageViewer[0]->SetImage(&QPixmap::fromImage(imageProcessor.Mat2QImage(grayImage)));//绘制图像
|
||
|
||
// for (size_t i = 0; i < sampleCount; i++)
|
||
// {
|
||
// //malloc申请的内存用法1:可以当做数组用
|
||
// //series->append(i, m_Imager->buffer[i + 5 * 900]);
|
||
// series->append(i, m_Imager->buffer[900 * 150 + i]);
|
||
// }
|
||
// std::cout << "-----------------------------------------------" << std::endl;
|
||
//}
|
||
|
||
}
|
||
|
||
void HPPA::onRecordFinishedSignal_WhenFrameNumberMeet()
|
||
{
|
||
std::cout << "停止采集原因:帧数采集完了。" << std::endl;
|
||
}
|
||
|
||
void HPPA::onRecordFinishedSignal_WhenFrameNumberNotMeet()
|
||
{
|
||
std::cout << "停止采集原因:(1)帧数没有采集够时,马达到达最大位置;(2)手动停止采集。" << std::endl;
|
||
}
|
||
|
||
ForLoopControl::ForLoopControl()
|
||
{
|
||
|
||
}
|
||
|
||
ForLoopControl::~ForLoopControl()
|
||
{
|
||
|
||
}
|
||
|
||
void ForLoopControl::setLoopCount(int loopCount)
|
||
{
|
||
m_loopCount = loopCount;
|
||
}
|
||
|
||
int ForLoopControl::getLoopCount() const
|
||
{
|
||
return m_loopCount;
|
||
}
|
||
|
||
void ForLoopControl::startLoop()
|
||
{
|
||
//std::cout << "共有" << m_loopCount << "次循环" << std::endl;
|
||
for (size_t i = 0; i < m_loopCount; i++)
|
||
{
|
||
//std::cout << "第" << i << "次循环" << std::endl;
|
||
|
||
emit recordSignal(i);
|
||
|
||
m_boolRecordNextLine = false;
|
||
m_boolQuitLoop = false;
|
||
while (!m_boolRecordNextLine)
|
||
{
|
||
Sleep(500);
|
||
|
||
if (m_boolQuitLoop)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (m_boolQuitLoop)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (m_boolQuitLoop == false)
|
||
{
|
||
emit recordSignal(-1);//采集完所有航线,自动停止
|
||
}
|
||
else if (m_boolQuitLoop == true)
|
||
{
|
||
emit recordSignal(-2);//手动停止采集
|
||
}
|
||
|
||
//std::cout << "退出循环!" << std::endl;
|
||
}
|
||
|
||
WorkerThread3::WorkerThread3(CFocusMotorControl * ctrlFocusMotor)
|
||
{
|
||
m_ctrlFocusMotor = ctrlFocusMotor;
|
||
}
|
||
|
||
void WorkerThread3::run()
|
||
{
|
||
m_ctrlFocusMotor->StartAutoFocus(820, 910, 20, 2);
|
||
|
||
emit AutoFocusFinishedSignal();
|
||
} |