diff --git a/HPPA/CaptureCoordinator.cpp b/HPPA/CaptureCoordinator.cpp index f293628..c799a45 100644 --- a/HPPA/CaptureCoordinator.cpp +++ b/HPPA/CaptureCoordinator.cpp @@ -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(); diff --git a/HPPA/CaptureCoordinator.h b/HPPA/CaptureCoordinator.h index 3303bd9..76d6612 100644 --- a/HPPA/CaptureCoordinator.h +++ b/HPPA/CaptureCoordinator.h @@ -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; diff --git a/HPPA/HPPA.cpp b/HPPA/HPPA.cpp index 4aa1f3e..6a4df56 100644 --- a/HPPA/HPPA.cpp +++ b/HPPA/HPPA.cpp @@ -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轴控制")); diff --git a/HPPA/SingleLensReflexCameraWindow.cpp b/HPPA/SingleLensReflexCameraWindow.cpp index 3f946d9..14baed7 100644 --- a/HPPA/SingleLensReflexCameraWindow.cpp +++ b/HPPA/SingleLensReflexCameraWindow.cpp @@ -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; diff --git a/HPPA/SingleLensReflexCameraWindow.h b/HPPA/SingleLensReflexCameraWindow.h index 3139bf9..dbb1c5d 100644 --- a/HPPA/SingleLensReflexCameraWindow.h +++ b/HPPA/SingleLensReflexCameraWindow.h @@ -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(); diff --git a/HPPA/TimedDataCollection.cpp b/HPPA/TimedDataCollection.cpp index a2c682c..08dbfbb 100644 --- a/HPPA/TimedDataCollection.cpp +++ b/HPPA/TimedDataCollection.cpp @@ -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) { diff --git a/HPPA/TimedDataCollection.h b/HPPA/TimedDataCollection.h index fce9701..6ea86d8 100644 --- a/HPPA/TimedDataCollection.h +++ b/HPPA/TimedDataCollection.h @@ -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; diff --git a/HPPA/TimedDataCollectionDataStructures.cpp b/HPPA/TimedDataCollectionDataStructures.cpp index 18f695e..6d98f3b 100644 --- a/HPPA/TimedDataCollectionDataStructures.cpp +++ b/HPPA/TimedDataCollectionDataStructures.cpp @@ -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); diff --git a/HPPA/TimedDataCollectionDataStructures.h b/HPPA/TimedDataCollectionDataStructures.h index 3e2e0c7..ecab499 100644 --- a/HPPA/TimedDataCollectionDataStructures.h +++ b/HPPA/TimedDataCollectionDataStructures.h @@ -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(); // 检查任务是否该启动 diff --git a/HPPA/TwoMotorControl.cpp b/HPPA/TwoMotorControl.cpp index 668e534..7007f48 100644 --- a/HPPA/TwoMotorControl.cpp +++ b/HPPA/TwoMotorControl.cpp @@ -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)), m_coordinator, SLOT(start(QVector))); + + 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 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() diff --git a/HPPA/TwoMotorControl.h b/HPPA/TwoMotorControl.h index afd9c13..de6a628 100644 --- a/HPPA/TwoMotorControl.h +++ b/HPPA/TwoMotorControl.h @@ -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);