完成新的二轴采集:二轴采集逻辑控制器
This commit is contained in:
443
HPPA/CaptureCoordinator.cpp
Normal file
443
HPPA/CaptureCoordinator.cpp
Normal file
@ -0,0 +1,443 @@
|
||||
#include "CaptureCoordinator.h"
|
||||
|
||||
TwoMotionCaptureCoordinator::TwoMotionCaptureCoordinator(
|
||||
IrisMultiMotorController* motorCtrl,
|
||||
ImagerOperationBase* cameraCtrl,
|
||||
QObject* parent)
|
||||
: QObject(parent)
|
||||
, m_motorCtrl(motorCtrl)
|
||||
, m_cameraCtrl(cameraCtrl)
|
||||
, m_isRunning(false)
|
||||
{
|
||||
//这些信号槽是按照逻辑顺序的
|
||||
connect(this, SIGNAL(moveTo(int, double, double, int)),
|
||||
m_motorCtrl, SLOT(moveTo(int, double, double, int)));
|
||||
connect(this, SIGNAL(moveTo(const std::vector<double>, const std::vector<double>, int)),
|
||||
m_motorCtrl, SLOT(moveTo(const std::vector<double>, const std::vector<double>, int)));
|
||||
connect(this, &TwoMotionCaptureCoordinator::stopMotorSignal, m_motorCtrl, &IrisMultiMotorController::stop);
|
||||
|
||||
connect(m_motorCtrl, &IrisMultiMotorController::motorStopSignal,
|
||||
this, &TwoMotionCaptureCoordinator::handlePositionReached);
|
||||
//connect(m_motorCtrl, &IrisMultiMotorController::moveFailed,
|
||||
// this, &TwoMotionCaptureCoordinator::handleError);
|
||||
|
||||
connect(this, &TwoMotionCaptureCoordinator::startRecordHSISignal,
|
||||
m_cameraCtrl, &ImagerOperationBase::start_record);
|
||||
connect(this, &TwoMotionCaptureCoordinator::stopRecordHSISignal,
|
||||
m_cameraCtrl, &ImagerOperationBase::stop_record);
|
||||
connect(m_cameraCtrl, &ImagerOperationBase::RecordFinishedSignal_WhenFrameNumberMeet,
|
||||
this, &TwoMotionCaptureCoordinator::handleCaptureCompleteWhenFrameNumberMeet);
|
||||
//connect(m_cameraCtrl, &ImagerOperationBase::RecordFinishedSignal_WhenFrameNumberNotMeet,
|
||||
// this, &TwoMotionCaptureCoordinator::handleCaptureCompleteWhenFrameNumberNotMeet);
|
||||
//connect(m_cameraCtrl, &ImagerOperationBase::captureFailed,
|
||||
// this, &TwoMotionCaptureCoordinator::handleError);
|
||||
}
|
||||
|
||||
TwoMotionCaptureCoordinator::TwoMotionCaptureCoordinator(
|
||||
IrisMultiMotorController* motorCtrl,
|
||||
QObject* parent)
|
||||
: QObject(parent)
|
||||
, m_motorCtrl(motorCtrl)
|
||||
, m_isRunning(false)
|
||||
{
|
||||
connect(this, SIGNAL(moveTo(int, double, double, int)),
|
||||
m_motorCtrl, SLOT(moveTo(int, double, double, int)));
|
||||
connect(this, SIGNAL(moveTo(const std::vector<double>, const std::vector<double>, int)),
|
||||
m_motorCtrl, SLOT(moveTo(const std::vector<double>, const std::vector<double>, int)));
|
||||
|
||||
connect(m_motorCtrl, &IrisMultiMotorController::motorStopSignal,
|
||||
this, &TwoMotionCaptureCoordinator::handlePositionReached);
|
||||
//connect(m_motorCtrl, &IrisMultiMotorController::moveFailed,
|
||||
// this, &TwoMotionCaptureCoordinator::handleError);
|
||||
}
|
||||
|
||||
TwoMotionCaptureCoordinator::~TwoMotionCaptureCoordinator()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void TwoMotionCaptureCoordinator::start(QVector<PathLine> pathLines)
|
||||
{
|
||||
//QMutexLocker locker(&m_dataMutex);
|
||||
|
||||
if (m_isRunning)
|
||||
{
|
||||
emit errorOccurred("Sequence already running");
|
||||
std::cout << "already running" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
getLocBeforeStart();
|
||||
|
||||
m_pathLines = pathLines;
|
||||
|
||||
m_isMoving2XMin = false;
|
||||
m_isMoving2XMax = false;
|
||||
m_isMoving2XStartLoc = false;
|
||||
|
||||
m_isMoving2YTargeLoc = false;
|
||||
m_isMoving2YStartLoc = false;
|
||||
m_isImagerFrameNumberMeet = false;
|
||||
|
||||
m_retryTimesMoving2XMin = 0;
|
||||
m_retryTimesMoving2XMax = 0;
|
||||
m_retryTimesMoving2YTargeLoc = 0;
|
||||
|
||||
m_isRunning = true;
|
||||
m_numCurrentPathLine = 0;
|
||||
processNextPathLine();
|
||||
}
|
||||
|
||||
void TwoMotionCaptureCoordinator::stop()
|
||||
{
|
||||
if (!m_isRunning) return;
|
||||
|
||||
//QMutexLocker locker(&m_dataMutex);
|
||||
|
||||
std::cout << "The user manually stops the collection! " << std::endl;
|
||||
savePathLinesToCsv();
|
||||
|
||||
emit sequenceComplete(1);
|
||||
emit finishRecordLineNumSignal(m_numCurrentPathLine);
|
||||
//emit stopRecordHSISignal(m_numCurrentPathLine);
|
||||
if (m_cameraCtrl != nullptr)
|
||||
{
|
||||
m_cameraCtrl->stop_record();
|
||||
}
|
||||
|
||||
move2LocBeforeStart();
|
||||
}
|
||||
|
||||
void TwoMotionCaptureCoordinator::getLocBeforeStart()
|
||||
{
|
||||
QEventLoop loop;
|
||||
bool received = false;
|
||||
|
||||
QTimer timer;
|
||||
timer.setSingleShot(true);
|
||||
connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);
|
||||
|
||||
QMetaObject::Connection conn = QObject::connect(m_motorCtrl, &IrisMultiMotorController::locationSignal,
|
||||
[&](std::vector<double> pos) {
|
||||
m_locBeforeStart = pos;
|
||||
received = true;
|
||||
loop.quit();
|
||||
});
|
||||
|
||||
QMetaObject::invokeMethod(m_motorCtrl, "getLoc", Qt::QueuedConnection);
|
||||
timer.start(3000);
|
||||
|
||||
loop.exec();
|
||||
|
||||
disconnect(conn);
|
||||
}
|
||||
|
||||
void TwoMotionCaptureCoordinator::getRecordState()
|
||||
{
|
||||
emit recordState(m_isRunning);
|
||||
}
|
||||
|
||||
void TwoMotionCaptureCoordinator::move2LocBeforeStart()
|
||||
{
|
||||
std::cout << "\nmove2LocBeforeStart." << std::endl;
|
||||
|
||||
PathLine& tmp = m_pathLines[0];
|
||||
std::vector<double> speed;
|
||||
speed.push_back(tmp.speedTargetXMinPosition);
|
||||
speed.push_back(tmp.speedTargetYPosition);
|
||||
emit moveTo(m_locBeforeStart, speed, 1000);
|
||||
|
||||
m_isRunning = false;
|
||||
|
||||
m_isMoving2XMin = false;
|
||||
m_isMoving2XMax = false;
|
||||
m_isMoving2YTargeLoc = false;
|
||||
|
||||
m_isMoving2XStartLoc = true;
|
||||
m_isMoving2YStartLoc = true;
|
||||
}
|
||||
|
||||
QVector<PathLine> TwoMotionCaptureCoordinator::pathLines() const
|
||||
{
|
||||
//QMutexLocker locker(&m_dataMutex);
|
||||
return m_pathLines;
|
||||
}
|
||||
|
||||
double TwoMotionCaptureCoordinator::getTimeDiffMinutes(QDateTime startTime, QDateTime endTime)
|
||||
{
|
||||
qint64 diffMillis = startTime.msecsTo(endTime);
|
||||
double diffMinutes = (double)diffMillis / 60000;//min
|
||||
|
||||
return diffMinutes;
|
||||
}
|
||||
|
||||
bool TwoMotionCaptureCoordinator::savePathLinesToCsv(QString filename)
|
||||
{
|
||||
//QMutexLocker locker(&m_dataMutex);
|
||||
if (filename.isEmpty())
|
||||
{
|
||||
FileOperation* fileOperation = new FileOperation();
|
||||
string directory = fileOperation->getDirectoryOfExe();
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
QString format1 = "yyyyMMdd_HHmmss";
|
||||
QString fileNameTmp = now.toString("yyyyMMdd_HHmmss");
|
||||
|
||||
filename = QDir::cleanPath(QString::fromStdString(directory) + QDir::separator() + "pathLines" + QDir::separator() + fileNameTmp + "_pathLines.csv");
|
||||
}
|
||||
|
||||
QDir dir = QFileInfo(filename).absoluteDir();
|
||||
|
||||
// 如果目录不存在,则递归创建
|
||||
if (!dir.exists()) {
|
||||
if (!dir.mkpath(".")) {
|
||||
qWarning() << "Failed to create directory:" << dir.path();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
QFile file(filename);
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QTextStream out(&file);
|
||||
out << "timestamp1,timestamp2,timestamp3,time consuming(min),targetYPosition,actualYPosition,targetXMinPosition,actualXMinPosition,targetXMaxPosition,actualXMaxPosition\n";
|
||||
|
||||
for (const auto& data : m_pathLines)
|
||||
{
|
||||
out << data.timestamp1.toString("yyyy-MM-dd HH:mm:ss.zzz") << ","
|
||||
<< data.timestamp2.toString("yyyy-MM-dd HH:mm:ss.zzz") << ","
|
||||
<< data.timestamp3.toString("yyyy-MM-dd HH:mm:ss.zzz") << ","
|
||||
<< QString::number(getTimeDiffMinutes(data.timestamp2, data.timestamp3), 'f', 4) << ","
|
||||
<< QString::number(data.targetYPosition, 'f', 4) << ","
|
||||
<< QString::number(data.actualYPosition, 'f', 4) << ","
|
||||
<< QString::number(data.targetXMinPosition, 'f', 4) << ","
|
||||
<< QString::number(data.actualXMinPosition, 'f', 4) << ","
|
||||
<< QString::number(data.targetXMaxPosition, 'f', 4) << ","
|
||||
<< QString::number(data.actualXMaxPosition, 'f', 4)
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
void TwoMotionCaptureCoordinator::handlePositionReached(int motorID, double pos)
|
||||
{
|
||||
if (!m_isRunning) return;
|
||||
|
||||
//QMutexLocker locker(&m_dataMutex);
|
||||
|
||||
PathLine &tmp = m_pathLines[m_numCurrentPathLine];
|
||||
|
||||
if (motorID == 1)//y马达
|
||||
{
|
||||
if (m_isMoving2YTargeLoc)
|
||||
{
|
||||
double threshold = getThre(tmp.targetYPosition, pos);
|
||||
|
||||
if (threshold > 5)
|
||||
{
|
||||
//没到准确位置,再次给马达发送命令
|
||||
if (m_retryTimesMoving2YTargeLoc < m_retryLimit)
|
||||
{
|
||||
m_retryTimesMoving2YTargeLoc++;
|
||||
|
||||
std::cout << "Y motor Moving2YTargeLoc error. Retry..." << std::endl;
|
||||
emit moveTo(1, tmp.targetYPosition, tmp.speedTargetYPosition, 1000);
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_retryTimesMoving2YTargeLoc = 0;
|
||||
|
||||
tmp.actualYPosition = pos;
|
||||
|
||||
m_isMoving2YTargeLoc = false;
|
||||
|
||||
std::cout << "y motor is reached!!!! " << std::endl;
|
||||
startRecordHsi();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_isMoving2YStartLoc)
|
||||
{
|
||||
m_isMoving2YStartLoc = false;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (motorID == 0)//x马达
|
||||
{
|
||||
if (m_isMoving2XMin)
|
||||
{
|
||||
double threshold = getThre(tmp.targetXMinPosition, pos);
|
||||
|
||||
if (threshold > 5)
|
||||
{
|
||||
//没到准确位置,再次给马达发送命令
|
||||
if (m_retryTimesMoving2XMin < m_retryLimit)
|
||||
{
|
||||
m_retryTimesMoving2XMin++;
|
||||
|
||||
std::cout << "X motor Moving2XMin error. Retry..." << std::endl;
|
||||
emit moveTo(0, tmp.targetXMinPosition, tmp.speedTargetXMinPosition, 1000);
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_retryTimesMoving2XMin = 0;
|
||||
|
||||
tmp.actualXMinPosition = pos;
|
||||
|
||||
m_isMoving2XMin = false;
|
||||
|
||||
std::cout << "x motor is reached!!!! " << std::endl;
|
||||
startRecordHsi();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_isMoving2XMax)
|
||||
{
|
||||
double threshold = getThre(tmp.targetXMaxPosition, pos);
|
||||
|
||||
if (threshold > 5 && !m_isImagerFrameNumberMeet)//马达没到准确位置 && 【非】光谱仪因帧数限制主动停止采集
|
||||
{
|
||||
//没到准确位置,再次给马达发送命令
|
||||
if (m_retryTimesMoving2XMax < m_retryLimit)
|
||||
{
|
||||
m_retryTimesMoving2XMax++;
|
||||
|
||||
std::cout << "X motor Moving2XMax error. Retry..." << std::endl;
|
||||
emit moveTo(0, tmp.targetXMaxPosition, tmp.speedTargetXMaxPosition, 1000);
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_retryTimesMoving2XMax = 0;
|
||||
|
||||
tmp.actualXMaxPosition = pos;
|
||||
tmp.timestamp3 = QDateTime::currentDateTime();
|
||||
|
||||
std::cout << "Line " << m_numCurrentPathLine << " time span(min):" << getTimeDiffMinutes(tmp.timestamp2, tmp.timestamp3) << std::endl;
|
||||
|
||||
//停止采集高光谱数据
|
||||
emit finishRecordLineNumSignal(m_numCurrentPathLine);
|
||||
//emit stopRecordHSISignal(m_numCurrentPathLine);
|
||||
if (m_cameraCtrl!=nullptr)
|
||||
{
|
||||
m_cameraCtrl->stop_record();
|
||||
}
|
||||
|
||||
m_isMoving2XMax = false;
|
||||
m_isImagerFrameNumberMeet = false;
|
||||
m_numCurrentPathLine++;
|
||||
processNextPathLine();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_isMoving2XStartLoc)
|
||||
{
|
||||
m_isMoving2XStartLoc = false;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double TwoMotionCaptureCoordinator::getThre(double targetLoc,double actualLoc)
|
||||
{
|
||||
double targetLocTmp;
|
||||
if (targetLoc == 0)
|
||||
{
|
||||
targetLocTmp = 0.001;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetLocTmp = targetLoc;
|
||||
}
|
||||
double thre = abs(targetLoc - actualLoc) / targetLocTmp * 100;
|
||||
|
||||
return thre;
|
||||
}
|
||||
|
||||
void TwoMotionCaptureCoordinator::startRecordHsi()
|
||||
{
|
||||
if (!m_isRunning) return;
|
||||
|
||||
//QMutexLocker locker(&m_dataMutex);
|
||||
|
||||
if (!m_isMoving2XMin && !m_isMoving2YTargeLoc)
|
||||
{
|
||||
//开始采集高光谱数据
|
||||
PathLine &tmp = m_pathLines[m_numCurrentPathLine];
|
||||
tmp.timestamp2 = QDateTime::currentDateTime();
|
||||
std::cout << "start recording hsi, moving to " << tmp.targetXMaxPosition << std::endl;
|
||||
|
||||
m_isMoving2XMax = true;
|
||||
emit moveTo(0, tmp.targetXMaxPosition, tmp.speedTargetXMaxPosition, 1000);
|
||||
|
||||
emit startRecordHSISignal(m_numCurrentPathLine);
|
||||
}
|
||||
}
|
||||
|
||||
void TwoMotionCaptureCoordinator::handleCaptureCompleteWhenFrameNumberMeet()
|
||||
{
|
||||
m_isImagerFrameNumberMeet = true;
|
||||
emit stopMotorSignal(0);
|
||||
}
|
||||
|
||||
void TwoMotionCaptureCoordinator::handleError(const QString& error)
|
||||
{
|
||||
//QMutexLocker locker(&m_dataMutex);
|
||||
m_isRunning = false;
|
||||
emit errorOccurred(error);
|
||||
}
|
||||
|
||||
void TwoMotionCaptureCoordinator::processNextPathLine()
|
||||
{
|
||||
if (!m_isRunning) return;
|
||||
|
||||
int numPathLines = m_pathLines.size();
|
||||
|
||||
if (numPathLines == 0)
|
||||
{
|
||||
move2LocBeforeStart();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_isMoving2YTargeLoc || m_isMoving2XMin)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_numCurrentPathLine > numPathLines - 1)
|
||||
{
|
||||
std::cout << "\nAll path lines is finished! " << std::endl;
|
||||
|
||||
move2LocBeforeStart();
|
||||
savePathLinesToCsv();
|
||||
|
||||
emit sequenceComplete(0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "\nNew path line: " << m_numCurrentPathLine << std::endl;
|
||||
emit startRecordLineNumSignal(m_numCurrentPathLine);
|
||||
|
||||
PathLine &tmp = m_pathLines[m_numCurrentPathLine];
|
||||
tmp.timestamp1 = QDateTime::currentDateTime();
|
||||
|
||||
std::vector<double> loc;
|
||||
loc.push_back(tmp.targetXMinPosition);
|
||||
loc.push_back(tmp.targetYPosition);
|
||||
std::vector<double> speed;
|
||||
speed.push_back(tmp.speedTargetXMinPosition);
|
||||
speed.push_back(tmp.speedTargetYPosition);
|
||||
|
||||
m_isMoving2YTargeLoc = true;
|
||||
m_isMoving2XMin = true;
|
||||
emit moveTo(loc, speed, 1000);
|
||||
}
|
107
HPPA/CaptureCoordinator.h
Normal file
107
HPPA/CaptureCoordinator.h
Normal file
@ -0,0 +1,107 @@
|
||||
#pragma once
|
||||
#include <QDateTime>
|
||||
#include <QObject>
|
||||
#include <QMutex>
|
||||
#include <QMetaType>
|
||||
|
||||
#include "ImagerOperationBase.h"
|
||||
#include "IrisMultiMotorController.h"
|
||||
|
||||
struct PathLine
|
||||
{
|
||||
double targetYPosition;
|
||||
double actualYPosition;
|
||||
double speedTargetYPosition;
|
||||
|
||||
double targetXMinPosition;
|
||||
double actualXMinPosition;
|
||||
double speedTargetXMinPosition;
|
||||
|
||||
double targetXMaxPosition;
|
||||
double actualXMaxPosition;
|
||||
double speedTargetXMaxPosition;
|
||||
|
||||
QDateTime timestamp1;//开始航线
|
||||
QDateTime timestamp2;//开始采集高光谱
|
||||
QDateTime timestamp3;//结束采集高光谱
|
||||
|
||||
PathLine(double targetYPosition_=0, double targetXMinPosition_ = 0, double targetXMaxPosition_ = 0)
|
||||
: targetYPosition(targetYPosition_), actualYPosition(0), speedTargetYPosition(0),
|
||||
targetXMinPosition(targetXMinPosition_), actualXMinPosition(0), speedTargetXMinPosition(0),
|
||||
targetXMaxPosition(targetXMaxPosition_), actualXMaxPosition(0), speedTargetXMaxPosition(0),
|
||||
timestamp1(QDateTime::currentDateTime()), timestamp2(QDateTime::currentDateTime()), timestamp3(QDateTime::currentDateTime()) {}
|
||||
};
|
||||
Q_DECLARE_METATYPE(PathLine);
|
||||
//Q_DECLARE_METATYPE(QVector<PathLine>);
|
||||
|
||||
class TwoMotionCaptureCoordinator : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TwoMotionCaptureCoordinator(IrisMultiMotorController* motorCtrl,
|
||||
ImagerOperationBase* cameraCtrl,
|
||||
QObject* parent = nullptr);
|
||||
TwoMotionCaptureCoordinator(IrisMultiMotorController* motorCtrl,
|
||||
QObject* parent = nullptr);
|
||||
~TwoMotionCaptureCoordinator();
|
||||
|
||||
QVector<PathLine> pathLines() const;
|
||||
|
||||
signals:
|
||||
void sequenceComplete(int);//0:所有采集线正常运行完成,1:用户主动取消采集
|
||||
void startRecordLineNumSignal(int lineNum);
|
||||
void finishRecordLineNumSignal(int lineNum);
|
||||
|
||||
void startRecordHSISignal(int lineNum);
|
||||
void stopRecordHSISignal(int lineNum);
|
||||
|
||||
void errorOccurred(const QString& error);
|
||||
void moveTo(int, double, double, int);
|
||||
void moveTo(const std::vector<double>, const std::vector<double>, int);
|
||||
void stopMotorSignal(int axis);
|
||||
|
||||
void recordState(bool state);
|
||||
|
||||
private slots:
|
||||
void start(QVector<PathLine> pathLines);
|
||||
void stop();
|
||||
void getRecordState();
|
||||
|
||||
void handlePositionReached(int motorID, double pos);
|
||||
void handleCaptureCompleteWhenFrameNumberMeet();
|
||||
void handleError(const QString& error);
|
||||
|
||||
void move2LocBeforeStart();
|
||||
|
||||
private:
|
||||
void processNextPathLine();
|
||||
void startRecordHsi();
|
||||
void getLocBeforeStart();
|
||||
double getThre(double targetLoc, double actualLoc);
|
||||
|
||||
double getTimeDiffMinutes(QDateTime startTime, QDateTime endTime);
|
||||
bool savePathLinesToCsv(QString filename= QString());
|
||||
|
||||
IrisMultiMotorController* m_motorCtrl;
|
||||
ImagerOperationBase* m_cameraCtrl=nullptr;
|
||||
QVector<PathLine> m_pathLines;
|
||||
mutable QMutex m_dataMutex;
|
||||
|
||||
bool m_isRunning;
|
||||
bool m_isMoving2YTargeLoc;
|
||||
bool m_isMoving2XMin;
|
||||
bool m_isMoving2XMax;
|
||||
|
||||
int m_retryLimit = 3;
|
||||
int m_retryTimesMoving2YTargeLoc;
|
||||
int m_retryTimesMoving2XMin;
|
||||
int m_retryTimesMoving2XMax;
|
||||
|
||||
bool m_isImagerFrameNumberMeet;//光谱仪帧数限制到了,主动停止采集
|
||||
std::vector<double> m_locBeforeStart;
|
||||
|
||||
bool m_isMoving2XStartLoc;
|
||||
bool m_isMoving2YStartLoc;
|
||||
|
||||
int m_numCurrentPathLine;
|
||||
};
|
@ -311,6 +311,18 @@ HPPA::HPPA(QWidget *parent)
|
||||
tabifyDockWidget(dock_rac, dock_omc);
|
||||
mPanelMenu->addAction(dock_omc->toggleViewAction());
|
||||
|
||||
//2<><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
tmc = new TwoMotorControl(this);
|
||||
connect(tmc, SIGNAL(startLineNumSignal(int)), this, SLOT(onCreateTab(int)));
|
||||
connect(tmc, SIGNAL(sequenceComplete()), this, SLOT(onsequenceComplete()));
|
||||
dock_tmc = new QDockWidget(QString::fromLocal8Bit("2<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"), this);
|
||||
dock_tmc->setObjectName("mDockTwoMotorControl");
|
||||
dock_tmc->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
||||
dock_tmc->setWidget(tmc);
|
||||
tabifyDockWidget(dock_omc, dock_tmc);
|
||||
mPanelMenu->addAction(dock_tmc->toggleViewAction());
|
||||
|
||||
|
||||
createActionGroups();
|
||||
connect(mImagerGroup, &QActionGroup::triggered, this, &HPPA::selectingImager);
|
||||
|
||||
@ -363,7 +375,6 @@ void HPPA::recordFromRobotArm(int fileCounter)
|
||||
}
|
||||
|
||||
onCreateTab(fileCounter-1);
|
||||
m_numberOfRecording = fileCounter - 1;
|
||||
emit StartRecordSignal();
|
||||
|
||||
ui.action_start_recording->setText(QString::fromLocal8Bit("<EFBFBD>ɼ<EFBFBD><EFBFBD><EFBFBD>"));
|
||||
@ -419,6 +430,7 @@ void HPPA::createMoveplatformActionGroup()
|
||||
moveplatformActionGroup->addAction(ui.mAction_2AxisMotor);
|
||||
moveplatformActionGroup->addAction(ui.mAction_RobotArm);
|
||||
moveplatformActionGroup->addAction(ui.mAction_1AxisMotor);
|
||||
moveplatformActionGroup->addAction(ui.mAction_2AxisMotor_new);
|
||||
|
||||
// <20><>ȡ<EFBFBD>ϴ<EFBFBD>ѡ<EFBFBD><D1A1><EFBFBD>Ľ<EFBFBD><C4BD><EFBFBD>
|
||||
QSettings settings;
|
||||
@ -441,6 +453,10 @@ void HPPA::createMoveplatformActionGroup()
|
||||
{
|
||||
ui.mAction_1AxisMotor->setChecked(true);
|
||||
}
|
||||
else if (lastSelectedAction == "mAction_2AxisMotor_new")
|
||||
{
|
||||
ui.mAction_2AxisMotor_new->setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
void HPPA::selectingMoveplatform(QAction* selectedAction)
|
||||
@ -562,6 +578,7 @@ void HPPA::onStartRecordStep1()
|
||||
string directory = fileOperation->getDirectoryFromString();
|
||||
//string imgPath = directory + "\\tmp_image";
|
||||
string imgPath = directory + "\\" + m_FilenameLineEdit->text().toStdString();
|
||||
string x_location = removeFileExtension(imgPath) + "_x_location.pos";
|
||||
|
||||
m_RecordState += 1;
|
||||
if (m_RecordState % 2 == 1)
|
||||
@ -599,7 +616,6 @@ void HPPA::onStartRecordStep1()
|
||||
ui.ImageViewerTabWidget->clear();
|
||||
|
||||
onCreateTab(0);
|
||||
m_numberOfRecording = 0;
|
||||
|
||||
m_Imager->setFileName2Save(imgPath);
|
||||
m_Imager->setFrameNumber(this->frame_number->text().toInt());
|
||||
@ -627,7 +643,6 @@ void HPPA::onStartRecordStep1()
|
||||
ui.ImageViewerTabWidget->clear();
|
||||
|
||||
onCreateTab(0);
|
||||
m_numberOfRecording = 0;
|
||||
|
||||
ui.action_start_recording->setText(QString::fromLocal8Bit("ֹͣ<EFBFBD>ɼ<EFBFBD>"));
|
||||
ui.mainToolBar->widgetForAction(ui.action_start_recording)->setStyleSheet("QWidget{background-color:rgb(255,0,0);}");
|
||||
@ -686,8 +701,6 @@ void HPPA::onStartRecordStep1()
|
||||
//ɾ<><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>tab
|
||||
ui.ImageViewerTabWidget->clear();
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼x<C2BC><78><EFBFBD><EFBFBD>λ<EFBFBD>õ<EFBFBD><C3B5>ļ<EFBFBD>
|
||||
string x_location = removeFileExtension(imgPath) + "x_location.pos";
|
||||
m_hTimesFile = fopen(x_location.c_str(), "w+");
|
||||
|
||||
m_Imager->setFileName2Save(imgPath);
|
||||
@ -721,6 +734,35 @@ void HPPA::onStartRecordStep1()
|
||||
|
||||
return;
|
||||
}
|
||||
else if (checkedName == "mAction_2AxisMotor_new")
|
||||
{
|
||||
m_RecordState += 1;
|
||||
|
||||
if (m_RecordState % 2 == 1)
|
||||
{
|
||||
ui.ImageViewerTabWidget->clear();
|
||||
|
||||
m_Imager->setFileName2Save(imgPath);
|
||||
m_Imager->setFrameNumber(this->frame_number->text().toInt());
|
||||
tmc->setImager(m_Imager);
|
||||
tmc->setPosFileName(QString::fromStdString(x_location));
|
||||
tmc->run();
|
||||
|
||||
ui.action_start_recording->setText(QString::fromLocal8Bit("ֹͣ<EFBFBD>ɼ<EFBFBD>"));
|
||||
ui.mainToolBar->widgetForAction(ui.action_start_recording)->setStyleSheet("QWidget{background-color:rgb(255,0,0);}");
|
||||
}
|
||||
else
|
||||
{
|
||||
tmc->stop();
|
||||
|
||||
m_RecordState--;
|
||||
|
||||
ui.action_start_recording->setText(QString::fromLocal8Bit("<EFBFBD>ɼ<EFBFBD>"));
|
||||
ui.mainToolBar->widgetForAction(ui.action_start_recording)->setStyleSheet("QWidget{background-color:rgb(0,255,0);}");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else if (checkedName == "mAction_RobotArm")
|
||||
{
|
||||
//<2F><><EFBFBD>ж<EFBFBD><D0B6>Ƿ<EFBFBD>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD>к<EFBFBD><D0BA><EFBFBD>RobotArmControl::executeTask<73><6B><EFBFBD><EFBFBD><DEB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾbug
|
||||
@ -790,6 +832,8 @@ void HPPA::onCreateTab(int trackNumber)
|
||||
{
|
||||
if (trackNumber >= 0)
|
||||
{
|
||||
m_numberOfRecording = trackNumber;
|
||||
|
||||
QWidget * tabTmp = new QWidget();
|
||||
|
||||
QGridLayout *GridLayout = new QGridLayout();
|
||||
@ -1755,6 +1799,13 @@ void HPPA::getRequest(QString str)
|
||||
|
||||
void HPPA::newMotor()
|
||||
{
|
||||
QAction* checked = moveplatformActionGroup->checkedAction();
|
||||
QString checkedName = checked->objectName();
|
||||
if (checkedName != "mAction_2AxisMotor")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_xMotor != nullptr && m_yMotor != nullptr)
|
||||
{
|
||||
return;
|
||||
@ -1932,7 +1983,7 @@ void HPPA::onconnect()
|
||||
|
||||
m_Imager->connect_imager(frame_number->text().toInt());
|
||||
m_Imager->setFileName2Save(m_FilenameLineEdit->text().toStdString());
|
||||
connect(m_Imager, SIGNAL(PlotSignal(int)), this, SLOT(onPlotHyperspectralImageRgbImage(int)));
|
||||
connect(m_Imager, SIGNAL(PlotSignal(int, int)), this, SLOT(onPlotHyperspectralImageRgbImage(int, int)));
|
||||
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)));
|
||||
@ -2171,19 +2222,19 @@ void HPPA::recordWhiteFinish()
|
||||
}
|
||||
}
|
||||
|
||||
void HPPA::onPlotHyperspectralImageRgbImage(int number)
|
||||
void HPPA::onPlotHyperspectralImageRgbImage(int fileNumber, int frameNumber)
|
||||
{
|
||||
//ʹ<>û<EFBFBD>е<EFBFBD>۲ɼ<DBB2>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֹͣ<CDA3>ɼ<EFBFBD><C9BC><EFBFBD><EFBFBD><EFBFBD>˲<EFBFBD><CBB2><EFBFBD>ֿ<EFBFBD>ʼ<EFBFBD>ɼ<EFBFBD><C9BC><EFBFBD><EFBFBD>ᵼ<EFBFBD><E1B5BC><EFBFBD>ϴβɼ<CEB2><C9BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>źŵ<C5BA><C5B5>ô˲ۺ<CBB2><DBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
QAction* checked = moveplatformActionGroup->checkedAction();
|
||||
QString checkedName = checked->objectName();
|
||||
if (number == -1 && checkedName == "mAction_RobotArm")
|
||||
if (frameNumber == -1 && checkedName == "mAction_RobotArm")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//return;
|
||||
//<2F><>ȡ<EFBFBD><C8A1>ͼ<EFBFBD>ؼ<EFBFBD>
|
||||
QWidget* currentWidget = ui.ImageViewerTabWidget->widget(m_numberOfRecording);
|
||||
QWidget* currentWidget = ui.ImageViewerTabWidget->widget(fileNumber);
|
||||
QList<ImageViewer *> currentImageViewer = currentWidget->findChildren<ImageViewer *>();
|
||||
currentImageViewer[0]->DisplayFrameNumber(m_Imager->getFrameCounter());//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD>Ѿ<EFBFBD><D1BE>ɼ<EFBFBD><C9BC><EFBFBD>֡<EFBFBD><D6A1>
|
||||
|
||||
@ -2333,6 +2384,10 @@ void HPPA::onRecordFinishedSignal_WhenFrameNumberNotMeet()
|
||||
return;
|
||||
}
|
||||
|
||||
if (checkedName == "mAction_2AxisMotor_new")//<2F><><EFBFBD>ж<EFBFBD><D0B6><EFBFBD><EFBFBD>ɼ<EFBFBD><C9BC>ߣ<EFBFBD><DFA3>м<EFBFBD><D0BC><EFBFBD>ij<EFBFBD><C4B3><EFBFBD>ɼ<EFBFBD><C9BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<C9BA><F3B2BBB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɼ<EFBFBD><C9BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "ֹͣ<EFBFBD>ɼ<EFBFBD>ԭ<EFBFBD><EFBFBD>1<EFBFBD><EFBFBD>֡<EFBFBD><EFBFBD>û<EFBFBD>вɼ<EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ﵽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD>ã<EFBFBD><EFBFBD><EFBFBD>2<EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD>ֹͣ<EFBFBD>ɼ<EFBFBD><EFBFBD><EFBFBD>" << std::endl;
|
||||
|
||||
@ -2342,6 +2397,14 @@ void HPPA::onRecordFinishedSignal_WhenFrameNumberNotMeet()
|
||||
m_RecordState++;
|
||||
}
|
||||
|
||||
void HPPA::onsequenceComplete()
|
||||
{
|
||||
ui.action_start_recording->setText(QString::fromLocal8Bit("<EFBFBD>ɼ<EFBFBD>"));
|
||||
ui.mainToolBar->widgetForAction(ui.action_start_recording)->setStyleSheet("QWidget{background-color:rgb(0,255,0);}");
|
||||
|
||||
m_RecordState++;
|
||||
}
|
||||
|
||||
ForLoopControl::ForLoopControl()
|
||||
{
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "PathPlan.h"
|
||||
#include "RobotArmControl.h"
|
||||
#include "OneMotorControl.h"
|
||||
#include "TwoMotorControl.h"
|
||||
|
||||
#include "hppaConfigFile.h"
|
||||
#include "path_tc.h"
|
||||
@ -248,6 +249,9 @@ private:
|
||||
|
||||
OneMotorControl* omc;
|
||||
QDockWidget* dock_omc;
|
||||
|
||||
TwoMotorControl* tmc;
|
||||
QDockWidget* dock_tmc;
|
||||
|
||||
|
||||
PathPlan* m_pathPlan;
|
||||
@ -255,10 +259,11 @@ private:
|
||||
FILE* m_hTimesFile;
|
||||
|
||||
public Q_SLOTS:
|
||||
void onPlotHyperspectralImageRgbImage(int number);
|
||||
void onPlotHyperspectralImageRgbImage(int fileNumber, int frameNumber);
|
||||
void PlotSpectral(int state);
|
||||
void onRecordFinishedSignal_WhenFrameNumberMeet();
|
||||
void onRecordFinishedSignal_WhenFrameNumberNotMeet();
|
||||
void onsequenceComplete();
|
||||
|
||||
void onExit();
|
||||
void onconnect();//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
|
149
HPPA/HPPA.ui
149
HPPA/HPPA.ui
@ -88,6 +88,11 @@
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>-1</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QMenuBar{
|
||||
background:#F0F0F0;
|
||||
@ -123,6 +128,10 @@ color:white;
|
||||
<property name="title">
|
||||
<string>文件</string>
|
||||
</property>
|
||||
<addaction name="action_9"/>
|
||||
<addaction name="action_10"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="action_11"/>
|
||||
<addaction name="action_exit"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuspectrometer">
|
||||
@ -130,6 +139,11 @@ color:white;
|
||||
<string>光谱仪</string>
|
||||
</property>
|
||||
<widget class="QMenu" name="menu">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>宋体</family>
|
||||
</font>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>选择相机类型</string>
|
||||
</property>
|
||||
@ -169,11 +183,33 @@ color:white;
|
||||
<addaction name="mAction_is_no_motor"/>
|
||||
<addaction name="mAction_1AxisMotor"/>
|
||||
<addaction name="mAction_2AxisMotor"/>
|
||||
<addaction name="mAction_2AxisMotor_new"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="mAction_RobotArm"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="mMenuScenario">
|
||||
<property name="title">
|
||||
<string>应用场景</string>
|
||||
</property>
|
||||
<addaction name="mActionOneMotorScenario"/>
|
||||
<addaction name="action_8"/>
|
||||
<addaction name="action2"/>
|
||||
<addaction name="action_7"/>
|
||||
<addaction name="action_3"/>
|
||||
<addaction name="action_6"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menu_4">
|
||||
<property name="title">
|
||||
<string>数据处理</string>
|
||||
</property>
|
||||
<addaction name="action_4"/>
|
||||
<addaction name="action_5"/>
|
||||
<addaction name="action_13"/>
|
||||
</widget>
|
||||
<addaction name="file"/>
|
||||
<addaction name="menuspectrometer"/>
|
||||
<addaction name="mMenuScenario"/>
|
||||
<addaction name="menu_4"/>
|
||||
<addaction name="menu_2"/>
|
||||
<addaction name="mWindowsMenu"/>
|
||||
<addaction name="menuhelp"/>
|
||||
@ -185,6 +221,12 @@ color:white;
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>宋体</family>
|
||||
<pointsize>2</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>相机控制</string>
|
||||
</property>
|
||||
@ -301,13 +343,6 @@ QGroupBox:title {
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="open_rgb_camera_btn">
|
||||
<property name="text">
|
||||
<string>打开</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="close_rgb_camera_btn">
|
||||
<property name="text">
|
||||
@ -315,6 +350,13 @@ QGroupBox:title {
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="open_rgb_camera_btn">
|
||||
<property name="text">
|
||||
<string>打开</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QLabel" name="cam_label">
|
||||
<property name="frameShape">
|
||||
@ -1450,6 +1492,11 @@ QDockWidget::title {
|
||||
<property name="text">
|
||||
<string>退出</string>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Adobe Devanagari</family>
|
||||
</font>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_open">
|
||||
<property name="text">
|
||||
@ -1493,6 +1540,11 @@ QDockWidget::title {
|
||||
<property name="text">
|
||||
<string>连接相机</string>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>宋体</family>
|
||||
</font>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionOpenDirectory">
|
||||
<property name="text">
|
||||
@ -1506,6 +1558,11 @@ QDockWidget::title {
|
||||
<property name="text">
|
||||
<string>Pika L</string>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>宋体</family>
|
||||
</font>
|
||||
</property>
|
||||
</action>
|
||||
<action name="mActionCorning_410">
|
||||
<property name="checkable">
|
||||
@ -1522,6 +1579,11 @@ QDockWidget::title {
|
||||
<property name="text">
|
||||
<string>Pika XC2</string>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>宋体</family>
|
||||
</font>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_about">
|
||||
<property name="text">
|
||||
@ -1535,6 +1597,11 @@ QDockWidget::title {
|
||||
<property name="text">
|
||||
<string>Pika NIR</string>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>宋体</family>
|
||||
</font>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionpanel">
|
||||
<property name="text">
|
||||
@ -1595,6 +1662,74 @@ QDockWidget::title {
|
||||
<string>1 轴线性马达</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="mActionOneMotorScenario">
|
||||
<property name="text">
|
||||
<string>室内1轴线性平台</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_4">
|
||||
<property name="text">
|
||||
<string>辐亮度</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_5">
|
||||
<property name="text">
|
||||
<string>反射率</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_6">
|
||||
<property name="text">
|
||||
<string>机械臂</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_7">
|
||||
<property name="text">
|
||||
<string>显微镜</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_8">
|
||||
<property name="text">
|
||||
<string>三脚架(旋转平台)</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_9">
|
||||
<property name="text">
|
||||
<string>打开影像</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_10">
|
||||
<property name="text">
|
||||
<string>关闭影像</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_11">
|
||||
<property name="text">
|
||||
<string>设置</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_13">
|
||||
<property name="text">
|
||||
<string>拼接</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_3">
|
||||
<property name="text">
|
||||
<string>植物表型</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action2">
|
||||
<property name="text">
|
||||
<string>2轴旋转平台</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="mAction_2AxisMotor_new">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>2 轴线性马达_new</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<customwidgets>
|
||||
|
@ -6,7 +6,7 @@ ImagerOperationBase::ImagerOperationBase()
|
||||
m_bRecordControlState = true;
|
||||
|
||||
m_FileName2Save = "tmp_image";
|
||||
m_FileSavedCounter = 1;
|
||||
m_FileSavedCounter = 0;
|
||||
|
||||
m_RgbImage = new CImage();
|
||||
|
||||
@ -299,7 +299,7 @@ void ImagerOperationBase::start_record()
|
||||
//ÿ<><C3BF>1s<31><73><EFBFBD><EFBFBD>һ<EFBFBD>ν<EFBFBD><CEBD><EFBFBD>ͼ<EFBFBD>λ<EFBFBD><CEBB><EFBFBD>
|
||||
if (m_iFrameCounter % (int)getFramerate() == 0)
|
||||
{
|
||||
emit PlotSignal(m_iFrameCounter);
|
||||
emit PlotSignal(m_FileSavedCounter, m_iFrameCounter);
|
||||
}
|
||||
|
||||
if (m_iFrameCounter >= m_iFrameNumber)
|
||||
@ -310,14 +310,14 @@ void ImagerOperationBase::start_record()
|
||||
}
|
||||
imagerStopCollect();
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>λ<EFBFBD>ͼǰ<CDBC><C7B0>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
//m_RgbImage
|
||||
emit PlotSignal(m_FileSavedCounter, -1);//<2F><>1<EFBFBD><31><EFBFBD>ɼ<EFBFBD><C9BC><EFBFBD><EFBFBD>ɺ<EFBFBD><C9BA><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>λ<EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>Է<EFBFBD><D4B7>ɼ<EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡<EFBFBD>ʵı<CAB5><C4B1><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>ȫ<EFBFBD><C8AB>2<EFBFBD><32>ʹ<EFBFBD>û<EFBFBD>е<EFBFBD>۲ɼ<DBB2>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֹͣ<CDA3>ɼ<EFBFBD><C9BC><EFBFBD><EFBFBD><EFBFBD>˲<EFBFBD>俪ʼ<E4BFAA>ɼ<EFBFBD><C9BC><EFBFBD><EFBFBD>ᵼ<EFBFBD><E1B5BC><EFBFBD>ϴβɼ<CEB2><C9BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4>źŵ<C5BA><C5B5>õIJۺ<C4B2><DBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>˼<EFBFBD><CBBC>ݣ<EFBFBD>ע<EFBFBD>͵<EFBFBD>
|
||||
|
||||
m_bRecordControlState = false;
|
||||
WriteHdr();
|
||||
m_FileSavedCounter++;
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>λ<EFBFBD>ͼǰ<CDBC><C7B0>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
//m_RgbImage
|
||||
emit PlotSignal(-1);//<2F><>1<EFBFBD><31><EFBFBD>ɼ<EFBFBD><C9BC><EFBFBD><EFBFBD>ɺ<EFBFBD><C9BA><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>λ<EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>Է<EFBFBD><D4B7>ɼ<EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡<EFBFBD>ʵı<CAB5><C4B1><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>ȫ<EFBFBD><C8AB>2<EFBFBD><32>ʹ<EFBFBD>û<EFBFBD>е<EFBFBD>۲ɼ<DBB2>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֹͣ<CDA3>ɼ<EFBFBD><C9BC><EFBFBD><EFBFBD><EFBFBD>˲<EFBFBD>俪ʼ<E4BFAA>ɼ<EFBFBD><C9BC><EFBFBD><EFBFBD>ᵼ<EFBFBD><E1B5BC><EFBFBD>ϴβɼ<CEB2><C9BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4>źŵ<C5BA><C5B5>õIJۺ<C4B2><DBBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>˼<EFBFBD><CBBC>ݣ<EFBFBD>ע<EFBFBD>͵<EFBFBD>
|
||||
|
||||
if (m_iFrameCounter >= m_iFrameNumber)
|
||||
{
|
||||
emit RecordFinishedSignal_WhenFrameNumberMeet();
|
||||
@ -341,7 +341,7 @@ void ImagerOperationBase::setFrameNumber(int FrameNumber)
|
||||
void ImagerOperationBase::setFileName2Save(string FileName)
|
||||
{
|
||||
m_FileName2Save = FileName;
|
||||
m_FileSavedCounter = 1;
|
||||
m_FileSavedCounter = 0;
|
||||
}
|
||||
|
||||
void ImagerOperationBase::setFocusControlState(bool FocusControlState)
|
||||
@ -449,6 +449,11 @@ void ImagerOperationBase::setRecordControlState(bool RecordControlState)
|
||||
m_bRecordControlState = RecordControlState;
|
||||
}
|
||||
|
||||
void ImagerOperationBase::stop_record()
|
||||
{
|
||||
m_bRecordControlState = false;
|
||||
}
|
||||
|
||||
int ImagerOperationBase::getFrameCounter() const
|
||||
{
|
||||
return m_iFrameCounter;
|
||||
|
@ -94,12 +94,13 @@ public slots:
|
||||
virtual double auto_exposure();
|
||||
virtual void focus();
|
||||
virtual void start_record();
|
||||
void stop_record();
|
||||
virtual void record_dark();
|
||||
virtual void record_white();
|
||||
|
||||
void getFocusIndexSobel();
|
||||
signals:
|
||||
void PlotSignal(int);//<2F><><EFBFBD><EFBFBD>Ӱ<EFBFBD><D3B0><EFBFBD>źţ<C5BA>-1<EFBFBD><EFBFBD><EFBFBD>˴βɼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD>
|
||||
void PlotSignal(int, int);//<2F><><EFBFBD><EFBFBD>Ӱ<EFBFBD><D3B0><EFBFBD>źţ<C5BA><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڼ<EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD>ڶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡<EFBFBD><EFBFBD><EFBFBD><EFBFBD>-1<><31><EFBFBD><EFBFBD><EFBFBD>˴βɼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD>
|
||||
void RecordFinishedSignal_WhenFrameNumberMeet();//<2F>ɼ<EFBFBD><C9BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>źţ<C5BA><C5A3><EFBFBD>Ҫ<EFBFBD>ɼ<EFBFBD><C9BC><EFBFBD><EFBFBD><EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD>m_iFrameNumber<65><72><EFBFBD>ɼ<EFBFBD><C9BC><EFBFBD><EFBFBD><EFBFBD>
|
||||
void RecordFinishedSignal_WhenFrameNumberNotMeet();//<2F>ɼ<EFBFBD><C9BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>źţ<C5BA><C5A3><EFBFBD>Ҫ<EFBFBD>ɼ<EFBFBD><C9BC><EFBFBD><EFBFBD><EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD>m_iFrameNumber<65><72>û<EFBFBD>вɼ<D0B2><C9BC><EFBFBD><EFBFBD>ɣ<EFBFBD><C9A3><EFBFBD>;ֹͣ<CDA3>ɼ<EFBFBD>
|
||||
void SpectralSignal(int);//<2F><><EFBFBD><EFBFBD>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƹ<EFBFBD><C6B9>ף<EFBFBD><D7A3><EFBFBD><EFBFBD><EFBFBD>0<EFBFBD><30>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɣ<EFBFBD>
|
||||
|
@ -353,7 +353,7 @@ void ResononNirImager::start_record()
|
||||
//ÿ<><C3BF>1s<31><73><EFBFBD><EFBFBD>һ<EFBFBD>ν<EFBFBD><CEBD><EFBFBD>ͼ<EFBFBD>λ<EFBFBD><CEBB><EFBFBD>
|
||||
if (m_iFrameCounter % (int)getFramerate() == 0)
|
||||
{
|
||||
emit PlotSignal(m_iFrameCounter);
|
||||
emit PlotSignal(m_FileSavedCounter, m_iFrameCounter);
|
||||
}
|
||||
|
||||
if (m_iFrameCounter >= m_iFrameNumber)
|
||||
@ -365,14 +365,14 @@ void ResononNirImager::start_record()
|
||||
}
|
||||
imagerStopCollect();
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>λ<EFBFBD>ͼǰ<CDBC><C7B0>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
//m_RgbImage
|
||||
emit PlotSignal(m_FileSavedCounter, -1);//<2F>ɼ<EFBFBD><C9BC><EFBFBD><EFBFBD>ɺ<EFBFBD><C9BA><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>λ<EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>Է<EFBFBD><D4B7>ɼ<EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡<EFBFBD>ʵı<CAB5><C4B1><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>ȫ
|
||||
|
||||
m_bRecordControlState = false;
|
||||
WriteHdr();
|
||||
m_FileSavedCounter++;
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>λ<EFBFBD>ͼǰ<CDBC><C7B0>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
//m_RgbImage
|
||||
emit PlotSignal(-1);//<2F>ɼ<EFBFBD><C9BC><EFBFBD><EFBFBD>ɺ<EFBFBD><C9BA><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>λ<EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>Է<EFBFBD><D4B7>ɼ<EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡<EFBFBD>ʵı<CAB5><C4B1><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>ȫ
|
||||
|
||||
if (m_iFrameCounter >= m_iFrameNumber)
|
||||
{
|
||||
emit RecordFinishedSignal_WhenFrameNumberMeet();
|
||||
|
581
HPPA/TwoMotorControl.cpp
Normal file
581
HPPA/TwoMotorControl.cpp
Normal file
@ -0,0 +1,581 @@
|
||||
#include "TwoMotorControl.h"
|
||||
|
||||
TwoMotorControl::TwoMotorControl(QWidget* parent) : QDialog(parent)
|
||||
{
|
||||
ui.setupUi(this);
|
||||
|
||||
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);//去除左边默认自带序列号
|
||||
|
||||
connect(this->ui.connect_btn, SIGNAL(pressed()), this, SLOT(onConnectMotor()));
|
||||
|
||||
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()));
|
||||
|
||||
connect(ui.run_btn, SIGNAL(clicked()), this, SLOT(run()));
|
||||
connect(ui.stop_btn, SIGNAL(clicked()), this, SLOT(stop()));
|
||||
}
|
||||
|
||||
void TwoMotorControl::setImager(ImagerOperationBase* imager)
|
||||
{
|
||||
m_Imager = imager;
|
||||
}
|
||||
|
||||
void TwoMotorControl::setPosFileName(QString posFileName)
|
||||
{
|
||||
isWritePosFile = true;
|
||||
m_posFileName = posFileName;
|
||||
m_posFileHandle = fopen(posFileName.toStdString().c_str(), "w+");
|
||||
}
|
||||
|
||||
bool TwoMotorControl::getState()
|
||||
{
|
||||
QEventLoop loop;
|
||||
bool tmp = false;
|
||||
bool received = false;
|
||||
|
||||
QTimer timer;
|
||||
timer.setSingleShot(true);
|
||||
connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);
|
||||
|
||||
QMetaObject::Connection conn = QObject::connect(
|
||||
m_coordinator, &TwoMotionCaptureCoordinator::recordState,
|
||||
[&](bool state) {
|
||||
tmp = state;
|
||||
received = true;
|
||||
loop.quit();
|
||||
});
|
||||
|
||||
QMetaObject::invokeMethod(m_coordinator, "getRecordState", Qt::QueuedConnection);
|
||||
timer.start(3000);
|
||||
|
||||
loop.exec();
|
||||
|
||||
disconnect(conn);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void TwoMotorControl::run()
|
||||
{
|
||||
if (m_coordinator==nullptr)
|
||||
{
|
||||
qRegisterMetaType<QVector<PathLine>>("QVector<PathLine>");
|
||||
m_coordinator = new TwoMotionCaptureCoordinator(m_multiAxisController, m_Imager);
|
||||
m_coordinator->moveToThread(&m_coordinatorThread);
|
||||
connect(&m_coordinatorThread, SIGNAL(finished()), m_coordinator, SLOT(deleteLater()));
|
||||
connect(this, SIGNAL(start(QVector<PathLine>)), m_coordinator, SLOT(start(QVector<PathLine>)));
|
||||
connect(this, SIGNAL(stopSignal()), m_coordinator, SLOT(stop()));
|
||||
connect(m_coordinator, SIGNAL(startRecordLineNumSignal(int)), this, SLOT(receiveStartRecordLineNum(int)));
|
||||
connect(m_coordinator, SIGNAL(finishRecordLineNumSignal(int)), this, SLOT(receiveFinishRecordLineNum(int)));
|
||||
connect(m_coordinator, SIGNAL(sequenceComplete(int)), this, SLOT(onSequenceComplete()));
|
||||
m_coordinatorThread.start();
|
||||
}
|
||||
|
||||
if (getState())
|
||||
{
|
||||
//std::cout << "已经开始运行,请勿重复点击!!!!!!!!" << std::endl;
|
||||
QMessageBox::information(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("已经开始运行,请勿重复点击!!!!!!!!!"));
|
||||
return;
|
||||
}
|
||||
|
||||
QVector<PathLine> pathLines;
|
||||
int rowCount = ui.recordLine_tableWidget->rowCount();
|
||||
//int columnCount = ui.recordLine_tableWidget->columnCount();
|
||||
for (size_t i = 0; i < rowCount; i++)
|
||||
{
|
||||
PathLine tmp;
|
||||
|
||||
tmp.targetYPosition = ui.recordLine_tableWidget->item(i, 0)->text().toDouble();
|
||||
tmp.speedTargetYPosition = ui.recordLine_tableWidget->item(i, 1)->text().toDouble();
|
||||
tmp.targetXMinPosition = ui.recordLine_tableWidget->item(i, 2)->text().toDouble();
|
||||
tmp.speedTargetXMinPosition = ui.recordLine_tableWidget->item(i, 3)->text().toDouble();
|
||||
tmp.targetXMaxPosition = ui.recordLine_tableWidget->item(i, 4)->text().toDouble();
|
||||
tmp.speedTargetXMaxPosition = ui.recordLine_tableWidget->item(i, 5)->text().toDouble();
|
||||
|
||||
pathLines.append(tmp);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
emit start(pathLines);
|
||||
}
|
||||
|
||||
void TwoMotorControl::stop()
|
||||
{
|
||||
emit stopSignal();
|
||||
}
|
||||
|
||||
TwoMotorControl::~TwoMotorControl()
|
||||
{
|
||||
m_motorThread.quit();
|
||||
m_motorThread.wait();
|
||||
|
||||
m_coordinatorThread.quit();
|
||||
m_coordinatorThread.wait();
|
||||
}
|
||||
|
||||
void TwoMotorControl::onConnectMotor()
|
||||
{
|
||||
try
|
||||
{
|
||||
FileOperation* fileOperation = new FileOperation();
|
||||
string directory = fileOperation->getDirectoryOfExe();
|
||||
QString configFilePath = QString::fromStdString(directory) + "\\twoMotorConfigFile.cfg";
|
||||
|
||||
m_multiAxisController = new IrisMultiMotorController(configFilePath);
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText(QString::fromLocal8Bit("请连接马达!"));
|
||||
msgBox.exec();
|
||||
}
|
||||
|
||||
m_multiAxisController->moveToThread(&m_motorThread);
|
||||
connect(&m_motorThread, SIGNAL(finished()), m_multiAxisController, SLOT(deleteLater()));
|
||||
|
||||
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.xmotor_left_btn, SIGNAL(pressed()), this, SLOT(onxMotorLeft()));
|
||||
connect(this->ui.xmotor_left_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()));
|
||||
|
||||
//connect(this->ui.move2loc_pushButton, SIGNAL(pressed()), this, SLOT(onxMove2Loc()));
|
||||
|
||||
connect(m_multiAxisController, SIGNAL(broadcastLocationSignal(std::vector<double>)), this, SLOT(displayRealTimeLoc(std::vector<double>)));
|
||||
|
||||
connect(this, SIGNAL(moveSignal(int, bool, double, int)), m_multiAxisController, SLOT(move(int, bool, double, int)));
|
||||
//connect(this, SIGNAL(move2LocSignal(int, double, double, int)), m_multiAxisController, SLOT(moveTo(int, double, double, int)));
|
||||
connect(this, SIGNAL(stopSignal(int)), m_multiAxisController, SLOT(stop(int)));
|
||||
|
||||
connect(this->ui.zero_start_btn, SIGNAL(released()), this, SLOT(zeroStart()));
|
||||
connect(this, SIGNAL(zeroStartSignal(int)), m_multiAxisController, SLOT(zeroStart(int)));
|
||||
|
||||
connect(this->ui.rangeMeasurement_btn, SIGNAL(pressed()), this, SLOT(on_rangeMeasurement()));
|
||||
connect(this, SIGNAL(rangeMeasurement(int, double, int)), m_multiAxisController, SLOT(rangeMeasurement(int, double, int)));
|
||||
|
||||
connect(this, SIGNAL(testConnectivitySignal(int, int)), m_multiAxisController, SLOT(testConnectivity(int, int)));
|
||||
connect(m_multiAxisController, SIGNAL(broadcastConnectivity(std::vector<int>)), this, SLOT(display_motors_connectivity(std::vector<int>)));
|
||||
|
||||
m_motorThread.start();
|
||||
emit testConnectivitySignal(0, 1000);
|
||||
emit testConnectivitySignal(1, 1000);
|
||||
}
|
||||
|
||||
void TwoMotorControl::receiveStartRecordLineNum(int lineNum)
|
||||
{
|
||||
emit startLineNumSignal(lineNum);
|
||||
for (size_t i = 0; i < ui.recordLine_tableWidget->columnCount(); i++)
|
||||
{
|
||||
ui.recordLine_tableWidget->item(lineNum, i)->setBackgroundColor(QColor(255, 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void TwoMotorControl::receiveFinishRecordLineNum(int lineNum)
|
||||
{
|
||||
for (size_t i = 0; i < ui.recordLine_tableWidget->columnCount(); i++)
|
||||
{
|
||||
ui.recordLine_tableWidget->item(lineNum, i)->setBackgroundColor(QColor(0, 255, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void TwoMotorControl::onSequenceComplete()
|
||||
{
|
||||
isWritePosFile = false;
|
||||
fclose(m_posFileHandle);
|
||||
|
||||
emit sequenceComplete();
|
||||
}
|
||||
|
||||
void TwoMotorControl::display_motors_connectivity(std::vector<int> connectivity)
|
||||
{
|
||||
//std::cout << "-----------------------------------"<<connectivity.size()<< std::endl;
|
||||
if (connectivity[0])
|
||||
{
|
||||
this->ui.xMotorStateLabel->setStyleSheet("QLabel{background-color:rgb(0,255,0);}");
|
||||
}
|
||||
else
|
||||
{
|
||||
this->ui.xMotorStateLabel->setStyleSheet("QLabel{background-color:rgb(255,0,0);}");
|
||||
}
|
||||
|
||||
if (connectivity[1])
|
||||
{
|
||||
this->ui.yMotorStateLabel->setStyleSheet("QLabel{background-color:rgb(0,255,0);}");
|
||||
}
|
||||
else
|
||||
{
|
||||
this->ui.yMotorStateLabel->setStyleSheet("QLabel{background-color:rgb(255,0,0);}");
|
||||
}
|
||||
}
|
||||
|
||||
void TwoMotorControl::onxMotorRight()
|
||||
{
|
||||
double s = ui.xmotor_move_speed_lineEdit->text().toDouble();
|
||||
|
||||
emit moveSignal(0, false, s, 1000);
|
||||
}
|
||||
|
||||
void TwoMotorControl::onxMotorLeft()
|
||||
{
|
||||
double s = ui.xmotor_move_speed_lineEdit->text().toDouble();
|
||||
|
||||
emit moveSignal(0, true, s, 1000);
|
||||
}
|
||||
|
||||
void TwoMotorControl::onxMotorStop()
|
||||
{
|
||||
emit stopSignal(0);
|
||||
}
|
||||
|
||||
void TwoMotorControl::onyMotorforward()
|
||||
{
|
||||
double s = ui.ymotor_move_speed_lineEdit->text().toDouble();
|
||||
|
||||
emit moveSignal(1, false, s, 1000);
|
||||
}
|
||||
|
||||
void TwoMotorControl::onyMotorbackward()
|
||||
{
|
||||
double s = ui.ymotor_move_speed_lineEdit->text().toDouble();
|
||||
|
||||
emit moveSignal(1, true, s, 1000);
|
||||
}
|
||||
|
||||
void TwoMotorControl::onyMotorStop()
|
||||
{
|
||||
emit stopSignal(1);
|
||||
}
|
||||
|
||||
void TwoMotorControl::displayRealTimeLoc(std::vector<double> loc)
|
||||
{
|
||||
double tmp = round(loc[0] * 100) / 100;
|
||||
if (isWritePosFile)
|
||||
{
|
||||
long long timeOs = getNanosecondsSinceMidnight();
|
||||
fprintf(m_posFileHandle, "%lld,%f\n", timeOs, loc[0]);
|
||||
}
|
||||
this->ui.xmotor_realTimeLoc_lineEdit->setText(QString::number(tmp));
|
||||
|
||||
tmp = round(loc[1] * 100) / 100;
|
||||
this->ui.ymotor_realTimeLoc_lineEdit->setText(QString::number(tmp));
|
||||
}
|
||||
|
||||
void TwoMotorControl::zeroStart()
|
||||
{
|
||||
zeroStartSignal(0);
|
||||
zeroStartSignal(1);
|
||||
}
|
||||
|
||||
void TwoMotorControl::on_rangeMeasurement()
|
||||
{
|
||||
double s0 = ui.xmotor_move_speed_lineEdit->text().toDouble();
|
||||
emit rangeMeasurement(0, s0, 1000);
|
||||
|
||||
s0 = ui.ymotor_move_speed_lineEdit->text().toDouble();
|
||||
emit rangeMeasurement(1, s0, 1000);
|
||||
}
|
||||
|
||||
void TwoMotorControl::onAddRecordLine_btn()
|
||||
{
|
||||
//准备数据:获取y马达的当前位置,获取x马达的当前位置和最大位置
|
||||
double currentPosOfYmotor = 15;
|
||||
|
||||
double currentPosOfXmotor = 0;
|
||||
double maxRangeOfXmotor = 50;
|
||||
|
||||
//获取选中行的索引
|
||||
int currentRow = ui.recordLine_tableWidget->currentRow();
|
||||
std::cout << "currentRow:" << currentRow << std::endl;
|
||||
|
||||
QTableWidgetItem* Item1 = new QTableWidgetItem(QString::number(currentPosOfYmotor, 10, 2));
|
||||
QTableWidgetItem* Item2 = new QTableWidgetItem(QString::number(1, 10, 2));
|
||||
QTableWidgetItem* Item3 = new QTableWidgetItem(QString::number(currentPosOfXmotor, 10, 2));
|
||||
QTableWidgetItem* Item4 = new QTableWidgetItem(QString::number(1, 10, 2));
|
||||
QTableWidgetItem* Item5 = new QTableWidgetItem(QString::number(maxRangeOfXmotor, 10, 2));
|
||||
QTableWidgetItem* Item6 = new QTableWidgetItem(QString::number(1, 10, 2));
|
||||
Item1->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
Item2->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
Item3->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
Item4->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
Item5->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
Item6->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
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, Item1);
|
||||
ui.recordLine_tableWidget->setItem(RowCount, 1, Item2);
|
||||
ui.recordLine_tableWidget->setItem(RowCount, 2, Item3);
|
||||
ui.recordLine_tableWidget->setItem(RowCount, 3, Item4);
|
||||
ui.recordLine_tableWidget->setItem(RowCount, 4, Item5);
|
||||
ui.recordLine_tableWidget->setItem(RowCount, 5, Item6);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui.recordLine_tableWidget->insertRow(currentRow + 1);//增加一行,形参是从0开始的
|
||||
|
||||
ui.recordLine_tableWidget->setItem(currentRow + 1, 0, Item1);
|
||||
ui.recordLine_tableWidget->setItem(currentRow + 1, 1, Item2);
|
||||
ui.recordLine_tableWidget->setItem(currentRow + 1, 2, Item3);
|
||||
ui.recordLine_tableWidget->setItem(currentRow + 1, 3, Item4);
|
||||
ui.recordLine_tableWidget->setItem(currentRow + 1, 4, Item5);
|
||||
ui.recordLine_tableWidget->setItem(currentRow + 1, 5, Item6);
|
||||
}
|
||||
}
|
||||
|
||||
void TwoMotorControl::onRemoveRecordLine_btn()
|
||||
{
|
||||
int rowIndex = ui.recordLine_tableWidget->currentRow();
|
||||
if (rowIndex != -1)
|
||||
ui.recordLine_tableWidget->removeRow(rowIndex);
|
||||
}
|
||||
|
||||
void TwoMotorControl::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 = 50;
|
||||
double yMotorRange = 500;
|
||||
|
||||
|
||||
//确定有多少条采集线,公式: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添加行(采集线)
|
||||
QTableWidgetItem* tmpItem;
|
||||
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
|
||||
{
|
||||
tmpItem = new QTableWidgetItem(QString::number(yMotorRange, 10, 2));
|
||||
tmpItem->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
ui.recordLine_tableWidget->setItem(i, 0, tmpItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
double x = swath * i - i * repetitiveLength + offset;
|
||||
tmpItem = new QTableWidgetItem(QString::number(x, 10, 2));
|
||||
tmpItem->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
ui.recordLine_tableWidget->setItem(i, 0, tmpItem);
|
||||
}
|
||||
tmpItem = new QTableWidgetItem(QString::number(1, 10, 2));
|
||||
tmpItem->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
ui.recordLine_tableWidget->setItem(i, 1, tmpItem);
|
||||
|
||||
tmpItem = new QTableWidgetItem(QString::number(0, 10, 2));
|
||||
tmpItem->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
ui.recordLine_tableWidget->setItem(i, 2, tmpItem);
|
||||
tmpItem = new QTableWidgetItem(QString::number(1, 10, 2));
|
||||
tmpItem->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
ui.recordLine_tableWidget->setItem(i, 3, tmpItem);
|
||||
|
||||
//设置x马达最大运动位置 → 值设置为x马达量程
|
||||
tmpItem = new QTableWidgetItem(QString::number(xMotorRange, 10, 2));
|
||||
tmpItem->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
ui.recordLine_tableWidget->setItem(i, 4, tmpItem);
|
||||
tmpItem = new QTableWidgetItem(QString::number(1, 10, 2));
|
||||
tmpItem->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
ui.recordLine_tableWidget->setItem(i, 5, tmpItem);
|
||||
}
|
||||
}
|
||||
|
||||
void TwoMotorControl::onDeleteRecordLine_btn()
|
||||
{
|
||||
int rowCount = ui.recordLine_tableWidget->rowCount();
|
||||
for (size_t i = 0; i < rowCount; i++)
|
||||
{
|
||||
ui.recordLine_tableWidget->removeRow(0);
|
||||
}
|
||||
}
|
||||
|
||||
void TwoMotorControl::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 RecordLine2 File"),
|
||||
QString::fromStdString(directory),
|
||||
tr("RecordLineFile2 (*.RecordLine2)"));
|
||||
|
||||
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 TwoMotorControl::onReadRecordLineFile_btn()
|
||||
{
|
||||
//打开文件
|
||||
FileOperation* fileOperation = new FileOperation();
|
||||
string directory = fileOperation->getDirectoryOfExe();
|
||||
|
||||
QString RecordLineFilePath = QFileDialog::getOpenFileName(this, tr("Open RecordLine2 File"),
|
||||
QString::fromStdString(directory),
|
||||
tr("RecordLineFile (*.RecordLine2)"));
|
||||
|
||||
if (RecordLineFilePath.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FILE* RecordLineFileHandle = fopen(RecordLineFilePath.toStdString().c_str(), "rb");
|
||||
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++)
|
||||
{
|
||||
QTableWidgetItem* tmp = new QTableWidgetItem(QString::number(data[i * ui.recordLine_tableWidget->columnCount() + j], 10, 5));
|
||||
tmp->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
ui.recordLine_tableWidget->setItem(i, j, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(RecordLineFileHandle);
|
||||
delete[] data;
|
||||
|
||||
QMessageBox::information(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("读取成功!"));
|
||||
}
|
89
HPPA/TwoMotorControl.h
Normal file
89
HPPA/TwoMotorControl.h
Normal file
@ -0,0 +1,89 @@
|
||||
#pragma once
|
||||
#include <QThread>
|
||||
#include <QMessageBox>
|
||||
#include <QFileDialog>
|
||||
|
||||
#include "ui_twoMotorControl.h"
|
||||
|
||||
#include "IrisMultiMotorController.h"
|
||||
#include "fileOperation.h"
|
||||
#include "CaptureCoordinator.h"
|
||||
|
||||
#define PI 3.1415926
|
||||
|
||||
|
||||
|
||||
class TwoMotorControl : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TwoMotorControl(QWidget* parent = nullptr);
|
||||
~TwoMotorControl();
|
||||
|
||||
void setImager(ImagerOperationBase* imager);
|
||||
void setPosFileName(QString posFileName);
|
||||
|
||||
private:
|
||||
ImagerOperationBase* m_Imager;
|
||||
bool getState();
|
||||
|
||||
bool isWritePosFile = false;
|
||||
QString m_posFileName;
|
||||
FILE* m_posFileHandle;
|
||||
|
||||
|
||||
public Q_SLOTS:
|
||||
void onConnectMotor();
|
||||
|
||||
void displayRealTimeLoc(std::vector<double> loc);
|
||||
void display_motors_connectivity(std::vector<int> connectivity);
|
||||
//void onxMove2Loc();
|
||||
void zeroStart();
|
||||
void on_rangeMeasurement();
|
||||
|
||||
void onxMotorRight();
|
||||
void onxMotorLeft();
|
||||
void onxMotorStop();
|
||||
|
||||
void onyMotorforward();
|
||||
void onyMotorbackward();
|
||||
void onyMotorStop();
|
||||
|
||||
void onAddRecordLine_btn();
|
||||
void onRemoveRecordLine_btn();
|
||||
void onGenerateRecordLine_btn();
|
||||
void onDeleteRecordLine_btn();
|
||||
void onSaveRecordLine2File_btn();
|
||||
void onReadRecordLineFile_btn();
|
||||
|
||||
void run();
|
||||
void stop();
|
||||
void receiveStartRecordLineNum(int lineNum);
|
||||
void receiveFinishRecordLineNum(int lineNum);
|
||||
void onSequenceComplete();
|
||||
|
||||
signals:
|
||||
void moveSignal(int, bool, double, int);
|
||||
void move2LocSignal(int, double, double, int);
|
||||
void move2LocSignal(const std::vector<double>, const std::vector<double>, int);
|
||||
void stopSignal(int);
|
||||
|
||||
void rangeMeasurement(int, double, int);
|
||||
void zeroStartSignal(int);
|
||||
void testConnectivitySignal(int, int);
|
||||
|
||||
void start(QVector<PathLine>);
|
||||
void stopSignal();
|
||||
|
||||
void startLineNumSignal(int lineNum);
|
||||
void sequenceComplete();//所有采集线正常运行完成
|
||||
|
||||
private:
|
||||
Ui::twoMotorControl_UI ui;
|
||||
QThread m_coordinatorThread;
|
||||
TwoMotionCaptureCoordinator* m_coordinator = nullptr;
|
||||
|
||||
QThread m_motorThread;
|
||||
IrisMultiMotorController* m_multiAxisController;
|
||||
};
|
1010
HPPA/twoMotorControl.ui
Normal file
1010
HPPA/twoMotorControl.ui
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user