add,山地所贡嘎山8:
1、在类GonggashanTaskExecutor中状态机协调控制整个采集流程;
This commit is contained in:
@ -972,3 +972,241 @@ double OneMotionCoordinator::getErrorRate(double targetLoc, double actualLoc)
|
|||||||
|
|
||||||
return errorRate;
|
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);
|
||||||
|
}
|
||||||
|
|||||||
@ -300,3 +300,74 @@ private:
|
|||||||
int m_retryTimes;
|
int m_retryTimes;
|
||||||
bool m_reached;
|
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;
|
||||||
|
};
|
||||||
|
|||||||
@ -55,6 +55,7 @@ void GonggaShanRecordCtl::logStatus(const QString& message, bool isHearderBlankL
|
|||||||
GonggaShanRecordCtl::GonggaShanRecordCtl(QWidget* parent)
|
GonggaShanRecordCtl::GonggaShanRecordCtl(QWidget* parent)
|
||||||
: QDialog(parent)
|
: QDialog(parent)
|
||||||
, m_taskScheduler(new GonggashanTaskScheduler(this))
|
, m_taskScheduler(new GonggashanTaskScheduler(this))
|
||||||
|
, m_taskExecutor(new GonggashanTaskExecutor(this))
|
||||||
{
|
{
|
||||||
ui.setupUi(this);
|
ui.setupUi(this);
|
||||||
|
|
||||||
@ -66,6 +67,20 @@ GonggaShanRecordCtl::GonggaShanRecordCtl(QWidget* parent)
|
|||||||
connect(ui.spinbox_Port, QOverload<int>::of(&QSpinBox::valueChanged), [this](int value) {
|
connect(ui.spinbox_Port, QOverload<int>::of(&QSpinBox::valueChanged), [this](int value) {
|
||||||
AppSettings::instance().setGonggaShanRecordPort(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()
|
GonggaShanRecordCtl::~GonggaShanRecordCtl()
|
||||||
@ -112,18 +127,11 @@ void GonggaShanRecordCtl::stopListen()
|
|||||||
|
|
||||||
void GonggaShanRecordCtl::startRecord(int position)
|
void GonggaShanRecordCtl::startRecord(int position)
|
||||||
{
|
{
|
||||||
if (m_taskScheduler->isTaskRunning())
|
|
||||||
{
|
|
||||||
logStatus("Data collection has begun....");
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString pos = QString::number(position);
|
QString pos = QString::number(position);
|
||||||
logStatus("Reach pos: " + pos, true);
|
logStatus("Reach pos: " + pos, true);
|
||||||
|
|
||||||
m_taskScheduler->setTaskRunning(true);
|
m_taskScheduler->setTaskRunning(true);
|
||||||
emit startRcordSignal("pos_" + pos);
|
m_taskExecutor->start("pos_" + pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GonggaShanRecordCtl::onFiberImagerStartExposureSignal()
|
void GonggaShanRecordCtl::onFiberImagerStartExposureSignal()
|
||||||
@ -144,3 +152,262 @@ void GonggaShanRecordCtl::onRcordFinished()
|
|||||||
|
|
||||||
logStatus("Record Finished.");
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@ -10,12 +10,29 @@
|
|||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QStateMachine>
|
||||||
|
#include <QSignalTransition>
|
||||||
|
#include <QFinalState>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
#include "ui_gonggashanCtl.h"
|
#include "ui_gonggashanCtl.h"
|
||||||
|
|
||||||
#include "CommunicationViaTCP.h"
|
#include "CommunicationViaTCP.h"
|
||||||
#include "AppSettings.h"
|
#include "AppSettings.h"
|
||||||
|
|
||||||
|
// ============ 执行阶段枚举 ============
|
||||||
|
enum class GonggaShanExecPhase {
|
||||||
|
Idle, // 空闲
|
||||||
|
Preparation, // 准备阶段
|
||||||
|
HyperExposure, // 高光谱传感器曝光
|
||||||
|
FiberExposure, // 光纤光谱仪曝光
|
||||||
|
GpsAcquisition, // 获取GPS位置
|
||||||
|
MotorCalc, // 计算马达速度
|
||||||
|
DataCollection, // 开始采集:高光谱、FODIS、rgb相机
|
||||||
|
Completed // 完成
|
||||||
|
};
|
||||||
|
|
||||||
|
// ============ 任务调度器 ============
|
||||||
class GonggashanTaskScheduler : public QObject
|
class GonggashanTaskScheduler : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -40,6 +57,79 @@ private:
|
|||||||
TaskState m_taskState;
|
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
|
class GonggaShanRecordCtl : public QDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -55,6 +145,12 @@ public Q_SLOTS:
|
|||||||
void onFiberImagerExposureCompleteSignal(int exposureTime);
|
void onFiberImagerExposureCompleteSignal(int exposureTime);
|
||||||
|
|
||||||
Q_SIGNALS:
|
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
|
// Emitted when user changes any of the R/G/B wavelength values
|
||||||
void startRcordSignal(QString posInfo);
|
void startRcordSignal(QString posInfo);
|
||||||
|
|
||||||
@ -64,12 +160,16 @@ private Q_SLOTS:
|
|||||||
|
|
||||||
void startRecord(int position);
|
void startRecord(int position);
|
||||||
|
|
||||||
|
// GonggashanTaskExecutor 反馈槽
|
||||||
|
void onTaskExecutorFinished(bool success);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void logStatus(const QString& message, bool isHearderBlankLine = false, bool isTailBlankLine = false);
|
void logStatus(const QString& message, bool isHearderBlankLine = false, bool isTailBlankLine = false);
|
||||||
|
|
||||||
Ui::gongga_control ui;
|
Ui::gongga_control ui;
|
||||||
QPointer<MotorParams::CommunicationViaTCP> tcpServer6005;
|
QPointer<MotorParams::CommunicationViaTCP> tcpServer6005;
|
||||||
GonggashanTaskScheduler* m_taskScheduler;
|
GonggashanTaskScheduler* m_taskScheduler;
|
||||||
|
GonggashanTaskExecutor* m_taskExecutor; // 新增
|
||||||
QString m_logFilePath;
|
QString m_logFilePath;
|
||||||
QFile m_logFile;
|
QFile m_logFile;
|
||||||
QTextStream m_logStream;
|
QTextStream m_logStream;
|
||||||
|
|||||||
@ -1112,16 +1112,40 @@ void HPPA::initControlTabwidget()
|
|||||||
|
|
||||||
void HPPA::setupGonggashanAutoRecordConnection()
|
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::startExposureSignal, m_gonggaShanRecordCtl, &GonggaShanRecordCtl::onFiberImagerStartExposureSignal);
|
||||||
connect(m_fodisWindow, &FodisWindow::exposureCompleteSignal, this, &HPPA::onStartRecordStep1);
|
connect(m_fodisWindow, &FodisWindow::exposureCompleteSignal, this, &HPPA::onStartRecordStep1);
|
||||||
connect(m_fodisWindow, &FodisWindow::exposureCompleteSignal, m_gonggaShanRecordCtl, &GonggaShanRecordCtl::onFiberImagerExposureCompleteSignal);
|
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_fodisWindow, &FodisWindow::closeFiberImager);
|
||||||
connect(m_omc, &OneMotorControl::sequenceComplete, m_gonggaShanRecordCtl, &GonggaShanRecordCtl::onRcordFinished);
|
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)
|
void HPPA::onGonggashanRecord(QString posInfo)
|
||||||
{
|
{
|
||||||
//设置文件名
|
//设置文件名
|
||||||
|
|||||||
@ -458,6 +458,8 @@ public Q_SLOTS:
|
|||||||
void onStretchProcessingError(int fileNumber, const QString& filePath, const QString& error);
|
void onStretchProcessingError(int fileNumber, const QString& filePath, const QString& error);
|
||||||
|
|
||||||
void onGonggashanRecord(QString posInfo);
|
void onGonggashanRecord(QString posInfo);
|
||||||
|
void onGonggashanHyperAutoExposure();
|
||||||
|
void onGonggashanFiberAutoExposure();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void closeEvent(QCloseEvent* event) override;
|
void closeEvent(QCloseEvent* event) override;
|
||||||
|
|||||||
@ -68,11 +68,12 @@ double ImagerOperationBase::auto_exposure()
|
|||||||
|
|
||||||
imagerStopCollect();
|
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()
|
void ImagerOperationBase::focus()
|
||||||
|
|||||||
@ -117,7 +117,7 @@ signals:
|
|||||||
|
|
||||||
|
|
||||||
void testImagerStatus();//表示可以测试相机连接状态:是否连接,并反映到界面上
|
void testImagerStatus();//表示可以测试相机连接状态:是否连接,并反映到界面上
|
||||||
void autoExposureSignal();
|
void autoExposureSignal(double exposureTime);
|
||||||
|
|
||||||
// 新增:当一组影像文件(.bil/.hdr)写入完成后发出(会从采集线程发出,Qt 会做 queued connection)
|
// 新增:当一组影像文件(.bil/.hdr)写入完成后发出(会从采集线程发出,Qt 会做 queued connection)
|
||||||
void ImageFileSaved(const QString& path, int fileIndex);
|
void ImageFileSaved(const QString& path, int fileIndex);
|
||||||
|
|||||||
@ -248,6 +248,34 @@ void OneMotorControl::stop()
|
|||||||
emit stopStepMotionSignal();
|
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)
|
void OneMotorControl::onSequenceComplete(int state)
|
||||||
{
|
{
|
||||||
emit sequenceComplete();
|
emit sequenceComplete();
|
||||||
|
|||||||
@ -26,6 +26,8 @@ public:
|
|||||||
void run();
|
void run();
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
|
void multiPosHyperAutoExposure();
|
||||||
|
|
||||||
void record_dark();
|
void record_dark();
|
||||||
void record_white();
|
void record_white();
|
||||||
|
|
||||||
@ -47,6 +49,7 @@ public Q_SLOTS:
|
|||||||
void onxMotorStop();
|
void onxMotorStop();
|
||||||
|
|
||||||
void onSequenceComplete(int state);
|
void onSequenceComplete(int state);
|
||||||
|
void onSequenceComplete_gonggashan_autoexpose(int state);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void moveSignal(int, bool, double, int);
|
void moveSignal(int, bool, double, int);
|
||||||
@ -65,6 +68,8 @@ signals:
|
|||||||
|
|
||||||
void broadcastLocationSignal(std::vector<double>);
|
void broadcastLocationSignal(std::vector<double>);
|
||||||
|
|
||||||
|
void hyperAutoExposureDoneSignal_gonggashan(double exposureTime);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::OneMotorControl_UI ui;
|
Ui::OneMotorControl_UI ui;
|
||||||
|
|
||||||
@ -78,6 +83,8 @@ private:
|
|||||||
DarkAndWhiteCaptureCoordinator* m_whiteCaptureCoordinator = nullptr;
|
DarkAndWhiteCaptureCoordinator* m_whiteCaptureCoordinator = nullptr;
|
||||||
|
|
||||||
bool m_xMotorConnectionStatus = false;
|
bool m_xMotorConnectionStatus = false;
|
||||||
|
|
||||||
|
QPointer<OneMotorMultiPosCoordinator> m_coordinator_gonggashan_autoexpose;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OneMotorControl_LiftingPlatform : public QDialog, public MotorWindowBase
|
class OneMotorControl_LiftingPlatform : public QDialog, public MotorWindowBase
|
||||||
|
|||||||
@ -128,9 +128,12 @@ double ResononNirImager::auto_exposure()
|
|||||||
reConnectImage();
|
reConnectImage();
|
||||||
//imagerStopCollect();
|
//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)
|
double ResononNirImager::getWavelengthAtBand(int band)
|
||||||
|
|||||||
Reference in New Issue
Block a user