env_params.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. """
  2. env_params.py
  3. 超滤(UF)强化学习环境的参数定义文件。
  4. 本文件集中定义 UF 强化学习环境中使用的所有【参数类(Parameter Schemas)】。
  5. 这些类仅用于描述系统配置、状态语义和约束边界,不包含任何数值计算、
  6. 物理模型、奖励逻辑或 Gym 接口实现。
  7. 本文件中的类只定义参数结构,不负责加载配置。具体数值应从YAML文件加载后在主程序中实例化。
  8. ========================
  9. 参数类总览
  10. ========================
  11. 1. UFState
  12. ------------------------
  13. 【环境动态状态】
  14. - 描述超滤系统在某一时刻的运行状态
  15. - 这些变量会在 env.step() 中随动作不断演化
  16. - 构成强化学习算法可观测的 observation
  17. - 生命周期:每个 step 更新一次
  18. 包含内容:
  19. - 实时运行工况(流量、温度、TMP)
  20. - 膜污染状态参数(短期污染、长期污染)
  21. - CEB 去除能力等可随 episode 演化的量
  22. 使用方:
  23. - 强化学习环境(step / reset)
  24. - 膜阻力物理模型(作为 forward 的 state 输入)
  25. - reward 计算逻辑
  26. 2. UFPhysicsParams
  27. ------------------------
  28. 【物理与工艺固定参数】
  29. - 描述超滤系统的客观工艺与设备配置
  30. - 在整个 episode 甚至整个训练生命周期中保持不变
  31. - 典型为“物理常数 / 工艺设定值”
  32. 设计约束:
  33. - 使用 frozen dataclass,防止运行时被意外修改
  34. 包含内容:
  35. - 物理反洗效率时间尺度
  36. - 反洗流量
  37. - CEB 间隔与用水量
  38. - 膜组件面积等硬件参数
  39. 使用方:
  40. - 膜阻力模型(上升 / 下降)
  41. - 回收率、能耗等物理量计算
  42. - 环境内部的物理约束判断
  43. 3. UFActionSpec
  44. ------------------------
  45. 【动作空间定义】
  46. - 描述智能体“可以选什么动作”,而不是“如何执行动作”
  47. - 仅定义动作的物理含义、取值范围和离散粒度
  48. - 不负责构造 Gym action_space
  49. 包含内容:
  50. - 过滤时长(L)范围与步长
  51. - 物理反洗时长(t_bw)范围与步长
  52. 使用方:
  53. - 环境初始化时构建离散动作空间
  54. - 不同算法(DQN / Dueling / PPO)共用同一动作语义
  55. 4. UFRewardSpec
  56. ------------------------
  57. 【奖励函数与安全约束参数】
  58. - 集中管理 reward 计算所需的权重、阈值与约束
  59. - 同时用于 episode 终止(terminated)判断
  60. - 不包含 reward 的计算公式本身
  61. 包含内容:
  62. - TMP 硬 / 软安全上限
  63. - 回收率与污染惩罚的敏感度系数
  64. - 回收率合理区间与参考污染比例
  65. 使用方:
  66. - reward 函数
  67. - 环境终止条件判断
  68. 5. UFStateBounds
  69. ------------------------
  70. 【状态初始化约束】
  71. - 仅用于 reset() 阶段的随机初始化
  72. - 不参与 step() 中的状态演化
  73. - 用于保证初始状态物理合理、覆盖足够多工况
  74. 包含内容:
  75. - TMP、流量、温度的初始化范围
  76. - 污染模型参数的合理区间
  77. - CEB 去除能力的上下限
  78. 使用方:
  79. - env.reset()
  80. - 用于构造多样化初始工况,增强策略鲁棒性
  81. ========================
  82. 设计原则(请勿破坏)
  83. ========================
  84. 1. 本文件只描述“参数是什么”,不描述“参数如何使用”
  85. 2. 禁止在本文件中出现:
  86. - torch / numpy 数值计算
  87. - Gym / Gymnasium space 定义
  88. - step / forward / reward 等逻辑
  89. 3. 若需要新增参数,请优先判断其生命周期:
  90. - 是否随 step 变化 → UFState
  91. - 是否全局不变 → UFPhysicsParams / Spec 类
  92. 4. 若发现需要在此文件中写计算代码,说明模块边界已经被破坏,应重构调用方
  93. """
  94. from dataclasses import dataclass, field
  95. from typing import Dict
  96. """
  97. 【说明:拆分 UFParams】
  98. 原 UFParams 类同时承担了多种不同职责,包括:
  99. 1. 环境状态(会在 step 中动态变化)
  100. 2. reset 时的初始状态约束
  101. 3. 超滤系统的物理 / 工艺固定参数
  102. 4. 强化学习动作空间定义
  103. 5. 奖励函数与安全约束参数
  104. 在强化学习工程中,这种参数结构会带来以下问题:
  105. - 状态与参数混杂,容易在 step() 中被误修改
  106. - reset 初始化逻辑与运行逻辑强耦合,难以调试
  107. - 奖励函数修改会影响环境动力学,增加不可控风险
  108. - 不利于算法切换(DQN / Dueling Q / PPO)
  109. 因此,现将 UFParams 拆分为多个“职责单一”的参数类,
  110. 每个类只负责一类明确的功能,从而实现:
  111. - 语义清晰
  112. - 边界明确
  113. - 易于维护
  114. - 算法无关(一个环境,多种算法共用)
  115. 【注意】
  116. 本次拆分不改变任何物理意义、数值含义与默认参数,仅做结构重组。
  117. """
  118. # ==================== 超滤系统参数配置类 ====================
  119. @dataclass
  120. class UFState:
  121. """
  122. 【环境动态状态】
  123. 描述超滤系统在当前时刻的运行状态。
  124. 这些变量会在 step() 中随动作不断演化,并构成强化学习的 observation。
  125. """
  126. # ========== 膜动态运行参数 ==========
  127. # 这些参数描述超滤膜的实时运行状态,在环境模拟中会动态变化
  128. q_UF: float = 360.0
  129. # 过滤进水流量(m³/h)
  130. # 说明:影响膜通量,进而影响污染速率
  131. # 典型范围:250-400 m³/h
  132. TMP: float = 0.03
  133. # 跨膜压差(MPa,兆帕)
  134. # 说明:反映膜阻力状态,TMP 越高表示膜污染越严重
  135. # 正常范围:0.01-0.035 MPa,超过 0.08 MPa 需停机检修
  136. temp: float = 25.0
  137. # 水温(摄氏度)
  138. # 说明:影响水的粘度,进而影响跨膜压差
  139. # 典型范围:10-40℃,25℃为标准温度
  140. R: float = 200.0
  141. # 膜阻力(缩放至1e2)
  142. # 说明:实际上的膜阻力应该根据q_UF/TMP0/temp动态计算,此处仅为构造状态类占位使用
  143. # ========== 膜阻力模型参数 ==========
  144. # 这些参数描述膜污染的物理化学特性,基于历史数据拟合得到
  145. nuK: float = 1.7e+02
  146. # 过滤阶段膜阻力增长系数(缩放后单位)
  147. # 说明:反映水质污染特性,nuK 越大表示水质越差、膜污染越快
  148. # 物理意义:单位膜通量、单位时间的阻力增长速率
  149. slope: float = 2
  150. # 全周期不可逆污染增长斜率
  151. # 说明:描述长期不可逆污染的累积速率(幂律模型的系数)
  152. power: float = 1.032
  153. # 全周期不可逆污染增长幂次
  154. # 说明:描述长期污染的非线性特性(幂律模型的指数)
  155. # power > 1 表示污染加速累积,power < 1 表示污染增速放缓
  156. ceb_removal: float = 100
  157. # 化学增强反洗(CEB)可去除的膜阻力(缩放后单位)
  158. # 说明:CEB 比物理反洗更彻底,可去除部分不可逆污染
  159. @dataclass(frozen=True)
  160. class UFPhysicsParams:
  161. """
  162. 【物理与工艺固定参数】
  163. 描述超滤系统的客观工艺条件,在整个 episode 中保持不变。
  164. """
  165. global_TMP_hard_limit: float = 0.08
  166. # TMP 硬上限(MPa)
  167. # 说明:超过此值将导致episode失败,需立即停机
  168. global_TMP_soft_limit: float = 0.06
  169. # TMP 软上限 (MPa)
  170. # 说明:此上限用于指导奖励函数中膜阻力允许上升值,越接近该上限,系统对膜阻力上升控制的更严格
  171. # ========== 反洗参数(固定配置) ==========
  172. tau_bw_s: float = 20.0
  173. # 物理反洗时长影响的时间尺度(秒)
  174. # 说明:反洗效率的特征时间,当反洗时长 = tau 时,达到约 63% 效率
  175. gamma_t: float = 1.0
  176. # 物理反洗时长作用指数(保留参数,当前未使用)
  177. q_bw_m3ph: float = 1000.0
  178. # 物理反洗流量(m³/h)
  179. # 说明:反洗流量通常为正常过滤流量的 2-3 倍
  180. # ========== CEB 化学反洗参数 ==========
  181. T_ceb_interval_h: float = 48.0
  182. # CEB 间隔时间(小时)
  183. # 说明:每运行约 60 小时执行一次化学增强反洗 TODO: PARAM 当前采用保守测试参数48h
  184. T_ceb_interval_times: int = 48
  185. # CEB 间隔次数
  186. # 说明: 每执行48次物理反冲洗进行一次CEB,与T_ceb_interval_h为互斥参数
  187. v_ceb_m3: float = 20.0
  188. # CEB 用水体积(m³)
  189. t_ceb_s: float = 40 * 60.0
  190. # CEB 时长(秒,这里为 40 分钟)
  191. # ========== 新增:膜面积 ==========
  192. # 膜有效面积(锡山水厂配置:128组膜,每组40m²)
  193. A: float = 5120.0 # [m²]
  194. # 参考吨水电耗查找表
  195. energy_lookup: Dict[int, float] = field(default_factory=lambda: {
  196. 2700: 0.1088, 2760: 0.1083, 2820: 0.1078, 2880: 0.1074,
  197. 2940: 0.1070, 3000: 0.1066, 3060: 0.1062, 3120: 0.1059,
  198. 3180: 0.1055, 3240: 0.1052, 3300: 0.1049, 3360: 0.1045,
  199. 3420: 0.1042, 3480: 0.1039, 3540: 0.1036, 3600: 0.1034,
  200. 3660: 0.1031, 3720: 0.1029, 3780: 0.1026, 3840: 0.1023,
  201. 3900: 0.1021, 3960: 0.1019, 4020: 0.1017, 4080: 0.1015,
  202. 4140: 0.1012, 4200: 0.1011, 4260: 0.1008, 4320: 0.1007,
  203. 4380: 0.1005, 4440: 0.1003, 4500: 0.1001, 4560: 0.0999,
  204. 4620: 0.0998, 4680: 0.0996, 4740: 0.0995, 4800: 0.0993,
  205. })
  206. # 实际吨水电耗计算指标
  207. p_feed_kw: float = 18.0
  208. p_bw_kw: float = 20.0
  209. # 实际吨水药耗计算指标
  210. dose_min: float = 0.10
  211. dose_max: float = 0.20
  212. @dataclass(frozen=True)
  213. class UFActionSpec:
  214. """
  215. 【动作空间定义】
  216. 描述智能体可选的过滤-反洗策略组合。
  217. """
  218. # ========== 强化学习动作空间搜索范围 ==========
  219. # 定义智能体可选择的动作范围(离散化)
  220. L_min_s: float = 3800.0 # 过滤时长下限(秒,约 63 分钟)
  221. L_max_s: float = 4800.0 # 过滤时长上限,当前为 4800s 80分钟
  222. t_bw_min_s: float = 40.0 # 物理反洗时长下限(秒)
  223. t_bw_max_s: float = 60.0 # 物理反洗时长上限(秒)
  224. # ========== 动作离散化网格 ==========
  225. L_step_s: float = 60.0 # 过滤时长步长(秒)
  226. t_bw_step_s: float = 5.0 # 物理反洗时长步长(秒)
  227. @dataclass(frozen=True)
  228. class UFRewardParams:
  229. """
  230. 【奖励函数与安全约束参数】用于 reward 计算和 episode 终止判断。
  231. """
  232. # TMP 限值
  233. global_TMP_hard_limit: float = 0.08
  234. # TMP 硬上限(MPa)
  235. # 说明:超过此值将导致 episode 失败,需立即停机
  236. global_TMP_soft_limit: float = 0.06 # TMP 软上限 (MPa)
  237. w_tmp_hard: float = 5.0 # TMP超硬限固定惩罚
  238. w_tmp: float = 1.5 # TMP软限惩罚
  239. p: float = 3 # TMP软限非线性指数
  240. w_trend: float = 1.0 # TMP趋势惩罚权重
  241. # 经济成本
  242. k_cost: float = 3.0
  243. cost_low: float = 0.10
  244. cost_high: float = 0.16
  245. w_cost: float = 1.0
  246. alpha_chemical: float = 5.0
  247. # 残余污染
  248. k_res: float = 3.0
  249. residual_ref_ratio: float = None # 动态=1/max_episode_steps
  250. w_res: float = 1.0
  251. @dataclass(frozen=True)
  252. class UFStateBounds:
  253. """
  254. 【状态初始化约束】
  255. 仅用于 reset() 时随机初始化环境状态,
  256. 不参与 step() 中的状态演化。
  257. """
  258. # --- 流量约束 ---
  259. q_UF_max: float = 380.0 # 进水流量上限(m³/h)
  260. q_UF_min: float = 210.0 # 进水流量下限(m³/h)
  261. # --- 温度约束 ---
  262. temp_max: float = 32.0 # 温度上限(℃)
  263. temp_min: float = 16.0 # 温度下限(℃)
  264. # --- 初始TMP约束 ---
  265. TMP0_max: float = 0.045 # 初始TMP上限(MPa)
  266. TMP0_min: float = 0.01 # 初始TMP下限(MPa)
  267. # --- TMP上限约束 ---
  268. global_TMP_hard_limit: float = 0.08
  269. # --- 短期污染模型参数约束 ---
  270. nuK_max: float = 2.6e+02 # 阻力增长系数上限
  271. nuK_min: float = 4e+01 # 阻力增长系数下限
  272. # --- 长期污染模型参数约束 ---
  273. slope_max: float = 27 # 不可逆污染斜率上限
  274. slope_min: float = 0.03 # 不可逆污染斜率下限
  275. power_max: float = 2.2 # 不可逆污染幂次上限
  276. power_min: float = 0.4 # 不可逆污染幂次下限
  277. # --- CEB去除能力约束 ---
  278. ceb_removal_max: float = 250 # CEB去除阻力上限(缩放后)
  279. ceb_removal_min: float = 40 # CEB去除阻力下限(缩放后)