| @@ -1,6 +1,6 @@ | |||||
| # Current Handoff | # Current Handoff | ||||
| - Goal: 完成综合平台编程器的结构化梯形图、数据点管理、离线仿真和 Modbus RTU 真机链路 | |||||
| - Goal: 完成综合平台编程器的结构化梯形图、HMI、离线仿真和 Modbus RTU 真机链路 | |||||
| - Branch: `main` | - Branch: `main` | ||||
| - Current status: 第 1~10 步的软件实现与自动化测试已完成,待连接 XDH-60T4-E 进行真机安全验证和整理最终交付资料 | - Current status: 第 1~10 步的软件实现与自动化测试已完成,待连接 XDH-60T4-E 进行真机安全验证和整理最终交付资料 | ||||
| @@ -10,22 +10,23 @@ | |||||
| - 编辑器使用固定行列网格和正交连线,支持当前节点后串联、单节点并联、连续节点范围并联、删除节点或网络以及设置输出线圈 | - 编辑器使用固定行列网格和正交连线,支持当前节点后串联、单节点并联、连续节点范围并联、删除节点或网络以及设置输出线圈 | ||||
| - 画布只选择可见节点,不暴露内部表达式容器;橡皮框或多选连续节点后可直接建立并联支路 | - 画布只选择可见节点,不暴露内部表达式容器;橡皮框或多选连续节点后可直接建立并联支路 | ||||
| - 执行器递归求值并生成节点、表达式、网络轨迹,离线运行时画布显示导通路径和故障位置 | - 执行器递归求值并生成节点、表达式、网络轨迹,离线运行时画布显示导通路径和故障位置 | ||||
| - 数据点表统一维护地址、类型、名称、注释、当前值和 HMI/LAD 引用位置 | |||||
| - HMI 和梯形图直接配置 M/D 地址,不依赖预先创建的数据点 | |||||
| - `ActiveRegisterRepository` 在离线虚拟仓库与 PLC 缓存仓库之间切换 | - `ActiveRegisterRepository` 在离线虚拟仓库与 PLC 缓存仓库之间切换 | ||||
| - `PlcCommunicationService` 使用 Qt SerialBus 异步连接、轮询和单点写入,UI 不阻塞 | - `PlcCommunicationService` 使用 Qt SerialBus 异步连接、轮询和单点写入,UI 不阻塞 | ||||
| - 真机连接收集数据点、HMI 和梯形图地址,按 M/D 分区并合并相邻地址读取 | |||||
| - 真机连接收集 HMI 和梯形图实际引用地址,按 M/D 分区并合并相邻地址读取 | |||||
| - 真机模式要求首次读取完成,不复制离线值,不运行 PC 软件逻辑执行器 | - 真机模式要求首次读取完成,不复制离线值,不运行 PC 软件逻辑执行器 | ||||
| - 通信错误停止轮询并保留最后一次有效缓存,状态栏和日志显示错误 | - 通信错误停止轮询并保留最后一次有效缓存,状态栏和日志显示错误 | ||||
| - 主窗口静态控件已迁入 `main_window.ui`,PLC 参数由独立配置对话框收集后再发起连接 | - 主窗口静态控件已迁入 `main_window.ui`,PLC 参数由独立配置对话框收集后再发起连接 | ||||
| ## 关键决策 | ## 关键决策 | ||||
| - 工程格式继续使用 `1.0`,当前文件直接保存表达式树和数据点 | |||||
| - 工程格式继续使用 `1.0`,当前文件只保存 HMI 和梯形图表达式树,不保留 `dataPoints` 结构及兼容代码 | |||||
| - 不读取旧的 `stages/branches` 结构,不添加旧格式迁移和兼容层 | - 不读取旧的 `stages/branches` 结构,不添加旧格式迁移和兼容层 | ||||
| - 梯形图编辑结构而不是自由线段,避免悬空线、环路和多个输出路径 | - 梯形图编辑结构而不是自由线段,避免悬空线、环路和多个输出路径 | ||||
| - 网格仅作为编辑投影,不进入工程格式;服务层把连续范围操作转换为规范化表达式树 | - 网格仅作为编辑投影,不进入工程格式;服务层把连续范围操作转换为规范化表达式树 | ||||
| - 条件节点继续使用 `std::variant` 的独立配置类型,不向通用节点添加无关字段 | - 条件节点继续使用 `std::variant` 的独立配置类型,不向通用节点添加无关字段 | ||||
| - HMI、梯形图和通信共享 `M0~M4000`、`D0~D4000` 数据点范围 | |||||
| - HMI、梯形图和通信共享 `M0~M4000`、`D0~D4000` 地址范围 | |||||
| - 已删除统一数据点表、主窗口数据点 Dock 和属性区数据点下拉框;软元件注释功能待后续按信捷业务单独设计 | |||||
| - PLC 读写使用从 `0` 开始的原始 Modbus 地址 | - PLC 读写使用从 `0` 开始的原始 Modbus 地址 | ||||
| - HMI 写请求不乐观修改 PLC 缓存,由下一次轮询确认真实值 | - HMI 写请求不乐观修改 PLC 缓存,由下一次轮询确认真实值 | ||||
| - 真机运行时 PLC 内部程序是控制源,软件逻辑执行器保持停止 | - 真机运行时 PLC 内部程序是控制源,软件逻辑执行器保持停止 | ||||
| @@ -40,12 +41,13 @@ | |||||
| - `project_management_tests` | - `project_management_tests` | ||||
| - `hmi_editor_service_tests` | - `hmi_editor_service_tests` | ||||
| - `runtime_mode_service_tests` | - `runtime_mode_service_tests` | ||||
| - `data_point_service_tests` | |||||
| - `plc_runtime_tests` | - `plc_runtime_tests` | ||||
| - `main_window_tests` | - `main_window_tests` | ||||
| `main_window_tests` 还覆盖 PLC 配置参数往返、独立配置弹窗入口,以及主窗口不再内嵌串口参数控件。 | `main_window_tests` 还覆盖 PLC 配置参数往返、独立配置弹窗入口,以及主窗口不再内嵌串口参数控件。 | ||||
| 本轮已完整删除统一数据点业务,包括领域模型、服务、主窗口 Dock、属性区下拉框、JSON 字段和独立测试工程。当前开发阶段不保留 `dataPoints` 旧结构的迁移或兼容逻辑。主窗口测试明确验证已删除控件不存在,PLC 轮询测试改为验证从 HMI 实际绑定收集地址。 | |||||
| 本轮梯形图编辑重构还验证了:固定网格渲染、水平/垂直正交布线、工具栏直接建立并联支路,以及连续范围 `A AND ((B AND C) OR D)` 的结构变换和非连续范围拒绝。 | 本轮梯形图编辑重构还验证了:固定网格渲染、水平/垂直正交布线、工具栏直接建立并联支路,以及连续范围 `A AND ((B AND C) OR D)` 的结构变换和非连续范围拒绝。 | ||||
| Qt Release 应用已完成干净构建,并执行了启动与正常退出冒烟验证。`git diff --check` 无空白错误。 | Qt Release 应用已完成干净构建,并执行了启动与正常退出冒烟验证。`git diff --check` 无空白错误。 | ||||
| @@ -14,7 +14,7 @@ app/ | |||||
| ├── src/ | ├── src/ | ||||
| │ ├── main.cpp 对象创建与依赖注入 | │ ├── main.cpp 对象创建与依赖注入 | ||||
| │ ├── ui/ Qt Widgets 视图和交互协调 | │ ├── ui/ Qt Widgets 视图和交互协调 | ||||
| │ ├── domain/ 工程、HMI、梯形图、数据点和寄存器模型 | |||||
| │ ├── domain/ 工程、HMI、梯形图和寄存器模型 | |||||
| │ ├── services/ 编辑、仿真、运行模式和通信契约 | │ ├── services/ 编辑、仿真、运行模式和通信契约 | ||||
| │ └── infrastructure/ JSON、PLC 缓存和 Qt Modbus RTU 实现 | │ └── infrastructure/ JSON、PLC 缓存和 Qt Modbus RTU 实现 | ||||
| └── tests/ 单元测试与集成测试工程 | └── tests/ 单元测试与集成测试工程 | ||||
| @@ -34,7 +34,7 @@ main.cpp -> UI + Services + Infrastructure | |||||
| - `ui` 只提交操作并展示模型、运行轨迹和错误状态 | - `ui` 只提交操作并展示模型、运行轨迹和错误状态 | ||||
| - `main.cpp` 负责组合依赖,不承载业务规则 | - `main.cpp` 负责组合依赖,不承载业务规则 | ||||
| 主窗口的菜单、工具栏、属性表单和数据点面板由 Qt Designer 的 | |||||
| 主窗口的菜单、工具栏和属性表单由 Qt Designer 的 | |||||
| `main_window.ui` 定义。C++ 仅创建 HMI/梯形图自定义画布、填充运行时数据并连接服务层信号。 | `main_window.ui` 定义。C++ 仅创建 HMI/梯形图自定义画布、填充运行时数据并连接服务层信号。 | ||||
| 真实 PLC 的串口与轮询参数由独立的 `PlcConnectionDialog` 收集,主窗口只保留配置连接和断开入口。 | 真实 PLC 的串口与轮询参数由独立的 `PlcConnectionDialog` 收集,主窗口只保留配置连接和断开入口。 | ||||
| @@ -45,13 +45,12 @@ main.cpp -> UI + Services + Infrastructure | |||||
| | `register_address.*` | 定义 `M0~M4000`、`D0~D4000` 地址和值域规则 | | | `register_address.*` | 定义 `M0~M4000`、`D0~D4000` 地址和值域规则 | | ||||
| | `register_repository.*` | 定义 M/D 统一读写接口和离线内存实现 | | | `register_repository.*` | 定义 M/D 统一读写接口和离线内存实现 | | ||||
| | `active_register_repository.*` | 在虚拟仓库与 PLC 缓存仓库之间切换当前数据源 | | | `active_register_repository.*` | 在虚拟仓库与 PLC 缓存仓库之间切换当前数据源 | | ||||
| | `data_point_model.*` | 定义地址、名称和注释统一数据点 | | |||||
| | `hmi_model.*` | 定义页面、控件、布局和寄存器绑定 | | | `hmi_model.*` | 定义页面、控件、布局和寄存器绑定 | | ||||
| | `control_logic_model.*` | 定义梯形图表达式树、条件节点和输出线圈 | | | `control_logic_model.*` | 定义梯形图表达式树、条件节点和输出线圈 | | ||||
| | `project_model.*` | 聚合数据点、HMI 页面和控制逻辑并执行工程校验 | | |||||
| | `project_model.*` | 聚合 HMI 页面和控制逻辑并执行工程校验 | | |||||
| | `runtime_state.*` | 定义编辑、离线运行和真机运行状态机 | | | `runtime_state.*` | 定义编辑、离线运行和真机运行状态机 | | ||||
| 工程文件格式保持 `1.0`。当前版本直接保存表达式树和数据点,不读取旧的 `stages/branches` 结构,也不包含旧格式迁移代码。加载必须先完成 JSON 解析、版本检查和领域校验,成功后才能替换当前工程;保存使用原子提交。 | |||||
| 工程文件格式保持 `1.0`。当前版本直接保存 HMI 和梯形图表达式树,不读取旧的 `stages/branches` 和 `dataPoints` 结构,也不包含旧格式迁移和兼容代码。加载必须先完成 JSON 解析、版本检查和领域校验,成功后才能替换当前工程;保存使用原子提交。 | |||||
| `Project::validate()` 允许未绑定控件、待配置节点和未完成网络作为编辑草稿保存。`Project::validateForRunning()` 额外拒绝未绑定 HMI、待配置节点、空条件和缺少输出的网络。 | `Project::validate()` 允许未绑定控件、待配置节点和未完成网络作为编辑草稿保存。`Project::validateForRunning()` 额外拒绝未绑定 HMI、待配置节点、空条件和缺少输出的网络。 | ||||
| @@ -92,15 +91,11 @@ Parallel | |||||
| `OfflineSimulationService` 以 50 ms 目标周期驱动扫描,启动时复制逻辑快照并清空虚拟 M/D。故障后停止扫描并保留最终寄存器值,HMI 可继续显示但禁止写入。该周期不提供硬实时保证。 | `OfflineSimulationService` 以 50 ms 目标周期驱动扫描,启动时复制逻辑快照并清空虚拟 M/D。故障后停止扫描并保留最终寄存器值,HMI 可继续显示但禁止写入。该周期不提供硬实时保证。 | ||||
| ## 数据点管理 | |||||
| ## M/D 地址使用 | |||||
| `DataPointService` 维护统一数据点表: | |||||
| HMI 控件和梯形图节点直接绑定 `M0~M4000`、`D0~D4000` 地址,不要求预先创建数据点。地址是程序和通信的真实标识,属性面板只编辑区域与地址。 | |||||
| ```text | |||||
| 地址 | 类型 | 名称 | 注释 | 当前值 | 引用位置 | |||||
| ``` | |||||
| 地址和名称在工程内唯一。引用位置从 HMI 绑定和梯形图节点动态计算;仍被引用的数据点不能删除或修改地址,但可以修改名称和注释。HMI 和梯形图属性区从同一数据点集合选择地址,运行时当前值由活动寄存器仓库读取。 | |||||
| 软元件注释、网络注释和命令语视图不属于当前实现。后续如增加注释,应把地址级软元件注释和网络级说明分开建模,不能重新引入“名称、注释、当前值、引用位置”混合的数据点表。 | |||||
| ## 寄存器与 Modbus RTU | ## 寄存器与 Modbus RTU | ||||
| @@ -109,7 +104,7 @@ Parallel | |||||
| - 离线运行使用 `VirtualRegisterRepository` | - 离线运行使用 `VirtualRegisterRepository` | ||||
| - 真机运行使用 `PlcRegisterRepository` 的最近一次有效缓存 | - 真机运行使用 `PlcRegisterRepository` 的最近一次有效缓存 | ||||
| `PlcCommunicationService` 使用 `QModbusRtuSerialMaster` 异步连接、读取和写入。连接时从数据点、HMI 和梯形图收集 M/D 地址,去重后按区域合并相邻地址进行轮询。M 使用线圈,D 使用保持寄存器;所有 Modbus 地址均为从 `0` 开始的原始地址。 | |||||
| `PlcCommunicationService` 使用 `QModbusRtuSerialMaster` 异步连接、读取和写入。连接时从 HMI 和梯形图的实际引用中收集 M/D 地址,去重后按区域合并相邻地址进行轮询。M 使用线圈,D 使用保持寄存器;所有 Modbus 地址均为从 `0` 开始的原始地址。 | |||||
| HMI 写入只表示异步请求已受理,不乐观修改 PLC 缓存,实际值由后续读回确认。超时、协议错误或断线会停止轮询、保留最后一次有效值并进入故障状态,错误通过运行模式服务交给 UI 展示。 | HMI 写入只表示异步请求已受理,不乐观修改 PLC 缓存,实际值由后续读回确认。超时、协议错误或断线会停止轮询、保留最后一次有效值并进入故障状态,错误通过运行模式服务交给 UI 展示。 | ||||
| @@ -128,7 +123,7 @@ HMI 写入只表示异步请求已受理,不乐观修改 PLC 缓存,实际 | |||||
| | 优先级 | 测试对象 | 重点内容 | | | 优先级 | 测试对象 | 重点内容 | | ||||
| | --- | --- | --- | | | --- | --- | --- | | ||||
| | 高 | 领域模型 | 地址边界、表达式校验与归一化、工程唯一性 | | | 高 | 领域模型 | 地址边界、表达式校验与归一化、工程唯一性 | | ||||
| | 高 | 编辑服务 | 嵌套串并联插入、删除、数据点引用保护 | | |||||
| | 高 | 编辑服务 | 嵌套串并联插入、删除和地址配置 | | |||||
| | 高 | 执行与模式服务 | 递归求值、轨迹、离线闭环、仓库切换和首次读取约束 | | | 高 | 执行与模式服务 | 递归求值、轨迹、离线闭环、仓库切换和首次读取约束 | | ||||
| | 高 | 工程存储 | `1.0` 往返、缺失字段、非法结构和不支持版本 | | | 高 | 工程存储 | `1.0` 往返、缺失字段、非法结构和不支持版本 | | ||||
| | 中 | PLC 通信 | 缓存有效性、地址集合、异步读写和错误反馈 | | | 中 | PLC 通信 | 缓存有效性、地址集合、异步读写和错误反馈 | | ||||
| @@ -24,7 +24,7 @@ | |||||
| ## 3. 定义核心数据模型与接口 | ## 3. 定义核心数据模型与接口 | ||||
| - 定义工程、HMI 页面、HMI 控件、结构化控制逻辑、统一数据点和 M/D 地址模型。 | |||||
| - 定义工程、HMI 页面、HMI 控件、结构化控制逻辑和 M/D 地址模型。 | |||||
| - 定义统一的寄存器仓库接口,隔离虚拟寄存器与真实 PLC 寄存器。 | - 定义统一的寄存器仓库接口,隔离虚拟寄存器与真实 PLC 寄存器。 | ||||
| - 定义编辑态、离线运行态和真机运行态的状态边界。 | - 定义编辑态、离线运行态和真机运行态的状态边界。 | ||||
| @@ -67,14 +67,6 @@ | |||||
| 完成标准:能够表达 `A OR (B AND C)` 等嵌套逻辑,并配置启动、停止和状态保持逻辑。 | 完成标准:能够表达 `A OR (B AND C)` 等嵌套逻辑,并配置启动、停止和状态保持逻辑。 | ||||
| ## 7.1 建立统一数据点表 | |||||
| - 统一维护地址、类型、名称、注释、当前值和引用位置。 | |||||
| - HMI 与梯形图从同一数据点集合选择 M/D 地址。 | |||||
| - 防止删除或修改仍被引用的数据点地址。 | |||||
| 完成标准:地址只需定义一次,能够查看 HMI 和梯形图中的全部引用位置。 | |||||
| ## 8. 实现离线仿真运行 | ## 8. 实现离线仿真运行 | ||||
| - 实现虚拟 M/D 寄存器和固定周期的软件逻辑执行器。 | - 实现虚拟 M/D 寄存器和固定周期的软件逻辑执行器。 | ||||
| @@ -89,7 +81,7 @@ | |||||
| - 使用 Qt SerialBus 的 `QModbusRtuSerialMaster` 封装独立通信服务。 | - 使用 Qt SerialBus 的 `QModbusRtuSerialMaster` 封装独立通信服务。 | ||||
| - 实现串口配置、连接、断开、M/D 读写、轮询、超时和错误反馈。 | - 实现串口配置、连接、断开、M/D 读写、轮询、超时和错误反馈。 | ||||
| - 使用从 `0` 开始的原始 Modbus 地址,通信过程不得阻塞 UI。 | - 使用从 `0` 开始的原始 Modbus 地址,通信过程不得阻塞 UI。 | ||||
| - 收集数据点、HMI 和梯形图地址,按 M/D 分区并合并相邻地址轮询。 | |||||
| - 收集 HMI 和梯形图实际引用地址,按 M/D 分区并合并相邻地址轮询。 | |||||
| - 写请求不乐观更新缓存,等待下一次读回确认 PLC 实际值。 | - 写请求不乐观更新缓存,等待下一次读回确认 PLC 实际值。 | ||||
| 完成标准:软件链路和自动化测试完成后,先在 PLC STOP 状态下稳定读取和写入 `M0`、`D0`,再验证批量轮询。 | 完成标准:软件链路和自动化测试完成后,先在 PLC STOP 状态下稳定读取和写入 `M0`、`D0`,再验证批量轮询。 | ||||