# 任务配置与调度 **本文档引用的文件** - [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp) - [DialCfgTaskPacket.h](file://h/DialCfgTaskPacket.h) - [DialCfgTerrain.cpp](file://cpp/Views/DialCfgTerrain.cpp) - [DialCfgTerrain.h](file://h/DialCfgTerrain.h) - [DialTimerTask.cpp](file://cpp/Views/DialTimerTask.cpp) - [DialTimerTask.h](file://h/DialTimerTask.h) - [DialLoopTaskQuery.cpp](file://cpp/Views/DialLoopTaskQuery.cpp) - [DialLoopTaskQuery.h](file://h/DialLoopTaskQuery.h) - [DialManageLoopTask.cpp](file://cpp/Views/DialManageLoopTask.cpp) - [DialManageLoopTask.h](file://h/DialManageLoopTask.h) - [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp) - [TaskDataOper.h](file://h/TaskDataOper.h) - [CtrlProtocolDef.h](file://h/CtrlProtocolDef.h) ## 目录 1. [引言](#引言) 2. [任务包配置 (DialCfgTaskPacket)](#任务包配置-dialcfgtaskpacket) 3. [地形参数设置 (DialCfgTerrain)](#地形参数设置-dialcfgterrain) 4. [定时任务 (DialTimerTask)](#定时任务-dialtimertask) 5. [循环任务管理 (DialLoopTaskQuery, DialManageLoopTask)](#循环任务管理-diallooptaskquery-dialmanagelooptask) 6. [任务树形结构与用户交互](#任务树形结构与用户交互) 7. [任务调度算法与状态机](#任务调度算法与状态机) 8. [任务序列化与反序列化机制](#任务序列化与反序列化机制) 9. [设备通信协议映射](#设备通信协议映射) 10. [操作指南](#操作指南) ## 引言 本系统提供了一套完整的任务配置与调度解决方案,涵盖了从任务创建、参数配置、地形数据管理到任务调度执行的全生命周期管理。系统通过任务包、定时任务和循环任务三种核心模式,实现了灵活、可靠的任务自动化。任务包允许用户将多个独立任务组合成一个有序序列,并进行循环执行;定时任务支持在指定时间点自动触发测量任务;循环任务则提供了更复杂的周期性执行策略。所有任务数据均通过统一的数据结构进行组织,并与设备通信协议紧密映射,确保了配置信息能够准确无误地传输到测量设备并执行。 ## 任务包配置 (DialCfgTaskPacket) 该模块实现了任务包的创建、编辑和管理功能。用户可以从现有任务列表中选择任务,将其添加到任务包中,并设置循环次数、执行间隔和PLC ID等全局属性。任务包本质上是一个有序的任务序列,其执行遵循“循环次数”次,每次循环内按顺序执行所有任务,任务间间隔为“时间间隔”秒。 **Section sources** - [DialCfgTaskPacket.cpp](file://cpp/Views/DialCfgTaskPacket.cpp#L1-L301) - [DialCfgTaskPacket.h](file://h/DialCfgTaskPacket.h#L1-L55) - [TaskDataOper.h](file://h/TaskDataOper.h#L324-L335) ## 地形参数设置 (DialCfgTerrain) 该模块负责为测量任务配置地形数据。用户可以通过手动输入或导入.dat文件的方式,添加一系列包含X、Y坐标的地形点。系统支持两种地形数据标志:水平距离和垂直距离。配置完成后,地形数据将被写入到与任务关联的原始.dat文件末尾,供设备在测量时使用。 **Section sources** - [DialCfgTerrain.cpp](file://cpp/Views/DialCfgTerrain.cpp#L1-L843) - [DialCfgTerrain.h](file://h/DialCfgTerrain.h#L1-L73) ## 定时任务 (DialTimerTask) 该模块实现了基于时间的定时任务调度功能。用户可以为任意任务设置一个未来的执行时间点。系统会将这些定时任务存储在数据库中,并在到达指定时间时自动触发任务执行。为了区分由定时器自动创建的任务和用户手动创建的任务,系统使用了任务ID的最高位作为标志位(0x80000000)。 **Section sources** - [DialTimerTask.cpp](file://cpp/Views/DialTimerTask.cpp#L1-L238) - [DialTimerTask.h](file://h/DialTimerTask.h#L1-L61) - [TaskDataOper.h](file://h/TaskDataOper.h#L275-L288) ## 循环任务管理 (DialLoopTaskQuery, DialManageLoopTask) 该模块提供了对循环任务的查询和管理功能。`DialLoopTaskQuery`用于从服务器查询当前存在的循环任务列表,用户可以选择一个或多个任务进行后续操作。`DialManageLoopTask`则是一个更高级的管理界面,它通过网络请求从服务器同步所有循环任务,并展示其详细信息,包括循环类型(次数循环或定时循环)、开始/结束时间以及包含的子任务列表。用户可以在此界面删除循环任务。 ```mermaid graph TD A[用户界面] --> B[DialManageLoopTask] B --> C{网络请求} C --> |EN_REQ_DOWNLOAD_LOOP_TABLE| D[服务器] D --> |返回循环任务表| C C --> E[解析并显示任务列表] E --> F[用户选择任务] F --> G{用户操作} G --> |删除| H[发送EN_CANCEL_LOOP_TASK_TRUST请求] G --> |查看详情| I[发送EN_REQ_DOWNLOAD_LOOP_SUB_TABLE请求] H --> D I --> D ``` **Diagram sources** - [DialManageLoopTask.cpp](file://cpp/Views/DialManageLoopTask.cpp#L230-L251) - [DialManageLoopTask.cpp](file://cpp/Views/DialManageLoopTask.cpp#L520-L582) **Section sources** - [DialLoopTaskQuery.cpp](file://cpp/Views/DialLoopTaskQuery.cpp#L1-L145) - [DialLoopTaskQuery.h](file://h/DialLoopTaskQuery.h#L1-L34) - [DialManageLoopTask.cpp](file://cpp/Views/DialManageLoopTask.cpp#L1-L621) - [DialManageLoopTask.h](file://h/DialManageLoopTask.h#L1-L70) ## 任务树形结构与用户交互 系统中的任务数据以树形结构进行组织,便于用户进行浏览和管理。任务树的根节点通常是项目或测区,其下包含不同类型的测量任务(如1D、2D、3D任务)。用户可以通过任务管理器界面直观地查看和操作这些任务。对于任务包和循环任务,它们在树形结构中表现为一个父节点,其子节点为包含的具体任务。用户交互逻辑主要通过对话框实现,例如`DialCfgTaskPacket`对话框允许用户通过“添加”、“删除”按钮来编辑任务包中的任务序列。 ## 任务调度算法与状态机 系统的任务调度由多个组件协同完成。`TaskDataOper`类是核心的数据操作引擎,它负责与数据库交互,查询和管理所有任务的元数据。对于定时任务,系统在启动时会查询所有未来有效的定时任务,并在后台进行监控。当系统时间到达任务设定的执行时间时,调度器会触发任务执行流程。循环任务的调度逻辑则更为复杂,它由服务器端控制,客户端主要负责查询和管理。任务状态机的设计体现在任务的生命周期上,一个任务可以处于“待执行”、“执行中”、“已完成”或“已取消”等状态,这些状态通过数据库中的字段进行记录和同步。 ## 任务序列化与反序列化机制 任务数据的序列化与反序列化主要通过`STQueryTaskBasicInfo`等结构体实现。这些结构体定义了任务的所有关键属性,如任务ID、名称、类型、脚本信息、电极配置等。当需要将任务信息从数据库读取到内存时,`TaskDataOper`类的`QueryTdBasicInfo`等方法会执行反序列化过程,将数据库记录填充到结构体实例中。反之,当需要保存任务配置时,系统会将结构体中的数据序列化为SQL语句或网络协议数据包。对于任务包,其序列化过程涉及将`STTdBrowseInfo`结构体的向量(vector)与`STTaskPacketAttr`结构体一起持久化到数据库。 **Section sources** - [TaskDataOper.h](file://h/TaskDataOper.h#L126-L204) - [TaskDataOper.h](file://h/TaskDataOper.h#L336-L335) - [TaskDataOper.cpp](file://cpp/Operator/TaskDataOper.cpp#L356-L364) ## 设备通信协议映射 任务配置数据最终需要通过网络协议传输给测量设备(如GD10)。`CtrlProtocolDef.h`头文件定义了与设备通信的协议结构。例如,`STMeasuTaskParam`结构体直接映射了发送给设备的任务参数,其中包含了测试类型、发射周期、堆栈数、采样间隔等关键信息。当一个任务被调度执行时,系统会从数据库中查询该任务的详细信息,然后将其填充到`STMeasuTaskParam`等协议结构体中,最后通过TCP/IP网络发送给设备。这种映射关系确保了在软件界面上配置的参数能够准确地转化为设备可理解的指令。 ```mermaid classDiagram class STQueryTaskBasicInfo { +int iTaskID +char szTaskName[60] +int iTestType +int iAR +int iSptType +float fXElecDistance +float fYElecDistance +UINT32 uiStartLayer +UINT32 uiEndLayer +UINT32 uiTimerTime } class STMeasuTaskParam { +BYTE ucTestType +BYTE ucTxPeriod +BYTE ucSptType +BYTE ucCableLayout +BYTE ucStacking +int iSAInterval +float fElecSpace +char ucTaskID[40] } class TaskDataOper { +QueryTdBasicInfo(int, STQueryTaskBasicInfo*) +QueryTimerTaskValiad(vector~STTimerTask~&, const SYSTEMTIME&) } class DialTimerTask { +OnButtonAdd() +OnButtonSave() +OnInitDialog() } STQueryTaskBasicInfo --> TaskDataOper : "查询" TaskDataOper --> STMeasuTaskParam : "映射" DialTimerTask --> TaskDataOper : "调用" ``` **Diagram sources** - [CtrlProtocolDef.h](file://h/CtrlProtocolDef.h#L111-L123) - [TaskDataOper.h](file://h/TaskDataOper.h#L126-L204) ## 操作指南 ### 创建任务包 1. 打开“任务包配置”对话框。 2. 在下拉列表中选择一个任务,点击“添加”按钮将其加入任务包列表。 3. 重复步骤2,按顺序添加所有需要的任务。 4. 在“循环次数”框中输入希望重复执行整个任务包的次数(1-60000)。 5. 在“时间间隔”框中输入每个任务执行后的等待时间(秒,1-60000)。 6. 输入PLC ID。 7. 点击“确定”保存配置。 ### 配置地形数据 1. 打开“地形参数设置”对话框。 2. 点击“导入文件”按钮,选择一个.dat格式的原始数据文件。 3. 在列表中输入或修改地形点的X、Y坐标,点击“添加”或“修改”按钮。 4. 选择“地形数据标志”(水平或垂直距离)。 5. 在“第一个电极对应的地形数据点编号”中输入起始点编号。 6. 点击“保存数据”按钮,将地形信息写入原始.dat文件。 ### 设置定时任务 1. 打开“定时任务”对话框。 2. 选择一个任务、设置执行日期和时间。 3. 输入PLC ID。 4. 点击“添加”按钮,该任务将出现在定时任务列表中。 5. 点击“保存”完成所有定时任务的设置。 ### 管理循环任务 1. 打开“循环任务管理”对话框。 2. 系统会自动从服务器加载所有循环任务。 3. 在列表中选择一个循环任务,其包含的子任务会显示在下方。 4. 如需删除,选中任务后点击“删除”按钮。