add,计划采集6:
实现部分计划采集功能:定时任务可控制单反
This commit is contained in:
@ -6,6 +6,7 @@ TwoMotionCaptureCoordinator::TwoMotionCaptureCoordinator(
|
||||
: QObject(parent)
|
||||
, m_motorCtrl(motorCtrl)
|
||||
, m_isRunning(false)
|
||||
, m_isValidCapturing(false)
|
||||
{
|
||||
//这些信号槽是按照逻辑顺序的
|
||||
connect(this, SIGNAL(moveTo(int, double, double, int)),
|
||||
@ -113,7 +114,7 @@ void TwoMotionCaptureCoordinator::move2LocBeforeStart()
|
||||
speed.push_back(tmp.speedTargetYPosition);
|
||||
emit moveTo(m_locBeforeStart, speed, 1000);
|
||||
|
||||
m_isRunning = false;
|
||||
m_isValidCapturing = false;
|
||||
|
||||
m_isMoving2XMin = false;
|
||||
m_isMoving2XMax = false;
|
||||
@ -195,12 +196,12 @@ void TwoMotionCaptureCoordinator::handlePositionReached(int motorID, double pos)
|
||||
|
||||
//QMutexLocker locker(&m_dataMutex);
|
||||
|
||||
PathLine &tmp = m_pathLines[m_numCurrentPathLine];
|
||||
|
||||
if (motorID == 1)//y马达
|
||||
{
|
||||
if (m_isMoving2YTargeLoc)
|
||||
{
|
||||
PathLine& tmp = m_pathLines[m_numCurrentPathLine];
|
||||
|
||||
double threshold = getThre(tmp.targetYPosition, pos);
|
||||
|
||||
if (threshold > 5)
|
||||
@ -230,6 +231,7 @@ void TwoMotionCaptureCoordinator::handlePositionReached(int motorID, double pos)
|
||||
if (m_isMoving2YStartLoc)
|
||||
{
|
||||
m_isMoving2YStartLoc = false;
|
||||
isBack2Origin();
|
||||
|
||||
return;
|
||||
}
|
||||
@ -238,6 +240,8 @@ void TwoMotionCaptureCoordinator::handlePositionReached(int motorID, double pos)
|
||||
{
|
||||
if (m_isMoving2XMin)
|
||||
{
|
||||
PathLine& tmp = m_pathLines[m_numCurrentPathLine];
|
||||
|
||||
double threshold = getThre(tmp.targetXMinPosition, pos);
|
||||
|
||||
if (threshold > 5)
|
||||
@ -266,6 +270,8 @@ void TwoMotionCaptureCoordinator::handlePositionReached(int motorID, double pos)
|
||||
|
||||
if (m_isMoving2XMax)
|
||||
{
|
||||
PathLine& tmp = m_pathLines[m_numCurrentPathLine];
|
||||
|
||||
double threshold = getThre(tmp.targetXMaxPosition, pos);
|
||||
|
||||
if (threshold > 5 && !m_isImagerFrameNumberMeet)//马达没到准确位置 && 【非】光谱仪因帧数限制主动停止采集
|
||||
@ -302,6 +308,7 @@ void TwoMotionCaptureCoordinator::handlePositionReached(int motorID, double pos)
|
||||
if (m_isMoving2XStartLoc)
|
||||
{
|
||||
m_isMoving2XStartLoc = false;
|
||||
isBack2Origin();
|
||||
|
||||
return;
|
||||
}
|
||||
@ -344,6 +351,21 @@ void TwoMotionCaptureCoordinator::startRecordHsi()
|
||||
}
|
||||
}
|
||||
|
||||
void TwoMotionCaptureCoordinator::isBack2Origin()
|
||||
{
|
||||
if (!m_isRunning) return;
|
||||
|
||||
//QMutexLocker locker(&m_dataMutex);
|
||||
|
||||
if (!m_isMoving2XStartLoc && !m_isMoving2YStartLoc)
|
||||
{
|
||||
m_isRunning = false;
|
||||
|
||||
emit back2OriginSignal();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TwoMotionCaptureCoordinator::handleCaptureCompleteWhenFrameNumberMeet()
|
||||
{
|
||||
m_isImagerFrameNumberMeet = true;
|
||||
@ -388,6 +410,7 @@ void TwoMotionCaptureCoordinator::processNextPathLine()
|
||||
|
||||
std::cout << "\nNew path line: " << m_numCurrentPathLine << std::endl;
|
||||
emit startRecordLineNumSignal(m_numCurrentPathLine);
|
||||
m_isValidCapturing = true;
|
||||
|
||||
PathLine &tmp = m_pathLines[m_numCurrentPathLine];
|
||||
tmp.timestamp1 = QDateTime::currentDateTime();
|
||||
|
||||
@ -46,6 +46,7 @@ public:
|
||||
|
||||
signals:
|
||||
void sequenceComplete(int);//0:所有采集线正常运行完成,1:用户主动取消采集
|
||||
void back2OriginSignal();
|
||||
void startRecordLineNumSignal(int lineNum);
|
||||
void finishRecordLineNumSignal(int lineNum);
|
||||
|
||||
@ -75,6 +76,7 @@ private slots:
|
||||
private:
|
||||
void processNextPathLine();
|
||||
void startRecordHsi();
|
||||
void isBack2Origin();
|
||||
void getLocBeforeStart();
|
||||
double getThre(double targetLoc, double actualLoc);
|
||||
|
||||
@ -87,6 +89,7 @@ private:
|
||||
mutable QMutex m_dataMutex;
|
||||
|
||||
bool m_isRunning;
|
||||
bool m_isValidCapturing;
|
||||
bool m_isMoving2YTargeLoc;
|
||||
bool m_isMoving2XMin;
|
||||
bool m_isMoving2XMax;
|
||||
|
||||
@ -604,6 +604,7 @@ void HPPA::initTimedDataCollection()
|
||||
|
||||
// 相机/马达 → 定时采集控制器
|
||||
connect(m_tmc, &TwoMotorControl::sequenceComplete, mTimedDataCollectionWindow, &TimedDataCollection::subTaskCompleted);
|
||||
connect(m_tmc, &TwoMotorControl::back2OriginSignal, mTimedDataCollectionWindow, &TimedDataCollection::onBack2Origin);
|
||||
|
||||
//连接马达控制和单反/深度
|
||||
}
|
||||
@ -690,10 +691,13 @@ void HPPA::onStartTimedDataCollection(int camType)
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
m_tmc->run2(m_singleLensReflexCameraWindow);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
//m_tmc->setImager(m_Imager);
|
||||
//m_tmc->run2();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -976,7 +980,7 @@ void HPPA::initControlTabwidget()
|
||||
//2轴马达控制
|
||||
m_tmc = new TwoMotorControl(this);
|
||||
//connect(m_tmc, SIGNAL(startLineNumSignal(int)), this, SLOT(onCreateTab(int)));
|
||||
connect(m_tmc, &TwoMotorControl::sequenceComplete, this, &HPPA::onsequenceComplete);
|
||||
connect(m_tmc, &TwoMotorControl::back2OriginSignal, this, &HPPA::onsequenceComplete);
|
||||
m_tmc->setWindowFlags(Qt::Widget);
|
||||
ui.controlTabWidget->addTab(m_tmc, QString::fromLocal8Bit("2轴控制"));
|
||||
|
||||
|
||||
@ -28,6 +28,8 @@ SingleLensReflexCameraWindow::SingleLensReflexCameraWindow(QWidget* parent)
|
||||
connect(ui.stopTakePhoto_btn, &QPushButton::clicked, this, &SingleLensReflexCameraWindow::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::CamClosedSignal, this, &SingleLensReflexCameraWindow::onCamClosed);
|
||||
|
||||
@ -75,6 +77,20 @@ SingleLensReflexCameraWindow::~SingleLensReflexCameraWindow()
|
||||
m_SingleLensReflexCameraOperation = nullptr;
|
||||
}
|
||||
|
||||
void SingleLensReflexCameraWindow::onStartTimedDataCollection(int lineNum)
|
||||
{
|
||||
if (lineNum == 0)
|
||||
{
|
||||
OpenAndTakePhotoSLRCamera();
|
||||
}
|
||||
}
|
||||
|
||||
void SingleLensReflexCameraWindow::onStopTimedDataCollection()
|
||||
{
|
||||
stopTakePhoto();
|
||||
closeSLRCamera();
|
||||
}
|
||||
|
||||
void SingleLensReflexCameraWindow::onSelectDataFolder()
|
||||
{
|
||||
QString dir = QFileDialog::getExistingDirectory(this,
|
||||
@ -118,6 +134,11 @@ void SingleLensReflexCameraWindow::takePhoto()
|
||||
}
|
||||
}
|
||||
|
||||
void SingleLensReflexCameraWindow::OpenAndTakePhotoSLRCamera()
|
||||
{
|
||||
emit OpenAndTakePhotoSLRCameraSignal();
|
||||
}
|
||||
|
||||
void SingleLensReflexCameraWindow::stopTakePhoto()
|
||||
{
|
||||
if (m_SingleLensReflexCameraOperation->getRecordStatus())
|
||||
@ -798,6 +819,64 @@ void SingleLensReflexCameraOperation::takePhoto()
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@ -94,6 +94,7 @@ private:
|
||||
public slots:
|
||||
void OpenSLRCamera();
|
||||
void takePhoto();
|
||||
void OpenAndTakePhotoSLRCamera();
|
||||
void stopTakePhoto();
|
||||
void OpenSLRCamera_callback();
|
||||
void CloseSLRCamera();
|
||||
@ -138,6 +139,7 @@ public Q_SLOTS:
|
||||
|
||||
void openSLRCamera();
|
||||
void takePhoto();
|
||||
void OpenAndTakePhotoSLRCamera();
|
||||
void stopTakePhoto();
|
||||
void onCamOpened();
|
||||
void closeSLRCamera();
|
||||
@ -153,9 +155,13 @@ public Q_SLOTS:
|
||||
void onCaptureStarted();
|
||||
void onCaptureStopped();
|
||||
|
||||
void onStartTimedDataCollection(int lineNum);
|
||||
void onStopTimedDataCollection();
|
||||
|
||||
signals:
|
||||
void openSLRCameraSignal();
|
||||
void takePhotoSignal();
|
||||
void OpenAndTakePhotoSLRCameraSignal();
|
||||
void stopTakePhotoSignal();
|
||||
void closeSLRCameraSignal();
|
||||
void PlotSLRImageSignal();
|
||||
|
||||
@ -30,6 +30,7 @@ TimedDataCollection::TimedDataCollection(QWidget* parent)
|
||||
connect(m_scheduler, &TaskScheduler::startRecordSignal, this, &TimedDataCollection::startRecordSignal);
|
||||
|
||||
connect(this, &TimedDataCollection::sequenceCompleteSignal, m_scheduler, &TaskScheduler::sequenceCompleteSignal);
|
||||
connect(this, &TimedDataCollection::Back2OriginSignal, m_scheduler, &TaskScheduler::Back2OriginSignal);
|
||||
|
||||
//writeRead();
|
||||
readTimedTaskFromFile("D:/0tmp/3Dtest/task.json");
|
||||
@ -54,6 +55,11 @@ void TimedDataCollection::subTaskCompleted(int status)
|
||||
emit sequenceCompleteSignal(status);
|
||||
}
|
||||
|
||||
void TimedDataCollection::onBack2Origin()
|
||||
{
|
||||
emit Back2OriginSignal();
|
||||
}
|
||||
|
||||
void TimedDataCollection::startScheduler()
|
||||
{
|
||||
if (m_scheduler) {
|
||||
|
||||
@ -22,6 +22,7 @@ public Q_SLOTS:
|
||||
void startScheduler();
|
||||
void stopScheduler();
|
||||
void subTaskCompleted(int status);
|
||||
void onBack2Origin();
|
||||
|
||||
Q_SIGNALS:
|
||||
void taskStarted(int taskId);
|
||||
@ -39,6 +40,7 @@ Q_SIGNALS:
|
||||
|
||||
// 马达反馈的信号
|
||||
void sequenceCompleteSignal(int status);
|
||||
void Back2OriginSignal();
|
||||
|
||||
private:
|
||||
Ui::TimedDataCollection_ui ui;
|
||||
|
||||
@ -273,13 +273,17 @@ void TaskExecutor::onSequenceComplete(int status)
|
||||
|
||||
emit subTaskFinished(m_currentSubTaskIndex, subTask.type, (status == 0));
|
||||
}
|
||||
}
|
||||
|
||||
void TaskExecutor::onBack2Origin()
|
||||
{
|
||||
// 检查是否还有更多子任务
|
||||
m_currentSubTaskIndex++;
|
||||
if (m_currentSubTaskIndex < m_task.subTasks.size()) {
|
||||
// 执行下一个子任务
|
||||
QTimer::singleShot(100, this, &TaskExecutor::executeNextSubTask);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// 所有子任务完成
|
||||
m_isRunning = false;
|
||||
qDebug() << "TaskExecutor: All subtasks completed";
|
||||
@ -498,6 +502,7 @@ void TaskScheduler::executeTask(TimedTask& task)
|
||||
this, &TaskScheduler::startRecordSignal);
|
||||
|
||||
connect(this, &TaskScheduler::sequenceCompleteSignal, m_currentExecutor, &TaskExecutor::onSequenceComplete);
|
||||
connect(this, &TaskScheduler::Back2OriginSignal, m_currentExecutor, &TaskExecutor::onBack2Origin);
|
||||
|
||||
// 开始执行
|
||||
m_currentExecutor->execute(task);
|
||||
|
||||
@ -147,6 +147,7 @@ signals:
|
||||
|
||||
public slots:
|
||||
void onSequenceComplete(int status);
|
||||
void onBack2Origin();
|
||||
void onError(const QString& error);
|
||||
|
||||
private:
|
||||
@ -200,6 +201,7 @@ signals:
|
||||
|
||||
// 马达反馈的信号
|
||||
void sequenceCompleteSignal(int status);
|
||||
void Back2OriginSignal();
|
||||
|
||||
private slots:
|
||||
void checkTasks(); // 检查任务是否该启动
|
||||
|
||||
@ -103,6 +103,61 @@ void TwoMotorControl::record_white()
|
||||
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 = new TwoMotionCaptureCoordinator(m_multiAxisController);
|
||||
connect(this, SIGNAL(start(QVector<PathLine>)), m_coordinator, SLOT(start(QVector<PathLine>)));
|
||||
|
||||
connect(m_coordinator, &TwoMotionCaptureCoordinator::startRecordLineNumSignal, this, &TwoMotorControl::receiveStartRecordLineNum);
|
||||
connect(m_coordinator, &TwoMotionCaptureCoordinator::finishRecordLineNumSignal, this, &TwoMotorControl::receiveFinishRecordLineNum);
|
||||
|
||||
connect(m_coordinator, &TwoMotionCaptureCoordinator::startRecordLineNumSignal, window, &SingleLensReflexCameraWindow::onStartTimedDataCollection);
|
||||
connect(m_coordinator, &TwoMotionCaptureCoordinator::sequenceComplete, window, &SingleLensReflexCameraWindow::onStopTimedDataCollection);
|
||||
|
||||
connect(m_coordinator, &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->deleteLater();
|
||||
emit back2OriginSignal();
|
||||
}
|
||||
|
||||
void TwoMotorControl::run()
|
||||
{
|
||||
if (getState())
|
||||
@ -130,6 +185,7 @@ void TwoMotorControl::run()
|
||||
connect(m_coordinator, SIGNAL(startRecordLineNumSignal(int)), this, SLOT(receiveStartRecordLineNum(int)));
|
||||
connect(m_coordinator, SIGNAL(finishRecordLineNumSignal(int)), this, SLOT(receiveFinishRecordLineNum(int)));
|
||||
connect(m_coordinator, SIGNAL(sequenceComplete(int)), this, SLOT(onSequenceComplete(int)));
|
||||
connect(m_coordinator, &TwoMotionCaptureCoordinator::back2OriginSignal, this, &TwoMotorControl::onBack2Origin);
|
||||
|
||||
connect(m_coordinator, &TwoMotionCaptureCoordinator::startRecordHSISignal, m_Imager, &ImagerOperationBase::start_record);
|
||||
connect(m_coordinator, &TwoMotionCaptureCoordinator::stopRecordHSISignal, this, &TwoMotorControl::stop_record);
|
||||
@ -268,11 +324,16 @@ void TwoMotorControl::onSequenceComplete(int status)
|
||||
isWritePosFile = false;
|
||||
fclose(m_posFileHandle);
|
||||
|
||||
emit sequenceComplete(status);
|
||||
}
|
||||
|
||||
void TwoMotorControl::onBack2Origin()
|
||||
{
|
||||
m_coordinatorThread.quit();
|
||||
m_coordinatorThread.wait();
|
||||
m_coordinator = nullptr;
|
||||
|
||||
emit sequenceComplete(status);
|
||||
emit back2OriginSignal();
|
||||
}
|
||||
|
||||
bool TwoMotorControl::getMotorsConnectionStatus()
|
||||
|
||||
@ -10,6 +10,9 @@
|
||||
#include "CaptureCoordinator.h"
|
||||
#include "MotorWindowBase.h"
|
||||
|
||||
#include "SingleLensReflexCameraWindow.h"
|
||||
#include "DepthCameraWindow.h"
|
||||
|
||||
#define PI 3.1415926
|
||||
|
||||
class TwoMotorControl : public QDialog, public MotorWindowBase
|
||||
@ -71,6 +74,10 @@ public Q_SLOTS:
|
||||
void receiveStartRecordLineNum(int lineNum);
|
||||
void receiveFinishRecordLineNum(int lineNum);
|
||||
void onSequenceComplete(int status);
|
||||
void onBack2Origin();
|
||||
|
||||
void run2(SingleLensReflexCameraWindow* w);
|
||||
void onBack2Origin2();
|
||||
|
||||
void stop_record();
|
||||
|
||||
@ -89,6 +96,7 @@ signals:
|
||||
|
||||
void startLineNumSignal(int lineNum);
|
||||
void sequenceComplete(int status);//所有采集线正常运行完成
|
||||
void back2OriginSignal();
|
||||
|
||||
void broadcastLocationSignal(std::vector<double>);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user