From a8760652bda99cdc110ffa52fc280fcc3defc48e Mon Sep 17 00:00:00 2001
From: tangchao0503 <735056338@qq.com>
Date: Tue, 2 Jun 2026 18:22:02 +0800
Subject: [PATCH] =?UTF-8?q?add=EF=BC=8C=E8=AE=A1=E5=88=92=E9=87=87?=
=?UTF-8?q?=E9=9B=863=EF=BC=9A=20=E5=AE=9E=E7=8E=B0=E9=83=A8=E5=88=86?=
=?UTF-8?q?=E8=AE=A1=E5=88=92=E9=87=87=E9=9B=86=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
HPPA/HPPA.cpp | 37 +-
HPPA/HPPA.h | 4 +
HPPA/HPPA.ui | 6 +
HPPA/HPPA.vcxproj | 2 +-
HPPA/HPPA.vcxproj.filters | 6 +-
HPPA/TimedDataCollection.cpp | 42 +-
HPPA/TimedDataCollection.h | 20 +-
HPPA/TimedDataCollectionDataStructures.cpp | 336 ++++++++++++-
HPPA/TimedDataCollectionDataStructures.h | 112 +++++
HPPA/TimedDataCollection_ui.ui | 543 ++++++++++-----------
10 files changed, 789 insertions(+), 319 deletions(-)
diff --git a/HPPA/HPPA.cpp b/HPPA/HPPA.cpp
index f4eff02..2057240 100644
--- a/HPPA/HPPA.cpp
+++ b/HPPA/HPPA.cpp
@@ -575,6 +575,10 @@ HPPA::HPPA(QWidget* parent)
initMapTools();
+ //定时采集
+ connect(this->ui.mActionTimedDataCollection, SIGNAL(triggered()), this, SLOT(onTimedDataCollection()));
+ mTimedDataCollectionWindow = new TimedDataCollection(m_tmc);
+
QString strPath = QCoreApplication::applicationDirPath() + "/UILayout.ini";
QFile file(strPath);
if (file.open(QIODevice::ReadOnly))
@@ -588,6 +592,23 @@ HPPA::HPPA(QWidget* parent)
this->showMaximized();
}
+void HPPA::onTimedDataCollection()
+{
+ QAction* checkedScenario = m_ScenarioActionGroup->checkedAction();
+ QString checkedScenarioName = checkedScenario->objectName();
+ if (checkedScenarioName == "mAction3DPlantPhenotypeScenario")//计划采集
+ {
+ mTimedDataCollectionWindow->show();
+ //mTimedDataCollectionWindow->exec();
+
+ return;
+ }
+ else if (checkedScenarioName == "mActionPlantPhenotypeScenario")
+ {
+
+ }
+}
+
void HPPA::initMenubarToolbar()
{
//自定义菜单栏和工具栏
@@ -1523,22 +1544,6 @@ bool HPPA::showResultMessageBox(QString title, QString msg)
void HPPA::onStartRecordStep1()
{
- QAction* checkedScenario = m_ScenarioActionGroup->checkedAction();
- QString checkedScenarioName = checkedScenario->objectName();
- if (checkedScenarioName == "mAction3DPlantPhenotypeScenario")//计划采集
- {
- TimedDataCollection* tmp = new TimedDataCollection();
- /*m_ic->setWindowFlags(Qt::Widget);*/
- tmp->show();
- //tmp->exec();
-
- return;
- }
- else if (checkedScenarioName == "mActionPlantPhenotypeScenario")
- {
-
- }
-
//判断移动平台
QAction* checked = moveplatformActionGroup->checkedAction();
if (!checked)
diff --git a/HPPA/HPPA.h b/HPPA/HPPA.h
index b8bd82b..6222afc 100644
--- a/HPPA/HPPA.h
+++ b/HPPA/HPPA.h
@@ -318,6 +318,8 @@ private:
bool showResultMessageBox(QString title, QString msg);
void disconnectImagerAndCleanup();
+ TimedDataCollection* mTimedDataCollectionWindow;
+
public Q_SLOTS:
void onPlotHyperspectralImageRgbImage(int fileNumber, int frameNumber, QString filePath);
void focusPlotSpectralImg(int state);
@@ -395,6 +397,8 @@ public Q_SLOTS:
void onMapToolPanTriggered();
void onMapToolSpectralTriggered();
+
+ void onTimedDataCollection();
protected:
void closeEvent(QCloseEvent* event) override;
diff --git a/HPPA/HPPA.ui b/HPPA/HPPA.ui
index ed4dd23..16c3dc1 100644
--- a/HPPA/HPPA.ui
+++ b/HPPA/HPPA.ui
@@ -105,6 +105,7 @@ color:white;
+
diff --git a/HPPA/HPPA.vcxproj b/HPPA/HPPA.vcxproj
index f51981d..2da6df4 100644
--- a/HPPA/HPPA.vcxproj
+++ b/HPPA/HPPA.vcxproj
@@ -254,7 +254,7 @@
-
+
diff --git a/HPPA/HPPA.vcxproj.filters b/HPPA/HPPA.vcxproj.filters
index 2a2ab2c..87b4009 100644
--- a/HPPA/HPPA.vcxproj.filters
+++ b/HPPA/HPPA.vcxproj.filters
@@ -384,6 +384,9 @@
Header Files
+
+ Header Files
+
@@ -440,9 +443,6 @@
Header Files
-
- Header Files
-
diff --git a/HPPA/TimedDataCollection.cpp b/HPPA/TimedDataCollection.cpp
index b49eb1a..cc7fcd7 100644
--- a/HPPA/TimedDataCollection.cpp
+++ b/HPPA/TimedDataCollection.cpp
@@ -1,9 +1,12 @@
#include "TimedDataCollection.h"
#include
#include
+#include "TwoMotorControl.h"
-TimedDataCollection::TimedDataCollection(QWidget* parent)
+TimedDataCollection::TimedDataCollection(TwoMotorControl* motorControl, QWidget* parent)
: QDialog(parent)
+ , m_motorControl(nullptr)
+ , m_scheduler(nullptr)
{
ui.setupUi(this);
@@ -12,21 +15,52 @@ TimedDataCollection::TimedDataCollection(QWidget* parent)
ui.treeWidget->setDropIndicatorShown(true); // 显示插入位置指示线
ui.treeWidget->setDragDropMode(QAbstractItemView::InternalMove); // 内部移动
+ // 初始化调度器
+ m_scheduler = new TaskScheduler(this);
+
+ // 连接调度器信号
+ connect(m_scheduler, &TaskScheduler::taskStarted, this, &TimedDataCollection::taskStarted);
+ connect(m_scheduler, &TaskScheduler::taskFinished, this, &TimedDataCollection::taskFinished);
+ connect(m_scheduler, &TaskScheduler::subTaskStarted, this, &TimedDataCollection::subTaskStarted);
+ connect(m_scheduler, &TaskScheduler::subTaskFinished, this, &TimedDataCollection::subTaskFinished);
+ connect(m_scheduler, &TaskScheduler::motorPositionUpdated, this, &TimedDataCollection::motorPositionUpdated);
+ connect(m_scheduler, &TaskScheduler::errorOccurred, this, &TimedDataCollection::errorOccurred);
+
//writeRead();
readTimedTaskFromFile("D:/0tmp/3Dtest/task.json");
- connect(ui.run_btn, SIGNAL(clicked()), this, SLOT(run()));
+ // 加载任务到调度器
+ m_scheduler->loadTasks(m_loadedTasks);
- connect(ui.run_btn, &QPushButton::clicked, this, &TimedDataCollection::run);
+ connect(ui.run_btn, &QPushButton::clicked, this, &TimedDataCollection::startScheduler);
}
TimedDataCollection::~TimedDataCollection()
{
+ if (m_scheduler) {
+ m_scheduler->stop();
+ }
}
-void TimedDataCollection::run()
+void TimedDataCollection::startScheduler()
{
+ if (m_scheduler) {
+ m_scheduler->start();
+ }
+}
+void TimedDataCollection::stopScheduler()
+{
+ if (m_scheduler) {
+ m_scheduler->stop();
+ }
+}
+
+void TimedDataCollection::setMotorControl(TwoMotorControl* motorControl)
+{
+ if (m_scheduler) {
+ m_scheduler->setMotorControl(motorControl);
+ }
}
void TimedDataCollection::readTimedTaskFromFile(const QString& filePath)
diff --git a/HPPA/TimedDataCollection.h b/HPPA/TimedDataCollection.h
index 5c557a6..d1d7df5 100644
--- a/HPPA/TimedDataCollection.h
+++ b/HPPA/TimedDataCollection.h
@@ -8,23 +8,39 @@
#include "ui_TimedDataCollection_ui.h"
#include "TimedDataCollectionDataStructures.h"
+class TwoMotorControl;
+
class TimedDataCollection : public QDialog
{
Q_OBJECT
public:
- TimedDataCollection(QWidget* parent = nullptr);
+ TimedDataCollection(TwoMotorControl* motorControl, QWidget* parent = nullptr);
~TimedDataCollection();
void readTimedTaskFromFile(const QString& filePath);
+ // 设置马达控制器供调度器使用
+ void setMotorControl(TwoMotorControl* motorControl);
+
public Q_SLOTS:
- void run();
+ void startScheduler();
+ void stopScheduler();
+
+Q_SIGNALS:
+ void taskStarted(int taskId);
+ void taskFinished(int taskId, bool success);
+ void subTaskStarted(int taskId, int subTaskIndex);
+ void subTaskFinished(int taskId, int subTaskIndex);
+ void motorPositionUpdated(double x, double y);
+ void errorOccurred(const QString& error);
private:
Ui::TimedDataCollection_ui ui;
+ TwoMotorControl* m_motorControl;
void writeRead();
QVector m_loadedTasks;
+ TaskScheduler* m_scheduler;
};
diff --git a/HPPA/TimedDataCollectionDataStructures.cpp b/HPPA/TimedDataCollectionDataStructures.cpp
index 8c303b0..8cb9b64 100644
--- a/HPPA/TimedDataCollectionDataStructures.cpp
+++ b/HPPA/TimedDataCollectionDataStructures.cpp
@@ -1,4 +1,4 @@
-#include "TimedDataCollectionDataStructures.h"
+#include "TimedDataCollectionDataStructures.h"
#include
#include
#include
@@ -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 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(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(&number), sizeof(double));
+
+ QVector pathLines;
+ for (int i = 0; i < static_cast(number) / 6; ++i) {
+ PathLine line;
+ for (int j = 0; j < 6; ++j) {
+ double value;
+ file.read(reinterpret_cast(&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& 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);
+}
diff --git a/HPPA/TimedDataCollectionDataStructures.h b/HPPA/TimedDataCollectionDataStructures.h
index ef8be0b..a4976a6 100644
--- a/HPPA/TimedDataCollectionDataStructures.h
+++ b/HPPA/TimedDataCollectionDataStructures.h
@@ -4,6 +4,10 @@
#include
#include
#include
+#include
+
+#include "TwoMotorControl.h"
+#include "CaptureCoordinator.h"
// ==================== 枚举定义 ====================
@@ -102,3 +106,111 @@ private:
static QString subTaskTypeToString(SubTaskType type);
static SubTaskType stringToSubTaskType(const QString& str);
};
+
+// ==================== 前向声明 ====================
+
+class TwoMotorControl;
+
+// ==================== 任务执行器 ====================
+
+class TaskExecutor : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit TaskExecutor(TwoMotorControl* motorControl, QObject* parent = nullptr);
+ ~TaskExecutor();
+
+ // 执行任务
+ void execute(const TimedTask& task);
+
+ // 获取当前执行的子任务索引
+ 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 subTaskStarted(int subTaskIndex, SubTaskType type); // 子任务开始
+ void subTaskFinished(int subTaskIndex, SubTaskType type, bool success); // 子任务完成
+ void motorPositionUpdated(double x, double y); // 马达位置更新
+ void errorOccurred(const QString& error); // 错误发生
+
+private slots:
+ void onSequenceComplete(int status);
+ void onMotorLocationUpdate(std::vector loc);
+ void onError(const QString& error);
+
+private:
+ void executeNextSubTask();
+ void loadPathLinesFromFile(const QString& filePath);
+
+ TwoMotorControl* m_motorControl;
+ TimedTask m_task;
+ int m_currentSubTaskIndex;
+ bool m_isRunning;
+};
+
+// ==================== 任务调度器 ====================
+
+class TaskScheduler : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit TaskScheduler(QObject* parent = nullptr);
+ ~TaskScheduler();
+
+ // 设置马达控制器
+ void setMotorControl(TwoMotorControl* motorControl);
+
+ // 加载任务列表
+ void loadTasks(const QVector& tasks);
+
+ // 获取任务列表
+ QVector 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 subTaskStarted(int taskId, int subTaskIndex); // 子任务开始
+ void subTaskFinished(int taskId, int subTaskIndex); // 子任务完成
+ void motorPositionUpdated(double x, double y); // 马达位置更新
+ void errorOccurred(const QString& error); // 错误发生
+ void schedulerStateChanged(bool running); // 调度器状态变化
+
+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);
+ void onExecutorMotorPositionUpdated(double x, double y);
+
+private:
+ void executeTask(TimedTask& task);
+ void updateTaskStatus(int taskId, TaskStatus status);
+ void emitError(const QString& error);
+
+ QTimer* m_timer;
+ QVector m_tasks;
+ TwoMotorControl* m_motorControl;
+ TaskExecutor* m_currentExecutor;
+ int m_currentTaskId;
+};
diff --git a/HPPA/TimedDataCollection_ui.ui b/HPPA/TimedDataCollection_ui.ui
index 546dca3..de0255e 100644
--- a/HPPA/TimedDataCollection_ui.ui
+++ b/HPPA/TimedDataCollection_ui.ui
@@ -6,314 +6,273 @@
0
0
- 970
- 456
+ 1160
+ 576
Dialog
-
-
-
- 9
- 9
- 491
- 281
-
-
-
- false
-
-
- true
-
-
-
- 任务
-
-
-
-
- 计划时间
-
-
-
-
- 开始时间
-
-
-
-
- 结束时间
-
-
-
-
- 耗时
-
-
-
-
- 状态
-
-
- -
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- a
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
- b
-
-
+
+ -
+
+
+
-
+
+
+ false
+
+
+ true
+
+
+
+ 任务
+
+
+
+
+ 计划时间
+
+
+
+
+ 开始时间
+
+
+
+
+ 结束时间
+
+
+
+
+ 耗时
+
+
+
+
+ 状态
+
+
+
-
+
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+ a
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+ b
+
+
+
+ -
+
+ 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+ a
+
+
+ -
+
+ b
+
+
+
+ -
+
+ 3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+ a
+
+
+ -
+
+ b
+
+
+
+ -
+
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+ a
+
+
+ -
+
+ b
+
+
+
+ -
+
+ 5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+ a
+
+
+ -
+
+ b
+
+
+
+
+
+ -
+
+
+ 1
+
+
+
+
+
+
+
- -
-
- 2
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
- a
+ 添加总计划任务
-
- -
-
- b
-
-
+
- -
-
- 3
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
- a
+ 删除总计划任务
-
- -
-
- b
-
-
+
- -
-
- 4
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
- a
+ 添加子任务
-
- -
-
- b
-
-
+
- -
-
- 5
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- a
-
-
- -
-
- b
-
-
+ -
+
-
-
-
-
- 40
- 310
- 101
- 23
-
-
-
- 添加总计划任务
-
-
-
-
-
- 40
- 370
- 101
- 23
-
-
-
- 添加子任务
-
-
-
-
-
- 170
- 370
- 69
- 22
-
-
-
-
-
-
- 40
- 410
- 101
- 23
-
-
-
- 删除子任务
-
-
-
-
-
- 40
- 340
- 101
- 23
-
-
-
- 删除总计划任务
-
-
-
-
-
- 520
- 20
- 381
- 261
-
-
-
- 1
-
-
-
-
-
-
-
- 850
- 420
- 101
- 23
-
-
-
- 运行
-
-
+ -
+
+
+ 删除子任务
+
+
+
+ -
+
+
+ 运行
+
+
+
+