Compare commits
8 Commits
3521a7f225
...
8329c00165
| Author | SHA1 | Date | |
|---|---|---|---|
| 8329c00165 | |||
| f69edcf2c9 | |||
| 509f4b0767 | |||
| 4a62d9a007 | |||
| 467bebe9dd | |||
| 41a1a938b9 | |||
| 3607913f13 | |||
| a8760652bd |
@ -6,6 +6,7 @@ TwoMotionCaptureCoordinator::TwoMotionCaptureCoordinator(
|
|||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_motorCtrl(motorCtrl)
|
, m_motorCtrl(motorCtrl)
|
||||||
, m_isRunning(false)
|
, m_isRunning(false)
|
||||||
|
, m_isValidCapturing(false)
|
||||||
{
|
{
|
||||||
//这些信号槽是按照逻辑顺序的
|
//这些信号槽是按照逻辑顺序的
|
||||||
connect(this, SIGNAL(moveTo(int, double, double, int)),
|
connect(this, SIGNAL(moveTo(int, double, double, int)),
|
||||||
@ -86,6 +87,7 @@ void TwoMotionCaptureCoordinator::getLocBeforeStart()
|
|||||||
QMetaObject::Connection conn = QObject::connect(m_motorCtrl, &IrisMultiMotorController::locationSignal,
|
QMetaObject::Connection conn = QObject::connect(m_motorCtrl, &IrisMultiMotorController::locationSignal,
|
||||||
[&](std::vector<double> pos) {
|
[&](std::vector<double> pos) {
|
||||||
m_locBeforeStart = pos;
|
m_locBeforeStart = pos;
|
||||||
|
std::cout << "start pos: "<< pos[0] <<", " << pos[1] << std::endl;
|
||||||
received = true;
|
received = true;
|
||||||
loop.quit();
|
loop.quit();
|
||||||
});
|
});
|
||||||
@ -113,7 +115,7 @@ void TwoMotionCaptureCoordinator::move2LocBeforeStart()
|
|||||||
speed.push_back(tmp.speedTargetYPosition);
|
speed.push_back(tmp.speedTargetYPosition);
|
||||||
emit moveTo(m_locBeforeStart, speed, 1000);
|
emit moveTo(m_locBeforeStart, speed, 1000);
|
||||||
|
|
||||||
m_isRunning = false;
|
m_isValidCapturing = false;
|
||||||
|
|
||||||
m_isMoving2XMin = false;
|
m_isMoving2XMin = false;
|
||||||
m_isMoving2XMax = false;
|
m_isMoving2XMax = false;
|
||||||
@ -195,12 +197,12 @@ void TwoMotionCaptureCoordinator::handlePositionReached(int motorID, double pos)
|
|||||||
|
|
||||||
//QMutexLocker locker(&m_dataMutex);
|
//QMutexLocker locker(&m_dataMutex);
|
||||||
|
|
||||||
PathLine &tmp = m_pathLines[m_numCurrentPathLine];
|
|
||||||
|
|
||||||
if (motorID == 1)//y马达
|
if (motorID == 1)//y马达
|
||||||
{
|
{
|
||||||
if (m_isMoving2YTargeLoc)
|
if (m_isMoving2YTargeLoc)
|
||||||
{
|
{
|
||||||
|
PathLine& tmp = m_pathLines[m_numCurrentPathLine];
|
||||||
|
|
||||||
double threshold = getThre(tmp.targetYPosition, pos);
|
double threshold = getThre(tmp.targetYPosition, pos);
|
||||||
|
|
||||||
if (threshold > 5)
|
if (threshold > 5)
|
||||||
@ -230,6 +232,7 @@ void TwoMotionCaptureCoordinator::handlePositionReached(int motorID, double pos)
|
|||||||
if (m_isMoving2YStartLoc)
|
if (m_isMoving2YStartLoc)
|
||||||
{
|
{
|
||||||
m_isMoving2YStartLoc = false;
|
m_isMoving2YStartLoc = false;
|
||||||
|
isBack2Origin();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -238,6 +241,8 @@ void TwoMotionCaptureCoordinator::handlePositionReached(int motorID, double pos)
|
|||||||
{
|
{
|
||||||
if (m_isMoving2XMin)
|
if (m_isMoving2XMin)
|
||||||
{
|
{
|
||||||
|
PathLine& tmp = m_pathLines[m_numCurrentPathLine];
|
||||||
|
|
||||||
double threshold = getThre(tmp.targetXMinPosition, pos);
|
double threshold = getThre(tmp.targetXMinPosition, pos);
|
||||||
|
|
||||||
if (threshold > 5)
|
if (threshold > 5)
|
||||||
@ -266,6 +271,8 @@ void TwoMotionCaptureCoordinator::handlePositionReached(int motorID, double pos)
|
|||||||
|
|
||||||
if (m_isMoving2XMax)
|
if (m_isMoving2XMax)
|
||||||
{
|
{
|
||||||
|
PathLine& tmp = m_pathLines[m_numCurrentPathLine];
|
||||||
|
|
||||||
double threshold = getThre(tmp.targetXMaxPosition, pos);
|
double threshold = getThre(tmp.targetXMaxPosition, pos);
|
||||||
|
|
||||||
if (threshold > 5 && !m_isImagerFrameNumberMeet)//马达没到准确位置 && 【非】光谱仪因帧数限制主动停止采集
|
if (threshold > 5 && !m_isImagerFrameNumberMeet)//马达没到准确位置 && 【非】光谱仪因帧数限制主动停止采集
|
||||||
@ -302,6 +309,7 @@ void TwoMotionCaptureCoordinator::handlePositionReached(int motorID, double pos)
|
|||||||
if (m_isMoving2XStartLoc)
|
if (m_isMoving2XStartLoc)
|
||||||
{
|
{
|
||||||
m_isMoving2XStartLoc = false;
|
m_isMoving2XStartLoc = false;
|
||||||
|
isBack2Origin();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -341,9 +349,25 @@ void TwoMotionCaptureCoordinator::startRecordHsi()
|
|||||||
emit moveTo(0, tmp.targetXMaxPosition, tmp.speedTargetXMaxPosition, 1000);
|
emit moveTo(0, tmp.targetXMaxPosition, tmp.speedTargetXMaxPosition, 1000);
|
||||||
|
|
||||||
emit startRecordHSISignal(m_numCurrentPathLine);
|
emit startRecordHSISignal(m_numCurrentPathLine);
|
||||||
|
emit startRecordLineNumSignal(m_numCurrentPathLine);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TwoMotionCaptureCoordinator::isBack2Origin()
|
||||||
|
{
|
||||||
|
if (!m_isRunning) return;
|
||||||
|
|
||||||
|
//QMutexLocker locker(&m_dataMutex);
|
||||||
|
|
||||||
|
if (!m_isMoving2XStartLoc && !m_isMoving2YStartLoc)
|
||||||
|
{
|
||||||
|
m_isRunning = false;
|
||||||
|
|
||||||
|
emit back2OriginSignal();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void TwoMotionCaptureCoordinator::handleCaptureCompleteWhenFrameNumberMeet()
|
void TwoMotionCaptureCoordinator::handleCaptureCompleteWhenFrameNumberMeet()
|
||||||
{
|
{
|
||||||
m_isImagerFrameNumberMeet = true;
|
m_isImagerFrameNumberMeet = true;
|
||||||
@ -387,7 +411,8 @@ void TwoMotionCaptureCoordinator::processNextPathLine()
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "\nNew path line: " << m_numCurrentPathLine << std::endl;
|
std::cout << "\nNew path line: " << m_numCurrentPathLine << std::endl;
|
||||||
emit startRecordLineNumSignal(m_numCurrentPathLine);
|
emit gotoRecordLineNumSignal(m_numCurrentPathLine);
|
||||||
|
m_isValidCapturing = true;
|
||||||
|
|
||||||
PathLine &tmp = m_pathLines[m_numCurrentPathLine];
|
PathLine &tmp = m_pathLines[m_numCurrentPathLine];
|
||||||
tmp.timestamp1 = QDateTime::currentDateTime();
|
tmp.timestamp1 = QDateTime::currentDateTime();
|
||||||
|
|||||||
@ -46,6 +46,8 @@ public:
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
void sequenceComplete(int);//0:所有采集线正常运行完成,1:用户主动取消采集
|
void sequenceComplete(int);//0:所有采集线正常运行完成,1:用户主动取消采集
|
||||||
|
void back2OriginSignal();
|
||||||
|
void gotoRecordLineNumSignal(int lineNum);
|
||||||
void startRecordLineNumSignal(int lineNum);
|
void startRecordLineNumSignal(int lineNum);
|
||||||
void finishRecordLineNumSignal(int lineNum);
|
void finishRecordLineNumSignal(int lineNum);
|
||||||
|
|
||||||
@ -75,6 +77,7 @@ private slots:
|
|||||||
private:
|
private:
|
||||||
void processNextPathLine();
|
void processNextPathLine();
|
||||||
void startRecordHsi();
|
void startRecordHsi();
|
||||||
|
void isBack2Origin();
|
||||||
void getLocBeforeStart();
|
void getLocBeforeStart();
|
||||||
double getThre(double targetLoc, double actualLoc);
|
double getThre(double targetLoc, double actualLoc);
|
||||||
|
|
||||||
@ -87,6 +90,7 @@ private:
|
|||||||
mutable QMutex m_dataMutex;
|
mutable QMutex m_dataMutex;
|
||||||
|
|
||||||
bool m_isRunning;
|
bool m_isRunning;
|
||||||
|
bool m_isValidCapturing;
|
||||||
bool m_isMoving2YTargeLoc;
|
bool m_isMoving2YTargeLoc;
|
||||||
bool m_isMoving2XMin;
|
bool m_isMoving2XMin;
|
||||||
bool m_isMoving2XMax;
|
bool m_isMoving2XMax;
|
||||||
|
|||||||
14
HPPA/CommunicationInterfaceBase.cpp
Normal file
14
HPPA/CommunicationInterfaceBase.cpp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include "CommunicationInterfaceBase.h"
|
||||||
|
|
||||||
|
using namespace MotorParams;
|
||||||
|
|
||||||
|
CommunicationInterfaceBase::CommunicationInterfaceBase(QObject* parent)
|
||||||
|
:QObject(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CommunicationInterfaceBase::~CommunicationInterfaceBase()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
36
HPPA/CommunicationInterfaceBase.h
Normal file
36
HPPA/CommunicationInterfaceBase.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <QObject>
|
||||||
|
#include <QString>
|
||||||
|
#include "motorParams.h"
|
||||||
|
|
||||||
|
namespace MotorParams {
|
||||||
|
|
||||||
|
struct TCPConnectionParams
|
||||||
|
{
|
||||||
|
QString serverIP;
|
||||||
|
int port;
|
||||||
|
};
|
||||||
|
class CommunicationInterfaceBase :public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
CommunicationInterfaceBase(QObject* parent = nullptr);
|
||||||
|
~CommunicationInterfaceBase();
|
||||||
|
|
||||||
|
virtual bool connect2Motor() = 0;
|
||||||
|
//virtual void disconnect() = 0;
|
||||||
|
//virtual bool isConnected() const = 0;
|
||||||
|
|
||||||
|
virtual int sendCommand(const QString command) = 0;
|
||||||
|
//virtual void sendCommandAsync(const QString& command) = 0;
|
||||||
|
virtual int recvData(QByteArray& dataRecv) = 0;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void dataReceived(const QByteArray& data);
|
||||||
|
|
||||||
|
void connected(); // <20><><EFBFBD>ܴ<EFBFBD><DCB4>ڻ<EFBFBD><DABB><EFBFBD>TCP<43><50><EFBFBD><EFBFBD><EFBFBD>ᷢ<EFBFBD><E1B7A2><EFBFBD><EFBFBD><EFBFBD>ź<EFBFBD>
|
||||||
|
void disconnected();
|
||||||
|
void errorOccurred(QString msg);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace MotorParams
|
||||||
95
HPPA/CommunicationViaTCP.cpp
Normal file
95
HPPA/CommunicationViaTCP.cpp
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
#include "CommunicationViaTCP.h"
|
||||||
|
|
||||||
|
using namespace MotorParams;
|
||||||
|
|
||||||
|
CommunicationViaTCP::CommunicationViaTCP(MotorParams::TCPConnectionParams connectionParams, QObject* parent)
|
||||||
|
:MotorParams::CommunicationInterfaceBase(parent)
|
||||||
|
{
|
||||||
|
m_bConnected = false;
|
||||||
|
m_tcpServer = new QTcpServer(this);
|
||||||
|
connect(m_tcpServer, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
|
||||||
|
|
||||||
|
m_tcpServer->listen(QHostAddress::Any, connectionParams.port);
|
||||||
|
}
|
||||||
|
|
||||||
|
CommunicationViaTCP::~CommunicationViaTCP()
|
||||||
|
{
|
||||||
|
m_tcpServer->close();
|
||||||
|
delete m_tcpServer;
|
||||||
|
|
||||||
|
//这两行代码要报错,为啥呢?????????????????
|
||||||
|
//m_tcpSocket->disconnectFromHost();
|
||||||
|
//delete m_tcpSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CommunicationViaTCP::connect2Motor()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CommunicationViaTCP::onNewConnection()
|
||||||
|
{
|
||||||
|
m_bConnected = true;
|
||||||
|
m_tcpSocket = m_tcpServer->nextPendingConnection();
|
||||||
|
connect(m_tcpSocket, SIGNAL(disconnected()), this, SLOT(onTcpSocketDisconnected()));
|
||||||
|
|
||||||
|
emit connected();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CommunicationViaTCP::isConnected() const
|
||||||
|
{
|
||||||
|
return m_bConnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
//从拔掉客户端的电源(客户端m_tcpSocket断开连接)到这个函数被调用有延迟,所以这个函数调用也有延迟,导致拔掉电源后的一小段时间函数isConnected()还是返回true
|
||||||
|
void CommunicationViaTCP::onTcpSocketDisconnected()
|
||||||
|
{
|
||||||
|
int a = 1;
|
||||||
|
m_bConnected = false;
|
||||||
|
m_tcpSocket->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
int CommunicationViaTCP::sendCommand(const QString cmd)
|
||||||
|
{
|
||||||
|
if (!isConnected()) {
|
||||||
|
QString error = "No client connected";
|
||||||
|
emit commandSendResult(-1, error);
|
||||||
|
qWarning() << error << "command:" << cmd;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 bytesWritten = m_tcpSocket->write(cmd.toUtf8().data());
|
||||||
|
m_tcpSocket->waitForBytesWritten(50);
|
||||||
|
|
||||||
|
return bytesWritten;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CommunicationViaTCP::recvData(QByteArray& dataRecv)
|
||||||
|
{
|
||||||
|
if (!isConnected()) {
|
||||||
|
QString error = "No client connected";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dataRecv.clear();
|
||||||
|
|
||||||
|
QByteArray temp;
|
||||||
|
|
||||||
|
temp = m_tcpSocket->readAll();
|
||||||
|
dataRecv.append(temp);
|
||||||
|
|
||||||
|
int counter = 0;
|
||||||
|
while (dataRecv.size() < 21)
|
||||||
|
{
|
||||||
|
counter++;
|
||||||
|
m_tcpSocket->waitForReadyRead(100);
|
||||||
|
temp = m_tcpSocket->readAll();
|
||||||
|
dataRecv.append(temp);
|
||||||
|
|
||||||
|
if (counter >= 5)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//qDebug() << "Hex:" << dataRecv.toHex();
|
||||||
|
|
||||||
|
return dataRecv.size();
|
||||||
|
}
|
||||||
45
HPPA/CommunicationViaTCP.h
Normal file
45
HPPA/CommunicationViaTCP.h
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <QObject>
|
||||||
|
#include <QThread>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QTcpServer>
|
||||||
|
#include <QTcpSocket>
|
||||||
|
|
||||||
|
#include "CommunicationInterfaceBase.h"
|
||||||
|
|
||||||
|
namespace MotorParams {
|
||||||
|
|
||||||
|
class CommunicationViaTCP :
|
||||||
|
public CommunicationInterfaceBase
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
CommunicationViaTCP(TCPConnectionParams connectionParams, QObject* parent = nullptr);
|
||||||
|
~CommunicationViaTCP();
|
||||||
|
|
||||||
|
//继承基类
|
||||||
|
bool connect2Motor();
|
||||||
|
//void disconnect();
|
||||||
|
//bool isConnected() const;
|
||||||
|
|
||||||
|
int sendCommand(const QString cmd);
|
||||||
|
//void sendCommandAsync(const QString& command);
|
||||||
|
int recvData(QByteArray& dataRecv);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QTcpServer* m_tcpServer;
|
||||||
|
QTcpSocket* m_tcpSocket;
|
||||||
|
int m_iCommunicationProtocol;
|
||||||
|
|
||||||
|
bool m_bConnected;
|
||||||
|
bool isConnected() const;
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void onNewConnection();
|
||||||
|
void onTcpSocketDisconnected();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void commandSendResult(int bytesWritten, const QString& error = QString());
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -41,11 +41,21 @@ void DepthCameraWindow::onSelectDataFolder()
|
|||||||
QString::fromLocal8Bit("选择数据保存路径"),
|
QString::fromLocal8Bit("选择数据保存路径"),
|
||||||
ui.dataFolderLineEdit->text());
|
ui.dataFolderLineEdit->text());
|
||||||
|
|
||||||
if (!dir.isEmpty())
|
setDataFolder(dir);
|
||||||
{
|
}
|
||||||
ui.dataFolderLineEdit->setText(dir);
|
|
||||||
AppSettings::instance().setDepthCameraDataFolder(dir);
|
void DepthCameraWindow::setDataFolder(QString dir)
|
||||||
}
|
{
|
||||||
|
if (!dir.isEmpty())
|
||||||
|
{
|
||||||
|
ui.dataFolderLineEdit->setText(dir);
|
||||||
|
AppSettings::instance().setDepthCameraDataFolder(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DepthCameraWindow::setCaptureInterval(int captureIntervalSeconds)
|
||||||
|
{
|
||||||
|
m_DepthCameraOperation->setCaptureInterval(captureIntervalSeconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DepthCameraWindow::openDepthCamera()
|
void DepthCameraWindow::openDepthCamera()
|
||||||
@ -83,6 +93,8 @@ DepthCameraOperation::DepthCameraOperation()
|
|||||||
m_pipe = nullptr;
|
m_pipe = nullptr;
|
||||||
m_func = nullptr;
|
m_func = nullptr;
|
||||||
record = false;
|
record = false;
|
||||||
|
|
||||||
|
m_captureIntervalMilliseconds = 3000;
|
||||||
}
|
}
|
||||||
|
|
||||||
DepthCameraOperation::~DepthCameraOperation()
|
DepthCameraOperation::~DepthCameraOperation()
|
||||||
@ -96,6 +108,11 @@ DepthCameraOperation::~DepthCameraOperation()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DepthCameraOperation::setCaptureInterval(int captureIntervalSeconds)
|
||||||
|
{
|
||||||
|
m_captureIntervalMilliseconds = captureIntervalSeconds * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
void DepthCameraOperation::OpenDepthCamera()
|
void DepthCameraOperation::OpenDepthCamera()
|
||||||
{
|
{
|
||||||
if (m_pipe)
|
if (m_pipe)
|
||||||
@ -142,14 +159,14 @@ void DepthCameraOperation::OpenDepthCamera()
|
|||||||
|
|
||||||
// Drop several frames
|
// Drop several frames
|
||||||
for (int i = 0; i < 15; ++i) {
|
for (int i = 0; i < 15; ++i) {
|
||||||
auto lost = m_pipe->waitForFrameset(100);
|
auto lost = m_pipe->waitForFrameset(m_captureIntervalMilliseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pointCloud = std::make_shared<ob::PointCloudFilter>();
|
auto pointCloud = std::make_shared<ob::PointCloudFilter>();
|
||||||
|
|
||||||
int frameIndex = 0;
|
int frameIndex = 0;
|
||||||
record = true;
|
record = true;
|
||||||
QString fileNamePrefix = AppSettings::instance().depthCameraDataFolder() + QDir::separator() + AppSettings::instance().fileName();
|
QString fileNamePrefix = AppSettings::instance().depthCameraDataFolder() + QDir::separator() + "Gemini336L";
|
||||||
QString imuFilePath = fileNamePrefix + "_IMU.txt";
|
QString imuFilePath = fileNamePrefix + "_IMU.txt";
|
||||||
std::ofstream imuFile(imuFilePath.toStdString(), std::ios::out | std::ios::trunc);
|
std::ofstream imuFile(imuFilePath.toStdString(), std::ios::out | std::ios::trunc);
|
||||||
while (record)
|
while (record)
|
||||||
@ -160,7 +177,7 @@ void DepthCameraOperation::OpenDepthCamera()
|
|||||||
std::cout << "Start recording..." << std::endl;
|
std::cout << "Start recording..." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto frameSet = m_pipe->waitForFrameset(100);
|
auto frameSet = m_pipe->waitForFrameset(m_captureIntervalMilliseconds);
|
||||||
if (frameSet == nullptr)
|
if (frameSet == nullptr)
|
||||||
{
|
{
|
||||||
std::cout << "No frames received in 100ms..." << std::endl;
|
std::cout << "No frames received in 100ms..." << std::endl;
|
||||||
@ -218,7 +235,7 @@ void DepthCameraOperation::OpenDepthCamera()
|
|||||||
pointCloud->setCreatePointFormat(OB_FORMAT_RGB_POINT);
|
pointCloud->setCreatePointFormat(OB_FORMAT_RGB_POINT);
|
||||||
std::shared_ptr<ob::Frame> frame = pointCloud->process(frameSet);
|
std::shared_ptr<ob::Frame> frame = pointCloud->process(frameSet);
|
||||||
|
|
||||||
QString plyPath = fileNamePrefix + "_"+ QString::number(frameIndex) + ".ply";
|
QString plyPath = fileNamePrefix + "_PointCloud_"+ QString::number(frameIndex) + ".ply";
|
||||||
ob::PointCloudHelper::savePointcloudToPly(plyPath.toStdString().c_str(), frame, false, false, 50);
|
ob::PointCloudHelper::savePointcloudToPly(plyPath.toStdString().c_str(), frame, false, false, 50);
|
||||||
|
|
||||||
//惯导数据
|
//惯导数据
|
||||||
|
|||||||
@ -33,6 +33,8 @@ public:
|
|||||||
void setCallback(void(*func)());
|
void setCallback(void(*func)());
|
||||||
bool getRecordStatus() const { return record; }
|
bool getRecordStatus() const { return record; }
|
||||||
|
|
||||||
|
void setCaptureInterval(int captureIntervalSeconds);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ob::Pipeline* m_pipe;
|
ob::Pipeline* m_pipe;
|
||||||
cv::Mat frame;
|
cv::Mat frame;
|
||||||
@ -46,6 +48,8 @@ private:
|
|||||||
|
|
||||||
bool record;
|
bool record;
|
||||||
|
|
||||||
|
int m_captureIntervalMilliseconds;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void OpenDepthCamera();
|
void OpenDepthCamera();
|
||||||
void OpenDepthCamera_callback();//不使用信号而使用回调函数来通知界面刷新视频
|
void OpenDepthCamera_callback();//不使用信号而使用回调函数来通知界面刷新视频
|
||||||
@ -68,6 +72,9 @@ public:
|
|||||||
|
|
||||||
DepthCameraOperation* m_DepthCameraOperation;
|
DepthCameraOperation* m_DepthCameraOperation;
|
||||||
|
|
||||||
|
void setDataFolder(QString dir);
|
||||||
|
void setCaptureInterval(int captureIntervalSeconds);
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void openDepthCamera();
|
void openDepthCamera();
|
||||||
void onCamOpened();
|
void onCamOpened();
|
||||||
|
|||||||
166
HPPA/HPPA.cpp
166
HPPA/HPPA.cpp
@ -575,6 +575,9 @@ HPPA::HPPA(QWidget* parent)
|
|||||||
|
|
||||||
initMapTools();
|
initMapTools();
|
||||||
|
|
||||||
|
//定时采集
|
||||||
|
initTimedDataCollection();
|
||||||
|
|
||||||
QString strPath = QCoreApplication::applicationDirPath() + "/UILayout.ini";
|
QString strPath = QCoreApplication::applicationDirPath() + "/UILayout.ini";
|
||||||
QFile file(strPath);
|
QFile file(strPath);
|
||||||
if (file.open(QIODevice::ReadOnly))
|
if (file.open(QIODevice::ReadOnly))
|
||||||
@ -588,6 +591,143 @@ HPPA::HPPA(QWidget* parent)
|
|||||||
this->showMaximized();
|
this->showMaximized();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HPPA::initTimedDataCollection()
|
||||||
|
{
|
||||||
|
connect(this->ui.mActionTimedDataCollection, SIGNAL(triggered()), this, SLOT(onTimedDataCollection()));
|
||||||
|
mTimedDataCollectionWindow = new TimedDataCollection();
|
||||||
|
|
||||||
|
// 定时采集控制器 → 相机/马达
|
||||||
|
connect(mTimedDataCollectionWindow, &TimedDataCollection::hyperCamParm, this, &HPPA::setTimedDataCollectionHyperCamParm);
|
||||||
|
connect(mTimedDataCollectionWindow, &TimedDataCollection::camParm, this, &HPPA::setTimedDataCollectionCamParm);
|
||||||
|
connect(mTimedDataCollectionWindow, &TimedDataCollection::motorParm, this, &HPPA::setTimedDataCollectionMotorParm);
|
||||||
|
connect(mTimedDataCollectionWindow, &TimedDataCollection::startRecordSignal, this, &HPPA::onStartTimedDataCollection);
|
||||||
|
|
||||||
|
connect(mTimedDataCollectionWindow, &TimedDataCollection::switchHalogenLampSignal, m_pc3D, &PowerControl3D::switchHalogenLampPower);
|
||||||
|
connect(mTimedDataCollectionWindow, &TimedDataCollection::switchD65LampSignal, m_pc3D, &PowerControl3D::switchD65LampPower);
|
||||||
|
connect(mTimedDataCollectionWindow, &TimedDataCollection::switchSlrSignal, m_pc3D, &PowerControl3D::switchSlrPower);
|
||||||
|
|
||||||
|
// 相机/马达 → 定时采集控制器
|
||||||
|
connect(m_tmc, &TwoMotorControl::sequenceComplete, mTimedDataCollectionWindow, &TimedDataCollection::subTaskCompleted);
|
||||||
|
connect(m_tmc, &TwoMotorControl::back2OriginSignal_TimedDataCollection, mTimedDataCollectionWindow, &TimedDataCollection::onBack2Origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HPPA::setTimedDataCollectionHyperCamParm(int camType, double f, double e, QString filePath, QString fileName)
|
||||||
|
{
|
||||||
|
switch (camType)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
disconnectImagerAndCleanup();
|
||||||
|
ui.mActionPica_L->setChecked(true);
|
||||||
|
|
||||||
|
AppSettings::instance().setFrameRate(f);
|
||||||
|
AppSettings::instance().setIntegrationTime(e);
|
||||||
|
AppSettings::instance().setDataFolder(filePath);
|
||||||
|
AppSettings::instance().setFileName(fileName);
|
||||||
|
|
||||||
|
this->frame_number->setText("100000");
|
||||||
|
|
||||||
|
onconnect();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
disconnectImagerAndCleanup();
|
||||||
|
ui.mActionPica_NIR->setChecked(true);
|
||||||
|
|
||||||
|
AppSettings::instance().setFrameRate(f);
|
||||||
|
AppSettings::instance().setIntegrationTime(e);
|
||||||
|
AppSettings::instance().setDataFolder(filePath);
|
||||||
|
AppSettings::instance().setFileName(fileName);
|
||||||
|
|
||||||
|
this->frame_number->setText("100000");
|
||||||
|
|
||||||
|
onconnect();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HPPA::setTimedDataCollectionCamParm(int camType, int captureIntervalSeconds, QString folder)
|
||||||
|
{
|
||||||
|
switch (camType)
|
||||||
|
{
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
//唤醒单反相机
|
||||||
|
m_pc3D->slrPowerDown();
|
||||||
|
m_pc3D->slrPowerOn();
|
||||||
|
|
||||||
|
m_singleLensReflexCameraWindow->setDataFolder(folder);
|
||||||
|
m_singleLensReflexCameraWindow->setCaptureInterval(captureIntervalSeconds);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
m_pc3D->d65LampPowerOn();
|
||||||
|
|
||||||
|
m_depthCameraWindow->setDataFolder(folder);
|
||||||
|
m_depthCameraWindow->setCaptureInterval(captureIntervalSeconds);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void HPPA::setTimedDataCollectionMotorParm(QString pathLineFilePath)
|
||||||
|
{
|
||||||
|
m_tmc->readRecordLineFile(pathLineFilePath);
|
||||||
|
//m_tmc->onConnectMotor();
|
||||||
|
//QThread::msleep(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HPPA::onStartTimedDataCollection(int camType)
|
||||||
|
{
|
||||||
|
switch (camType)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
onStartRecordStep1();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
onStartRecordStep1();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
m_tmc->run2(m_singleLensReflexCameraWindow);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
m_tmc->run3(m_depthCameraWindow);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HPPA::onTimedDataCollection()
|
||||||
|
{
|
||||||
|
QAction* checkedScenario = m_ScenarioActionGroup->checkedAction();
|
||||||
|
QString checkedScenarioName = checkedScenario->objectName();
|
||||||
|
if (checkedScenarioName == "mAction3DPlantPhenotypeScenario")//计划采集
|
||||||
|
{
|
||||||
|
mTimedDataCollectionWindow->show();
|
||||||
|
//mTimedDataCollectionWindow->exec();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (checkedScenarioName == "mActionPlantPhenotypeScenario")
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void HPPA::initMenubarToolbar()
|
void HPPA::initMenubarToolbar()
|
||||||
{
|
{
|
||||||
//自定义菜单栏和工具栏
|
//自定义菜单栏和工具栏
|
||||||
@ -833,6 +973,11 @@ void HPPA::initControlTabwidget()
|
|||||||
m_pc->setWindowFlags(Qt::Widget);
|
m_pc->setWindowFlags(Qt::Widget);
|
||||||
ui.controlTabWidget->addTab(m_pc, QString::fromLocal8Bit("电源控制"));
|
ui.controlTabWidget->addTab(m_pc, QString::fromLocal8Bit("电源控制"));
|
||||||
|
|
||||||
|
//电源控制3D
|
||||||
|
m_pc3D = new PowerControl3D();
|
||||||
|
m_pc3D->setWindowFlags(Qt::Widget);
|
||||||
|
ui.controlTabWidget->addTab(m_pc3D, QString::fromLocal8Bit("电源控制3D"));
|
||||||
|
|
||||||
//机械臂控制
|
//机械臂控制
|
||||||
m_rac = new RobotArmControl();
|
m_rac = new RobotArmControl();
|
||||||
connect(m_rac->robotController, SIGNAL(hsiRecordSignal(int)), this, SLOT(recordFromRobotArm(int)));
|
connect(m_rac->robotController, SIGNAL(hsiRecordSignal(int)), this, SLOT(recordFromRobotArm(int)));
|
||||||
@ -847,7 +992,7 @@ void HPPA::initControlTabwidget()
|
|||||||
//2轴马达控制
|
//2轴马达控制
|
||||||
m_tmc = new TwoMotorControl(this);
|
m_tmc = new TwoMotorControl(this);
|
||||||
//connect(m_tmc, SIGNAL(startLineNumSignal(int)), this, SLOT(onCreateTab(int)));
|
//connect(m_tmc, SIGNAL(startLineNumSignal(int)), this, SLOT(onCreateTab(int)));
|
||||||
connect(m_tmc, SIGNAL(sequenceComplete()), this, SLOT(onsequenceComplete()));
|
connect(m_tmc, &TwoMotorControl::back2OriginSignal, this, &HPPA::onsequenceComplete);
|
||||||
m_tmc->setWindowFlags(Qt::Widget);
|
m_tmc->setWindowFlags(Qt::Widget);
|
||||||
ui.controlTabWidget->addTab(m_tmc, QString::fromLocal8Bit("2轴控制"));
|
ui.controlTabWidget->addTab(m_tmc, QString::fromLocal8Bit("2轴控制"));
|
||||||
|
|
||||||
@ -1382,7 +1527,8 @@ void HPPA::create3DPlantPhenotypeScenario()
|
|||||||
m_tabManager->showTab(m_singleLensReflexCameraWindow);
|
m_tabManager->showTab(m_singleLensReflexCameraWindow);
|
||||||
//m_tabManager->showTab(m_rgbCameraControlWindow);
|
//m_tabManager->showTab(m_rgbCameraControlWindow);
|
||||||
m_tabManager->showTab(m_adt);
|
m_tabManager->showTab(m_adt);
|
||||||
m_tabManager->showTab(m_pc);
|
//m_tabManager->showTab(m_pc);
|
||||||
|
m_tabManager->showTab(m_pc3D);
|
||||||
m_tabManager->showTab(m_tmc);
|
m_tabManager->showTab(m_tmc);
|
||||||
|
|
||||||
m_view3DModelManager->switchScenario(View3DModelManager::ScenarioType::PlantPhenotype);
|
m_view3DModelManager->switchScenario(View3DModelManager::ScenarioType::PlantPhenotype);
|
||||||
@ -1523,22 +1669,6 @@ bool HPPA::showResultMessageBox(QString title, QString msg)
|
|||||||
|
|
||||||
void HPPA::onStartRecordStep1()
|
void HPPA::onStartRecordStep1()
|
||||||
{
|
{
|
||||||
QAction* checkedScenario = m_ScenarioActionGroup->checkedAction();
|
|
||||||
QString checkedScenarioName = checkedScenario->objectName();
|
|
||||||
if (checkedScenarioName == "mAction3DPlantPhenotypeScenario")//计划采集
|
|
||||||
{
|
|
||||||
TimedDataCollection* tmp = new TimedDataCollection();
|
|
||||||
/*m_ic->setWindowFlags(Qt::Widget);*/
|
|
||||||
tmp->show();
|
|
||||||
//tmp->exec();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (checkedScenarioName == "mActionPlantPhenotypeScenario")
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//判断移动平台
|
//判断移动平台
|
||||||
QAction* checked = moveplatformActionGroup->checkedAction();
|
QAction* checked = moveplatformActionGroup->checkedAction();
|
||||||
if (!checked)
|
if (!checked)
|
||||||
|
|||||||
12
HPPA/HPPA.h
12
HPPA/HPPA.h
@ -85,6 +85,8 @@
|
|||||||
|
|
||||||
#include "TimedDataCollection.h"
|
#include "TimedDataCollection.h"
|
||||||
|
|
||||||
|
#include "PowerControl3D.h"
|
||||||
|
|
||||||
#define PI 3.1415926
|
#define PI 3.1415926
|
||||||
|
|
||||||
QT_CHARTS_USE_NAMESPACE//QChartView 使用 需要加宏, 否则无法使用
|
QT_CHARTS_USE_NAMESPACE//QChartView 使用 需要加宏, 否则无法使用
|
||||||
@ -290,6 +292,7 @@ private:
|
|||||||
SingleLensReflexCameraWindow* m_singleLensReflexCameraWindow;
|
SingleLensReflexCameraWindow* m_singleLensReflexCameraWindow;
|
||||||
adjustTable* m_adt;
|
adjustTable* m_adt;
|
||||||
PowerControl* m_pc;
|
PowerControl* m_pc;
|
||||||
|
PowerControl3D* m_pc3D;
|
||||||
RobotArmControl* m_rac;
|
RobotArmControl* m_rac;
|
||||||
OneMotorControl* m_omc;
|
OneMotorControl* m_omc;
|
||||||
TwoMotorControl* m_tmc;
|
TwoMotorControl* m_tmc;
|
||||||
@ -318,6 +321,9 @@ private:
|
|||||||
bool showResultMessageBox(QString title, QString msg);
|
bool showResultMessageBox(QString title, QString msg);
|
||||||
void disconnectImagerAndCleanup();
|
void disconnectImagerAndCleanup();
|
||||||
|
|
||||||
|
TimedDataCollection* mTimedDataCollectionWindow;
|
||||||
|
void initTimedDataCollection();
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void onPlotHyperspectralImageRgbImage(int fileNumber, int frameNumber, QString filePath);
|
void onPlotHyperspectralImageRgbImage(int fileNumber, int frameNumber, QString filePath);
|
||||||
void focusPlotSpectralImg(int state);
|
void focusPlotSpectralImg(int state);
|
||||||
@ -395,6 +401,12 @@ public Q_SLOTS:
|
|||||||
|
|
||||||
void onMapToolPanTriggered();
|
void onMapToolPanTriggered();
|
||||||
void onMapToolSpectralTriggered();
|
void onMapToolSpectralTriggered();
|
||||||
|
|
||||||
|
void onTimedDataCollection();
|
||||||
|
void setTimedDataCollectionHyperCamParm(int camType, double f, double e, QString filePath, QString fileName);
|
||||||
|
void setTimedDataCollectionCamParm(int camType, int captureIntervalSeconds, QString folder);
|
||||||
|
void setTimedDataCollectionMotorParm(QString pathLineFilePath);
|
||||||
|
void onStartTimedDataCollection(int camType);
|
||||||
protected:
|
protected:
|
||||||
void closeEvent(QCloseEvent* event) override;
|
void closeEvent(QCloseEvent* event) override;
|
||||||
|
|
||||||
|
|||||||
@ -105,6 +105,7 @@ color:white;
|
|||||||
<addaction name="action_start_recording"/>
|
<addaction name="action_start_recording"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="actionOpenDirectory"/>
|
<addaction name="actionOpenDirectory"/>
|
||||||
|
<addaction name="mActionTimedDataCollection"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenu" name="menuhelp">
|
<widget class="QMenu" name="menuhelp">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
@ -743,6 +744,11 @@ QPushButton:pressed
|
|||||||
<string>3D植物表型</string>
|
<string>3D植物表型</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="mActionTimedDataCollection">
|
||||||
|
<property name="text">
|
||||||
|
<string>定时采集</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<layoutdefault spacing="6" margin="11"/>
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
|
|||||||
@ -112,6 +112,8 @@
|
|||||||
<ClCompile Include="AspectRatioLabel.cpp" />
|
<ClCompile Include="AspectRatioLabel.cpp" />
|
||||||
<ClCompile Include="CaptureCoordinator.cpp" />
|
<ClCompile Include="CaptureCoordinator.cpp" />
|
||||||
<ClCompile Include="Carousel.cpp" />
|
<ClCompile Include="Carousel.cpp" />
|
||||||
|
<ClCompile Include="CommunicationInterfaceBase.cpp" />
|
||||||
|
<ClCompile Include="CommunicationViaTCP.cpp" />
|
||||||
<ClCompile Include="Corning410Imager.cpp" />
|
<ClCompile Include="Corning410Imager.cpp" />
|
||||||
<ClCompile Include="CustomDockWidgetBase.cpp" />
|
<ClCompile Include="CustomDockWidgetBase.cpp" />
|
||||||
<ClCompile Include="DepthCameraWindow.cpp" />
|
<ClCompile Include="DepthCameraWindow.cpp" />
|
||||||
@ -140,6 +142,7 @@
|
|||||||
<ClCompile Include="OneMotorControl.cpp" />
|
<ClCompile Include="OneMotorControl.cpp" />
|
||||||
<ClCompile Include="path_tc.cpp" />
|
<ClCompile Include="path_tc.cpp" />
|
||||||
<ClCompile Include="PowerControl.cpp" />
|
<ClCompile Include="PowerControl.cpp" />
|
||||||
|
<ClCompile Include="PowerControl3D.cpp" />
|
||||||
<ClCompile Include="QDoubleSlider.cpp" />
|
<ClCompile Include="QDoubleSlider.cpp" />
|
||||||
<ClCompile Include="QMotorDoubleSlider.cpp" />
|
<ClCompile Include="QMotorDoubleSlider.cpp" />
|
||||||
<ClCompile Include="RasterDataProvider.cpp" />
|
<ClCompile Include="RasterDataProvider.cpp" />
|
||||||
@ -189,6 +192,7 @@
|
|||||||
<QtUic Include="oneMotorControl.ui" />
|
<QtUic Include="oneMotorControl.ui" />
|
||||||
<QtUic Include="PathPlan.ui" />
|
<QtUic Include="PathPlan.ui" />
|
||||||
<QtUic Include="PowerControl.ui" />
|
<QtUic Include="PowerControl.ui" />
|
||||||
|
<QtUic Include="PowerControl3D.ui" />
|
||||||
<QtUic Include="RadianceConversion.ui" />
|
<QtUic Include="RadianceConversion.ui" />
|
||||||
<QtUic Include="ReflectanceConversion.ui" />
|
<QtUic Include="ReflectanceConversion.ui" />
|
||||||
<QtUic Include="rgbCamera.ui" />
|
<QtUic Include="rgbCamera.ui" />
|
||||||
@ -223,6 +227,8 @@
|
|||||||
<ClInclude Include="AppSettings.h" />
|
<ClInclude Include="AppSettings.h" />
|
||||||
<QtMoc Include="FileNameLineEdit.h" />
|
<QtMoc Include="FileNameLineEdit.h" />
|
||||||
<QtMoc Include="DepthCameraWindow.h" />
|
<QtMoc Include="DepthCameraWindow.h" />
|
||||||
|
<QtMoc Include="CommunicationViaTCP.h" />
|
||||||
|
<QtMoc Include="CommunicationInterfaceBase.h" />
|
||||||
<ClInclude Include="imager_base.h" />
|
<ClInclude Include="imager_base.h" />
|
||||||
<ClInclude Include="irisximeaimager.h" />
|
<ClInclude Include="irisximeaimager.h" />
|
||||||
<QtMoc Include="OneMotorControl.h" />
|
<QtMoc Include="OneMotorControl.h" />
|
||||||
@ -244,6 +250,7 @@
|
|||||||
<QtMoc Include="MapToolSpectral.h" />
|
<QtMoc Include="MapToolSpectral.h" />
|
||||||
<QtMoc Include="MapTools.h" />
|
<QtMoc Include="MapTools.h" />
|
||||||
<ClInclude Include="MotorWindowBase.h" />
|
<ClInclude Include="MotorWindowBase.h" />
|
||||||
|
<QtMoc Include="PowerControl3D.h" />
|
||||||
<ClInclude Include="RasterDataProvider.h" />
|
<ClInclude Include="RasterDataProvider.h" />
|
||||||
<ClInclude Include="MultibandRasterRenderer.h" />
|
<ClInclude Include="MultibandRasterRenderer.h" />
|
||||||
<ClInclude Include="RasterImageLayer.h" />
|
<ClInclude Include="RasterImageLayer.h" />
|
||||||
@ -254,7 +261,7 @@
|
|||||||
<QtMoc Include="rgbCameraWindow.h" />
|
<QtMoc Include="rgbCameraWindow.h" />
|
||||||
<QtMoc Include="SingleLensReflexCameraWindow.h" />
|
<QtMoc Include="SingleLensReflexCameraWindow.h" />
|
||||||
<QtMoc Include="TimedDataCollection.h" />
|
<QtMoc Include="TimedDataCollection.h" />
|
||||||
<ClInclude Include="TimedDataCollectionDataStructures.h" />
|
<QtMoc Include="TimedDataCollectionDataStructures.h" />
|
||||||
<ClInclude Include="utility_tc.h" />
|
<ClInclude Include="utility_tc.h" />
|
||||||
<QtMoc Include="aboutWindow.h" />
|
<QtMoc Include="aboutWindow.h" />
|
||||||
<ClInclude Include="hppaConfigFile.h" />
|
<ClInclude Include="hppaConfigFile.h" />
|
||||||
|
|||||||
@ -238,6 +238,15 @@
|
|||||||
<ClCompile Include="TimedDataCollectionDataStructures.cpp">
|
<ClCompile Include="TimedDataCollectionDataStructures.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="CommunicationViaTCP.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="CommunicationInterfaceBase.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="PowerControl3D.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<QtMoc Include="fileOperation.h">
|
<QtMoc Include="fileOperation.h">
|
||||||
@ -384,6 +393,18 @@
|
|||||||
<QtMoc Include="TimedDataCollection.h">
|
<QtMoc Include="TimedDataCollection.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</QtMoc>
|
</QtMoc>
|
||||||
|
<QtMoc Include="TimedDataCollectionDataStructures.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</QtMoc>
|
||||||
|
<QtMoc Include="CommunicationViaTCP.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</QtMoc>
|
||||||
|
<QtMoc Include="CommunicationInterfaceBase.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</QtMoc>
|
||||||
|
<QtMoc Include="PowerControl3D.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</QtMoc>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="imageProcessor.h">
|
<ClInclude Include="imageProcessor.h">
|
||||||
@ -440,9 +461,6 @@
|
|||||||
<ClInclude Include="MotorWindowBase.h">
|
<ClInclude Include="MotorWindowBase.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="TimedDataCollectionDataStructures.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<QtUic Include="FocusDialog.ui">
|
<QtUic Include="FocusDialog.ui">
|
||||||
@ -496,6 +514,9 @@
|
|||||||
<QtUic Include="TimedDataCollection_ui.ui">
|
<QtUic Include="TimedDataCollection_ui.ui">
|
||||||
<Filter>Form Files</Filter>
|
<Filter>Form Files</Filter>
|
||||||
</QtUic>
|
</QtUic>
|
||||||
|
<QtUic Include="PowerControl3D.ui">
|
||||||
|
<Filter>Form Files</Filter>
|
||||||
|
</QtUic>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="cpp.hint" />
|
<None Include="cpp.hint" />
|
||||||
|
|||||||
100
HPPA/PowerControl3D.cpp
Normal file
100
HPPA/PowerControl3D.cpp
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
#include "PowerControl3D.h"
|
||||||
|
|
||||||
|
using namespace MotorParams;
|
||||||
|
|
||||||
|
PowerControl3D::PowerControl3D(QWidget* parent)
|
||||||
|
: QDialog(parent)
|
||||||
|
{
|
||||||
|
ui.setupUi(this);
|
||||||
|
|
||||||
|
connect(ui.halogenLampPowerOn_btn, &QPushButton::clicked, this, &PowerControl3D::halogenLampPowerOn);
|
||||||
|
connect(ui.halogenLampPowerDown_btn, &QPushButton::clicked, this, &PowerControl3D::halogenLampPowerDown);
|
||||||
|
|
||||||
|
connect(ui.d65LampPowerOn_btn, &QPushButton::clicked, this, &PowerControl3D::d65LampPowerOn);
|
||||||
|
connect(ui.d65LampPowerDown_btn, &QPushButton::clicked, this, &PowerControl3D::d65LampPowerDown);
|
||||||
|
|
||||||
|
connect(ui.slrPowerOn_btn, &QPushButton::clicked, this, &PowerControl3D::slrPowerOn);
|
||||||
|
connect(ui.slrPowerDown_btn, &QPushButton::clicked, this, &PowerControl3D::slrPowerDown);
|
||||||
|
|
||||||
|
MotorParams::TCPConnectionParams tcpConnectionParams6003;
|
||||||
|
tcpConnectionParams6003.port = 6003;
|
||||||
|
tcpConnectionParams6003.serverIP = "192.168.1.2";
|
||||||
|
tcpServer6003 = new CommunicationViaTCP(tcpConnectionParams6003, this);
|
||||||
|
|
||||||
|
MotorParams::TCPConnectionParams tcpConnectionParams6004;
|
||||||
|
tcpConnectionParams6004.port = 6004;
|
||||||
|
tcpConnectionParams6004.serverIP = "192.168.1.2";
|
||||||
|
tcpServer6004 = new CommunicationViaTCP(tcpConnectionParams6004, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
PowerControl3D::~PowerControl3D()
|
||||||
|
{
|
||||||
|
delete tcpServer6003;
|
||||||
|
delete tcpServer6004;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PowerControl3D::halogenLampPowerOn()
|
||||||
|
{
|
||||||
|
tcpServer6003->sendCommand(R"({"key1":1,"type":"event"})");
|
||||||
|
}
|
||||||
|
|
||||||
|
void PowerControl3D::halogenLampPowerDown()
|
||||||
|
{
|
||||||
|
tcpServer6003->sendCommand(R"({"key1":0,"type":"event"})");
|
||||||
|
}
|
||||||
|
|
||||||
|
void PowerControl3D::switchHalogenLampPower(int state)
|
||||||
|
{
|
||||||
|
if (state==0)
|
||||||
|
{
|
||||||
|
halogenLampPowerDown();
|
||||||
|
}
|
||||||
|
else if(state == 1)
|
||||||
|
{
|
||||||
|
halogenLampPowerOn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PowerControl3D::d65LampPowerOn()
|
||||||
|
{
|
||||||
|
tcpServer6004->sendCommand(R"({"key1":1,"type":"event"})");
|
||||||
|
}
|
||||||
|
|
||||||
|
void PowerControl3D::d65LampPowerDown()
|
||||||
|
{
|
||||||
|
tcpServer6004->sendCommand(R"({"key1":0,"type":"event"})");
|
||||||
|
}
|
||||||
|
|
||||||
|
void PowerControl3D::switchD65LampPower(int state)
|
||||||
|
{
|
||||||
|
if (state == 0)
|
||||||
|
{
|
||||||
|
d65LampPowerDown();
|
||||||
|
}
|
||||||
|
else if (state == 1)
|
||||||
|
{
|
||||||
|
d65LampPowerOn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PowerControl3D::slrPowerOn()
|
||||||
|
{
|
||||||
|
tcpServer6003->sendCommand(R"({"key2":1,"type":"event"})");
|
||||||
|
}
|
||||||
|
|
||||||
|
void PowerControl3D::slrPowerDown()
|
||||||
|
{
|
||||||
|
tcpServer6003->sendCommand(R"({"key2":0,"type":"event"})");
|
||||||
|
}
|
||||||
|
|
||||||
|
void PowerControl3D::switchSlrPower(int state)
|
||||||
|
{
|
||||||
|
if (state == 0)
|
||||||
|
{
|
||||||
|
slrPowerDown();
|
||||||
|
}
|
||||||
|
else if (state == 1)
|
||||||
|
{
|
||||||
|
slrPowerOn();
|
||||||
|
}
|
||||||
|
}
|
||||||
42
HPPA/PowerControl3D.h
Normal file
42
HPPA/PowerControl3D.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QNetworkRequest>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
|
||||||
|
#include "ui_PowerControl3D.h"
|
||||||
|
|
||||||
|
#include "CommunicationViaTCP.h"
|
||||||
|
|
||||||
|
//using namespace MotorParams;
|
||||||
|
|
||||||
|
class PowerControl3D : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
PowerControl3D(QWidget* parent = nullptr);
|
||||||
|
~PowerControl3D();
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void halogenLampPowerOn();
|
||||||
|
void halogenLampPowerDown();
|
||||||
|
void switchHalogenLampPower(int state);
|
||||||
|
|
||||||
|
void d65LampPowerOn();
|
||||||
|
void d65LampPowerDown();
|
||||||
|
void switchD65LampPower(int state);
|
||||||
|
|
||||||
|
void slrPowerOn();
|
||||||
|
void slrPowerDown();
|
||||||
|
void switchSlrPower(int state);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
//void powerOpened();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::PowerControl3D_UI ui;
|
||||||
|
|
||||||
|
MotorParams::CommunicationViaTCP* tcpServer6003;
|
||||||
|
MotorParams::CommunicationViaTCP* tcpServer6004;
|
||||||
|
};
|
||||||
350
HPPA/PowerControl3D.ui
Normal file
350
HPPA/PowerControl3D.ui
Normal file
@ -0,0 +1,350 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>PowerControl3D_UI</class>
|
||||||
|
<widget class="QDialog" name="PowerControl3D_UI">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>493</width>
|
||||||
|
<height>369</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>PowerControl3D</string>
|
||||||
|
</property>
|
||||||
|
<property name="styleSheet">
|
||||||
|
<string notr="true">QGroupBox
|
||||||
|
{
|
||||||
|
border: 12px solid transparent;
|
||||||
|
/*border-top: 12px solid transparent;
|
||||||
|
border-right: 0px solid transparent;
|
||||||
|
border-bottom: 0px solid transparent;
|
||||||
|
border-left: 0px solid transparent;*/
|
||||||
|
color: #ACCDFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton
|
||||||
|
{
|
||||||
|
/*width: 172px;
|
||||||
|
height: 56px;*/
|
||||||
|
font: 19pt "新宋体";
|
||||||
|
background-color: qlineargradient(
|
||||||
|
spread:pad,
|
||||||
|
x1:0.5, y1:0, x2:0.5, y2:1,
|
||||||
|
stop:0 #283D86,
|
||||||
|
stop:1 #0F1A40
|
||||||
|
);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 8px 16px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
QPushButton:hover
|
||||||
|
{
|
||||||
|
background-color: qlineargradient(
|
||||||
|
spread:pad,
|
||||||
|
x1:0, y1:0, x2:1, y2:0,
|
||||||
|
stop:0 #3A4875,
|
||||||
|
stop:1 #5F6B91
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/* 按下时的效果 */
|
||||||
|
QPushButton:pressed
|
||||||
|
{
|
||||||
|
background-color: qlineargradient(
|
||||||
|
spread:pad,
|
||||||
|
x1:0, y1:0, x2:1, y2:0,
|
||||||
|
stop:0 #1A254F,
|
||||||
|
stop:1 #3A466B
|
||||||
|
);
|
||||||
|
/* 可选:添加下压效果 */
|
||||||
|
padding-top: 9px;
|
||||||
|
padding-bottom: 7px;
|
||||||
|
}</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_4" rowstretch="1,2,2,2,1" columnstretch="1,10,1">
|
||||||
|
<item row="0" column="1">
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>66</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>63</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QGroupBox" name="groupBox_8">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>卤素灯</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="horizontalSpacing">
|
||||||
|
<number>18</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QPushButton" name="halogenLampPowerOn_btn">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>打 开</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QPushButton" name="halogenLampPowerDown_btn">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>关 闭</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<spacer name="horizontalSpacer_4">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>63</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>63</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QGroupBox" name="groupBox_7">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>D65灯</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_3">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="horizontalSpacing">
|
||||||
|
<number>18</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QPushButton" name="d65LampPowerOn_btn">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>打 开</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QPushButton" name="d65LampPowerDown_btn">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>关 闭</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
|
<spacer name="horizontalSpacer_6">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>63</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<spacer name="horizontalSpacer_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>63</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QGroupBox" name="groupBox_6">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>单反</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="horizontalSpacing">
|
||||||
|
<number>18</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QPushButton" name="slrPowerDown_btn">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>下 电</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QPushButton" name="slrPowerOn_btn">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>上 电</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="2">
|
||||||
|
<spacer name="horizontalSpacer_5">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>63</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<spacer name="verticalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>65</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
@ -28,6 +28,8 @@ SingleLensReflexCameraWindow::SingleLensReflexCameraWindow(QWidget* parent)
|
|||||||
connect(ui.stopTakePhoto_btn, &QPushButton::clicked, this, &SingleLensReflexCameraWindow::stopTakePhoto);
|
connect(ui.stopTakePhoto_btn, &QPushButton::clicked, this, &SingleLensReflexCameraWindow::stopTakePhoto);
|
||||||
connect(this, &SingleLensReflexCameraWindow::stopTakePhotoSignal, m_SingleLensReflexCameraOperation, &SingleLensReflexCameraOperation::stopTakePhoto);
|
connect(this, &SingleLensReflexCameraWindow::stopTakePhotoSignal, m_SingleLensReflexCameraOperation, &SingleLensReflexCameraOperation::stopTakePhoto);
|
||||||
|
|
||||||
|
connect(this, &SingleLensReflexCameraWindow::OpenAndTakePhotoSLRCameraSignal, m_SingleLensReflexCameraOperation, &SingleLensReflexCameraOperation::OpenAndTakePhotoSLRCamera);
|
||||||
|
|
||||||
connect(m_SingleLensReflexCameraOperation, &SingleLensReflexCameraOperation::CamOpenedSignal, this, &SingleLensReflexCameraWindow::onCamOpened);
|
connect(m_SingleLensReflexCameraOperation, &SingleLensReflexCameraOperation::CamOpenedSignal, this, &SingleLensReflexCameraWindow::onCamOpened);
|
||||||
connect(m_SingleLensReflexCameraOperation, &SingleLensReflexCameraOperation::CamClosedSignal, this, &SingleLensReflexCameraWindow::onCamClosed);
|
connect(m_SingleLensReflexCameraOperation, &SingleLensReflexCameraOperation::CamClosedSignal, this, &SingleLensReflexCameraWindow::onCamClosed);
|
||||||
|
|
||||||
@ -75,12 +77,31 @@ SingleLensReflexCameraWindow::~SingleLensReflexCameraWindow()
|
|||||||
m_SingleLensReflexCameraOperation = nullptr;
|
m_SingleLensReflexCameraOperation = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SingleLensReflexCameraWindow::onStartTimedDataCollection(int lineNum)
|
||||||
|
{
|
||||||
|
if (lineNum == 0)
|
||||||
|
{
|
||||||
|
OpenAndTakePhotoSLRCamera();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SingleLensReflexCameraWindow::onStopTimedDataCollection()
|
||||||
|
{
|
||||||
|
stopTakePhoto();
|
||||||
|
closeSLRCamera();
|
||||||
|
}
|
||||||
|
|
||||||
void SingleLensReflexCameraWindow::onSelectDataFolder()
|
void SingleLensReflexCameraWindow::onSelectDataFolder()
|
||||||
{
|
{
|
||||||
QString dir = QFileDialog::getExistingDirectory(this,
|
QString dir = QFileDialog::getExistingDirectory(this,
|
||||||
QString::fromLocal8Bit("选择数据保存路径"),
|
QString::fromLocal8Bit("选择数据保存路径"),
|
||||||
ui.dataFolderLineEdit->text());
|
ui.dataFolderLineEdit->text());
|
||||||
|
|
||||||
|
setDataFolder(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SingleLensReflexCameraWindow::setDataFolder(QString dir)
|
||||||
|
{
|
||||||
if (!dir.isEmpty())
|
if (!dir.isEmpty())
|
||||||
{
|
{
|
||||||
ui.dataFolderLineEdit->setText(dir);
|
ui.dataFolderLineEdit->setText(dir);
|
||||||
@ -92,6 +113,11 @@ void SingleLensReflexCameraWindow::onSelectDataFolder()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SingleLensReflexCameraWindow::setCaptureInterval(int captureIntervalSeconds)
|
||||||
|
{
|
||||||
|
m_SingleLensReflexCameraOperation->setCaptureInterval(captureIntervalSeconds);
|
||||||
|
}
|
||||||
|
|
||||||
void SingleLensReflexCameraWindow::openSLRCamera()
|
void SingleLensReflexCameraWindow::openSLRCamera()
|
||||||
{
|
{
|
||||||
if (!m_SingleLensReflexCameraOperation->getRecordStatus())
|
if (!m_SingleLensReflexCameraOperation->getRecordStatus())
|
||||||
@ -108,6 +134,11 @@ void SingleLensReflexCameraWindow::takePhoto()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SingleLensReflexCameraWindow::OpenAndTakePhotoSLRCamera()
|
||||||
|
{
|
||||||
|
emit OpenAndTakePhotoSLRCameraSignal();
|
||||||
|
}
|
||||||
|
|
||||||
void SingleLensReflexCameraWindow::stopTakePhoto()
|
void SingleLensReflexCameraWindow::stopTakePhoto()
|
||||||
{
|
{
|
||||||
if (m_SingleLensReflexCameraOperation->getRecordStatus())
|
if (m_SingleLensReflexCameraOperation->getRecordStatus())
|
||||||
@ -200,6 +231,7 @@ SingleLensReflexCameraOperation::SingleLensReflexCameraOperation()
|
|||||||
m_isSessionOpen = false;
|
m_isSessionOpen = false;
|
||||||
m_isLiveViewActive = false;
|
m_isLiveViewActive = false;
|
||||||
m_imageCounter = 0;
|
m_imageCounter = 0;
|
||||||
|
m_captureIntervalMilliseconds = 3000;
|
||||||
|
|
||||||
// 设置保存路径(从 AppSettings 获取,如果为空则使用默认的 CapturedImages 目录)
|
// 设置保存路径(从 AppSettings 获取,如果为空则使用默认的 CapturedImages 目录)
|
||||||
m_savePath = AppSettings::instance().slrDataFolder();
|
m_savePath = AppSettings::instance().slrDataFolder();
|
||||||
@ -780,13 +812,76 @@ void SingleLensReflexCameraOperation::takePhoto()
|
|||||||
// 启动拍照定时器(每3秒拍一张)
|
// 启动拍照定时器(每3秒拍一张)
|
||||||
if (m_captureTimer && !m_captureTimer->isActive())
|
if (m_captureTimer && !m_captureTimer->isActive())
|
||||||
{
|
{
|
||||||
m_captureTimer->start(3000);
|
m_captureTimer->start(m_captureIntervalMilliseconds);
|
||||||
std::cout << "capture timer started (1 photo 3 second)" << std::endl;
|
//std::cout << "capture timer started (1 photo 3 second)" << std::endl;
|
||||||
|
|
||||||
emit CaptureStartedSignal();
|
emit CaptureStartedSignal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SingleLensReflexCameraOperation::OpenAndTakePhotoSLRCamera()
|
||||||
|
{
|
||||||
|
std::cout << "SingleLensReflexCameraOperation::OpenSLRCamera, 打开单反相机" << std::endl;
|
||||||
|
|
||||||
|
EdsError err = EDS_ERR_OK;
|
||||||
|
|
||||||
|
// 初始化SDK
|
||||||
|
err = initializeSDK();
|
||||||
|
if (err != EDS_ERR_OK)
|
||||||
|
{
|
||||||
|
emit ErrorSignal(QString::fromLocal8Bit("初始化SDK失败,错误码: %1").arg(err));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开相机
|
||||||
|
err = openCamera();
|
||||||
|
if (err != EDS_ERR_OK)
|
||||||
|
{
|
||||||
|
terminateSDK();
|
||||||
|
emit ErrorSignal(QString::fromLocal8Bit("打开相机失败,错误码: %1").arg(err));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置保存到PC
|
||||||
|
err = setupSaveToHost();
|
||||||
|
if (err != EDS_ERR_OK)
|
||||||
|
{
|
||||||
|
closeCamera();
|
||||||
|
terminateSDK();
|
||||||
|
emit ErrorSignal(QString::fromLocal8Bit("设置保存位置失败,错误码: %1").arg(err));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启动实时取景
|
||||||
|
err = startLiveView();
|
||||||
|
if (err != EDS_ERR_OK)
|
||||||
|
{
|
||||||
|
std::cout << "Warning: Failed to start live view, error: " << err << std::endl;
|
||||||
|
// 实时取景启动失败不是致命错误,继续执行
|
||||||
|
}
|
||||||
|
|
||||||
|
m_isRecord = true;
|
||||||
|
|
||||||
|
// 启动实时取景定时器(约30fps)
|
||||||
|
if (m_liveViewTimer && !m_liveViewTimer->isActive()) {
|
||||||
|
m_liveViewTimer->start(33); // 约30fps
|
||||||
|
}
|
||||||
|
|
||||||
|
m_captureTimer->start(m_captureIntervalMilliseconds);
|
||||||
|
//std::cout << "capture timer started (1 photo 3 second)" << std::endl;
|
||||||
|
|
||||||
|
emit CaptureStartedSignal();
|
||||||
|
|
||||||
|
emit CamOpenedSignal();
|
||||||
|
|
||||||
|
std::cout << "Camera opened, live view started." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SingleLensReflexCameraOperation::setCaptureInterval(int captureIntervalSeconds)
|
||||||
|
{
|
||||||
|
m_captureIntervalMilliseconds = captureIntervalSeconds * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
void SingleLensReflexCameraOperation::stopTakePhoto()
|
void SingleLensReflexCameraOperation::stopTakePhoto()
|
||||||
{
|
{
|
||||||
if (m_captureTimer && m_captureTimer->isActive())
|
if (m_captureTimer && m_captureTimer->isActive())
|
||||||
|
|||||||
@ -46,6 +46,8 @@ public:
|
|||||||
// 获取当前实时取景图像
|
// 获取当前实时取景图像
|
||||||
QImage getCurrentLiveViewImage();
|
QImage getCurrentLiveViewImage();
|
||||||
|
|
||||||
|
void setCaptureInterval(int captureIntervalSeconds);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
cv::Mat frame;
|
cv::Mat frame;
|
||||||
func m_func;
|
func m_func;
|
||||||
@ -62,6 +64,7 @@ private:
|
|||||||
|
|
||||||
QString m_savePath;
|
QString m_savePath;
|
||||||
int m_imageCounter;
|
int m_imageCounter;
|
||||||
|
int m_captureIntervalMilliseconds;
|
||||||
QMutex m_mutex;
|
QMutex m_mutex;
|
||||||
QMutex m_liveViewMutex;
|
QMutex m_liveViewMutex;
|
||||||
|
|
||||||
@ -91,6 +94,7 @@ private:
|
|||||||
public slots:
|
public slots:
|
||||||
void OpenSLRCamera();
|
void OpenSLRCamera();
|
||||||
void takePhoto();
|
void takePhoto();
|
||||||
|
void OpenAndTakePhotoSLRCamera();
|
||||||
void stopTakePhoto();
|
void stopTakePhoto();
|
||||||
void OpenSLRCamera_callback();
|
void OpenSLRCamera_callback();
|
||||||
void CloseSLRCamera();
|
void CloseSLRCamera();
|
||||||
@ -127,12 +131,15 @@ public:
|
|||||||
~SingleLensReflexCameraWindow();
|
~SingleLensReflexCameraWindow();
|
||||||
|
|
||||||
SingleLensReflexCameraOperation* m_SingleLensReflexCameraOperation;
|
SingleLensReflexCameraOperation* m_SingleLensReflexCameraOperation;
|
||||||
|
void setDataFolder(QString dir);
|
||||||
|
void setCaptureInterval(int captureIntervalSeconds);
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void onSelectDataFolder();
|
void onSelectDataFolder();
|
||||||
|
|
||||||
void openSLRCamera();
|
void openSLRCamera();
|
||||||
void takePhoto();
|
void takePhoto();
|
||||||
|
void OpenAndTakePhotoSLRCamera();
|
||||||
void stopTakePhoto();
|
void stopTakePhoto();
|
||||||
void onCamOpened();
|
void onCamOpened();
|
||||||
void closeSLRCamera();
|
void closeSLRCamera();
|
||||||
@ -148,9 +155,13 @@ public Q_SLOTS:
|
|||||||
void onCaptureStarted();
|
void onCaptureStarted();
|
||||||
void onCaptureStopped();
|
void onCaptureStopped();
|
||||||
|
|
||||||
|
void onStartTimedDataCollection(int lineNum);
|
||||||
|
void onStopTimedDataCollection();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void openSLRCameraSignal();
|
void openSLRCameraSignal();
|
||||||
void takePhotoSignal();
|
void takePhotoSignal();
|
||||||
|
void OpenAndTakePhotoSLRCameraSignal();
|
||||||
void stopTakePhotoSignal();
|
void stopTakePhotoSignal();
|
||||||
void closeSLRCameraSignal();
|
void closeSLRCameraSignal();
|
||||||
void PlotSLRImageSignal();
|
void PlotSLRImageSignal();
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
TimedDataCollection::TimedDataCollection(QWidget* parent)
|
TimedDataCollection::TimedDataCollection(QWidget* parent)
|
||||||
: QDialog(parent)
|
: QDialog(parent)
|
||||||
|
, m_scheduler(nullptr)
|
||||||
{
|
{
|
||||||
ui.setupUi(this);
|
ui.setupUi(this);
|
||||||
|
|
||||||
@ -12,21 +13,69 @@ TimedDataCollection::TimedDataCollection(QWidget* parent)
|
|||||||
ui.treeWidget->setDropIndicatorShown(true); // 显示插入位置指示线
|
ui.treeWidget->setDropIndicatorShown(true); // 显示插入位置指示线
|
||||||
ui.treeWidget->setDragDropMode(QAbstractItemView::InternalMove); // 内部移动
|
ui.treeWidget->setDragDropMode(QAbstractItemView::InternalMove); // 内部移动
|
||||||
|
|
||||||
|
// 初始化调度器
|
||||||
|
m_scheduler = new TaskScheduler(this);
|
||||||
|
|
||||||
|
// 连接调度器信号
|
||||||
|
connect(m_scheduler, &TaskScheduler::taskStarted, this, &TimedDataCollection::taskStarted);
|
||||||
|
connect(m_scheduler, &TaskScheduler::taskFinished, this, &TimedDataCollection::taskFinished);
|
||||||
|
connect(m_scheduler, &TaskScheduler::subTaskStarted, this, &TimedDataCollection::subTaskStarted);
|
||||||
|
connect(m_scheduler, &TaskScheduler::subTaskFinished, this, &TimedDataCollection::subTaskFinished);
|
||||||
|
connect(m_scheduler, &TaskScheduler::errorOccurred, this, &TimedDataCollection::errorOccurred);
|
||||||
|
|
||||||
|
// 采集相关信号透传
|
||||||
|
connect(m_scheduler, &TaskScheduler::hyperCamParm, this, &TimedDataCollection::hyperCamParm);
|
||||||
|
connect(m_scheduler, &TaskScheduler::camParm, this, &TimedDataCollection::camParm);
|
||||||
|
connect(m_scheduler, &TaskScheduler::motorParm, this, &TimedDataCollection::motorParm);
|
||||||
|
connect(m_scheduler, &TaskScheduler::startRecordSignal, this, &TimedDataCollection::startRecordSignal);
|
||||||
|
|
||||||
|
connect(m_scheduler, &TaskScheduler::switchHalogenLampSignal, this, &TimedDataCollection::switchHalogenLampSignal);
|
||||||
|
connect(m_scheduler, &TaskScheduler::switchD65LampSignal, this, &TimedDataCollection::switchD65LampSignal);
|
||||||
|
connect(m_scheduler, &TaskScheduler::switchSlrSignal, this, &TimedDataCollection::switchSlrSignal);
|
||||||
|
|
||||||
|
connect(this, &TimedDataCollection::sequenceCompleteSignal, m_scheduler, &TaskScheduler::sequenceCompleteSignal);
|
||||||
|
connect(this, &TimedDataCollection::Back2OriginSignal, m_scheduler, &TaskScheduler::Back2OriginSignal);
|
||||||
|
|
||||||
//writeRead();
|
//writeRead();
|
||||||
readTimedTaskFromFile("D:/0tmp/3Dtest/task.json");
|
readTimedTaskFromFile("D:/0tmp/3Dtest/task.json");
|
||||||
|
|
||||||
connect(ui.run_btn, SIGNAL(clicked()), this, SLOT(run()));
|
// 加载任务到调度器
|
||||||
|
m_scheduler->loadTasks(m_loadedTasks);
|
||||||
|
|
||||||
connect(ui.run_btn, &QPushButton::clicked, this, &TimedDataCollection::run);
|
connect(ui.run_btn, &QPushButton::clicked, this, &TimedDataCollection::startScheduler);
|
||||||
|
|
||||||
|
startScheduler();
|
||||||
}
|
}
|
||||||
|
|
||||||
TimedDataCollection::~TimedDataCollection()
|
TimedDataCollection::~TimedDataCollection()
|
||||||
{
|
{
|
||||||
|
if (m_scheduler) {
|
||||||
|
m_scheduler->stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimedDataCollection::run()
|
void TimedDataCollection::subTaskCompleted(int status)
|
||||||
{
|
{
|
||||||
|
emit sequenceCompleteSignal(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimedDataCollection::onBack2Origin()
|
||||||
|
{
|
||||||
|
emit Back2OriginSignal();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimedDataCollection::startScheduler()
|
||||||
|
{
|
||||||
|
if (m_scheduler) {
|
||||||
|
m_scheduler->start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TimedDataCollection::stopScheduler()
|
||||||
|
{
|
||||||
|
if (m_scheduler) {
|
||||||
|
m_scheduler->stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimedDataCollection::readTimedTaskFromFile(const QString& filePath)
|
void TimedDataCollection::readTimedTaskFromFile(const QString& filePath)
|
||||||
@ -70,8 +119,8 @@ void TimedDataCollection::writeRead()
|
|||||||
subTask.type = types[j];
|
subTask.type = types[j];
|
||||||
subTask.startTime = task.scheduledTime.addSecs(j * 3600);
|
subTask.startTime = task.scheduledTime.addSecs(j * 3600);
|
||||||
subTask.endTime = subTask.startTime.addSecs(1800);
|
subTask.endTime = subTask.startTime.addSecs(1800);
|
||||||
subTask.durationSeconds = 1800;
|
subTask.durationMinutes = 1800;
|
||||||
subTask.estimatedDurationSeconds = 1800;
|
subTask.estimatedDurationMinutes = 1800;
|
||||||
subTask.pathLineFilePath = QString("D:/0tmp/3Dtest/pathLine/%1.RecordLine3").arg(j);
|
subTask.pathLineFilePath = QString("D:/0tmp/3Dtest/pathLine/%1.RecordLine3").arg(j);
|
||||||
subTask.status = TaskStatus::Waiting;
|
subTask.status = TaskStatus::Waiting;
|
||||||
|
|
||||||
|
|||||||
@ -19,7 +19,32 @@ public:
|
|||||||
void readTimedTaskFromFile(const QString& filePath);
|
void readTimedTaskFromFile(const QString& filePath);
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void run();
|
void startScheduler();
|
||||||
|
void stopScheduler();
|
||||||
|
void subTaskCompleted(int status);
|
||||||
|
void onBack2Origin();
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void taskStarted(int taskId);
|
||||||
|
void taskFinished(int taskId, bool success);
|
||||||
|
|
||||||
|
void subTaskStarted(int taskId, int subTaskIndex);
|
||||||
|
void subTaskFinished(int taskId, int subTaskIndex);
|
||||||
|
void errorOccurred(const QString& error);
|
||||||
|
|
||||||
|
// 采集相关信号 (透传 TaskScheduler)
|
||||||
|
void hyperCamParm(int camType, double f, double e, QString filePath, QString fileName);
|
||||||
|
void camParm(int camType, int captureIntervalSeconds, QString folder);
|
||||||
|
void motorParm(QString pathLineFilePath);
|
||||||
|
void startRecordSignal(int camType);
|
||||||
|
|
||||||
|
void switchHalogenLampSignal(int state);
|
||||||
|
void switchD65LampSignal(int state);
|
||||||
|
void switchSlrSignal(int state);
|
||||||
|
|
||||||
|
// 马达反馈的信号
|
||||||
|
void sequenceCompleteSignal(int status);
|
||||||
|
void Back2OriginSignal();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::TimedDataCollection_ui ui;
|
Ui::TimedDataCollection_ui ui;
|
||||||
@ -27,4 +52,5 @@ private:
|
|||||||
void writeRead();
|
void writeRead();
|
||||||
|
|
||||||
QVector<TimedTask> m_loadedTasks;
|
QVector<TimedTask> m_loadedTasks;
|
||||||
|
TaskScheduler* m_scheduler;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
#include "TimedDataCollectionDataStructures.h"
|
#include "TimedDataCollectionDataStructures.h"
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
@ -121,8 +121,8 @@ QJsonObject TimedDataCollectionDataStructuresReaderWriter::subTaskToJson(const S
|
|||||||
obj["type"] = subTaskTypeToString(subTask.type);
|
obj["type"] = subTaskTypeToString(subTask.type);
|
||||||
obj["startTime"] = subTask.startTime.toString(Qt::ISODate);
|
obj["startTime"] = subTask.startTime.toString(Qt::ISODate);
|
||||||
obj["endTime"] = subTask.endTime.toString(Qt::ISODate);
|
obj["endTime"] = subTask.endTime.toString(Qt::ISODate);
|
||||||
obj["durationSeconds"] = subTask.durationSeconds;
|
obj["durationMinutes"] = subTask.durationMinutes;
|
||||||
obj["estimatedDurationSeconds"] = subTask.estimatedDurationSeconds;
|
obj["estimatedDurationMinutes"] = subTask.estimatedDurationMinutes;
|
||||||
obj["pathLineFilePath"] = subTask.pathLineFilePath;
|
obj["pathLineFilePath"] = subTask.pathLineFilePath;
|
||||||
obj["status"] = taskStatusToString(subTask.status);
|
obj["status"] = taskStatusToString(subTask.status);
|
||||||
obj["frameRate"] = subTask.frameRate;
|
obj["frameRate"] = subTask.frameRate;
|
||||||
@ -137,14 +137,14 @@ bool TimedDataCollectionDataStructuresReaderWriter::jsonToSubTask(const QJsonObj
|
|||||||
subTask.type = stringToSubTaskType(json["type"].toString());
|
subTask.type = stringToSubTaskType(json["type"].toString());
|
||||||
subTask.startTime = QDateTime::fromString(json["startTime"].toString(), Qt::ISODate);
|
subTask.startTime = QDateTime::fromString(json["startTime"].toString(), Qt::ISODate);
|
||||||
subTask.endTime = QDateTime::fromString(json["endTime"].toString(), Qt::ISODate);
|
subTask.endTime = QDateTime::fromString(json["endTime"].toString(), Qt::ISODate);
|
||||||
subTask.durationSeconds = json["durationSeconds"].toInt();
|
subTask.durationMinutes = json["durationMinutes"].toDouble();
|
||||||
subTask.estimatedDurationSeconds = json["estimatedDurationSeconds"].toInt();
|
subTask.estimatedDurationMinutes = json["estimatedDurationMinutes"].toDouble();
|
||||||
subTask.pathLineFilePath = json["pathLineFilePath"].toString();
|
subTask.pathLineFilePath = json["pathLineFilePath"].toString();
|
||||||
subTask.status = stringToTaskStatus(json["status"].toString());
|
subTask.status = stringToTaskStatus(json["status"].toString());
|
||||||
subTask.frameRate = json["frameRate"].toDouble();
|
subTask.frameRate = json["frameRate"].toDouble();
|
||||||
subTask.exposureTime = json["exposureTime"].toDouble();
|
subTask.exposureTime = json["exposureTime"].toDouble();
|
||||||
subTask.defaultRenderBand = json["defaultRenderBand"].toInt();
|
subTask.defaultRenderBand = json["defaultRenderBand"].toInt();
|
||||||
subTask.captureIntervalSeconds = json["captureIntervalSeconds"].toInt();
|
subTask.captureIntervalSeconds = json["captureIntervalSeconds"].toDouble();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,9 +157,10 @@ QJsonObject TimedDataCollectionDataStructuresReaderWriter::timedTaskToJson(const
|
|||||||
obj["scheduledTime"] = task.scheduledTime.toString(Qt::ISODate);
|
obj["scheduledTime"] = task.scheduledTime.toString(Qt::ISODate);
|
||||||
obj["startTime"] = task.startTime.toString(Qt::ISODate);
|
obj["startTime"] = task.startTime.toString(Qt::ISODate);
|
||||||
obj["endTime"] = task.endTime.toString(Qt::ISODate);
|
obj["endTime"] = task.endTime.toString(Qt::ISODate);
|
||||||
obj["durationSeconds"] = task.durationSeconds;
|
obj["durationMinutes"] = task.durationMinutes;
|
||||||
obj["savePath"] = task.savePath;
|
obj["savePath"] = task.savePath;
|
||||||
obj["status"] = taskStatusToString(task.status);
|
obj["status"] = taskStatusToString(task.status);
|
||||||
|
obj["HalogenLampPreheatingTime_Minute"] = task.HalogenLampPreheatingTime_Minute;
|
||||||
|
|
||||||
QJsonArray subTasksArray;
|
QJsonArray subTasksArray;
|
||||||
for (const auto& subTask : task.subTasks) {
|
for (const auto& subTask : task.subTasks) {
|
||||||
@ -176,9 +177,10 @@ bool TimedDataCollectionDataStructuresReaderWriter::jsonToTimedTask(const QJsonO
|
|||||||
task.scheduledTime = QDateTime::fromString(json["scheduledTime"].toString(), Qt::ISODate);
|
task.scheduledTime = QDateTime::fromString(json["scheduledTime"].toString(), Qt::ISODate);
|
||||||
task.startTime = QDateTime::fromString(json["startTime"].toString(), Qt::ISODate);
|
task.startTime = QDateTime::fromString(json["startTime"].toString(), Qt::ISODate);
|
||||||
task.endTime = QDateTime::fromString(json["endTime"].toString(), Qt::ISODate);
|
task.endTime = QDateTime::fromString(json["endTime"].toString(), Qt::ISODate);
|
||||||
task.durationSeconds = json["durationSeconds"].toInt();
|
task.durationMinutes = json["durationMinutes"].toDouble();
|
||||||
task.savePath = json["savePath"].toString();
|
task.savePath = json["savePath"].toString();
|
||||||
task.status = stringToTaskStatus(json["status"].toString());
|
task.status = stringToTaskStatus(json["status"].toString());
|
||||||
|
task.HalogenLampPreheatingTime_Minute = json["HalogenLampPreheatingTime_Minute"].toDouble();
|
||||||
|
|
||||||
QJsonArray subTasksArray = json["subTasks"].toArray();
|
QJsonArray subTasksArray = json["subTasks"].toArray();
|
||||||
task.subTasks.clear();
|
task.subTasks.clear();
|
||||||
@ -194,3 +196,420 @@ bool TimedDataCollectionDataStructuresReaderWriter::jsonToTimedTask(const QJsonO
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================== TaskExecutor 实现 ====================
|
||||||
|
|
||||||
|
TaskExecutor::TaskExecutor(QObject* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, m_currentSubTaskIndex(0)
|
||||||
|
, m_isRunning(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskExecutor::~TaskExecutor()
|
||||||
|
{
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskExecutor::execute(const TimedTask& task)
|
||||||
|
{
|
||||||
|
if (m_isRunning) {
|
||||||
|
qWarning() << "TaskExecutor: Already running, ignoring execute request";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_task = task;
|
||||||
|
m_task.startTime = QDateTime::currentDateTime();
|
||||||
|
|
||||||
|
m_currentSubTaskIndex = 0;
|
||||||
|
m_isRunning = true;
|
||||||
|
|
||||||
|
qDebug() << "TaskExecutor: Starting task" << task.id;
|
||||||
|
|
||||||
|
// 打开卤素灯预热
|
||||||
|
emit switchHalogenLampSignal(1);
|
||||||
|
printMsgAndTime("open HalogenLamp");
|
||||||
|
|
||||||
|
makeFolder(m_task.savePath);
|
||||||
|
|
||||||
|
// 开始执行第一个子任务
|
||||||
|
double sleepTimeSecond = m_task.HalogenLampPreheatingTime_Minute * 60;
|
||||||
|
QTimer::singleShot(sleepTimeSecond *1000, this, &TaskExecutor::executeNextSubTask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskExecutor::printMsgAndTime(QString msg)
|
||||||
|
{
|
||||||
|
QDateTime now = QDateTime::currentDateTime();
|
||||||
|
QString timeString = now.toString("yyyy-MM-dd hh:mm:ss.zzz");
|
||||||
|
qDebug() << msg + " time:" << timeString;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskExecutor::stop()
|
||||||
|
{
|
||||||
|
if (!m_isRunning) return;
|
||||||
|
|
||||||
|
qDebug() << "TaskExecutor: Stopping task" << m_task.id;
|
||||||
|
|
||||||
|
m_isRunning = false;
|
||||||
|
emit finished(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskExecutor::makeFolder(QString savePath)
|
||||||
|
{
|
||||||
|
QDir dir(savePath);
|
||||||
|
if (!dir.exists()) {
|
||||||
|
if (dir.mkpath(".")) {
|
||||||
|
qDebug() << "TaskExecutor: Created data folder:" << savePath;
|
||||||
|
} else {
|
||||||
|
qWarning() << "TaskExecutor: Failed to create data folder:" << savePath;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qDebug() << "TaskExecutor: Data folder already exists:" << savePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString TaskExecutor::makeSubTaskDataFolder(QString suffix)
|
||||||
|
{
|
||||||
|
QString dateStr = QDateTime::currentDateTime().toString("yyyy-MM-dd_HH-mm-ss");
|
||||||
|
QString folderPath = m_task.savePath + QDir::separator() + dateStr + "_" + suffix;
|
||||||
|
makeFolder(folderPath);
|
||||||
|
|
||||||
|
return folderPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskExecutor::onSequenceComplete(int status)
|
||||||
|
{
|
||||||
|
if (!m_isRunning) return;
|
||||||
|
|
||||||
|
qDebug() << "TaskExecutor: Sequence complete, status:" << status;
|
||||||
|
|
||||||
|
// 更新当前子任务状态
|
||||||
|
if (m_currentSubTaskIndex < m_task.subTasks.size()) {
|
||||||
|
SubTask& subTask = m_task.subTasks[m_currentSubTaskIndex];
|
||||||
|
subTask.status = (status == 0) ? TaskStatus::Finished : TaskStatus::Waiting;
|
||||||
|
|
||||||
|
subTask.endTime = QDateTime::currentDateTime();
|
||||||
|
subTask.durationMinutes = (double)subTask.startTime.secsTo(subTask.endTime) / 60;
|
||||||
|
qDebug() << "TaskExecutor: subtask "<< m_currentSubTaskIndex<< " time consuming(Minutes): "<< subTask.durationMinutes;
|
||||||
|
|
||||||
|
emit subTaskFinished(m_currentSubTaskIndex, subTask.type, (status == 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
switch (m_task.subTasks[m_currentSubTaskIndex].type)
|
||||||
|
{
|
||||||
|
case SubTaskType::SingleLensReflex:
|
||||||
|
{
|
||||||
|
emit switchD65LampSignal(0);
|
||||||
|
emit switchSlrSignal(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SubTaskType::DepthCamera:
|
||||||
|
{
|
||||||
|
emit switchD65LampSignal(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断下一次的任务是否为高光谱任务,如果不是关闭卤素灯
|
||||||
|
int nestSubTaskIndex = m_currentSubTaskIndex + 1;
|
||||||
|
if (nestSubTaskIndex >= m_task.subTasks.size())
|
||||||
|
{
|
||||||
|
emit switchHalogenLampSignal(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (m_task.subTasks[nestSubTaskIndex].type)
|
||||||
|
{
|
||||||
|
case SubTaskType::SingleLensReflex:
|
||||||
|
{
|
||||||
|
emit switchHalogenLampSignal(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SubTaskType::DepthCamera:
|
||||||
|
{
|
||||||
|
emit switchHalogenLampSignal(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskExecutor::onBack2Origin()
|
||||||
|
{
|
||||||
|
// 检查是否还有更多子任务
|
||||||
|
m_currentSubTaskIndex++;
|
||||||
|
if (m_currentSubTaskIndex < m_task.subTasks.size()) {
|
||||||
|
// 执行下一个子任务
|
||||||
|
if(m_task.subTasks[m_currentSubTaskIndex].type== SubTaskType::SingleLensReflex)
|
||||||
|
{
|
||||||
|
printMsgAndTime("Slr task,for weak up,please wait 135 seconds!");
|
||||||
|
emit switchSlrSignal(0);
|
||||||
|
|
||||||
|
QTimer::singleShot(135*1000, this, &TaskExecutor::executeNextSubTask);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QTimer::singleShot(1000, this, &TaskExecutor::executeNextSubTask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// 所有子任务完成
|
||||||
|
m_task.endTime = QDateTime::currentDateTime();
|
||||||
|
m_task.durationMinutes = (double)m_task.startTime.secsTo(m_task.endTime) / 60;
|
||||||
|
qDebug() << "TaskExecutor: task time consuming(Minutes): " << m_task.durationMinutes;
|
||||||
|
|
||||||
|
m_isRunning = false;
|
||||||
|
qDebug() << "TaskExecutor: All subtasks completed";
|
||||||
|
emit finished(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskExecutor::onError(const QString& error)
|
||||||
|
{
|
||||||
|
if (!m_isRunning) return;
|
||||||
|
|
||||||
|
qWarning() << "TaskExecutor: Error occurred:" << error;
|
||||||
|
m_isRunning = false;
|
||||||
|
emit errorOccurred(error);
|
||||||
|
emit finished(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskExecutor::executeNextSubTask()
|
||||||
|
{
|
||||||
|
if (!m_isRunning || m_currentSubTaskIndex >= m_task.subTasks.size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SubTask& subTask = m_task.subTasks[m_currentSubTaskIndex];
|
||||||
|
subTask.status = TaskStatus::Running;
|
||||||
|
subTask.startTime = QDateTime::currentDateTime();
|
||||||
|
|
||||||
|
QString tmp = "TaskExecutor: Starting subtask" + QString::number(m_currentSubTaskIndex) + "type:" + static_cast<int>(subTask.type);
|
||||||
|
printMsgAndTime(tmp);
|
||||||
|
//printMsgAndTime("excute " + QString::number(m_currentSubTaskIndex) + " subTask: ");
|
||||||
|
|
||||||
|
//qDebug() << "TaskExecutor: Starting subtask" << m_currentSubTaskIndex
|
||||||
|
// << "type:" << static_cast<int>(subTask.type);
|
||||||
|
|
||||||
|
emit subTaskStarted(m_currentSubTaskIndex, subTask.type);
|
||||||
|
|
||||||
|
emit motorParm(subTask.pathLineFilePath);
|
||||||
|
|
||||||
|
int camType;
|
||||||
|
switch (subTask.type)
|
||||||
|
{
|
||||||
|
case SubTaskType::HyperSpectual400_1000nm:
|
||||||
|
{
|
||||||
|
camType = 0;
|
||||||
|
emit hyperCamParm(camType, subTask.frameRate, subTask.exposureTime, makeSubTaskDataFolder("L"), "test");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SubTaskType::HyperSpectual1000_1700nm:
|
||||||
|
{
|
||||||
|
camType = 1;
|
||||||
|
emit hyperCamParm(camType, subTask.frameRate, subTask.exposureTime, makeSubTaskDataFolder("NIR"), "test");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SubTaskType::SingleLensReflex:
|
||||||
|
{
|
||||||
|
camType = 2;
|
||||||
|
emit camParm(camType, 3, makeSubTaskDataFolder("SLR"));
|
||||||
|
|
||||||
|
emit switchD65LampSignal(1);
|
||||||
|
|
||||||
|
|
||||||
|
emit switchSlrSignal(1);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SubTaskType::DepthCamera:
|
||||||
|
{
|
||||||
|
camType = 3;
|
||||||
|
emit camParm(camType, 3, makeSubTaskDataFolder("DepthCamera"));
|
||||||
|
|
||||||
|
emit switchD65LampSignal(1);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
emit startRecordSignal(camType);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== TaskScheduler 实现 ====================
|
||||||
|
|
||||||
|
TaskScheduler::TaskScheduler(QObject* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, m_timer(nullptr)
|
||||||
|
, m_currentExecutor(nullptr)
|
||||||
|
, m_currentTaskId(-1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskScheduler::~TaskScheduler()
|
||||||
|
{
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskScheduler::loadTasks(const QVector<TimedTask>& tasks)
|
||||||
|
{
|
||||||
|
m_tasks = tasks;
|
||||||
|
qDebug() << "TaskScheduler: Loaded" << tasks.size() << "tasks";
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskScheduler::start()
|
||||||
|
{
|
||||||
|
if (m_timer) {
|
||||||
|
qDebug() << "TaskScheduler: Already running";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "TaskScheduler: Starting";
|
||||||
|
|
||||||
|
m_timer = new QTimer(this);
|
||||||
|
connect(m_timer, &QTimer::timeout, this, &TaskScheduler::checkTasks);
|
||||||
|
m_timer->start(1000); // 每秒检查一次
|
||||||
|
|
||||||
|
emit schedulerStateChanged(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskScheduler::stop()
|
||||||
|
{
|
||||||
|
if (m_timer) {
|
||||||
|
m_timer->stop();
|
||||||
|
delete m_timer;
|
||||||
|
m_timer = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_currentExecutor) {
|
||||||
|
m_currentExecutor->stop();
|
||||||
|
m_currentExecutor->deleteLater();
|
||||||
|
m_currentExecutor = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "TaskScheduler: Stopped";
|
||||||
|
emit schedulerStateChanged(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskScheduler::checkTasks()
|
||||||
|
{
|
||||||
|
QDateTime now = QDateTime::currentDateTime();
|
||||||
|
|
||||||
|
for (auto& task : m_tasks) {
|
||||||
|
if (task.status != TaskStatus::Waiting) continue;
|
||||||
|
|
||||||
|
// 超过计划时间1分钟以上,认为任务已过时,跳过
|
||||||
|
if (task.scheduledTime.addSecs(60) < now) {
|
||||||
|
std::cerr << "TaskScheduler::checkTasks,任务已过时,跳过:" << task.id << std::endl;
|
||||||
|
task.status = TaskStatus::Finished;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (task.scheduledTime > now) continue;
|
||||||
|
|
||||||
|
// 到达计划时间,启动任务
|
||||||
|
std::cerr << "TaskScheduler::checkTasks,到达计划时间,启动任务" << std::endl;
|
||||||
|
executeTask(task);
|
||||||
|
break; // 一次只执行一个任务
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskScheduler::onTaskFinished(bool success)
|
||||||
|
{
|
||||||
|
if (m_currentTaskId > 0) {
|
||||||
|
TaskStatus status = success ? TaskStatus::Finished : TaskStatus::Waiting;
|
||||||
|
updateTaskStatus(m_currentTaskId, status);
|
||||||
|
emit taskFinished(m_currentTaskId, success);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清理执行器
|
||||||
|
if (m_currentExecutor) {
|
||||||
|
m_currentExecutor->deleteLater();
|
||||||
|
m_currentExecutor = nullptr;
|
||||||
|
}
|
||||||
|
m_currentTaskId = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskScheduler::onSubTaskStarted(int subTaskIndex, SubTaskType type)
|
||||||
|
{
|
||||||
|
if (m_currentTaskId > 0) {
|
||||||
|
emit subTaskStarted(m_currentTaskId, subTaskIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskScheduler::onSubTaskFinished(int subTaskIndex, SubTaskType type, bool success)
|
||||||
|
{
|
||||||
|
if (m_currentTaskId > 0) {
|
||||||
|
emit subTaskFinished(m_currentTaskId, subTaskIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskScheduler::onExecutorError(const QString& error)
|
||||||
|
{
|
||||||
|
emitError(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskScheduler::executeTask(TimedTask& task)
|
||||||
|
{
|
||||||
|
qDebug() << "TaskScheduler: Executing task" << task.id;
|
||||||
|
|
||||||
|
updateTaskStatus(task.id, TaskStatus::Running);
|
||||||
|
m_currentTaskId = task.id;
|
||||||
|
|
||||||
|
emit taskStarted(task.id);
|
||||||
|
|
||||||
|
// 创建任务执行器
|
||||||
|
m_currentExecutor = new TaskExecutor(this);
|
||||||
|
|
||||||
|
// 连接信号
|
||||||
|
connect(m_currentExecutor, &TaskExecutor::finished,
|
||||||
|
this, &TaskScheduler::onTaskFinished);
|
||||||
|
connect(m_currentExecutor, &TaskExecutor::subTaskStarted,
|
||||||
|
this, &TaskScheduler::onSubTaskStarted);
|
||||||
|
connect(m_currentExecutor, &TaskExecutor::subTaskFinished,
|
||||||
|
this, &TaskScheduler::onSubTaskFinished);
|
||||||
|
connect(m_currentExecutor, &TaskExecutor::errorOccurred,
|
||||||
|
this, &TaskScheduler::onExecutorError);
|
||||||
|
|
||||||
|
// 采集相关信号透传
|
||||||
|
connect(m_currentExecutor, &TaskExecutor::hyperCamParm,
|
||||||
|
this, &TaskScheduler::hyperCamParm);
|
||||||
|
connect(m_currentExecutor, &TaskExecutor::camParm,
|
||||||
|
this, &TaskScheduler::camParm);
|
||||||
|
connect(m_currentExecutor, &TaskExecutor::motorParm,
|
||||||
|
this, &TaskScheduler::motorParm);
|
||||||
|
connect(m_currentExecutor, &TaskExecutor::startRecordSignal,
|
||||||
|
this, &TaskScheduler::startRecordSignal);
|
||||||
|
|
||||||
|
connect(m_currentExecutor, &TaskExecutor::switchHalogenLampSignal, this, &TaskScheduler::switchHalogenLampSignal);
|
||||||
|
connect(m_currentExecutor, &TaskExecutor::switchD65LampSignal, this, &TaskScheduler::switchD65LampSignal);
|
||||||
|
connect(m_currentExecutor, &TaskExecutor::switchSlrSignal, this, &TaskScheduler::switchSlrSignal);
|
||||||
|
|
||||||
|
connect(this, &TaskScheduler::sequenceCompleteSignal, m_currentExecutor, &TaskExecutor::onSequenceComplete);
|
||||||
|
connect(this, &TaskScheduler::Back2OriginSignal, m_currentExecutor, &TaskExecutor::onBack2Origin);
|
||||||
|
|
||||||
|
// 开始执行
|
||||||
|
m_currentExecutor->execute(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskScheduler::updateTaskStatus(int taskId, TaskStatus status)
|
||||||
|
{
|
||||||
|
for (auto& task : m_tasks) {
|
||||||
|
if (task.id == taskId) {
|
||||||
|
task.status = status;
|
||||||
|
if (status == TaskStatus::Running) {
|
||||||
|
task.startTime = QDateTime::currentDateTime();
|
||||||
|
} else if (status == TaskStatus::Finished) {
|
||||||
|
task.endTime = QDateTime::currentDateTime();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskScheduler::emitError(const QString& error)
|
||||||
|
{
|
||||||
|
qWarning() << "TaskScheduler: Error:" << error;
|
||||||
|
emit errorOccurred(error);
|
||||||
|
}
|
||||||
|
|||||||
@ -4,6 +4,9 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include <QMetaType>
|
#include <QMetaType>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include "CaptureCoordinator.h"
|
||||||
|
|
||||||
// ==================== 枚举定义 ====================
|
// ==================== 枚举定义 ====================
|
||||||
|
|
||||||
@ -11,7 +14,8 @@
|
|||||||
enum class TaskStatus {
|
enum class TaskStatus {
|
||||||
Waiting, // 等待
|
Waiting, // 等待
|
||||||
Running, // 运行中
|
Running, // 运行中
|
||||||
Finished // 结束
|
Finished, // 结束
|
||||||
|
Skiped //跳过
|
||||||
};
|
};
|
||||||
|
|
||||||
// 子任务类型
|
// 子任务类型
|
||||||
@ -30,8 +34,8 @@ struct SubTask {
|
|||||||
// 共享属性
|
// 共享属性
|
||||||
QDateTime startTime;
|
QDateTime startTime;
|
||||||
QDateTime endTime;
|
QDateTime endTime;
|
||||||
int durationSeconds = 0;
|
double durationMinutes = 0;
|
||||||
int estimatedDurationSeconds = 0;
|
double estimatedDurationMinutes = 0;
|
||||||
QString pathLineFilePath;
|
QString pathLineFilePath;
|
||||||
TaskStatus status = TaskStatus::Waiting;
|
TaskStatus status = TaskStatus::Waiting;
|
||||||
|
|
||||||
@ -49,16 +53,17 @@ struct TimedTask {
|
|||||||
QDateTime scheduledTime; // 计划时间
|
QDateTime scheduledTime; // 计划时间
|
||||||
QDateTime startTime; // 开始时间
|
QDateTime startTime; // 开始时间
|
||||||
QDateTime endTime; // 结束时间
|
QDateTime endTime; // 结束时间
|
||||||
int durationSeconds = 0; // 耗时(秒)
|
double durationMinutes = 0; // 耗时(秒)
|
||||||
QString savePath; // 数据保存路径
|
QString savePath; // 数据保存路径
|
||||||
QVector<SubTask> subTasks; // 子任务列表
|
QVector<SubTask> subTasks; // 子任务列表
|
||||||
TaskStatus status = TaskStatus::Waiting; // 状态
|
TaskStatus status = TaskStatus::Waiting; // 状态
|
||||||
|
double HalogenLampPreheatingTime_Minute;
|
||||||
|
|
||||||
// 计算所有子任务的预计总时间
|
// 计算所有子任务的预计总时间
|
||||||
int totalEstimatedDuration() const {
|
int totalEstimatedDuration() const {
|
||||||
int total = 0;
|
int total = 0;
|
||||||
for (const auto& subTask : subTasks) {
|
for (const auto& subTask : subTasks) {
|
||||||
total += subTask.estimatedDurationSeconds;
|
total += subTask.estimatedDurationMinutes;
|
||||||
}
|
}
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
@ -102,3 +107,129 @@ private:
|
|||||||
static QString subTaskTypeToString(SubTaskType type);
|
static QString subTaskTypeToString(SubTaskType type);
|
||||||
static SubTaskType stringToSubTaskType(const QString& str);
|
static SubTaskType stringToSubTaskType(const QString& str);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ==================== 任务执行器 ====================
|
||||||
|
|
||||||
|
class TaskExecutor : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit TaskExecutor(QObject* parent = nullptr);
|
||||||
|
~TaskExecutor();
|
||||||
|
|
||||||
|
// 执行任务
|
||||||
|
void execute(const TimedTask& task);
|
||||||
|
void makeFolder(QString savePath);
|
||||||
|
QString makeSubTaskDataFolder(QString suffix);
|
||||||
|
|
||||||
|
// 获取当前执行的子任务索引
|
||||||
|
int currentSubTaskIndex() const { return m_currentSubTaskIndex; }
|
||||||
|
|
||||||
|
// 获取正在执行的任务
|
||||||
|
const TimedTask& currentTask() const { return m_task; }
|
||||||
|
|
||||||
|
// 是否正在执行
|
||||||
|
bool isRunning() const { return m_isRunning; }
|
||||||
|
|
||||||
|
// 停止执行
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void finished(bool success); // 任务完成
|
||||||
|
void subTaskStarted(int subTaskIndex, SubTaskType type); // 子任务开始
|
||||||
|
void subTaskFinished(int subTaskIndex, SubTaskType type, bool success); // 子任务完成
|
||||||
|
void errorOccurred(const QString& error); // 错误发生
|
||||||
|
|
||||||
|
// 采集相关信号
|
||||||
|
void hyperCamParm(int camType, double f, double e, QString filePath, QString fileName);
|
||||||
|
void camParm(int camType, int captureIntervalSeconds, QString folder);
|
||||||
|
void motorParm(QString pathLineFilePath);
|
||||||
|
void startRecordSignal(int camType);
|
||||||
|
|
||||||
|
void switchHalogenLampSignal(int state);
|
||||||
|
void switchD65LampSignal(int state);
|
||||||
|
void switchSlrSignal(int state);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void onSequenceComplete(int status);
|
||||||
|
void onBack2Origin();
|
||||||
|
void onError(const QString& error);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void executeNextSubTask();
|
||||||
|
|
||||||
|
void printMsgAndTime(QString msg);
|
||||||
|
|
||||||
|
TimedTask m_task;
|
||||||
|
int m_currentSubTaskIndex;
|
||||||
|
bool m_isRunning;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ==================== 任务调度器 ====================
|
||||||
|
|
||||||
|
class TaskScheduler : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit TaskScheduler(QObject* parent = nullptr);
|
||||||
|
~TaskScheduler();
|
||||||
|
|
||||||
|
// 加载任务列表
|
||||||
|
void loadTasks(const QVector<TimedTask>& tasks);
|
||||||
|
|
||||||
|
// 获取任务列表
|
||||||
|
QVector<TimedTask> tasks() const { return m_tasks; }
|
||||||
|
|
||||||
|
// 开始调度
|
||||||
|
void start();
|
||||||
|
|
||||||
|
// 停止调度
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
// 是否正在运行
|
||||||
|
bool isRunning() const { return m_timer != nullptr && m_timer->isActive(); }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void taskStarted(int taskId); // 任务开始
|
||||||
|
void taskFinished(int taskId, bool success); // 任务完成
|
||||||
|
|
||||||
|
void schedulerStateChanged(bool running); // 调度器状态变化
|
||||||
|
|
||||||
|
// 子任务的信号
|
||||||
|
void subTaskStarted(int taskId, int subTaskIndex); // 子任务开始
|
||||||
|
void subTaskFinished(int taskId, int subTaskIndex); // 子任务完成
|
||||||
|
void errorOccurred(const QString& error); // 错误发生
|
||||||
|
|
||||||
|
// 采集相关信号 (透传 TaskExecutor)
|
||||||
|
void hyperCamParm(int camType, double f, double e, QString filePath, QString fileName);
|
||||||
|
void camParm(int camType, int captureIntervalSeconds, QString folder);
|
||||||
|
void motorParm(QString pathLineFilePath);
|
||||||
|
void startRecordSignal(int camType);
|
||||||
|
|
||||||
|
void switchHalogenLampSignal(int state);
|
||||||
|
void switchD65LampSignal(int state);
|
||||||
|
void switchSlrSignal(int state);
|
||||||
|
|
||||||
|
// 马达反馈的信号
|
||||||
|
void sequenceCompleteSignal(int status);
|
||||||
|
void Back2OriginSignal();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void checkTasks(); // 检查任务是否该启动
|
||||||
|
void onTaskFinished(bool success);
|
||||||
|
void onSubTaskStarted(int subTaskIndex, SubTaskType type);
|
||||||
|
void onSubTaskFinished(int subTaskIndex, SubTaskType type, bool success);
|
||||||
|
void onExecutorError(const QString& error);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void executeTask(TimedTask& task);
|
||||||
|
void updateTaskStatus(int taskId, TaskStatus status);
|
||||||
|
void emitError(const QString& error);
|
||||||
|
|
||||||
|
QTimer* m_timer;
|
||||||
|
QVector<TimedTask> m_tasks;
|
||||||
|
TaskExecutor* m_currentExecutor;
|
||||||
|
int m_currentTaskId;
|
||||||
|
};
|
||||||
|
|||||||
@ -6,314 +6,273 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>970</width>
|
<width>1160</width>
|
||||||
<height>456</height>
|
<height>576</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Dialog</string>
|
<string>Dialog</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QTreeWidget" name="treeWidget">
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
<property name="geometry">
|
<item row="0" column="0" colspan="3">
|
||||||
<rect>
|
<widget class="QWidget" name="widget" native="true">
|
||||||
<x>9</x>
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<y>9</y>
|
<item row="0" column="0">
|
||||||
<width>491</width>
|
<widget class="QTreeWidget" name="treeWidget">
|
||||||
<height>281</height>
|
<property name="allColumnsShowFocus">
|
||||||
</rect>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="allColumnsShowFocus">
|
<attribute name="headerVisible">
|
||||||
<bool>false</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</attribute>
|
||||||
<attribute name="headerVisible">
|
<column>
|
||||||
<bool>true</bool>
|
<property name="text">
|
||||||
</attribute>
|
<string>任务</string>
|
||||||
<column>
|
</property>
|
||||||
<property name="text">
|
</column>
|
||||||
<string>任务</string>
|
<column>
|
||||||
</property>
|
<property name="text">
|
||||||
</column>
|
<string>计划时间</string>
|
||||||
<column>
|
</property>
|
||||||
<property name="text">
|
</column>
|
||||||
<string>计划时间</string>
|
<column>
|
||||||
</property>
|
<property name="text">
|
||||||
</column>
|
<string>开始时间</string>
|
||||||
<column>
|
</property>
|
||||||
<property name="text">
|
</column>
|
||||||
<string>开始时间</string>
|
<column>
|
||||||
</property>
|
<property name="text">
|
||||||
</column>
|
<string>结束时间</string>
|
||||||
<column>
|
</property>
|
||||||
<property name="text">
|
</column>
|
||||||
<string>结束时间</string>
|
<column>
|
||||||
</property>
|
<property name="text">
|
||||||
</column>
|
<string>耗时</string>
|
||||||
<column>
|
</property>
|
||||||
<property name="text">
|
</column>
|
||||||
<string>耗时</string>
|
<column>
|
||||||
</property>
|
<property name="text">
|
||||||
</column>
|
<string>状态</string>
|
||||||
<column>
|
</property>
|
||||||
<property name="text">
|
</column>
|
||||||
<string>状态</string>
|
<item>
|
||||||
</property>
|
<property name="text">
|
||||||
</column>
|
<string>1</string>
|
||||||
<item>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>1</string>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<item>
|
||||||
<string/>
|
<property name="text">
|
||||||
</property>
|
<string>a</string>
|
||||||
<item>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>a</string>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
</item>
|
||||||
<string/>
|
<item>
|
||||||
</property>
|
<property name="text">
|
||||||
</item>
|
<string>b</string>
|
||||||
<item>
|
</property>
|
||||||
<property name="text">
|
</item>
|
||||||
<string>b</string>
|
</item>
|
||||||
</property>
|
<item>
|
||||||
</item>
|
<property name="text">
|
||||||
|
<string>2</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>a</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>b</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>3</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>a</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>b</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>4</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>a</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>b</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>5</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>a</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>b</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QStackedWidget" name="stackedWidget">
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="page"/>
|
||||||
|
<widget class="QWidget" name="page_2"/>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="1" column="0">
|
||||||
<property name="text">
|
<widget class="QPushButton" name="addToptask_btn">
|
||||||
<string>2</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>a</string>
|
<string>添加总计划任务</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</widget>
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>b</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="2" column="0">
|
||||||
<property name="text">
|
<widget class="QPushButton" name="delToptask_btn">
|
||||||
<string>3</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>a</string>
|
<string>删除总计划任务</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</widget>
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>b</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="3" column="0">
|
||||||
<property name="text">
|
<widget class="QPushButton" name="addSubtask_btn">
|
||||||
<string>4</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>a</string>
|
<string>添加子任务</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</widget>
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>b</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="3" column="1">
|
||||||
<property name="text">
|
<widget class="QComboBox" name="comboBox"/>
|
||||||
<string>5</string>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>a</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>b</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</item>
|
</item>
|
||||||
</widget>
|
<item row="4" column="0">
|
||||||
<widget class="QPushButton" name="addToptask_btn">
|
<widget class="QPushButton" name="delSubtask_btn">
|
||||||
<property name="geometry">
|
<property name="text">
|
||||||
<rect>
|
<string>删除子任务</string>
|
||||||
<x>40</x>
|
</property>
|
||||||
<y>310</y>
|
</widget>
|
||||||
<width>101</width>
|
</item>
|
||||||
<height>23</height>
|
<item row="4" column="2">
|
||||||
</rect>
|
<widget class="QPushButton" name="run_btn">
|
||||||
</property>
|
<property name="text">
|
||||||
<property name="text">
|
<string>运行</string>
|
||||||
<string>添加总计划任务</string>
|
</property>
|
||||||
</property>
|
</widget>
|
||||||
</widget>
|
</item>
|
||||||
<widget class="QPushButton" name="addSubtask_btn">
|
</layout>
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>40</x>
|
|
||||||
<y>370</y>
|
|
||||||
<width>101</width>
|
|
||||||
<height>23</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>添加子任务</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QComboBox" name="comboBox">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>170</x>
|
|
||||||
<y>370</y>
|
|
||||||
<width>69</width>
|
|
||||||
<height>22</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QPushButton" name="delSubtask_btn">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>40</x>
|
|
||||||
<y>410</y>
|
|
||||||
<width>101</width>
|
|
||||||
<height>23</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>删除子任务</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QPushButton" name="delToptask_btn">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>40</x>
|
|
||||||
<y>340</y>
|
|
||||||
<width>101</width>
|
|
||||||
<height>23</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>删除总计划任务</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QStackedWidget" name="stackedWidget">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>520</x>
|
|
||||||
<y>20</y>
|
|
||||||
<width>381</width>
|
|
||||||
<height>261</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="currentIndex">
|
|
||||||
<number>1</number>
|
|
||||||
</property>
|
|
||||||
<widget class="QWidget" name="page"/>
|
|
||||||
<widget class="QWidget" name="page_2"/>
|
|
||||||
</widget>
|
|
||||||
<widget class="QPushButton" name="run_btn">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>850</x>
|
|
||||||
<y>420</y>
|
|
||||||
<width>101</width>
|
|
||||||
<height>23</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>运行</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
|||||||
@ -103,6 +103,113 @@ void TwoMotorControl::record_white()
|
|||||||
m_whiteCaptureCoordinator->startStepMotion(s);
|
m_whiteCaptureCoordinator->startStepMotion(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TwoMotorControl::run2(SingleLensReflexCameraWindow* window)
|
||||||
|
{
|
||||||
|
int rowCount = ui.recordLine_tableWidget->rowCount();
|
||||||
|
if (rowCount == 0)
|
||||||
|
{
|
||||||
|
QMessageBox::information(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("请至少添加一行采集线!"));
|
||||||
|
|
||||||
|
emit sequenceComplete(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_coordinator_TimedDataCollection = new TwoMotionCaptureCoordinator(m_multiAxisController);
|
||||||
|
connect(this, SIGNAL(start(QVector<PathLine>)), m_coordinator_TimedDataCollection, SLOT(start(QVector<PathLine>)));
|
||||||
|
|
||||||
|
connect(m_coordinator_TimedDataCollection, &TwoMotionCaptureCoordinator::startRecordLineNumSignal, this, &TwoMotorControl::receiveStartRecordLineNum);
|
||||||
|
connect(m_coordinator_TimedDataCollection, &TwoMotionCaptureCoordinator::finishRecordLineNumSignal, this, &TwoMotorControl::receiveFinishRecordLineNum);
|
||||||
|
|
||||||
|
connect(m_coordinator_TimedDataCollection, &TwoMotionCaptureCoordinator::startRecordLineNumSignal, window, &SingleLensReflexCameraWindow::onStartTimedDataCollection);
|
||||||
|
connect(m_coordinator_TimedDataCollection, &TwoMotionCaptureCoordinator::sequenceComplete, window, &SingleLensReflexCameraWindow::onStopTimedDataCollection);
|
||||||
|
connect(m_coordinator_TimedDataCollection, &TwoMotionCaptureCoordinator::sequenceComplete, this, &TwoMotorControl::sequenceComplete);
|
||||||
|
|
||||||
|
connect(m_coordinator_TimedDataCollection, &TwoMotionCaptureCoordinator::back2OriginSignal, this, &TwoMotorControl::onBack2Origin2);
|
||||||
|
|
||||||
|
QVector<PathLine> pathLines;
|
||||||
|
//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("#0E1C4C"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
emit start(pathLines);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TwoMotorControl::run3(DepthCameraWindow* window)
|
||||||
|
{
|
||||||
|
int rowCount = ui.recordLine_tableWidget->rowCount();
|
||||||
|
if (rowCount == 0)
|
||||||
|
{
|
||||||
|
QMessageBox::information(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("请至少添加一行采集线!"));
|
||||||
|
|
||||||
|
emit sequenceComplete(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_coordinator_TimedDataCollection = new TwoMotionCaptureCoordinator(m_multiAxisController);
|
||||||
|
connect(this, SIGNAL(start(QVector<PathLine>)), m_coordinator_TimedDataCollection, SLOT(start(QVector<PathLine>)));
|
||||||
|
|
||||||
|
connect(m_coordinator_TimedDataCollection, &TwoMotionCaptureCoordinator::startRecordLineNumSignal, this, &TwoMotorControl::receiveStartRecordLineNum);
|
||||||
|
connect(m_coordinator_TimedDataCollection, &TwoMotionCaptureCoordinator::finishRecordLineNumSignal, this, &TwoMotorControl::receiveFinishRecordLineNum);
|
||||||
|
|
||||||
|
connect(m_coordinator_TimedDataCollection, &TwoMotionCaptureCoordinator::startRecordLineNumSignal, window, &DepthCameraWindow::openDepthCamera);
|
||||||
|
connect(m_coordinator_TimedDataCollection, &TwoMotionCaptureCoordinator::sequenceComplete, window, &DepthCameraWindow::closeDepthCamera);
|
||||||
|
connect(m_coordinator_TimedDataCollection, &TwoMotionCaptureCoordinator::sequenceComplete, this, &TwoMotorControl::sequenceComplete);
|
||||||
|
|
||||||
|
connect(m_coordinator_TimedDataCollection, &TwoMotionCaptureCoordinator::back2OriginSignal, this, &TwoMotorControl::onBack2Origin2);
|
||||||
|
|
||||||
|
QVector<PathLine> pathLines;
|
||||||
|
//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("#0E1C4C"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
emit start(pathLines);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TwoMotorControl::onBack2Origin2()
|
||||||
|
{
|
||||||
|
m_coordinator_TimedDataCollection->deleteLater();
|
||||||
|
m_coordinator_TimedDataCollection = nullptr;
|
||||||
|
emit back2OriginSignal_TimedDataCollection();
|
||||||
|
}
|
||||||
|
|
||||||
void TwoMotorControl::run()
|
void TwoMotorControl::run()
|
||||||
{
|
{
|
||||||
if (getState())
|
if (getState())
|
||||||
@ -116,7 +223,7 @@ void TwoMotorControl::run()
|
|||||||
{
|
{
|
||||||
QMessageBox::information(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("请至少添加一行采集线!"));
|
QMessageBox::information(this, QString::fromLocal8Bit("提示"), QString::fromLocal8Bit("请至少添加一行采集线!"));
|
||||||
|
|
||||||
emit sequenceComplete();
|
emit sequenceComplete(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,7 +236,8 @@ void TwoMotorControl::run()
|
|||||||
connect(this, SIGNAL(stopSignal()), m_coordinator, SLOT(stop()));
|
connect(this, SIGNAL(stopSignal()), m_coordinator, SLOT(stop()));
|
||||||
connect(m_coordinator, SIGNAL(startRecordLineNumSignal(int)), this, SLOT(receiveStartRecordLineNum(int)));
|
connect(m_coordinator, SIGNAL(startRecordLineNumSignal(int)), this, SLOT(receiveStartRecordLineNum(int)));
|
||||||
connect(m_coordinator, SIGNAL(finishRecordLineNumSignal(int)), this, SLOT(receiveFinishRecordLineNum(int)));
|
connect(m_coordinator, SIGNAL(finishRecordLineNumSignal(int)), this, SLOT(receiveFinishRecordLineNum(int)));
|
||||||
connect(m_coordinator, SIGNAL(sequenceComplete(int)), this, SLOT(onSequenceComplete()));
|
connect(m_coordinator, SIGNAL(sequenceComplete(int)), this, SLOT(onSequenceComplete(int)));
|
||||||
|
connect(m_coordinator, &TwoMotionCaptureCoordinator::back2OriginSignal, this, &TwoMotorControl::onBack2Origin);
|
||||||
|
|
||||||
connect(m_coordinator, &TwoMotionCaptureCoordinator::startRecordHSISignal, m_Imager, &ImagerOperationBase::start_record);
|
connect(m_coordinator, &TwoMotionCaptureCoordinator::startRecordHSISignal, m_Imager, &ImagerOperationBase::start_record);
|
||||||
connect(m_coordinator, &TwoMotionCaptureCoordinator::stopRecordHSISignal, this, &TwoMotorControl::stop_record);
|
connect(m_coordinator, &TwoMotionCaptureCoordinator::stopRecordHSISignal, this, &TwoMotorControl::stop_record);
|
||||||
@ -263,16 +371,22 @@ void TwoMotorControl::receiveFinishRecordLineNum(int lineNum)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TwoMotorControl::onSequenceComplete()
|
void TwoMotorControl::onSequenceComplete(int status)
|
||||||
{
|
{
|
||||||
isWritePosFile = false;
|
isWritePosFile = false;
|
||||||
fclose(m_posFileHandle);
|
fclose(m_posFileHandle);
|
||||||
|
|
||||||
|
emit sequenceComplete(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TwoMotorControl::onBack2Origin()
|
||||||
|
{
|
||||||
m_coordinatorThread.quit();
|
m_coordinatorThread.quit();
|
||||||
m_coordinatorThread.wait();
|
m_coordinatorThread.wait();
|
||||||
m_coordinator = nullptr;
|
m_coordinator = nullptr;
|
||||||
|
|
||||||
emit sequenceComplete();
|
emit back2OriginSignal();
|
||||||
|
emit back2OriginSignal_TimedDataCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TwoMotorControl::getMotorsConnectionStatus()
|
bool TwoMotorControl::getMotorsConnectionStatus()
|
||||||
@ -551,7 +665,10 @@ void TwoMotorControl::onReadRecordLineFile_btn()
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
readRecordLineFile(RecordLineFilePath);
|
||||||
|
}
|
||||||
|
void TwoMotorControl::readRecordLineFile(QString RecordLineFilePath)
|
||||||
|
{
|
||||||
FILE* RecordLineFileHandle = fopen(RecordLineFilePath.toStdString().c_str(), "rb");
|
FILE* RecordLineFileHandle = fopen(RecordLineFilePath.toStdString().c_str(), "rb");
|
||||||
double number;
|
double number;
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,9 @@
|
|||||||
#include "CaptureCoordinator.h"
|
#include "CaptureCoordinator.h"
|
||||||
#include "MotorWindowBase.h"
|
#include "MotorWindowBase.h"
|
||||||
|
|
||||||
|
#include "SingleLensReflexCameraWindow.h"
|
||||||
|
#include "DepthCameraWindow.h"
|
||||||
|
|
||||||
#define PI 3.1415926
|
#define PI 3.1415926
|
||||||
|
|
||||||
class TwoMotorControl : public QDialog, public MotorWindowBase
|
class TwoMotorControl : public QDialog, public MotorWindowBase
|
||||||
@ -27,6 +30,8 @@ public:
|
|||||||
void record_white();
|
void record_white();
|
||||||
|
|
||||||
bool getMotorsConnectionStatus();
|
bool getMotorsConnectionStatus();
|
||||||
|
|
||||||
|
void readRecordLineFile(QString RecordLineFilePath);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ImagerOperationBase* m_Imager;
|
ImagerOperationBase* m_Imager;
|
||||||
@ -68,7 +73,12 @@ public Q_SLOTS:
|
|||||||
void stop();
|
void stop();
|
||||||
void receiveStartRecordLineNum(int lineNum);
|
void receiveStartRecordLineNum(int lineNum);
|
||||||
void receiveFinishRecordLineNum(int lineNum);
|
void receiveFinishRecordLineNum(int lineNum);
|
||||||
void onSequenceComplete();
|
void onSequenceComplete(int status);
|
||||||
|
void onBack2Origin();
|
||||||
|
|
||||||
|
void run2(SingleLensReflexCameraWindow* w);
|
||||||
|
void run3(DepthCameraWindow* window);
|
||||||
|
void onBack2Origin2();
|
||||||
|
|
||||||
void stop_record();
|
void stop_record();
|
||||||
|
|
||||||
@ -86,7 +96,9 @@ signals:
|
|||||||
void stopSignal();
|
void stopSignal();
|
||||||
|
|
||||||
void startLineNumSignal(int lineNum);
|
void startLineNumSignal(int lineNum);
|
||||||
void sequenceComplete();//所有采集线正常运行完成
|
void sequenceComplete(int status);//所有采集线正常运行完成
|
||||||
|
void back2OriginSignal();
|
||||||
|
void back2OriginSignal_TimedDataCollection();
|
||||||
|
|
||||||
void broadcastLocationSignal(std::vector<double>);
|
void broadcastLocationSignal(std::vector<double>);
|
||||||
|
|
||||||
@ -94,6 +106,7 @@ private:
|
|||||||
Ui::twoMotorControl_UI ui;
|
Ui::twoMotorControl_UI ui;
|
||||||
QThread m_coordinatorThread;
|
QThread m_coordinatorThread;
|
||||||
TwoMotionCaptureCoordinator* m_coordinator = nullptr;
|
TwoMotionCaptureCoordinator* m_coordinator = nullptr;
|
||||||
|
TwoMotionCaptureCoordinator* m_coordinator_TimedDataCollection = nullptr;
|
||||||
|
|
||||||
DarkAndWhiteCaptureCoordinator* m_darkCaptureCoordinator = nullptr;
|
DarkAndWhiteCaptureCoordinator* m_darkCaptureCoordinator = nullptr;
|
||||||
DarkAndWhiteCaptureCoordinator* m_whiteCaptureCoordinator = nullptr;
|
DarkAndWhiteCaptureCoordinator* m_whiteCaptureCoordinator = nullptr;
|
||||||
|
|||||||
Reference in New Issue
Block a user