add,计划采集5:
实现部分计划采集功能:
This commit is contained in:
@ -197,20 +197,11 @@ bool TimedDataCollectionDataStructuresReaderWriter::jsonToTimedTask(const QJsonO
|
||||
|
||||
// ==================== TaskExecutor 实现 ====================
|
||||
|
||||
TaskExecutor::TaskExecutor(TwoMotorControl* motorControl, QObject* parent)
|
||||
TaskExecutor::TaskExecutor(QObject* parent)
|
||||
: QObject(parent)
|
||||
, m_motorControl(motorControl)
|
||||
, m_currentSubTaskIndex(0)
|
||||
, m_isRunning(false)
|
||||
{
|
||||
if (m_motorControl) {
|
||||
connect(m_motorControl, &TwoMotorControl::broadcastLocationSignal,
|
||||
this, &TaskExecutor::onMotorLocationUpdate);
|
||||
//connect(m_motorControl, &TwoMotorControl::sequenceComplete,
|
||||
// this, &TaskExecutor::onSequenceComplete);
|
||||
//connect(m_motorControl, &TwoMotorControl::errorOccurred,
|
||||
// this, &TaskExecutor::onError);
|
||||
}
|
||||
}
|
||||
|
||||
TaskExecutor::~TaskExecutor()
|
||||
@ -232,6 +223,7 @@ void TaskExecutor::execute(const TimedTask& task)
|
||||
qDebug() << "TaskExecutor: Starting task" << task.id;
|
||||
|
||||
// 开始执行第一个子任务
|
||||
makeFolder(m_task.savePath);
|
||||
executeNextSubTask();
|
||||
}
|
||||
|
||||
@ -241,14 +233,33 @@ void TaskExecutor::stop()
|
||||
|
||||
qDebug() << "TaskExecutor: Stopping task" << m_task.id;
|
||||
|
||||
if (m_motorControl) {
|
||||
m_motorControl->stop();
|
||||
}
|
||||
|
||||
m_isRunning = false;
|
||||
emit finished(false);
|
||||
}
|
||||
|
||||
void TaskExecutor::makeFolder(QString savePath)
|
||||
{
|
||||
QDir dir(savePath);
|
||||
if (!dir.exists()) {
|
||||
if (dir.mkpath(".")) {
|
||||
qDebug() << "TaskExecutor: Created data folder:" << savePath;
|
||||
} else {
|
||||
qWarning() << "TaskExecutor: Failed to create data folder:" << savePath;
|
||||
}
|
||||
} else {
|
||||
qDebug() << "TaskExecutor: Data folder already exists:" << savePath;
|
||||
}
|
||||
}
|
||||
|
||||
QString TaskExecutor::makeSubTaskDataFolder(QString suffix)
|
||||
{
|
||||
QString dateStr = QDateTime::currentDateTime().toString("yyyy-MM-dd_HH-mm-ss");
|
||||
QString folderPath = m_task.savePath + QDir::separator() + dateStr + "_" + suffix;
|
||||
makeFolder(folderPath);
|
||||
|
||||
return folderPath;
|
||||
}
|
||||
|
||||
void TaskExecutor::onSequenceComplete(int status)
|
||||
{
|
||||
if (!m_isRunning) return;
|
||||
@ -276,13 +287,6 @@ void TaskExecutor::onSequenceComplete(int status)
|
||||
}
|
||||
}
|
||||
|
||||
void TaskExecutor::onMotorLocationUpdate(std::vector<double> loc)
|
||||
{
|
||||
if (loc.size() >= 2) {
|
||||
emit motorPositionUpdated(loc[0], loc[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void TaskExecutor::onError(const QString& error)
|
||||
{
|
||||
if (!m_isRunning) return;
|
||||
@ -299,6 +303,8 @@ void TaskExecutor::executeNextSubTask()
|
||||
return;
|
||||
}
|
||||
|
||||
std::cerr << "TaskExecutor::executeNextSubTask,执行子任务" << std::endl;
|
||||
|
||||
SubTask& subTask = m_task.subTasks[m_currentSubTaskIndex];
|
||||
subTask.status = TaskStatus::Running;
|
||||
subTask.startTime = QDateTime::currentDateTime();
|
||||
@ -307,55 +313,43 @@ void TaskExecutor::executeNextSubTask()
|
||||
<< "type:" << static_cast<int>(subTask.type);
|
||||
|
||||
emit subTaskStarted(m_currentSubTaskIndex, subTask.type);
|
||||
|
||||
emit motorParm(subTask.pathLineFilePath);
|
||||
|
||||
//根据任务类型切换相机类型,还需要考虑相关信号和槽
|
||||
|
||||
// 如果有路径线文件,加载路径线并启动马达
|
||||
if (!subTask.pathLineFilePath.isEmpty()) {
|
||||
loadPathLinesFromFile(subTask.pathLineFilePath);
|
||||
} else {
|
||||
qDebug() << "TaskExecutor: No path line file for subtask";
|
||||
}
|
||||
}
|
||||
|
||||
void TaskExecutor::loadPathLinesFromFile(const QString& filePath)
|
||||
{
|
||||
// 从 .RecordLine3 文件加载路径线
|
||||
QFile file(filePath);
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
qWarning() << "TaskExecutor: Failed to open path line file:" << filePath;
|
||||
emit errorOccurred("Failed to open path line file: " + filePath);
|
||||
return;
|
||||
}
|
||||
|
||||
double number;
|
||||
file.read(reinterpret_cast<char*>(&number), sizeof(double));
|
||||
|
||||
QVector<PathLine> pathLines;
|
||||
for (int i = 0; i < static_cast<int>(number) / 6; ++i) {
|
||||
PathLine line;
|
||||
for (int j = 0; j < 6; ++j) {
|
||||
double value;
|
||||
file.read(reinterpret_cast<char*>(&value), sizeof(double));
|
||||
switch (j) {
|
||||
case 0: line.targetYPosition = value; break;
|
||||
case 1: line.speedTargetYPosition = value; break;
|
||||
case 2: line.targetXMinPosition = value; break;
|
||||
case 3: line.speedTargetXMinPosition = value; break;
|
||||
case 4: line.targetXMaxPosition = value; break;
|
||||
case 5: line.speedTargetXMaxPosition = value; break;
|
||||
}
|
||||
int camType;
|
||||
switch (subTask.type)
|
||||
{
|
||||
case SubTaskType::HyperSpectual400_1000nm:
|
||||
{
|
||||
camType = 0;
|
||||
emit hyperCamParm(camType, subTask.frameRate, subTask.exposureTime, makeSubTaskDataFolder("L"), "test");
|
||||
|
||||
break;
|
||||
}
|
||||
pathLines.append(line);
|
||||
}
|
||||
file.close();
|
||||
case SubTaskType::HyperSpectual1000_1700nm:
|
||||
{
|
||||
camType = 1;
|
||||
emit hyperCamParm(camType, subTask.frameRate, subTask.exposureTime, makeSubTaskDataFolder("NIR"), "test");
|
||||
|
||||
qDebug() << "TaskExecutor: Loaded" << pathLines.size() << "path lines from" << filePath;
|
||||
break;
|
||||
}
|
||||
case SubTaskType::SingleLensReflex:
|
||||
{
|
||||
camType = 2;
|
||||
emit camParm(camType, 3, makeSubTaskDataFolder("SLR"));
|
||||
|
||||
// 通知马达控制器开始执行
|
||||
if (m_motorControl) {
|
||||
emit m_motorControl->start(pathLines);
|
||||
break;
|
||||
}
|
||||
case SubTaskType::DepthCamera:
|
||||
{
|
||||
camType = 3;
|
||||
emit camParm(camType, 3, makeSubTaskDataFolder("DepthCamera"));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
emit startRecordSignal(camType);
|
||||
}
|
||||
|
||||
// ==================== TaskScheduler 实现 ====================
|
||||
@ -363,7 +357,6 @@ void TaskExecutor::loadPathLinesFromFile(const QString& filePath)
|
||||
TaskScheduler::TaskScheduler(QObject* parent)
|
||||
: QObject(parent)
|
||||
, m_timer(nullptr)
|
||||
, m_motorControl(nullptr)
|
||||
, m_currentExecutor(nullptr)
|
||||
, m_currentTaskId(-1)
|
||||
{
|
||||
@ -374,11 +367,6 @@ TaskScheduler::~TaskScheduler()
|
||||
stop();
|
||||
}
|
||||
|
||||
void TaskScheduler::setMotorControl(TwoMotorControl* motorControl)
|
||||
{
|
||||
m_motorControl = motorControl;
|
||||
}
|
||||
|
||||
void TaskScheduler::loadTasks(const QVector<TimedTask>& tasks)
|
||||
{
|
||||
m_tasks = tasks;
|
||||
@ -421,15 +409,22 @@ void TaskScheduler::stop()
|
||||
|
||||
void TaskScheduler::checkTasks()
|
||||
{
|
||||
if (!m_motorControl) return;
|
||||
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
|
||||
for (auto& task : m_tasks) {
|
||||
if (task.status != TaskStatus::Waiting) continue;
|
||||
|
||||
// 超过计划时间1分钟以上,认为任务已过时,跳过
|
||||
if (task.scheduledTime.addSecs(60) < now) {
|
||||
std::cerr << "TaskScheduler::checkTasks,任务已过时,跳过:" << task.id << std::endl;
|
||||
task.status = TaskStatus::Finished;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (task.scheduledTime > now) continue;
|
||||
|
||||
// 到达计划时间,启动任务
|
||||
std::cerr << "TaskScheduler::checkTasks,到达计划时间,启动任务" << std::endl;
|
||||
executeTask(task);
|
||||
break; // 一次只执行一个任务
|
||||
}
|
||||
@ -470,18 +465,8 @@ void TaskScheduler::onExecutorError(const QString& error)
|
||||
emitError(error);
|
||||
}
|
||||
|
||||
void TaskScheduler::onExecutorMotorPositionUpdated(double x, double y)
|
||||
{
|
||||
emit motorPositionUpdated(x, y);
|
||||
}
|
||||
|
||||
void TaskScheduler::executeTask(TimedTask& task)
|
||||
{
|
||||
if (!m_motorControl) {
|
||||
emitError("Motor control not set");
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "TaskScheduler: Executing task" << task.id;
|
||||
|
||||
updateTaskStatus(task.id, TaskStatus::Running);
|
||||
@ -490,7 +475,7 @@ void TaskScheduler::executeTask(TimedTask& task)
|
||||
emit taskStarted(task.id);
|
||||
|
||||
// 创建任务执行器
|
||||
m_currentExecutor = new TaskExecutor(m_motorControl, this);
|
||||
m_currentExecutor = new TaskExecutor(this);
|
||||
|
||||
// 连接信号
|
||||
connect(m_currentExecutor, &TaskExecutor::finished,
|
||||
@ -501,8 +486,18 @@ void TaskScheduler::executeTask(TimedTask& task)
|
||||
this, &TaskScheduler::onSubTaskFinished);
|
||||
connect(m_currentExecutor, &TaskExecutor::errorOccurred,
|
||||
this, &TaskScheduler::onExecutorError);
|
||||
connect(m_currentExecutor, &TaskExecutor::motorPositionUpdated,
|
||||
this, &TaskScheduler::onExecutorMotorPositionUpdated);
|
||||
|
||||
// 采集相关信号透传
|
||||
connect(m_currentExecutor, &TaskExecutor::hyperCamParm,
|
||||
this, &TaskScheduler::hyperCamParm);
|
||||
connect(m_currentExecutor, &TaskExecutor::camParm,
|
||||
this, &TaskScheduler::camParm);
|
||||
connect(m_currentExecutor, &TaskExecutor::motorParm,
|
||||
this, &TaskScheduler::motorParm);
|
||||
connect(m_currentExecutor, &TaskExecutor::startRecordSignal,
|
||||
this, &TaskScheduler::startRecordSignal);
|
||||
|
||||
connect(this, &TaskScheduler::sequenceCompleteSignal, m_currentExecutor, &TaskExecutor::onSequenceComplete);
|
||||
|
||||
// 开始执行
|
||||
m_currentExecutor->execute(task);
|
||||
|
||||
Reference in New Issue
Block a user