综合平台编程器项目的远程存储
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.
 
 
 
 

186 lines
4.4 KiB

  1. #pragma once
  2. #include "register_address.h"
  3. #include <cstdint>
  4. #include <optional>
  5. #include <string>
  6. #include <variant>
  7. #include <vector>
  8. enum class ContactMode
  9. {
  10. NormallyOpen,
  11. NormallyClosed
  12. };
  13. enum class CoilMode
  14. {
  15. Normal,
  16. Set,
  17. Reset
  18. };
  19. enum class EdgeMode
  20. {
  21. Rising,
  22. Falling
  23. };
  24. enum class ComparisonOperator
  25. {
  26. Equal,
  27. NotEqual,
  28. LessThan,
  29. LessThanOrEqual,
  30. GreaterThan,
  31. GreaterThanOrEqual
  32. };
  33. struct ContactNodeConfig
  34. {
  35. RegisterAddress address{RegisterArea::M, 0};
  36. ContactMode mode = ContactMode::NormallyOpen;
  37. };
  38. struct EdgeContactNodeConfig
  39. {
  40. RegisterAddress address{RegisterArea::M, 0};
  41. EdgeMode mode = EdgeMode::Rising;
  42. };
  43. struct CoilNodeConfig
  44. {
  45. RegisterAddress address{RegisterArea::M, 0};
  46. CoilMode mode = CoilMode::Normal;
  47. };
  48. struct CompareNodeConfig
  49. {
  50. RegisterAddress address{RegisterArea::D, 0};
  51. ComparisonOperator comparison = ComparisonOperator::Equal;
  52. std::int16_t value = 0;
  53. };
  54. class TimerAddress
  55. {
  56. public:
  57. static constexpr int kMinimumIndex = 0;
  58. static constexpr int kMaximumIndex = 4000;
  59. explicit TimerAddress(int index = 0);
  60. int index() const;
  61. bool isValid() const;
  62. std::string toString() const;
  63. bool operator==(const TimerAddress &other) const;
  64. bool operator!=(const TimerAddress &other) const;
  65. private:
  66. int index_ = 0;
  67. };
  68. struct TimerContactNodeConfig
  69. {
  70. TimerAddress address;
  71. ContactMode mode = ContactMode::NormallyOpen;
  72. };
  73. struct TonNodeConfig
  74. {
  75. static constexpr int kMinimumPresetMs = 1;
  76. static constexpr int kMaximumPresetMs = 86400000;
  77. TimerAddress address;
  78. int presetMs = 1000;
  79. };
  80. using LogicNodeConfig = std::variant<
  81. ContactNodeConfig,
  82. EdgeContactNodeConfig,
  83. TimerContactNodeConfig,
  84. CoilNodeConfig,
  85. CompareNodeConfig,
  86. TonNodeConfig>;
  87. std::optional<RegisterAddress> registerAddressForLogicNode(
  88. const LogicNodeConfig &config);
  89. struct LogicNode
  90. {
  91. std::string id;
  92. LogicNodeConfig config;
  93. bool configured = true;
  94. bool validate(std::string *error = nullptr) const;
  95. bool isConfigured() const;
  96. bool isCondition() const;
  97. bool isOutput() const;
  98. };
  99. enum class ConditionExpressionKind
  100. {
  101. Node,
  102. Series,
  103. Parallel
  104. };
  105. // 结构化表达式只允许合法的串并联拓扑,不保存可产生悬空线或环路的像素连接
  106. struct ConditionExpression
  107. {
  108. std::string id;
  109. ConditionExpressionKind kind = ConditionExpressionKind::Node;
  110. std::optional<LogicNode> node;
  111. std::vector<ConditionExpression> children;
  112. static ConditionExpression fromNode(LogicNode node);
  113. bool validate(std::string *error = nullptr) const;
  114. bool validateForRunning(std::string *error = nullptr) const;
  115. };
  116. // 删除后折叠单子项容器并合并相邻同类容器,保持表达式的规范形态
  117. void normalizeConditionExpression(std::optional<ConditionExpression> *expression);
  118. const LogicNode *findConditionNode(
  119. const ConditionExpression &expression, const std::string &node_id);
  120. LogicNode *findConditionNode(
  121. ConditionExpression &expression, const std::string &node_id);
  122. const ConditionExpression *findConditionExpression(
  123. const ConditionExpression &expression, const std::string &expression_id);
  124. ConditionExpression *findConditionExpression(
  125. ConditionExpression &expression, const std::string &expression_id);
  126. void collectConditionNodes(
  127. const ConditionExpression &expression, std::vector<const LogicNode *> *nodes);
  128. void collectConditionExpressionIds(
  129. const ConditionExpression &expression, std::vector<std::string> *ids);
  130. // 一个网络包含一棵结构化条件表达式,输出指令固定在最右侧
  131. struct LadderRung
  132. {
  133. std::string id;
  134. std::string name;
  135. std::string comment;
  136. std::optional<ConditionExpression> condition;
  137. std::optional<LogicNode> output;
  138. bool validate(std::string *error = nullptr) const;
  139. bool validateStructure(std::string *error = nullptr) const;
  140. bool validateForRunning(std::string *error = nullptr) const;
  141. };
  142. struct ControlLogic
  143. {
  144. std::string id;
  145. std::string name;
  146. std::vector<LadderRung> rungs;
  147. bool enabled = true;
  148. bool validate(std::string *error = nullptr) const;
  149. bool validateStructure(std::string *error = nullptr) const;
  150. bool validateForRunning(std::string *error = nullptr) const;
  151. };
  152. bool validateTimerReferencesForRunning(
  153. const std::vector<ControlLogic> &logics,
  154. std::string *error = nullptr);