add,计划采集3:

实现部分计划采集功能
This commit is contained in:
tangchao0503
2026-06-02 18:22:02 +08:00
parent 3521a7f225
commit a8760652bd
10 changed files with 789 additions and 319 deletions

View File

@ -1,4 +1,4 @@
#include "TimedDataCollectionDataStructures.h"
#include "TimedDataCollectionDataStructures.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
@ -194,3 +194,337 @@ bool TimedDataCollectionDataStructuresReaderWriter::jsonToTimedTask(const QJsonO
return true;
}
// ==================== TaskExecutor 实现 ====================
TaskExecutor::TaskExecutor(TwoMotorControl* motorControl, 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()
{
stop();
}
void TaskExecutor::execute(const TimedTask& task)
{
if (m_isRunning) {
qWarning() << "TaskExecutor: Already running, ignoring execute request";
return;
}
m_task = task;
m_currentSubTaskIndex = 0;
m_isRunning = true;
qDebug() << "TaskExecutor: Starting task" << task.id;
// 开始执行第一个子任务
executeNextSubTask();
}
void TaskExecutor::stop()
{
if (!m_isRunning) return;
qDebug() << "TaskExecutor: Stopping task" << m_task.id;
if (m_motorControl) {
m_motorControl->stop();
}
m_isRunning = false;
emit finished(false);
}
void TaskExecutor::onSequenceComplete(int status)
{
if (!m_isRunning) return;
qDebug() << "TaskExecutor: Sequence complete, status:" << status;
// 更新当前子任务状态
if (m_currentSubTaskIndex < m_task.subTasks.size()) {
SubTask& subTask = m_task.subTasks[m_currentSubTaskIndex];
subTask.status = (status == 0) ? TaskStatus::Finished : TaskStatus::Waiting;
emit subTaskFinished(m_currentSubTaskIndex, subTask.type, (status == 0));
}
// 检查是否还有更多子任务
m_currentSubTaskIndex++;
if (m_currentSubTaskIndex < m_task.subTasks.size()) {
// 执行下一个子任务
QTimer::singleShot(100, this, &TaskExecutor::executeNextSubTask);
} else {
// 所有子任务完成
m_isRunning = false;
qDebug() << "TaskExecutor: All subtasks completed";
emit finished(true);
}
}
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;
qWarning() << "TaskExecutor: Error occurred:" << error;
m_isRunning = false;
emit errorOccurred(error);
emit finished(false);
}
void TaskExecutor::executeNextSubTask()
{
if (!m_isRunning || m_currentSubTaskIndex >= m_task.subTasks.size()) {
return;
}
SubTask& subTask = m_task.subTasks[m_currentSubTaskIndex];
subTask.status = TaskStatus::Running;
subTask.startTime = QDateTime::currentDateTime();
qDebug() << "TaskExecutor: Starting subtask" << m_currentSubTaskIndex
<< "type:" << static_cast<int>(subTask.type);
emit subTaskStarted(m_currentSubTaskIndex, subTask.type);
//根据任务类型切换相机类型,还需要考虑相关信号和槽
// 如果有路径线文件,加载路径线并启动马达
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;
}
}
pathLines.append(line);
}
file.close();
qDebug() << "TaskExecutor: Loaded" << pathLines.size() << "path lines from" << filePath;
// 通知马达控制器开始执行
if (m_motorControl) {
emit m_motorControl->start(pathLines);
}
}
// ==================== TaskScheduler 实现 ====================
TaskScheduler::TaskScheduler(QObject* parent)
: QObject(parent)
, m_timer(nullptr)
, m_motorControl(nullptr)
, m_currentExecutor(nullptr)
, m_currentTaskId(-1)
{
}
TaskScheduler::~TaskScheduler()
{
stop();
}
void TaskScheduler::setMotorControl(TwoMotorControl* motorControl)
{
m_motorControl = motorControl;
}
void TaskScheduler::loadTasks(const QVector<TimedTask>& tasks)
{
m_tasks = tasks;
qDebug() << "TaskScheduler: Loaded" << tasks.size() << "tasks";
}
void TaskScheduler::start()
{
if (m_timer) {
qDebug() << "TaskScheduler: Already running";
return;
}
qDebug() << "TaskScheduler: Starting";
m_timer = new QTimer(this);
connect(m_timer, &QTimer::timeout, this, &TaskScheduler::checkTasks);
m_timer->start(1000); // 每秒检查一次
emit schedulerStateChanged(true);
}
void TaskScheduler::stop()
{
if (m_timer) {
m_timer->stop();
delete m_timer;
m_timer = nullptr;
}
if (m_currentExecutor) {
m_currentExecutor->stop();
m_currentExecutor->deleteLater();
m_currentExecutor = nullptr;
}
qDebug() << "TaskScheduler: Stopped";
emit schedulerStateChanged(false);
}
void TaskScheduler::checkTasks()
{
if (!m_motorControl) return;
QDateTime now = QDateTime::currentDateTime();
for (auto& task : m_tasks) {
if (task.status != TaskStatus::Waiting) continue;
if (task.scheduledTime > now) continue;
// 到达计划时间,启动任务
executeTask(task);
break; // 一次只执行一个任务
}
}
void TaskScheduler::onTaskFinished(bool success)
{
if (m_currentTaskId > 0) {
TaskStatus status = success ? TaskStatus::Finished : TaskStatus::Waiting;
updateTaskStatus(m_currentTaskId, status);
emit taskFinished(m_currentTaskId, success);
}
// 清理执行器
if (m_currentExecutor) {
m_currentExecutor->deleteLater();
m_currentExecutor = nullptr;
}
m_currentTaskId = -1;
}
void TaskScheduler::onSubTaskStarted(int subTaskIndex, SubTaskType type)
{
if (m_currentTaskId > 0) {
emit subTaskStarted(m_currentTaskId, subTaskIndex);
}
}
void TaskScheduler::onSubTaskFinished(int subTaskIndex, SubTaskType type, bool success)
{
if (m_currentTaskId > 0) {
emit subTaskFinished(m_currentTaskId, subTaskIndex);
}
}
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);
m_currentTaskId = task.id;
emit taskStarted(task.id);
// 创建任务执行器
m_currentExecutor = new TaskExecutor(m_motorControl, this);
// 连接信号
connect(m_currentExecutor, &TaskExecutor::finished,
this, &TaskScheduler::onTaskFinished);
connect(m_currentExecutor, &TaskExecutor::subTaskStarted,
this, &TaskScheduler::onSubTaskStarted);
connect(m_currentExecutor, &TaskExecutor::subTaskFinished,
this, &TaskScheduler::onSubTaskFinished);
connect(m_currentExecutor, &TaskExecutor::errorOccurred,
this, &TaskScheduler::onExecutorError);
connect(m_currentExecutor, &TaskExecutor::motorPositionUpdated,
this, &TaskScheduler::onExecutorMotorPositionUpdated);
// 开始执行
m_currentExecutor->execute(task);
}
void TaskScheduler::updateTaskStatus(int taskId, TaskStatus status)
{
for (auto& task : m_tasks) {
if (task.id == taskId) {
task.status = status;
if (status == TaskStatus::Running) {
task.startTime = QDateTime::currentDateTime();
} else if (status == TaskStatus::Finished) {
task.endTime = QDateTime::currentDateTime();
}
break;
}
}
}
void TaskScheduler::emitError(const QString& error)
{
qWarning() << "TaskScheduler: Error:" << error;
emit errorOccurred(error);
}