add,山地所贡嘎山8:

1、在类GonggashanTaskExecutor中状态机协调控制整个采集流程;
This commit is contained in:
tangchao0503
2026-08-31 17:22:42 +08:00
parent 9307947ed0
commit ebc39f9f9d
11 changed files with 756 additions and 15 deletions

View File

@ -972,3 +972,241 @@ double OneMotionCoordinator::getErrorRate(double targetLoc, double actualLoc)
return errorRate;
}
//---------------------------------------------------------------------------------------------------------------------------------------------
OneMotorMultiPosCoordinator::OneMotorMultiPosCoordinator(
IrisMultiMotorController* motorCtrl,
ImagerOperationBase* cameraCtrl,
QObject* parent)
: QObject(parent)
, m_motorCtrl(motorCtrl)
, m_cameraCtrl(cameraCtrl)
, m_currentPos(0)
, m_isRunning(false)
, m_isZeroing(false)
{
//这些信号槽是按照逻辑顺序的
connect(this, SIGNAL(moveTo(int, double, double, int)),
m_motorCtrl, SLOT(moveTo(int, double, double, int)));
connect(this, &OneMotorMultiPosCoordinator::zeroStart,
m_motorCtrl, &IrisMultiMotorController::zeroStart);
connect(m_motorCtrl, &IrisMultiMotorController::motorStopSignal,
this, &OneMotorMultiPosCoordinator::handlePositionReached);
//connect(m_motorCtrl, &IrisMultiMotorController::moveFailed,
// this, &OneMotorMultiPosCoordinator::handleError);
connect(this, &OneMotorMultiPosCoordinator::getFocusIndexSobel,
m_cameraCtrl, &ImagerOperationBase::auto_exposure);
connect(m_cameraCtrl, &ImagerOperationBase::autoExposureSignal,
this, &OneMotorMultiPosCoordinator::handleCaptureComplete);
//connect(m_cameraCtrl, &ImagerOperationBase::captureFailed,
// this, &OneMotorMultiPosCoordinator::handleError);
}
OneMotorMultiPosCoordinator::~OneMotorMultiPosCoordinator()
{
}
void OneMotorMultiPosCoordinator::startStepMotion(double speed, std::vector<double> locations)
{
QMutexLocker locker(&m_dataMutex);
if (locations.empty())
{
emit sequenceComplete(1);
return;
}
if (m_isRunning)
{
emit errorOccurred("Sequence already running");
return;
}
m_locations = locations;
m_counter = 0;
m_positionData.clear();
m_speed = speed;
m_iStepIntervalRealTime = 1;
m_isRunning = true;
m_isZeroing = true;
// 先执行归零操作
emit zeroStart(0);
qDebug() << "OneMotorMultiPosCoordinator::startStepMotion: Zeroing started.";
}
void OneMotorMultiPosCoordinator::startMotionSequence()
{
QMutexLocker locker(&m_dataMutex);
m_isZeroing = false;
qDebug() << "OneMotorMultiPosCoordinator::startMotionSequence: Zeroing complete. Starting motion sequence.";
processNextPosition();
}
void OneMotorMultiPosCoordinator::handleZeroComplete(int motorID, double pos)
{
if (!m_isRunning || !m_isZeroing) return;
// 归零完成,开始分步运动
startMotionSequence();
}
void OneMotorMultiPosCoordinator::stopStepMotion()
{
QMutexLocker locker(&m_dataMutex);
m_isRunning = false;
emit sequenceStopped();
}
QVector<PositionsLogData> OneMotorMultiPosCoordinator::getAllPositionData() const
{
//QMutexLocker locker(&m_dataMutex);
return m_positionData;
}
bool OneMotorMultiPosCoordinator::saveToCsv(const QString& filename)
{
//QMutexLocker locker(&m_dataMutex);
QFile file(filename);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
{
return false;
}
QTextStream out(&file);
out << "Timestamp,targetPosition,ActualPosition,exposureTime\n";
for (const auto& data : m_positionData)
{
out << data.timestamp.toString("yyyy-MM-dd HH:mm:ss.zzz") << ","
<< QString::number(data.targetPosition, 'f', 4) << ","
<< QString::number(data.actualPosition, 'f', 4) << ","
<< QString::number(data.exposureTime, 'f', 4) << "\n";
}
file.close();
return true;
}
void OneMotorMultiPosCoordinator::handlePositionReached(int motorID, double pos)
{
if (!m_isRunning) return;
// 如果正在等待归零完成,调用归零完成处理
if (m_isZeroing)
{
handleZeroComplete(motorID, pos);
return;
}
QMutexLocker locker(&m_dataMutex);
//验证马达运动位置是否到达指定位置
//if (pos != m_currentPos) return;
// 记录位置信息
PositionsLogData data;
data.targetPosition = m_currentPos;
data.actualPosition = pos;
data.timestamp = QDateTime::currentDateTime();
m_positionData.append(data);
// 开始采集
emit getFocusIndexSobel();
}
void OneMotorMultiPosCoordinator::handleCaptureComplete(double index)
{
if (!m_isRunning) return;
QMutexLocker locker(&m_dataMutex);
// 更新最近一条记录的相机指数
//if (!m_positionData.isEmpty() &&
// m_positionData.last().targetPosition == m_positionData.last().actualPosition)
//{
// m_positionData.last().cameraIndex = index;
//}
m_positionData.last().exposureTime = index;
std::cout << "" << m_counter << "次曝光:" << std::endl;
std::cout << "目标位置:" << m_positionData.last().targetPosition << std::endl;
std::cout << "实际位置:" << m_positionData.last().actualPosition << std::endl;
std::cout << "曝光时间:" << m_positionData.last().exposureTime << std::endl;
processNextPosition();
}
void OneMotorMultiPosCoordinator::handleError(const QString& error)
{
QMutexLocker locker(&m_dataMutex);
m_isRunning = false;
emit errorOccurred(error);
}
void OneMotorMultiPosCoordinator::processNextPosition()
{
if (!m_isRunning) return;
if (m_locations.empty())
{
m_isRunning = false;
emit sequenceComplete(0);
// 计算平均曝光时间
double avgExposureTime = 0.0;
for (const auto& data : m_positionData) {
avgExposureTime += data.exposureTime;
}
if (!m_positionData.isEmpty()) {
avgExposureTime /= m_positionData.size();
}
emit hyperAutoExposureDoneSignal(avgExposureTime);
m_cameraCtrl->setIntegrationTime(avgExposureTime);
return;
}
m_currentPos = m_locations.front();
m_locations.erase(m_locations.begin());
emit moveTo(0, m_currentPos, m_speed, 1000);
}

View File

@ -300,3 +300,74 @@ private:
int m_retryTimes;
bool m_reached;
};
// 数据记录结构体
struct PositionsLogData
{
double targetPosition; // 目标位置
double actualPosition; // 实际马达位置
double exposureTime; //
QDateTime timestamp; // 时间戳
PositionsLogData(double target = 0, double actual = 0.0, double exposure = 0.0)
: targetPosition(target), actualPosition(actual),
exposureTime(exposure ), timestamp(QDateTime::currentDateTime()) {
}
};
// 协调控制器
class OneMotorMultiPosCoordinator : public QObject
{
Q_OBJECT
public:
OneMotorMultiPosCoordinator(IrisMultiMotorController* motorCtrl,
ImagerOperationBase* cameraCtrl,
QObject* parent = nullptr);
~OneMotorMultiPosCoordinator();
QVector<PositionsLogData> getAllPositionData() const;
bool saveToCsv(const QString& filename);
public slots:
void startStepMotion(double speed, std::vector<double> locations);
void stopStepMotion();
signals:
void progressChanged(int progress);
void sequenceComplete(int status);
void sequenceStopped();
void errorOccurred(const QString& error);
void moveTo(int, double, double, int);
void getFocusIndexSobel();
void zeroStart(int motorID);
void hyperAutoExposureDoneSignal(double exposureTime);
private slots:
void handlePositionReached(int motorID, double pos);
void handleCaptureComplete(double index);
void handleError(const QString& error);
void handleZeroComplete(int motorID, double pos);
private:
void processNextPosition();
void startMotionSequence();
IrisMultiMotorController* m_motorCtrl;
ImagerOperationBase* m_cameraCtrl;
QVector<PositionsLogData> m_positionData;
mutable QMutex m_dataMutex;
double m_currentPos;
bool m_isRunning;
double m_speed;
int m_iStepInterval;
int m_iStepIntervalRealTime;
int m_counter;
bool m_isZeroing;
std::vector<double> m_locations;
};

View File

@ -55,6 +55,7 @@ void GonggaShanRecordCtl::logStatus(const QString& message, bool isHearderBlankL
GonggaShanRecordCtl::GonggaShanRecordCtl(QWidget* parent)
: QDialog(parent)
, m_taskScheduler(new GonggashanTaskScheduler(this))
, m_taskExecutor(new GonggashanTaskExecutor(this))
{
ui.setupUi(this);
@ -66,6 +67,20 @@ GonggaShanRecordCtl::GonggaShanRecordCtl(QWidget* parent)
connect(ui.spinbox_Port, QOverload<int>::of(&QSpinBox::valueChanged), [this](int value) {
AppSettings::instance().setGonggaShanRecordPort(value);
});
// 连接 GonggashanTaskExecutor 信号
connect(m_taskExecutor, &GonggashanTaskExecutor::finished,
this, &GonggaShanRecordCtl::onTaskExecutorFinished);
connect(m_taskExecutor, &GonggashanTaskExecutor::hyperAutoExposureSignal_gonggashan,
this, &GonggaShanRecordCtl::hyperAutoExposureSignal_gonggashan);
connect(this, &GonggaShanRecordCtl::hyperAutoExposureDoneSignal_gonggashan,
m_taskExecutor, &GonggashanTaskExecutor::onHyperExposureComplete);
connect(m_taskExecutor, &GonggashanTaskExecutor::fiberExposureSignal,
this, &GonggaShanRecordCtl::fiberExposureSignal_gonggashan);
connect(this, &GonggaShanRecordCtl::fiberExposureDoneSignal_gonggashan,
m_taskExecutor, &GonggashanTaskExecutor::onFiberExposureComplete);
}
GonggaShanRecordCtl::~GonggaShanRecordCtl()
@ -112,18 +127,11 @@ void GonggaShanRecordCtl::stopListen()
void GonggaShanRecordCtl::startRecord(int position)
{
if (m_taskScheduler->isTaskRunning())
{
logStatus("Data collection has begun....");
return;
}
QString pos = QString::number(position);
logStatus("Reach pos: " + pos, true);
m_taskScheduler->setTaskRunning(true);
emit startRcordSignal("pos_" + pos);
m_taskExecutor->start("pos_" + pos);
}
void GonggaShanRecordCtl::onFiberImagerStartExposureSignal()
@ -144,3 +152,262 @@ void GonggaShanRecordCtl::onRcordFinished()
logStatus("Record Finished.");
}
void GonggaShanRecordCtl::onTaskExecutorFinished(bool success)
{
qDebug() << "GonggaShanRecordCtl: TaskExecutor finished, success:" << success;
if (success) {
logStatus("Task completed successfully.");
} else {
logStatus("Task failed or stopped.");
}
m_taskScheduler->setTaskRunning(false);
}
// ==================== GonggashanTaskExecutor 实现 ====================
GonggashanTaskExecutor::GonggashanTaskExecutor(QObject* parent)
: QObject(parent)
, m_machine(new QStateMachine(this))
{
buildStateMachine();
}
GonggashanTaskExecutor::~GonggashanTaskExecutor()
{
if (m_machine) {
m_machine->stop();
}
}
void GonggashanTaskExecutor::buildStateMachine()
{
// ---- 创建所有状态 ----
m_hyperExposureState = new QState(QState::ExclusiveStates);
m_hyperExposureState->setObjectName("HyperExposure");
m_fiberExposureState = new QState(QState::ExclusiveStates);
m_fiberExposureState->setObjectName("FiberExposure");
m_gpsAcquisitionState = new QState(QState::ExclusiveStates);
m_gpsAcquisitionState->setObjectName("GpsAcquisition");
m_motorCalcState = new QState(QState::ExclusiveStates);
m_motorCalcState->setObjectName("MotorCalc");
m_dataCollectionState = new QState(QState::ExclusiveStates);
m_dataCollectionState->setObjectName("DataCollection");
m_finalState = new QFinalState();
m_finalState->setObjectName("Completed");
// ---- HyperExposure 状态:等待外部硬件回调 ----
connect(m_hyperExposureState, &QState::entered, this, [this]() {
qDebug() << "GonggashanTaskExecutor: Enter m_hyperExposureState";
emit hyperAutoExposureSignal_gonggashan();
});
connect(m_hyperExposureState, &QState::exited, this, [this]() {
qDebug() << "GonggashanTaskExecutor: Exit m_hyperExposureState";
leavePhase(m_hyperExposureState);
});
QSignalTransition* hyperDone = new QSignalTransition(this, &GonggashanTaskExecutor::hyperExposureDone);
hyperDone->setTargetState(m_fiberExposureState);
m_hyperExposureState->addTransition(hyperDone);
//m_hyperExposureState->addTransition(this, &GonggashanTaskExecutor::hyperExposureDone, m_fiberExposureState);
// ---- FiberExposure 状态:等待外部硬件回调 ----
connect(m_fiberExposureState, &QState::entered, this, [this]() {
qDebug() << "GonggashanTaskExecutor: Enter m_fiberExposureState";
emit fiberExposureSignal();
});
connect(m_fiberExposureState, &QState::exited, this, [this]() {
qDebug() << "GonggashanTaskExecutor: Exit m_fiberExposureState";
leavePhase(m_fiberExposureState);
});
QSignalTransition* fiberDone = new QSignalTransition(this, &GonggashanTaskExecutor::fiberExposureDone);
fiberDone->setTargetState(m_gpsAcquisitionState);
m_fiberExposureState->addTransition(fiberDone);
// ---- GpsAcquisition 状态:等待外部硬件回调 ----
connect(m_gpsAcquisitionState, &QState::entered, this, [this]() {
qDebug() << "GonggashanTaskExecutor: Enter m_gpsAcquisitionState";
emit gpsAcquisitionSignal();
});
connect(m_gpsAcquisitionState, &QState::exited, this, [this]() {
qDebug() << "GonggashanTaskExecutor: Exit m_gpsAcquisitionState";
leavePhase(m_gpsAcquisitionState);
});
QSignalTransition* gpsDone = new QSignalTransition(this, &GonggashanTaskExecutor::gpsAcquisitionDone);
gpsDone->setTargetState(m_motorCalcState);
m_gpsAcquisitionState->addTransition(gpsDone);
// ---- MotorCalc 状态:等待外部硬件回调 ----
connect(m_motorCalcState, &QState::entered, this, [this]() {
qDebug() << "GonggashanTaskExecutor: Enter m_motorCalcState";
});
connect(m_motorCalcState, &QState::exited, this, [this]() {
qDebug() << "GonggashanTaskExecutor: Exit m_motorCalcState";
leavePhase(m_motorCalcState);
});
QSignalTransition* motorDone = new QSignalTransition(this, &GonggashanTaskExecutor::motorSpeedDone);
motorDone->setTargetState(m_dataCollectionState);
m_motorCalcState->addTransition(motorDone);
// ---- DataCollection 状态:同步阶段 ----
connect(m_dataCollectionState, &QState::entered, this, [this]() {
qDebug() << "GonggashanTaskExecutor: Enter m_dataCollectionState";
if (dataCollectionImpl()) {
QTimer::singleShot(0, this, &GonggashanTaskExecutor::dataCollectionDone);
}
});
connect(m_dataCollectionState, &QState::exited, this, [this]() {
qDebug() << "GonggashanTaskExecutor: Exit m_dataCollectionState";
leavePhase(m_dataCollectionState);
});
QSignalTransition* collDone = new QSignalTransition(this, &GonggashanTaskExecutor::dataCollectionDone);
collDone->setTargetState(m_finalState);
m_dataCollectionState->addTransition(collDone);
// ---- FinalState完成 ----
connect(m_finalState, &QState::entered, this, &GonggashanTaskExecutor::onFinalStateEntered);
// ---- stop() 可在任何状态下触发,直接跳转到 finalState ----
QSignalTransition* stopTrans = new QSignalTransition(this, &GonggashanTaskExecutor::stopRequested);
stopTrans->setTargetState(m_finalState);
for (QState* s : {
m_hyperExposureState,
m_fiberExposureState, m_gpsAcquisitionState, m_motorCalcState,
m_dataCollectionState
}) {
s->addTransition(stopTrans);
}
// ---- 设置状态机 ----
m_machine->addState(m_hyperExposureState);
m_machine->addState(m_fiberExposureState);
m_machine->addState(m_gpsAcquisitionState);
m_machine->addState(m_motorCalcState);
m_machine->addState(m_dataCollectionState);
m_machine->addState(m_finalState);
m_machine->setInitialState(m_hyperExposureState);
}
QState* GonggashanTaskExecutor::currentState() const
{
if (!m_machine || m_machine->configuration().isEmpty()) {
return nullptr;
}
return qobject_cast<QState*>(*m_machine->configuration().begin());
}
void GonggashanTaskExecutor::leavePhase(QState* state)
{
Q_UNUSED(state);
}
void GonggashanTaskExecutor::onFinalStateEntered()
{
qDebug() << "GonggashanTaskExecutor: Final state entered, stopRequested:" << m_stopRequested;
emit finished(!m_stopRequested);
m_stopRequested = false;
}
void GonggashanTaskExecutor::start(const QString& posInfo)
{
if (isRunning()) {
qDebug() << "GonggashanTaskExecutor: Task is running, ignore new signal";
return;
}
m_machine->start();
m_posInfo = posInfo;
m_stopRequested = false;
qDebug() << "GonggashanTaskExecutor: Starting with pos:" << posInfo;
QTimer::singleShot(0, this, [this, posInfo]() {
emit taskStartRequested(posInfo);
});
}
void GonggashanTaskExecutor::stop()
{
if (!isRunning()) return;
m_stopRequested = true;
qDebug() << "GonggashanTaskExecutor: Stop requested";
emit stopRequested();
}
void GonggashanTaskExecutor::onHyperExposureComplete(int exposureTime)
{
if (currentState() != m_hyperExposureState) return;
m_hyperExposureTime = exposureTime;
hyperExposureImpl(exposureTime);
emit hyperExposureDone();
}
void GonggashanTaskExecutor::onFiberExposureComplete(int exposureTime)
{
if (currentState() != m_fiberExposureState) return;
m_fiberExposureTime = exposureTime;
fiberExposureImpl(exposureTime);
emit fiberExposureDone();
}
void GonggashanTaskExecutor::onGpsAcquired(double latitude, double longitude, double altitude)
{
if (currentState() != m_gpsAcquisitionState) return;
m_gpsData = QString("%1,%2,%3").arg(latitude).arg(longitude).arg(altitude);
gpsAcquisitionImpl(latitude, longitude, altitude);
emit gpsAcquisitionDone();
}
void GonggashanTaskExecutor::onMotorSpeedCalculated(double speed)
{
if (currentState() != m_motorCalcState) return;
m_motorSpeed = speed;
emit motorSpeedSignal(speed);
if (motorCalcImpl()) {
emit motorSpeedDone();
}
}
bool GonggashanTaskExecutor::preparationImpl()
{
qDebug() << "GonggashanTaskExecutor: Enter m_preparationState\n";
return true;
}
bool GonggashanTaskExecutor::hyperExposureImpl(int exposureTime)
{
qDebug() << "GonggashanTaskExecutor: Hyper exposure complete, time:" << exposureTime;
return true;
}
bool GonggashanTaskExecutor::fiberExposureImpl(int exposureTime)
{
qDebug() << "GonggashanTaskExecutor: Fiber exposure complete, time:" << exposureTime;
return true;
}
bool GonggashanTaskExecutor::gpsAcquisitionImpl(double lat, double lon, double alt)
{
qDebug() << "GonggashanTaskExecutor: GPS acquired:" << lat << lon << alt;
return true;
}
bool GonggashanTaskExecutor::motorCalcImpl()
{
qDebug() << "GonggashanTaskExecutor: Motor speed calculated:" << m_motorSpeed;
return true;
}
bool GonggashanTaskExecutor::dataCollectionImpl()
{
qDebug() << "GonggashanTaskExecutor: Start data collection";
emit startCollectionSignal(m_posInfo, m_gpsData);
return true;
}

View File

@ -10,12 +10,29 @@
#include <QFile>
#include <QTextStream>
#include <QDir>
#include <QStateMachine>
#include <QSignalTransition>
#include <QFinalState>
#include <QTimer>
#include "ui_gonggashanCtl.h"
#include "CommunicationViaTCP.h"
#include "AppSettings.h"
// ============ 执行阶段枚举 ============
enum class GonggaShanExecPhase {
Idle, // 空闲
Preparation, // 准备阶段
HyperExposure, // 高光谱传感器曝光
FiberExposure, // 光纤光谱仪曝光
GpsAcquisition, // 获取GPS位置
MotorCalc, // 计算马达速度
DataCollection, // 开始采集高光谱、FODIS、rgb相机
Completed // 完成
};
// ============ 任务调度器 ============
class GonggashanTaskScheduler : public QObject
{
Q_OBJECT
@ -40,6 +57,79 @@ private:
TaskState m_taskState;
};
// ============ 任务执行器 ============
class GonggashanTaskExecutor : public QObject
{
Q_OBJECT
public:
explicit GonggashanTaskExecutor(QObject* parent = nullptr);
~GonggashanTaskExecutor();
bool isRunning() const { return m_machine && m_machine->isRunning() && !m_machine->configuration().isEmpty(); }
public slots:
void start(const QString& posInfo);
void stop();
void onHyperExposureComplete(int exposureTime);
void onFiberExposureComplete(int exposureTime);
void onGpsAcquired(double latitude, double longitude, double altitude);
void onMotorSpeedCalculated(double speed);
signals:
void hyperAutoExposureSignal_gonggashan();
void fiberExposureSignal();
void gpsAcquisitionSignal();
void motorSpeedSignal(double speed);
void startCollectionSignal(const QString& posInfo, const QString& gpsData);
void finished(bool success);
void errorOccurred(const QString& error);
// ---- 以下为状态机内部信号,供 transition 使用 ----
void taskStartRequested(const QString& posInfo);
void preparationComplete();
void hyperExposureDone();
void fiberExposureDone();
void gpsAcquisitionDone();
void motorSpeedDone();
void dataCollectionDone();
void stopRequested();
protected:
virtual bool preparationImpl();
virtual bool hyperExposureImpl(int exposureTime);
virtual bool fiberExposureImpl(int exposureTime);
virtual bool gpsAcquisitionImpl(double lat, double lon, double alt);
virtual bool motorCalcImpl();
virtual bool dataCollectionImpl();
private slots:
void onFinalStateEntered();
private:
void buildStateMachine();
QState* currentState() const;
void leavePhase(QState* state);
QString m_posInfo;
QString m_gpsData;
double m_motorSpeed = 0.0;
int m_hyperExposureTime = 0;
int m_fiberExposureTime = 0;
bool m_stopRequested = false;
// Qt State Machine
QStateMachine* m_machine = nullptr;
QState* m_hyperExposureState = nullptr;
QState* m_fiberExposureState = nullptr;
QState* m_gpsAcquisitionState = nullptr;
QState* m_motorCalcState = nullptr;
QState* m_dataCollectionState = nullptr;
QFinalState* m_finalState = nullptr;
};
class GonggaShanRecordCtl : public QDialog
{
Q_OBJECT
@ -55,6 +145,12 @@ public Q_SLOTS:
void onFiberImagerExposureCompleteSignal(int exposureTime);
Q_SIGNALS:
void hyperAutoExposureSignal_gonggashan();
void hyperAutoExposureDoneSignal_gonggashan(double exposureTime);
void fiberExposureSignal_gonggashan();
void fiberExposureDoneSignal_gonggashan(double exposureTime);
// Emitted when user changes any of the R/G/B wavelength values
void startRcordSignal(QString posInfo);
@ -64,12 +160,16 @@ private Q_SLOTS:
void startRecord(int position);
// GonggashanTaskExecutor 反馈槽
void onTaskExecutorFinished(bool success);
private:
void logStatus(const QString& message, bool isHearderBlankLine = false, bool isTailBlankLine = false);
Ui::gongga_control ui;
QPointer<MotorParams::CommunicationViaTCP> tcpServer6005;
GonggashanTaskScheduler* m_taskScheduler;
GonggashanTaskExecutor* m_taskExecutor; // 新增
QString m_logFilePath;
QFile m_logFile;
QTextStream m_logStream;

View File

@ -1112,16 +1112,40 @@ void HPPA::initControlTabwidget()
void HPPA::setupGonggashanAutoRecordConnection()
{
connect(m_gonggaShanRecordCtl, &GonggaShanRecordCtl::startRcordSignal, this, &HPPA::onGonggashanRecord);
connect(m_gonggaShanRecordCtl, &GonggaShanRecordCtl::hyperAutoExposureSignal_gonggashan, this, &HPPA::onGonggashanHyperAutoExposure);
connect(m_omc, &OneMotorControl::hyperAutoExposureDoneSignal_gonggashan, m_gonggaShanRecordCtl, &GonggaShanRecordCtl::hyperAutoExposureDoneSignal_gonggashan);
connect(m_gonggaShanRecordCtl, &GonggaShanRecordCtl::fiberExposureSignal_gonggashan, this, &HPPA::onGonggashanFiberAutoExposure);
connect(m_fodisWindow, &FodisWindow::exposureCompleteSignal, m_gonggaShanRecordCtl, &GonggaShanRecordCtl::fiberExposureDoneSignal_gonggashan);
connect(m_fodisWindow, &FodisWindow::startExposureSignal, m_gonggaShanRecordCtl, &GonggaShanRecordCtl::onFiberImagerStartExposureSignal);
connect(m_fodisWindow, &FodisWindow::exposureCompleteSignal, this, &HPPA::onStartRecordStep1);
connect(m_fodisWindow, &FodisWindow::exposureCompleteSignal, m_gonggaShanRecordCtl, &GonggaShanRecordCtl::onFiberImagerExposureCompleteSignal);
connect(m_gonggaShanRecordCtl, &GonggaShanRecordCtl::startRcordSignal, this, &HPPA::onGonggashanRecord);
connect(m_omc, &OneMotorControl::sequenceComplete, m_fodisWindow, &FodisWindow::closeFiberImager);
connect(m_omc, &OneMotorControl::sequenceComplete, m_gonggaShanRecordCtl, &GonggaShanRecordCtl::onRcordFinished);
}
void HPPA::onGonggashanHyperAutoExposure()
{
//连接马达和光谱仪
m_omc->connectMotor(false);
if (!testImagerVality())
{
onconnect();
}
m_omc->setImager(m_Imager);
m_omc->multiPosHyperAutoExposure();
}
void HPPA::onGonggashanFiberAutoExposure()
{
//m_fodisWindow->openFiberImager_expose_record(posInfo);
}
void HPPA::onGonggashanRecord(QString posInfo)
{
//设置文件名

View File

@ -458,6 +458,8 @@ public Q_SLOTS:
void onStretchProcessingError(int fileNumber, const QString& filePath, const QString& error);
void onGonggashanRecord(QString posInfo);
void onGonggashanHyperAutoExposure();
void onGonggashanFiberAutoExposure();
protected:
void closeEvent(QCloseEvent* event) override;

View File

@ -68,11 +68,12 @@ double ImagerOperationBase::auto_exposure()
imagerStopCollect();
emit autoExposureSignal();
double exposureTime = getIntegrationTime();
emit autoExposureSignal(exposureTime);
//std::cout << "自动曝光:" << getIntegrationTime() << std::endl;
//std::cout << "自动曝光:" << exposureTime << std::endl;
return getIntegrationTime();
return exposureTime;
}
void ImagerOperationBase::focus()

View File

@ -117,7 +117,7 @@ signals:
void testImagerStatus();//表示可以测试相机连接状态:是否连接,并反映到界面上
void autoExposureSignal();
void autoExposureSignal(double exposureTime);
// 新增:当一组影像文件(.bil/.hdr写入完成后发出会从采集线程发出Qt 会做 queued connection
void ImageFileSaved(const QString& path, int fileIndex);

View File

@ -248,6 +248,34 @@ void OneMotorControl::stop()
emit stopStepMotionSignal();
}
void OneMotorControl::multiPosHyperAutoExposure()
{
//所有该自动曝光的位置
std::vector<double> maxRangeLocations = m_multiAxisController->getMaxPos();
double maxPos = maxRangeLocations[0];
std::vector<double> locations;
locations.push_back(maxPos * 0.2);
locations.push_back(maxPos * 0.5);
locations.push_back(maxPos * 0.8);
//创建协调器,并连接信号槽
m_coordinator_gonggashan_autoexpose = new OneMotorMultiPosCoordinator(m_multiAxisController, m_Imager);
//connect(this, SIGNAL(stopStepMotionSignal()), m_coordinator_gonggashan_autoexpose, SLOT(stopStepMotion()));
connect(m_coordinator_gonggashan_autoexpose, &OneMotorMultiPosCoordinator::sequenceComplete, this, &OneMotorControl::onSequenceComplete_gonggashan_autoexpose);
connect(m_coordinator_gonggashan_autoexpose, &OneMotorMultiPosCoordinator::hyperAutoExposureDoneSignal, this, &OneMotorControl::hyperAutoExposureDoneSignal_gonggashan);
m_coordinator_gonggashan_autoexpose->startStepMotion(ui.speed_lineEdit->text().toDouble(), locations);
}
void OneMotorControl::onSequenceComplete_gonggashan_autoexpose(int state)
{
emit sequenceComplete();
m_coordinator_gonggashan_autoexpose->deleteLater();
}
void OneMotorControl::onSequenceComplete(int state)
{
emit sequenceComplete();

View File

@ -26,6 +26,8 @@ public:
void run();
void stop();
void multiPosHyperAutoExposure();
void record_dark();
void record_white();
@ -47,6 +49,7 @@ public Q_SLOTS:
void onxMotorStop();
void onSequenceComplete(int state);
void onSequenceComplete_gonggashan_autoexpose(int state);
signals:
void moveSignal(int, bool, double, int);
@ -65,6 +68,8 @@ signals:
void broadcastLocationSignal(std::vector<double>);
void hyperAutoExposureDoneSignal_gonggashan(double exposureTime);
private:
Ui::OneMotorControl_UI ui;
@ -78,6 +83,8 @@ private:
DarkAndWhiteCaptureCoordinator* m_whiteCaptureCoordinator = nullptr;
bool m_xMotorConnectionStatus = false;
QPointer<OneMotorMultiPosCoordinator> m_coordinator_gonggashan_autoexpose;
};
class OneMotorControl_LiftingPlatform : public QDialog, public MotorWindowBase

View File

@ -128,9 +128,12 @@ double ResononNirImager::auto_exposure()
reConnectImage();
//imagerStopCollect();
//std::cout << "自动曝光:" << getIntegrationTime() << std::endl;
double exposureTime = getIntegrationTime();
emit autoExposureSignal(exposureTime);
return getIntegrationTime();
//std::cout << "自动曝光:" << exposureTime << std::endl;
return exposureTime;
}
double ResononNirImager::getWavelengthAtBand(int band)