综合平台编程器项目的远程存储
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 
 

153 líneas
4.4 KiB

  1. #pragma once
  2. #include "domain/control_logic_model.h"
  3. #include "domain/register_repository.h"
  4. #include <chrono>
  5. #include <cstdint>
  6. #include <map>
  7. #include <string>
  8. #include <unordered_map>
  9. #include <utility>
  10. #include <vector>
  11. // 一轮离线扫描可能返回的错误
  12. enum class LogicScanError
  13. {
  14. None,
  15. InvalidLogic,
  16. ConflictingOutput,
  17. RegisterReadFailed,
  18. RegisterWriteFailed
  19. };
  20. // 扫描结果;失败时携带出错的逻辑、网络和节点 ID
  21. struct LogicScanResult
  22. {
  23. bool succeeded = false;
  24. LogicScanError error = LogicScanError::None;
  25. std::string message;
  26. std::string logicId;
  27. std::string rungId;
  28. std::string nodeId;
  29. };
  30. // TON 节点在最近一轮扫描中的可视化状态
  31. struct TonTraceValue
  32. {
  33. bool input = false;
  34. bool done = false;
  35. std::int64_t elapsedMs = 0;
  36. int presetMs = 0;
  37. };
  38. // CTU/CTD 节点在最近一轮扫描中的可视化状态
  39. struct CounterTraceValue
  40. {
  41. bool input = false;
  42. bool reset = false;
  43. bool done = false;
  44. std::int16_t value = 0;
  45. std::int16_t preset = 0;
  46. };
  47. // MOVE/ADD/SUB 节点的结果值和溢出标记
  48. struct WordTraceValue
  49. {
  50. std::int16_t value = 0;
  51. bool overflow = false;
  52. };
  53. // 一条逻辑或一个网络的运行轨迹快照
  54. struct LogicTraceValues
  55. {
  56. std::unordered_map<std::string, bool> nodeValues;
  57. std::unordered_map<std::string, bool> nodePowerValues;
  58. std::unordered_map<std::string, bool> expressionValues;
  59. std::unordered_map<std::string, bool> expressionInputValues;
  60. std::unordered_map<std::string, bool> expressionPowerValues;
  61. std::unordered_map<std::string, bool> rungValues;
  62. std::unordered_map<std::string, TonTraceValue> tonValues;
  63. std::unordered_map<std::string, CounterTraceValue> counterValues;
  64. std::unordered_map<std::string, WordTraceValue> wordValues;
  65. void clear();
  66. };
  67. // 全工程轨迹;logicValues 按逻辑 ID 隔离,避免节点 ID 重复互相覆盖
  68. struct LogicTraceSnapshot : LogicTraceValues
  69. {
  70. std::unordered_map<std::string, LogicTraceValues> logicValues;
  71. void clear();
  72. LogicTraceSnapshot forLogic(const std::string &logic_id) const;
  73. };
  74. // 按工程顺序执行受限梯形图的一次确定性扫描
  75. class SoftwareLogicExecutor
  76. {
  77. public:
  78. using Clock = std::chrono::steady_clock;
  79. using TimePoint = Clock::time_point;
  80. // 在启动仿真前检查所有启用逻辑及 T/C 资源引用
  81. LogicScanResult validate(const std::vector<ControlLogic> &logics) const;
  82. // 清除沿触发、定时器和计数器的跨扫描运行状态
  83. void resetRuntime();
  84. // 使用当前 steady_clock 执行一轮扫描
  85. LogicScanResult executeScan(
  86. const std::vector<ControlLogic> &logics,
  87. RegisterRepository &repository,
  88. LogicTraceSnapshot *trace = nullptr);
  89. // 使用指定时间执行扫描,便于稳定验证 TON 等时间逻辑
  90. LogicScanResult executeScanAt(
  91. const std::vector<ControlLogic> &logics,
  92. RegisterRepository &repository,
  93. TimePoint now,
  94. LogicTraceSnapshot *trace = nullptr);
  95. private:
  96. struct TonRuntimeState
  97. {
  98. bool timing = false;
  99. bool done = false;
  100. TimePoint startedAt{};
  101. std::chrono::milliseconds elapsed{0};
  102. };
  103. LogicScanResult evaluateCondition(
  104. const std::string &logic_id,
  105. const LogicNode &node,
  106. RegisterRepository &repository,
  107. bool *value);
  108. LogicScanResult evaluateExpression(
  109. const std::string &logic_id,
  110. const ConditionExpression &expression,
  111. RegisterRepository &repository,
  112. LogicTraceValues *trace,
  113. bool input_power,
  114. bool *value);
  115. LogicScanResult executeOutput(
  116. const std::string &logic_id,
  117. const LogicNode &node,
  118. bool rung_value,
  119. RegisterRepository &repository,
  120. TimePoint now,
  121. LogicTraceValues *trace,
  122. bool *output_value);
  123. LogicScanResult readWordOperand(
  124. const WordOperand &operand,
  125. RegisterRepository &repository,
  126. std::int16_t *value,
  127. const std::string &node_id) const;
  128. std::map<std::pair<std::string, std::string>, bool> previous_edge_inputs_;
  129. std::map<std::pair<std::string, std::string>, bool> previous_counter_inputs_;
  130. std::unordered_map<int, TonRuntimeState> ton_states_;
  131. struct CounterRuntimeState
  132. {
  133. bool done = false;
  134. };
  135. std::unordered_map<int, CounterRuntimeState> counter_states_;
  136. };