综合平台编程器项目的远程存储
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

204 lines
4.6 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,
  12. NormallyClosed
  13. };
  14. enum class CoilMode
  15. {
  16. Normal,
  17. Set,
  18. Reset
  19. };
  20. enum class EdgeMode
  21. {
  22. Rising,
  23. Falling
  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
  38. };
  39. struct WordOperand
  40. {
  41. WordOperandKind kind = WordOperandKind::Constant;
  42. RegisterAddress address{RegisterArea::D, 0};
  43. std::int16_t constant = 0;
  44. bool validate(std::string *error = nullptr) const;
  45. };
  46. struct ContactNodeConfig
  47. {
  48. RegisterAddress address{RegisterArea::M, 0};
  49. ContactMode mode = ContactMode::NormallyOpen;
  50. };
  51. struct EdgeContactNodeConfig
  52. {
  53. RegisterAddress address{RegisterArea::M, 0};
  54. EdgeMode mode = EdgeMode::Rising;
  55. };
  56. struct CoilNodeConfig
  57. {
  58. RegisterAddress address{RegisterArea::M, 0};
  59. CoilMode mode = CoilMode::Normal;
  60. };
  61. struct CompareNodeConfig
  62. {
  63. RegisterAddress address{RegisterArea::D, 0};
  64. ComparisonOperator comparison = ComparisonOperator::Equal;
  65. std::int16_t value = 0;
  66. };
  67. struct MoveNodeConfig
  68. {
  69. WordOperand source;
  70. RegisterAddress destination{RegisterArea::D, 0};
  71. };
  72. enum class ArithmeticOperation
  73. {
  74. Add,
  75. Subtract
  76. };
  77. struct ArithmeticNodeConfig
  78. {
  79. ArithmeticOperation operation = ArithmeticOperation::Add;
  80. WordOperand left;
  81. WordOperand right;
  82. RegisterAddress destination{RegisterArea::D, 0};
  83. };
  84. using LogicNodeConfig = std::variant<
  85. ContactNodeConfig,
  86. EdgeContactNodeConfig,
  87. CoilNodeConfig,
  88. CompareNodeConfig,
  89. MoveNodeConfig,
  90. ArithmeticNodeConfig>;
  91. std::optional<RegisterAddress> registerAddressForLogicNode(
  92. const LogicNodeConfig &config);
  93. void collectRegisterAddressesForLogicNode(
  94. const LogicNodeConfig &config,
  95. std::vector<RegisterAddress> *addresses);
  96. struct LogicNode
  97. {
  98. std::string id;
  99. LogicNodeConfig config;
  100. bool configured = true;
  101. bool validate(std::string *error = nullptr) const;
  102. bool isConfigured() const;
  103. bool isCondition() const;
  104. bool isOutput() const;
  105. };
  106. enum class LadderCellKind
  107. {
  108. Gap,
  109. Wire,
  110. Node
  111. };
  112. // 条件区的一个固定网格,横线和空白与条件节点具有同等持久化地位
  113. struct LadderCell
  114. {
  115. std::string id;
  116. LadderCellKind kind = LadderCellKind::Gap;
  117. std::optional<LogicNode> node;
  118. bool validate(std::string *error = nullptr) const;
  119. };
  120. // 两个相邻视觉行之间、指定列边界上的一段竖线
  121. struct VerticalConnection
  122. {
  123. std::string id;
  124. std::string upperRungId;
  125. std::string lowerRungId;
  126. int columnBoundary = 0;
  127. bool validate(std::string *error = nullptr) const;
  128. };
  129. // 连续梯形图的一条视觉行,不再是隔离的网络容器
  130. struct LadderRung
  131. {
  132. std::string id;
  133. std::string name;
  134. std::string comment;
  135. std::optional<LogicNode> output;
  136. std::vector<LadderCell> cells;
  137. bool validate(std::string *error = nullptr) const;
  138. bool validateStructure(std::string *error = nullptr) const;
  139. bool validateForRunning(std::string *error = nullptr) const;
  140. };
  141. // 一张连续梯形图,网络由横竖连接关系自然形成
  142. struct ControlLogic
  143. {
  144. std::string id;
  145. std::string name;
  146. std::vector<LadderRung> rungs;
  147. bool enabled = true;
  148. std::vector<VerticalConnection> verticalConnections;
  149. std::size_t networkHeadIndex(std::size_t rung_index) const;
  150. bool validate(
  151. const ProjectLimitSettings &limits,
  152. std::string *error = nullptr) const;
  153. bool validateStructure(std::string *error = nullptr) const;
  154. bool validateStructure(
  155. const ProjectLimitSettings &limits,
  156. std::string *error = nullptr) const;
  157. bool validateForRunning(std::string *error = nullptr) const;
  158. bool validateForRunning(
  159. const ProjectLimitSettings &limits,
  160. std::string *error = nullptr) const;
  161. };
  162. const LadderCell *findLadderCell(
  163. const LadderRung &rung, const std::string &cell_id);
  164. LadderCell *findLadderCell(
  165. LadderRung &rung, const std::string &cell_id);
  166. const VerticalConnection *findVerticalConnection(
  167. const ControlLogic &logic, const std::string &connection_id);
  168. VerticalConnection *findVerticalConnection(
  169. ControlLogic &logic, const std::string &connection_id);
  170. void collectConditionNodes(
  171. const LadderRung &rung, std::vector<const LogicNode *> *nodes);
  172. void collectLogicNodes(
  173. const ControlLogic &logic, std::vector<const LogicNode *> *nodes);