From 392fcfb2554ac9ab96cba4ece30683b4e705acf0 Mon Sep 17 00:00:00 2001 From: ypc <15051963820@163.com> Date: Wed, 8 Jul 2026 19:14:10 +0800 Subject: [PATCH] =?UTF-8?q?fix(plc):=20=E4=BF=AE=E5=A4=8DRS/SR=E8=A7=A6?= =?UTF-8?q?=E5=8F=91=E5=99=A8dst=5Fpin=E5=85=A8=E9=83=A8=E4=B8=BA-1?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 第二遍XML解析时Comb→Gate、Inputs→Gate、R/S属性→Input 链接创建全部未设置dst_pin,导致collect_input_signals 无法区分S/R引脚,SR/RS运算结果错误。 修复内容: - has_comb路径: Comb→链级Gate根据R/S属性匹配Comb#N设置dst_pin - has_comb路径: 链级Inputs→Gate根据R/S属性匹配Input#N设置dst_pin - R/S属性→Input链接改为!ins_el条件下创建,避免与Inputs→Gate重复 - 简单链路径: Inputs→Gate根据R/S属性设置dst_pin --- src/system/libplc/src/plc.cpp | 102 ++++++++++++++++++++++++++-------- 1 file changed, 78 insertions(+), 24 deletions(-) diff --git a/src/system/libplc/src/plc.cpp b/src/system/libplc/src/plc.cpp index d153b1a..af5591d 100644 --- a/src/system/libplc/src/plc.cpp +++ b/src/system/libplc/src/plc.cpp @@ -485,6 +485,20 @@ int parse_reclose_logic_xml(const char *file_path, LogicGraph graphs[], int *gra if(has_comb) { + // 收集链级 Gate 的 R/S 属性(RS/SR 用) + const char *gateS = NULL, *gateR = NULL; + int isChainSRRS = 0; + if(gate_el) + { + int cgtTmp = gate_type_from_xml_str(gate_el->Attribute("type")); + if(cgtTmp == NODE_TYPE_SR_LATCH || cgtTmp == NODE_TYPE_RS_LATCH) + { + isChainSRRS = cgtTmp; + gateS = gate_el->Attribute("S"); + gateR = gate_el->Attribute("R"); + } + } + // 收集所有 Comb 的 Gate 索引(第一遍已解析) // Comb Gate → 链级 Gate (一个Comb一根线) if(gate_el) @@ -508,6 +522,18 @@ int parse_reclose_logic_xml(const char *file_path, LogicGraph graphs[], int *gra l.src_id = cur->nodes[ci].id; l.dest_type = cur->nodes[cgi].type; l.dest_id = cur->nodes[cgi].id; + + // RS/SR: 根据 R/S 属性设置 dst_pin + if(isChainSRRS) + { + int combId = c->IntAttribute("id"); + char combRef[16]; + snprintf(combRef, sizeof(combRef), "Comb#%d", combId); + if(gateR && strcmp(gateR, combRef) == 0) + l.dst_pin = (isChainSRRS == NODE_TYPE_SR_LATCH) ? 1 : 0; + else if(gateS && strcmp(gateS, combRef) == 0) + l.dst_pin = (isChainSRRS == NODE_TYPE_SR_LATCH) ? 0 : 1; + } } } } @@ -535,28 +561,40 @@ int parse_reclose_logic_xml(const char *file_path, LogicGraph graphs[], int *gra } // 链级 Inputs → 链级 Gate(如 RS/SR 直接连 Input 信号) - if(gate_el && ins_el) - { - int cgt = gate_type_from_xml_str(gate_el->Attribute("type")); - int cgi = find_node_index(cur, cgt, gate_el->IntAttribute("id")); - if(cgi >= 0) - { - for(tinyxml2::XMLElement *sig = ins_el->FirstChildElement("Signal"); sig; - sig = sig->NextSiblingElement("Signal")) - { - if(cur->link_count >= MAX_LINKS_PER_GRAPH) break; - int si = find_node_index(cur, NODE_TYPE_HW_INPUT, sig->IntAttribute("no")); - if(si >= 0) - { LogicLink &l = cur->links[cur->link_count++]; - memset(&l, 0, sizeof(l)); l.dst_pin = -1; - l.src_type=NODE_TYPE_HW_INPUT; l.src_id=cur->nodes[si].id; - l.dest_type=cur->nodes[cgi].type; l.dest_id=cur->nodes[cgi].id; } - } - } - } + if(gate_el && ins_el) + { + int cgt = gate_type_from_xml_str(gate_el->Attribute("type")); + int cgi = find_node_index(cur, cgt, gate_el->IntAttribute("id")); + if(cgi >= 0) + { + for(tinyxml2::XMLElement *sig = ins_el->FirstChildElement("Signal"); sig; + sig = sig->NextSiblingElement("Signal")) + { + if(cur->link_count >= MAX_LINKS_PER_GRAPH) break; + int si = find_node_index(cur, NODE_TYPE_HW_INPUT, sig->IntAttribute("no")); + if(si >= 0) + { LogicLink &l = cur->links[cur->link_count++]; + memset(&l, 0, sizeof(l)); l.dst_pin = -1; + l.src_type=NODE_TYPE_HW_INPUT; l.src_id=cur->nodes[si].id; + l.dest_type=cur->nodes[cgi].type; l.dest_id=cur->nodes[cgi].id; - // RS/SR 的 R/S 属性引用的 Input 信号(无 块时也需创建链接) - if(gate_el) + // RS/SR: 根据 R/S 属性设置 dst_pin + if(isChainSRRS) + { + char inRef[16]; + snprintf(inRef, sizeof(inRef), "Input#%d", sig->IntAttribute("no")); + if(gateR && strcmp(gateR, inRef) == 0) + l.dst_pin = (isChainSRRS == NODE_TYPE_SR_LATCH) ? 1 : 0; + else if(gateS && strcmp(gateS, inRef) == 0) + l.dst_pin = (isChainSRRS == NODE_TYPE_SR_LATCH) ? 0 : 1; + } + } + } + } + } + + // RS/SR 的 R/S 属性引用的 Input 信号(仅当无 块时创建链接,避免重复) + if(gate_el && !ins_el) { int cgt = gate_type_from_xml_str(gate_el->Attribute("type")); if(cgt == NODE_TYPE_SR_LATCH || cgt == NODE_TYPE_RS_LATCH) @@ -574,7 +612,8 @@ int parse_reclose_logic_xml(const char *file_path, LogicGraph graphs[], int *gra { LogicLink &l = cur->links[cur->link_count++]; memset(&l, 0, sizeof(l)); l.dst_pin = -1; l.src_type=NODE_TYPE_HW_INPUT; l.src_id=cur->nodes[si].id; - l.dest_type=cur->nodes[cgi2].type; l.dest_id=cur->nodes[cgi2].id; } + l.dest_type=cur->nodes[cgi2].type; l.dest_id=cur->nodes[cgi2].id; + l.dst_pin = (cgt == NODE_TYPE_SR_LATCH) ? 0 : 1; } } if(r_attr2 && strncmp(r_attr2, "Input#", 6) == 0) { @@ -584,7 +623,8 @@ int parse_reclose_logic_xml(const char *file_path, LogicGraph graphs[], int *gra { LogicLink &l = cur->links[cur->link_count++]; memset(&l, 0, sizeof(l)); l.dst_pin = -1; l.src_type=NODE_TYPE_HW_INPUT; l.src_id=cur->nodes[si].id; - l.dest_type=cur->nodes[cgi2].type; l.dest_id=cur->nodes[cgi2].id; } + l.dest_type=cur->nodes[cgi2].type; l.dest_id=cur->nodes[cgi2].id; + l.dst_pin = (cgt == NODE_TYPE_SR_LATCH) ? 1 : 0; } } } } @@ -608,7 +648,21 @@ int parse_reclose_logic_xml(const char *file_path, LogicGraph graphs[], int *gra { LogicLink &l = cur->links[cur->link_count++]; memset(&l, 0, sizeof(l)); l.dst_pin = -1; l.src_type=NODE_TYPE_HW_INPUT; l.src_id=cur->nodes[si].id; - l.dest_type=cur->nodes[gi].type; l.dest_id=cur->nodes[gi].id; } + l.dest_type=cur->nodes[gi].type; l.dest_id=cur->nodes[gi].id; + + // SR/RS: 根据 R/S 属性设置 dst_pin + if(gt == NODE_TYPE_SR_LATCH || gt == NODE_TYPE_RS_LATCH) + { + const char *sA = gate_el->Attribute("S"); + const char *rA = gate_el->Attribute("R"); + char inRef[16]; + snprintf(inRef, sizeof(inRef), "Input#%d", sig->IntAttribute("no")); + if(rA && strcmp(rA, inRef) == 0) + l.dst_pin = (gt == NODE_TYPE_SR_LATCH) ? 1 : 0; + else if(sA && strcmp(sA, inRef) == 0) + l.dst_pin = (gt == NODE_TYPE_SR_LATCH) ? 0 : 1; + } + } } if(ous_el)