282 lines
8.7 KiB
C++
282 lines
8.7 KiB
C++
#pragma once
|
||
|
||
#include <QDateTime>
|
||
#include <QString>
|
||
#include <QVector>
|
||
#include <QMetaType>
|
||
#include <QTimer>
|
||
|
||
#include "CaptureCoordinator.h"
|
||
|
||
// ==================== 枚举定义 ====================
|
||
|
||
// 任务状态
|
||
enum class TaskStatus {
|
||
default, //未调度
|
||
Waiting, // 等待
|
||
Running, // 运行中
|
||
Finished, // 结束
|
||
Skiped, //跳过
|
||
Timeout //超时
|
||
};
|
||
|
||
// 子任务类型
|
||
enum class SubTaskType {
|
||
HyperSpectual400_1000nm, // 400nm-1000nm高光谱相机
|
||
HyperSpectual1000_1700nm, // 1000nm-1700nm高光谱相机
|
||
SingleLensReflex, // 单反相机
|
||
DepthCamera, // 深度相机采集任务
|
||
ObtainingDepthInformation, //通过深度相机获取被测物体的深度信息
|
||
AutoFocus, // 自动对焦
|
||
LiftingPlatform // 升降平台
|
||
};
|
||
enum class HyperImagerType {
|
||
Pika_L,
|
||
Pika_NIR
|
||
};
|
||
|
||
// ==================== 统一子任务封装 ====================
|
||
|
||
struct SubTask {
|
||
SubTaskType type; // 子任务类型
|
||
|
||
// 共享属性
|
||
QDateTime startTime;
|
||
QDateTime endTime;
|
||
double durationMinutes = 0;
|
||
double estimatedDurationMinutes = 0;
|
||
QString pathLineFilePath;
|
||
TaskStatus status = TaskStatus::Waiting;
|
||
|
||
// 类型特有属性(根据type选择使用)
|
||
double frameRate = 0.0; // 高光谱相机用
|
||
double exposureTime = 0.0; // 高光谱相机用
|
||
int defaultRenderBand = 550; // 1000-1700nm高光谱用
|
||
int captureIntervalSeconds = 5; // 单反/深度相机用
|
||
|
||
//任务ObtainingDepthInformation所需的x和y坐标
|
||
int depthAlgorithm = 0;//0:深度图像的范围(percentageOfEffectiveArea)平均,1:深度范围(depthRangePercentage)的百分比,2:通过彩色图像分割植被区域的深度图像,然后平均
|
||
int depthType = 0;//0表示植被深度,1表示白板/调焦版深度
|
||
double depthInfoX = 0.0;
|
||
double depthInfoY = 0.0;
|
||
int averageNumberOfTimes = 1; //任务ObtainingDepthInformation所需的平均次数
|
||
double percentageOfEffectiveArea = 50.0; //深度图像的有效范围百分比
|
||
double depthRangePercentage = 80.0; //深度范围的百分比
|
||
|
||
//高光谱自动调焦
|
||
HyperImagerType autoFocusHyperImagerType;//取值范围:L、NIR
|
||
QString autoFocusMotorConfigFilePath;//马达配置文件
|
||
double autoFocusX = 0.0;
|
||
double autoFocusY = 0.0;
|
||
};
|
||
|
||
// ==================== 定时任务 ====================
|
||
|
||
struct TimedTask {
|
||
int id = 0;
|
||
QDateTime scheduledTime;
|
||
QDateTime startTime;
|
||
QDateTime endTime;
|
||
double durationMinutes = 0;
|
||
double estimatedDurationMinutes = 0;
|
||
QString savePath;
|
||
QVector<SubTask> subTasks;
|
||
TaskStatus status = TaskStatus::Waiting;
|
||
double HalogenLampPreheatingTime_Minute;
|
||
|
||
// 计算所有子任务的预计总时间
|
||
int totalEstimatedDuration() const {
|
||
int total = 0;
|
||
for (const auto& subTask : subTasks) {
|
||
total += subTask.estimatedDurationMinutes;
|
||
}
|
||
return total;
|
||
}
|
||
|
||
// 获取子任务数量
|
||
int subTaskCount() const {
|
||
return subTasks.size();
|
||
}
|
||
};
|
||
|
||
// ==================== Qt元类型声明 ====================
|
||
Q_DECLARE_METATYPE(TaskStatus)
|
||
Q_DECLARE_METATYPE(SubTaskType)
|
||
Q_DECLARE_METATYPE(SubTask)
|
||
Q_DECLARE_METATYPE(TimedTask)
|
||
|
||
// ==================== 任务文件读写类 ====================
|
||
|
||
class TimedDataCollectionDataStructuresReaderWriter
|
||
{
|
||
public:
|
||
// 保存任务到文件
|
||
static bool saveTasksToFile(const QString& filePath, const QVector<TimedTask>& tasks);
|
||
|
||
// 从文件读取任务
|
||
static bool loadTasksFromFile(const QString& filePath, QVector<TimedTask>& tasks);
|
||
|
||
private:
|
||
// SubTask序列化
|
||
static QJsonObject subTaskToJson(const SubTask& subTask);
|
||
static bool jsonToSubTask(const QJsonObject& json, SubTask& subTask);
|
||
|
||
// TimedTask序列化
|
||
static QJsonObject timedTaskToJson(const TimedTask& task);
|
||
static bool jsonToTimedTask(const QJsonObject& json, TimedTask& task);
|
||
|
||
// 枚举转换
|
||
static QString taskStatusToString(TaskStatus status);
|
||
static TaskStatus stringToTaskStatus(const QString& str);
|
||
|
||
static QString subTaskTypeToString(SubTaskType type);
|
||
static SubTaskType stringToSubTaskType(const QString& str);
|
||
|
||
static QString hyperImagerTypeToString(HyperImagerType type);
|
||
static HyperImagerType stringToHyperImagerType(const QString& str);
|
||
};
|
||
|
||
// ==================== 任务执行器 ====================
|
||
|
||
class TaskExecutor : public QObject
|
||
{
|
||
Q_OBJECT
|
||
|
||
public:
|
||
explicit TaskExecutor(QObject* parent = nullptr);
|
||
~TaskExecutor();
|
||
|
||
// 执行任务
|
||
void execute(const TimedTask& task);
|
||
void makeFolder(QString savePath);
|
||
QString makeSubTaskDataFolder(QString suffix);
|
||
|
||
// 获取当前执行的子任务索引
|
||
int currentSubTaskIndex() const { return m_currentSubTaskIndex; }
|
||
|
||
// 获取正在执行的任务
|
||
const TimedTask& currentTask() const { return m_task; }
|
||
|
||
// 是否正在执行
|
||
bool isRunning() const { return m_isRunning; }
|
||
|
||
// 停止执行
|
||
void stop();
|
||
|
||
signals:
|
||
void finished(bool success); // 任务完成
|
||
void taskUpdated(const TimedTask& task); // 确保有这个信号
|
||
void subTaskStarted(int subTaskIndex, SubTaskType type); // 子任务开始
|
||
void subTaskFinished(int subTaskIndex, SubTaskType type, bool success); // 子任务完成
|
||
void errorOccurred(const QString& error); // 错误发生
|
||
|
||
// 采集相关信号
|
||
void hyperCamParm(int camType, double f, double e, QString filePath, QString fileName);
|
||
void camParm(int camType, int captureIntervalSeconds, QString folder);
|
||
void motorParm(QString pathLineFilePath);
|
||
void startRecordSignal(int camType);
|
||
|
||
void ObtainingDepthInformationSignals(SubTask info);
|
||
void LiftingPlatformSignals(SubTask info);
|
||
void AutoFocusSignals(SubTask info);
|
||
|
||
void switchHalogenLampSignal(int state);
|
||
void switchD65LampSignal(int state);
|
||
void switchSlrSignal(int state);
|
||
|
||
public slots:
|
||
void onSequenceComplete(int status);
|
||
void onBack2Origin();
|
||
void onError(const QString& error);
|
||
|
||
void emitRecordSignal();
|
||
void emitAutoFocusSignal();
|
||
|
||
private:
|
||
QString m_currentFolder;
|
||
void executeNextSubTask();
|
||
void ensurePreTaskLighting();
|
||
void ensurePostTaskLighting();
|
||
|
||
void printMsgAndTime(QString msg);
|
||
|
||
TimedTask m_task;
|
||
int m_currentSubTaskIndex;
|
||
bool m_isRunning;
|
||
|
||
int m_camType;
|
||
};
|
||
|
||
// ==================== 任务调度器 ====================
|
||
|
||
class TaskScheduler : public QObject
|
||
{
|
||
Q_OBJECT
|
||
|
||
public:
|
||
explicit TaskScheduler(QObject* parent = nullptr);
|
||
~TaskScheduler();
|
||
|
||
// 加载任务列表
|
||
void loadTasks(const QVector<TimedTask>& tasks);
|
||
|
||
// 获取任务列表
|
||
QVector<TimedTask> tasks() const { return m_tasks; }
|
||
|
||
// 开始调度
|
||
void start();
|
||
|
||
// 停止调度
|
||
void stop();
|
||
|
||
// 是否正在运行
|
||
bool isRunning() const { return m_timer != nullptr && m_timer->isActive(); }
|
||
|
||
signals:
|
||
void taskStarted(int taskId); // 任务开始
|
||
void taskFinished(int taskId, bool success); // 任务完成
|
||
void taskDataChanged(const TimedTask& task);
|
||
|
||
void schedulerStateChanged(bool running); // 调度器状态变化
|
||
|
||
// 子任务的信号
|
||
void subTaskStarted(int taskId, int subTaskIndex); // 子任务开始
|
||
void subTaskFinished(int taskId, int subTaskIndex); // 子任务完成
|
||
void errorOccurred(const QString& error); // 错误发生
|
||
|
||
// 采集相关信号 (透传 TaskExecutor)
|
||
void hyperCamParm(int camType, double f, double e, QString filePath, QString fileName);
|
||
void camParm(int camType, int captureIntervalSeconds, QString folder);
|
||
void motorParm(QString pathLineFilePath);
|
||
void startRecordSignal(int camType);
|
||
|
||
void ObtainingDepthInformationSignals(SubTask info);
|
||
void LiftingPlatformSignals(SubTask info);
|
||
void AutoFocusSignals(SubTask info);
|
||
|
||
void switchHalogenLampSignal(int state);
|
||
void switchD65LampSignal(int state);
|
||
void switchSlrSignal(int state);
|
||
|
||
// 马达反馈的信号
|
||
void sequenceCompleteSignal(int status);
|
||
void Back2OriginSignal();
|
||
|
||
private slots:
|
||
void checkTasks(); // 检查任务是否该启动
|
||
void onTaskFinished(bool success);
|
||
void onSubTaskStarted(int subTaskIndex, SubTaskType type);
|
||
void onSubTaskFinished(int subTaskIndex, SubTaskType type, bool success);
|
||
void onExecutorError(const QString& error);
|
||
|
||
private:
|
||
void executeTask(TimedTask& task);
|
||
void updateTaskStatus(int taskId, TaskStatus status);
|
||
void emitError(const QString& error);
|
||
|
||
QTimer* m_timer;
|
||
QVector<TimedTask> m_tasks;
|
||
TaskExecutor* m_currentExecutor;
|
||
int m_currentTaskId;
|
||
};
|