| @@ -24,6 +24,11 @@ | |||||
| - 自由监控支持 `M0~M4000`、`D0~D4000` 地址输入、连续批量添加、去重、删除、清空和最多 64 项限制 | - 自由监控支持 `M0~M4000`、`D0~D4000` 地址输入、连续批量添加、去重、删除、清空和最多 64 项限制 | ||||
| - 自由监控读取活动寄存器仓库,离线使用虚拟 M/D,真机使用 PLC 缓存,通信故障保留并标记最后有效值 | - 自由监控读取活动寄存器仓库,离线使用虚拟 M/D,真机使用 PLC 缓存,通信故障保留并标记最后有效值 | ||||
| - HMI 按钮支持 TouchWin 同类的置 ON、置 OFF、取反和瞬时 ON,默认瞬时 ON | - HMI 按钮支持 TouchWin 同类的置 ON、置 OFF、取反和瞬时 ON,默认瞬时 ON | ||||
| - 工程支持多个有序 HMI 页面和多个有序控制逻辑,工程树可选择切换、新增、重命名、删除、启停和上下移动 | |||||
| - 主窗口使用会话态当前页面 ID、当前逻辑 ID,所有编辑入口不再固定操作第一项 | |||||
| - 工程持久化初始 HMI 页面;运行态由 `HmiNavigationService` 从初始页启动并处理本地 PageJump 导航 | |||||
| - HMI 已开放不绑定寄存器的 `Label` 和独立 `PageJump` 创建入口,属性区按控件类型显示绑定、按钮操作或目标页面 | |||||
| - 离线执行器按工程顺序扫描所有启用逻辑,禁用草稿不阻止运行;轨迹按逻辑 ID 隔离,运行工作台可切换当前投影 | |||||
| - HMI 运行按钮已区分悬停、按下、释放和禁止写入外观,运行态不再显示编辑选中框,可写按钮使用手型光标 | - HMI 运行按钮已区分悬停、按下、释放和禁止写入外观,运行态不再显示编辑选中框,可写按钮使用手型光标 | ||||
| - PLC 轮询集合已扩展为 HMI、梯形图和自由监控地址的并集,连接后可动态增删监控地址 | - PLC 轮询集合已扩展为 HMI、梯形图和自由监控地址的并集,连接后可动态增删监控地址 | ||||
| - 已在真实 `COM3 / 9600 / 8E1 / 站号 1` 上完成只读联机验证,项目通信服务可完成 M/D 首次读取并进入真机运行前置状态 | - 已在真实 `COM3 / 9600 / 8E1 / 站号 1` 上完成只读联机验证,项目通信服务可完成 M/D 首次读取并进入真机运行前置状态 | ||||
| @@ -31,6 +36,8 @@ | |||||
| ## 关键决策 | ## 关键决策 | ||||
| - 工程格式继续使用 `1.0`,当前文件只保存 HMI 和梯形图表达式树,不保留 `dataPoints` 结构及兼容代码 | - 工程格式继续使用 `1.0`,当前文件只保存 HMI 和梯形图表达式树,不保留 `dataPoints` 结构及兼容代码 | ||||
| - 当前 `1.0` 直接要求 `initialHmiPageId` 和 PageJump 的 `targetPageId`,开发阶段不为同版本旧草稿补默认值或迁移分支 | |||||
| - 页面跳转保存目标页面稳定 ID,不保存名称或数组索引;编辑器当前页面和当前逻辑属于会话状态,不写入工程 | |||||
| - 按钮操作是工程 `1.0` 的必填字段,不兼容或迁移缺少该字段的旧按钮数据 | - 按钮操作是工程 `1.0` 的必填字段,不兼容或迁移缺少该字段的旧按钮数据 | ||||
| - 不读取旧的 `stages/branches` 结构,不添加旧格式迁移和兼容层 | - 不读取旧的 `stages/branches` 结构,不添加旧格式迁移和兼容层 | ||||
| - 梯形图编辑结构而不是自由线段,避免悬空线、环路和多个输出路径 | - 梯形图编辑结构而不是自由线段,避免悬空线、环路和多个输出路径 | ||||
| @@ -60,6 +67,8 @@ | |||||
| `main_window_tests` 还覆盖 PLC 配置参数往返、独立配置弹窗入口,以及主窗口不再内嵌串口参数控件。 | `main_window_tests` 还覆盖 PLC 配置参数往返、独立配置弹窗入口,以及主窗口不再内嵌串口参数控件。 | ||||
| 本轮多页面和多逻辑实现增加了领域、服务、存储和主窗口集成覆盖:初始页约束、页面引用删除保护、页面/逻辑名称唯一性和顺序、禁用草稿逻辑、多逻辑扫描与轨迹隔离、严格 JSON `1.0` 必填字段、工程树选择切换、Label/PageJump 属性可见性、运行态页面跳转和逻辑轨迹选择。 | |||||
| 2026-08-13 真机排查发现 `QModbusRtuSerialMaster::connectDevice()` 在当前 Windows | 2026-08-13 真机排查发现 `QModbusRtuSerialMaster::connectDevice()` 在当前 Windows | ||||
| 串口驱动上会同步触发 `ConnectedState`。旧实现随后再次写入 `Connecting`,导致已经发出的 | 串口驱动上会同步触发 `ConnectedState`。旧实现随后再次写入 `Connecting`,导致已经发出的 | ||||
| 读取响应因服务状态不是 `Connected` 而被丢弃,首次读取标志永远不能完成。现已把 | 读取响应因服务状态不是 `Connected` 而被丢弃,首次读取标志永远不能完成。现已把 | ||||
| @@ -103,6 +112,21 @@ PLC 断开状态现已与底层 Qt Modbus 会话保持一致。连接中断类 | |||||
| 禁用“断开 PLC”但重连仍提示连接已经启动。串口无法打开时,输出区只通过 PLC 状态刷新记录 | 禁用“断开 PLC”但重连仍提示连接已经启动。串口无法打开时,输出区只通过 PLC 状态刷新记录 | ||||
| 一次故障,连接操作不再重复追加同一错误,但仍保留警告对话框。 | 一次故障,连接操作不再重复追加同一错误,但仍保留警告对话框。 | ||||
| PLC 未响应或通信超时且本地串口仍打开时,服务停止正常轮询,每次探测失败后等待 2 秒再发送 | |||||
| 一次单地址只读探测,不重复输出相同的超时日志。探测成功后进入 `Recovering` 状态,重新读取全部轮询地址; | |||||
| 完整首读完成后才恢复 `Connected`。故障和恢复过程始终停留在编辑态,不自动回到真机运行, | |||||
| “断开 PLC”继续用于释放本地串口会话。 | |||||
| 2026-08-14 使用真实 `COM3 / 9600 / 8E1 / 站号 1` 完成只读恢复测试。连续 5 次读取 | |||||
| `M0~M2、D0` 的完整首读耗时为 `304 / 304 / 288 / 271 / 287 ms`,平均约 `291 ms`;串口 | |||||
| 进入已连接状态平均约 `51 ms`。真机运行时拔掉 PLC 侧 RS-485 A/B 后,服务进入 `Faulted`, | |||||
| 运行模式同步退回 `Editing`;接回线后约 `7.05 s` 进入 `Recovering`,再用约 `224 ms` 完成 | |||||
| 完整首读并恢复 `Connected`,最终仍保持 `Editing`。测试结束后再次首读耗时 `288 ms`,确认 | |||||
| 恢复探针已释放 COM3。底层 Qt SerialBus 单次复测中,连接状态约 `58 ms`,读取 `M0~M2` | |||||
| 到 `96 ms`,继续读取 `D0` 到 `128 ms`,单次读响应约 `32~38 ms`;生产服务完整首读的主要 | |||||
| 额外耗时来自 `200 ms` 正常轮询节拍。本次测试全程没有写入 PLC,读回值为 | |||||
| `M0=0、M1=0、M2=0、D0=0`。 | |||||
| 本轮新增自动化测试覆盖故障自动退回编辑态、首读资格撤销、故障后禁止重新进入真机、故障态 | 本轮新增自动化测试覆盖故障自动退回编辑态、首读资格撤销、故障后禁止重新进入真机、故障态 | ||||
| 直接重连清理旧会话、主窗口重新配置入口和五类核心通信错误。`plc_runtime_tests`、 | 直接重连清理旧会话、主窗口重新配置入口和五类核心通信错误。`plc_runtime_tests`、 | ||||
| `runtime_mode_service_tests`、`main_window_tests` 均通过,Qt Release 工程完成干净构建。 | `runtime_mode_service_tests`、`main_window_tests` 均通过,Qt Release 工程完成干净构建。 | ||||
| @@ -4,7 +4,7 @@ | |||||
| 项目采用 UI、领域、服务和基础设施分层。HMI 编辑、结构化梯形图、离线仿真和真机联机共用工程模型,UI 不直接依赖文件系统、串口或 Modbus 实现。 | 项目采用 UI、领域、服务和基础设施分层。HMI 编辑、结构化梯形图、离线仿真和真机联机共用工程模型,UI 不直接依赖文件系统、串口或 Modbus 实现。 | ||||
| 当前目标是完成基础设备控制闭环,不生成、编译或下载 PLC 程序,不实现 XDPPro 的完整指令集,也不提供任意自由画线。 | |||||
| 当前目标是完成单工程、单 PLC、多 HMI 页面和多控制逻辑的基础设备控制闭环,不生成、编译或下载 PLC 程序,不实现 XDPPro 的完整 POU/指令集,也不提供任意自由画线。 | |||||
| ## 目录与依赖 | ## 目录与依赖 | ||||
| @@ -51,7 +51,9 @@ main.cpp -> UI + Services + Infrastructure | |||||
| | `project_model.*` | 聚合 HMI 页面和控制逻辑并执行工程校验 | | | `project_model.*` | 聚合 HMI 页面和控制逻辑并执行工程校验 | | ||||
| | `runtime_state.*` | 定义编辑、离线运行和真机运行状态机 | | | `runtime_state.*` | 定义编辑、离线运行和真机运行状态机 | | ||||
| 工程文件格式保持 `1.0`。当前版本直接保存 HMI 和梯形图表达式树,不读取旧的 `stages/branches` 和 `dataPoints` 结构,也不包含旧格式迁移和兼容代码。加载必须先完成 JSON 解析、版本检查和领域校验,成功后才能替换当前工程;保存使用原子提交。 | |||||
| 工程文件格式保持 `1.0`。当前 `1.0` 直接保存有序 `hmiPages`、`initialHmiPageId`、有序 `controlLogics` 和梯形图表达式树,不读取其他结构,也不包含迁移和兼容代码。加载必须先完成 JSON 解析、版本检查和领域校验,成功后才能替换当前工程;保存使用原子提交。完整字段定义见 `docs/工程格式说明.md`。 | |||||
| `HmiPage.id` 和 `ControlLogic.id` 是稳定内部标识,名称可修改,数组顺序分别决定工程树页面顺序和离线逻辑扫描顺序。`MainWindow` 保存 `current_hmi_page_id_` 与 `current_logic_id_` 作为编辑会话选择,它们不进入 JSON。`Project.initialHmiPageId` 是运行态每次启动 HMI 时使用的持久化初始页,与编辑器当前正在查看的页面相互独立。 | |||||
| `Project::validate()` 允许未绑定控件、待配置节点和未完成网络作为编辑草稿保存。`Project::validateForRunning()` 额外拒绝未绑定 HMI、待配置节点、空条件和缺少输出的网络。 | `Project::validate()` 允许未绑定控件、待配置节点和未完成网络作为编辑草稿保存。`Project::validateForRunning()` 额外拒绝未绑定 HMI、待配置节点、空条件和缺少输出的网络。 | ||||
| @@ -59,6 +61,8 @@ HMI 按钮操作作为工程 `1.0` 的强类型字段保存,支持 `置 ON`、 | |||||
| `瞬时 ON`。新建按钮默认使用瞬时 ON;按钮按下和释放事件由 UI 转交运行服务解释,UI | `瞬时 ON`。新建按钮默认使用瞬时 ON;按钮按下和释放事件由 UI 转交运行服务解释,UI | ||||
| 不直接决定写入值。当前版本不迁移缺少按钮操作字段的旧工程文件。 | 不直接决定写入值。当前版本不迁移缺少按钮操作字段的旧工程文件。 | ||||
| `Label` 是不绑定 M/D 的固定文本控件。`PageJump` 是独立控件,使用强类型 `targetPageId` 引用目标页面稳定 ID,同样不绑定 M/D。编辑态点击 PageJump 只执行选择和拖动;离线或真机运行态点击后由 `HmiNavigationService` 在本地切换运行页面,不发出 PLC 写请求,因此 PLC 通信写权限不可用时也不影响页面导航。被 PageJump 引用的页面不能删除,初始页必须先切换后才能删除,工程至少保留一个页面。 | |||||
| ## 结构化梯形图 | ## 结构化梯形图 | ||||
| 网络条件采用递归表达式: | 网络条件采用递归表达式: | ||||
| @@ -90,9 +94,9 @@ Parallel | |||||
| ## 执行与运行反馈 | ## 执行与运行反馈 | ||||
| `SoftwareLogicExecutor` 按控制逻辑、网络顺序扫描,并递归求值 `Node / Series / Parallel`。普通线圈每周期写入网络结果,置位和复位线圈只在网络成立时写入;前面网络的写入对后面网络同一扫描周期立即可见。 | |||||
| `SoftwareLogicExecutor` 按 `controlLogics` 数组顺序扫描所有已启用逻辑,再按网络顺序递归求值 `Node / Series / Parallel`。禁用逻辑仅保留结构校验,未完成的禁用草稿不会阻止离线运行。普通线圈每周期写入网络结果,置位和复位线圈只在网络成立时写入;前面逻辑或网络的写入对后面逻辑和网络在同一扫描周期立即可见。 | |||||
| 每次扫描生成 `LogicTraceSnapshot`,记录节点、表达式、网络和线圈的导通状态。逻辑画布在运行时以绿色显示导通节点和路径;执行错误携带逻辑、网络和节点上下文,画布选择并以红色突出故障位置。 | |||||
| 每次扫描生成按逻辑 ID 分区的 `LogicTraceSnapshot`,记录节点、表达式、网络和线圈的导通状态,避免不同逻辑中重复的 `rung-1`、`contact-1` 相互覆盖。运行工作台的逻辑下拉框只切换当前轨迹投影,所有已启用逻辑仍持续执行。逻辑画布以绿色显示导通节点和路径;执行错误携带逻辑、网络和节点上下文,画布选择并以红色突出故障位置。 | |||||
| `OfflineSimulationService` 以 50 ms 目标周期驱动扫描,启动时复制逻辑快照并清空虚拟 M/D。故障后停止扫描并保留最终寄存器值,HMI 可继续显示但禁止写入。该周期不提供硬实时保证。 | `OfflineSimulationService` 以 50 ms 目标周期驱动扫描,启动时复制逻辑快照并清空虚拟 M/D。故障后停止扫描并保留最终寄存器值,HMI 可继续显示但禁止写入。该周期不提供硬实时保证。 | ||||
| @@ -116,7 +120,7 @@ HMI 控件和梯形图节点直接绑定 `M0~M4000`、`D0~D4000` 地址,不要 | |||||
| | 模式 | 同时显示 | 统一数据源 | | | 模式 | 同时显示 | 统一数据源 | | ||||
| | --- | --- | --- | | | --- | --- | --- | | ||||
| | 离线运行 | HMI、梯形图仿真轨迹、自由监控 | 虚拟 M/D | | |||||
| | 离线运行 | 可导航 HMI、当前所选逻辑轨迹、自由监控 | 虚拟 M/D | | |||||
| | 真机运行 | HMI、自由监控 | PLC 缓存 | | | 真机运行 | HMI、自由监控 | PLC 缓存 | | ||||
| 真机模式不显示本地梯形图导通轨迹。当前项目不能读取 PLC 内部程序和网络执行轨迹,本地 | 真机模式不显示本地梯形图导通轨迹。当前项目不能读取 PLC 内部程序和网络执行轨迹,本地 | ||||
| @@ -138,11 +142,18 @@ PLC 连接后可以动态增删自由监控地址。存在读取请求时,新 | |||||
| 运行资格;新增地址自身在首次读回前显示“等待读取”。如果连接首次读取尚未完成,新的完整 | 运行资格;新增地址自身在首次读回前显示“等待读取”。如果连接首次读取尚未完成,新的完整 | ||||
| 轮询集合会共同参与首次读取判定。 | 轮询集合会共同参与首次读取判定。 | ||||
| HMI 写入只表示异步请求已受理,不乐观修改 PLC 缓存,实际值由后续读回确认。超时、协议错误或断线会停止轮询、保留最后一次有效值并进入故障状态,错误通过运行模式服务交给 UI 展示。 | |||||
| HMI 写入只表示异步请求已受理,不乐观修改 PLC 缓存,实际值由后续读回确认。协议错误或断线会停止轮询、保留最后一次有效值并进入故障状态,错误通过运行模式服务交给 UI 展示。 | |||||
| PLC 未响应或通信超时且本地串口仍然打开时,通信服务停止正常高频轮询,每次探测失败后等待 | |||||
| 2 秒,再只读探测一次当前轮询集合的首个地址。探测失败不重复打印同一超时日志;探测成功后进入恢复状态, | |||||
| 重新读取全部轮询地址并重建当前连接的首次读取资格,完整首读完成后才恢复为已连接状态。 | |||||
| 通信故障会立即撤销当前连接的首次读取资格。若故障发生在真机运行态,运行模式服务自动返回 | 通信故障会立即撤销当前连接的首次读取资格。若故障发生在真机运行态,运行模式服务自动返回 | ||||
| 编辑态,PLC 最后一次有效缓存仍保留用于日志和故障诊断,但不能作为再次进入真机运行态的依据。 | 编辑态,PLC 最后一次有效缓存仍保留用于日志和故障诊断,但不能作为再次进入真机运行态的依据。 | ||||
| 重新进入真机运行必须重新连接 PLC,并在当前连接中重新完成首次读取。 | |||||
| 重新进入真机运行必须等待当前串口会话恢复或重新连接 PLC,并重新完成首次读取。 | |||||
| 通信超时后的自动探测只恢复通信和缓存,不自动恢复真机运行。接线或 PLC 供电恢复后,应用 | |||||
| 完成新的首次读取并继续停留在编辑态,由用户手动决定是否重新进入真机运行。“断开 PLC” | |||||
| 在超时和恢复过程中保持可用,用于关闭并释放仍然打开的本地串口会话。 | |||||
| 通信服务根据 Qt Modbus 错误和串口是否曾成功打开区分连接阶段失败与运行中连接中断。连接阶段 | 通信服务根据 Qt Modbus 错误和串口是否曾成功打开区分连接阶段失败与运行中连接中断。连接阶段 | ||||
| 无法打开串口时直接保持未连接状态;已经连接后收到 `ConnectionError` 或意外进入 | 无法打开串口时直接保持未连接状态;已经连接后收到 `ConnectionError` 或意外进入 | ||||
| @@ -0,0 +1,84 @@ | |||||
| # 工程 JSON 1.0 格式说明 | |||||
| ## 格式策略 | |||||
| 当前开发阶段只有一个有效工程格式:`1.0`。代码直接读写本文描述的结构,不为早期开发草稿增加同版本默认值、字段推断、迁移分支或双写逻辑。缺少必填字段、字段类型错误、引用不存在或领域校验失败时,加载必须失败且不得替换当前工程。 | |||||
| ## 顶层结构 | |||||
| ```json | |||||
| { | |||||
| "formatVersion": "1.0", | |||||
| "id": "project-1", | |||||
| "name": "包装线", | |||||
| "hmiPages": [], | |||||
| "initialHmiPageId": "", | |||||
| "controlLogics": [] | |||||
| } | |||||
| ``` | |||||
| 所有顶层字段必填。空工程允许 `hmiPages` 和 `controlLogics` 为空,此时 `initialHmiPageId` 必须为空。存在页面时,`initialHmiPageId` 必须引用 `hmiPages` 中的页面 ID。 | |||||
| `hmiPages` 与 `controlLogics` 都是有序数组。页面顺序用于工程树显示;控制逻辑顺序是离线扫描顺序。对象 ID 稳定且唯一,名称可修改且在同类对象中唯一。 | |||||
| 编辑器的当前页面 ID 和当前逻辑 ID 是主窗口会话状态,不进入工程 JSON。每次进入运行态时,HMI 从 `initialHmiPageId` 重新启动。 | |||||
| ## HMI 页面与控件 | |||||
| ```json | |||||
| { | |||||
| "id": "page-1", | |||||
| "name": "主操作页面", | |||||
| "width": 800, | |||||
| "height": 480, | |||||
| "controls": [] | |||||
| } | |||||
| ``` | |||||
| 每个控件都要求 `id`、`type`、`bounds`、`text`、`binding` 和 `properties`。`bounds` 包含整数 `x`、`y`、`width`、`height`,矩形必须完整位于页面内。`binding` 为寄存器对象或 JSON `null`。 | |||||
| | `type` | 绑定 | 额外必填字段 | | |||||
| | --- | --- | --- | | |||||
| | `button` | M 地址或 `null` 草稿 | `buttonOperation` | | |||||
| | `indicator` | M 地址或 `null` 草稿 | 无 | | |||||
| | `numericDisplay` | D 地址或 `null` 草稿 | 无 | | |||||
| | `numericInput` | D 地址或 `null` 草稿 | 无 | | |||||
| | `label` | 必须为 `null` | 无 | | |||||
| | `pageJump` | 必须为 `null` | `targetPageId` | | |||||
| 按钮操作字符串为 `setOn`、`setOff`、`toggle` 或 `momentaryOn`。PageJump 使用目标页面稳定 ID,不使用名称或数组位置: | |||||
| ```json | |||||
| { | |||||
| "id": "page-jump-1", | |||||
| "type": "pageJump", | |||||
| "bounds": {"x": 20, "y": 20, "width": 120, "height": 40}, | |||||
| "text": "参数设置", | |||||
| "binding": null, | |||||
| "properties": {}, | |||||
| "targetPageId": "page-2" | |||||
| } | |||||
| ``` | |||||
| 编辑草稿允许 `targetPageId` 为空字符串,但进入运行态前必须配置为现存页面 ID。任何页面被 PageJump 引用时不得删除。 | |||||
| ## 控制逻辑 | |||||
| ```json | |||||
| { | |||||
| "id": "logic-1", | |||||
| "name": "主控制逻辑", | |||||
| "enabled": true, | |||||
| "rungs": [] | |||||
| } | |||||
| ``` | |||||
| `enabled` 决定离线执行器是否扫描该逻辑。所有启用逻辑按 `controlLogics` 数组顺序执行;禁用逻辑仍要求 ID、名称、网络和表达式结构合法,但允许保留未完成节点作为草稿。 | |||||
| 网络、`Node / Series / Parallel` 条件表达式、触点、比较和线圈字段沿用当前结构化梯形图模型。网格坐标、画布连线和运行轨迹是 UI 或运行会话投影,不进入 JSON。 | |||||
| ## 校验与读写 | |||||
| 保存顺序为领域校验、JSON 序列化、`QSaveFile` 原子提交。加载顺序为 JSON 语法、`formatVersion`、必填字段和类型、领域关系校验,全部成功后才替换当前工程。 | |||||
| 工程保存允许未绑定的寄存器控件和未完成梯形图草稿。进入离线运行还必须通过运行校验:所有 HMI 寄存器控件完成绑定、所有 PageJump 目标有效、所有启用逻辑完整;禁用草稿逻辑不阻止运行。 | |||||
| @@ -53,7 +53,7 @@ | |||||
| - 支持按钮、指示灯、数值显示和数值输入等基础控件。 | - 支持按钮、指示灯、数值显示和数值输入等基础控件。 | ||||
| - HMI 控件只绑定统一寄存器仓库,不直接访问仿真器或串口。 | - HMI 控件只绑定统一寄存器仓库,不直接访问仿真器或串口。 | ||||
| 完成标准:能够设计一个基础操作页面,并随工程保存和加载。 | |||||
| 完成标准:能够管理多个有序 HMI 页面,配置初始页、固定文本和页面跳转,并随工程保存和加载。 | |||||
| ## 7. 实现控制逻辑编辑器 | ## 7. 实现控制逻辑编辑器 | ||||
| @@ -63,6 +63,7 @@ | |||||
| - 定时器不属于当前原始需求范围,只有在后续需求明确时才新增对应配置和执行逻辑。 | - 定时器不属于当前原始需求范围,只有在后续需求明确时才新增对应配置和执行逻辑。 | ||||
| - 新增节点类型时使用独立配置类型,不向通用节点结构持续堆叠无关字段。 | - 新增节点类型时使用独立配置类型,不向通用节点结构持续堆叠无关字段。 | ||||
| - 编辑器只生成逻辑模型,不直接修改 HMI 或 PLC。 | - 编辑器只生成逻辑模型,不直接修改 HMI 或 PLC。 | ||||
| - 工程可包含多个有序控制逻辑,离线执行器按顺序扫描全部启用项,运行工作台只切换当前轨迹投影。 | |||||
| - 画布按表达式结构自动布线,显示节点或支路选择范围,不允许节点自由拖动,也不保存自由线段。 | - 画布按表达式结构自动布线,显示节点或支路选择范围,不允许节点自由拖动,也不保存自由线段。 | ||||
| 完成标准:能够表达 `A OR (B AND C)` 等嵌套逻辑,并配置启动、停止和状态保持逻辑。 | 完成标准:能够表达 `A OR (B AND C)` 等嵌套逻辑,并配置启动、停止和状态保持逻辑。 | ||||