综合平台编程器项目的远程存储
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 

228 Zeilen
7.2 KiB

  1. #pragma once
  2. #include "project_limits.h"
  3. #include "register_address.h"
  4. #include <cstdint>
  5. #include <optional>
  6. #include <string>
  7. #include <variant>
  8. #include <vector>
  9. enum class ContactMode
  10. {
  11. NormallyOpen, // 常开触点,M 为 1 时条件成立
  12. NormallyClosed // 常闭触点,M 为 0 时条件成立
  13. };
  14. enum class CoilMode
  15. {
  16. Normal, // 普通线圈,直接写入条件结果
  17. Set, // 条件成立时置位 M
  18. Reset // 条件成立时复位 M
  19. };
  20. enum class EdgeMode
  21. {
  22. Rising, // 检测 M 从 0 变为 1
  23. Falling // 检测 M 从 1 变为 0
  24. };
  25. enum class ComparisonOperator
  26. {
  27. Equal, // 等于
  28. NotEqual, // 不等于
  29. LessThan, // 小于
  30. LessThanOrEqual, // 小于或等于
  31. GreaterThan, // 大于
  32. GreaterThanOrEqual // 大于或等于
  33. };
  34. enum class WordOperandKind
  35. {
  36. Constant, // 使用固定数值
  37. Register // 使用 D 区寄存器的值
  38. };
  39. struct WordOperand
  40. {
  41. WordOperandKind kind = WordOperandKind::Constant; // 操作数来源类型
  42. RegisterAddress address{RegisterArea::D, 0}; // 寄存器操作数使用的 D 地址
  43. std::int16_t constant = 0; // 常量操作数的数值
  44. // 校验操作数类型和寄存器地址是否有效
  45. bool validate(std::string *error = nullptr) const;
  46. };
  47. struct ContactNodeConfig
  48. {
  49. RegisterAddress address{RegisterArea::M, 0}; // 触点监控的 M 地址
  50. ContactMode mode = ContactMode::NormallyOpen; // 触点的常开或常闭模式
  51. };
  52. struct EdgeContactNodeConfig
  53. {
  54. RegisterAddress address{RegisterArea::M, 0}; // 边沿触点监控的 M 地址
  55. EdgeMode mode = EdgeMode::Rising; // 上升沿或下降沿模式
  56. };
  57. struct CoilNodeConfig
  58. {
  59. RegisterAddress address{RegisterArea::M, 0}; // 线圈写入的 M 地址
  60. CoilMode mode = CoilMode::Normal; // 普通、置位或复位模式
  61. };
  62. struct CompareNodeConfig
  63. {
  64. RegisterAddress address{RegisterArea::D, 0}; // 参与比较的 D 地址
  65. ComparisonOperator comparison = ComparisonOperator::Equal; // 比较方式
  66. std::int16_t value = 0; // 与 D 值比较的常量
  67. };
  68. struct MoveNodeConfig
  69. {
  70. WordOperand source; // MOVE 的源操作数
  71. RegisterAddress destination{RegisterArea::D, 0}; // MOVE 的目标 D 地址
  72. };
  73. enum class ArithmeticOperation
  74. {
  75. Add, // 加法
  76. Subtract // 减法
  77. };
  78. struct ArithmeticNodeConfig
  79. {
  80. ArithmeticOperation operation = ArithmeticOperation::Add; // 算术运算类型
  81. WordOperand left; // 左操作数
  82. WordOperand right; // 右操作数
  83. RegisterAddress destination{RegisterArea::D, 0}; // 运算结果写入的 D 地址
  84. };
  85. using LogicNodeConfig = std::variant<
  86. ContactNodeConfig,
  87. EdgeContactNodeConfig,
  88. CoilNodeConfig,
  89. CompareNodeConfig,
  90. MoveNodeConfig,
  91. ArithmeticNodeConfig>;
  92. // 返回逻辑节点主要使用的地址
  93. std::optional<RegisterAddress> registerAddressForLogicNode(
  94. const LogicNodeConfig &config);
  95. // 收集逻辑节点涉及的全部有效寄存器地址
  96. void collectRegisterAddressesForLogicNode(
  97. const LogicNodeConfig &config,
  98. std::vector<RegisterAddress> *addresses);
  99. struct LogicNode
  100. {
  101. std::string id; // 逻辑节点的唯一 ID
  102. LogicNodeConfig config; // 节点类型和具体参数
  103. bool configured = true; // 是否已完成运行所需的配置
  104. // 校验节点 ID 和节点参数
  105. bool validate(std::string *error = nullptr) const;
  106. // 返回节点是否已完成运行配置
  107. bool isConfigured() const;
  108. // 返回节点是否属于条件节点
  109. bool isCondition() const;
  110. // 返回节点是否属于输出节点
  111. bool isOutput() const;
  112. };
  113. enum class LadderCellKind
  114. {
  115. Gap, // 空白网格
  116. Wire, // 横向导线网格
  117. Node // 条件节点网格
  118. };
  119. // 条件区的一个固定网格,横线和空白与条件节点具有同等持久化地位
  120. struct LadderCell
  121. {
  122. std::string id; // 网格的唯一 ID
  123. LadderCellKind kind = LadderCellKind::Gap; // 网格类型
  124. std::optional<LogicNode> node; // 网格中的条件节点
  125. // 校验网格 ID、类型和节点内容是否匹配
  126. bool validate(std::string *error = nullptr) const;
  127. };
  128. // 两个相邻视觉行之间、指定列边界上的一段竖线
  129. struct VerticalConnection
  130. {
  131. std::string id; // 竖线的唯一 ID
  132. std::string upperRungId; // 竖线连接的上方行 ID
  133. std::string lowerRungId; // 竖线连接的下方行 ID
  134. int columnBoundary = 0; // 竖线所在的列边界
  135. // 校验竖线的关联行和列边界
  136. bool validate(std::string *error = nullptr) const;
  137. };
  138. // 连续梯形图的一条视觉行,不再是隔离的网络容器
  139. struct LadderRung
  140. {
  141. std::string id; // 梯形图行的唯一 ID
  142. std::string name; // 梯形图行名称
  143. std::string comment; // 网络首行上的注释
  144. std::optional<LogicNode> output; // 行末输出节点
  145. std::vector<LadderCell> cells; // 固定数量的条件网格
  146. // 校验梯形图行的完整结构
  147. bool validate(std::string *error = nullptr) const;
  148. // 校验保存时需要满足的结构规则
  149. bool validateStructure(std::string *error = nullptr) const;
  150. // 校验运行前的结构和节点配置
  151. bool validateForRunning(std::string *error = nullptr) const;
  152. };
  153. // 一张连续梯形图,网络由横竖连接关系自然形成
  154. struct ControlLogic
  155. {
  156. std::string id; // 控制逻辑的唯一 ID
  157. std::string name; // 控制逻辑名称
  158. std::vector<LadderRung> rungs; // 按视觉顺序保存的梯形图行
  159. bool enabled = true; // 是否参与运行扫描
  160. std::vector<VerticalConnection> verticalConnections; // 行之间的竖向连接
  161. // 返回指定行所在连续网络的首行下标
  162. std::size_t networkHeadIndex(std::size_t rung_index) const;
  163. // 使用指定工程限制校验控制逻辑
  164. bool validate(
  165. const ProjectLimitSettings &limits,
  166. std::string *error = nullptr) const;
  167. // 使用默认工程限制校验控制逻辑结构
  168. bool validateStructure(std::string *error = nullptr) const;
  169. // 使用指定工程限制校验控制逻辑结构
  170. bool validateStructure(
  171. const ProjectLimitSettings &limits,
  172. std::string *error = nullptr) const;
  173. // 使用默认工程限制校验运行前的控制逻辑
  174. bool validateForRunning(std::string *error = nullptr) const;
  175. // 使用指定工程限制校验运行前的控制逻辑
  176. bool validateForRunning(
  177. const ProjectLimitSettings &limits,
  178. std::string *error = nullptr) const;
  179. };
  180. // 在梯形图行中查找指定 ID 的只读网格
  181. const LadderCell *findLadderCell(
  182. const LadderRung &rung, const std::string &cell_id);
  183. // 在梯形图行中查找指定 ID 的可写网格
  184. LadderCell *findLadderCell(
  185. LadderRung &rung, const std::string &cell_id);
  186. // 在控制逻辑中查找指定 ID 的只读竖线
  187. const VerticalConnection *findVerticalConnection(
  188. const ControlLogic &logic, const std::string &connection_id);
  189. // 在控制逻辑中查找指定 ID 的可写竖线
  190. VerticalConnection *findVerticalConnection(
  191. ControlLogic &logic, const std::string &connection_id);
  192. // 收集一行中的全部条件节点
  193. void collectConditionNodes(
  194. const LadderRung &rung, std::vector<const LogicNode *> *nodes);
  195. // 收集控制逻辑中的全部条件节点和输出节点
  196. void collectLogicNodes(
  197. const ControlLogic &logic, std::vector<const LogicNode *> *nodes);