PlatingCellInitializeRoutine.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. using Aitex.Core.RT.Device;
  2. using Aitex.Core.RT.Log;
  3. using Aitex.Core.RT.Routine;
  4. using Aitex.Core.RT.SCCore;
  5. using Aitex.Core.Util;
  6. using MECF.Framework.Common.Persistent.Reservoirs;
  7. using MECF.Framework.Common.RecipeCenter;
  8. using MECF.Framework.Common.Routine;
  9. using MECF.Framework.Common.ToolLayout;
  10. using PunkHPX8_Core;
  11. using PunkHPX8_RT.Devices.AXIS;
  12. using PunkHPX8_RT.Devices.PlatingCell;
  13. using PunkHPX8_RT.Devices.Reservoir;
  14. using System;
  15. using System.Collections.Generic;
  16. using System.Diagnostics.Eventing.Reader;
  17. using System.Linq;
  18. using System.Text;
  19. using System.Threading.Tasks;
  20. using System.Windows.Media.Imaging;
  21. namespace PunkHPX8_RT.Modules.PlatingCell
  22. {
  23. public class PlatingCellInitializeRoutine : RoutineBase, IRoutine
  24. {
  25. private enum InitializeStep
  26. {
  27. CheckPowerSupplierConnected,
  28. CheckClamShellClosed,
  29. VerticalGotoLoad,
  30. VerticalGotoLoadCheck,
  31. RotationHome,
  32. RotationHomeCheck,
  33. AngleEntryTilt,
  34. AngleEntryVertical,
  35. CheckClamShellOpen,
  36. OpenCAAndANIsoltaionValve,
  37. CheckCellFlowWait,
  38. CheckCellFlow,
  39. OpenCCRAndRinseValve,
  40. RinseDripIdleDelay,
  41. CloseCCRAndRinseValve,
  42. End
  43. }
  44. #region 内部变量
  45. /// <summary>
  46. /// 持久化对象
  47. /// </summary>
  48. private PlatingCellPersistentValue _persistentValue;
  49. /// <summary>
  50. /// 设备对象
  51. /// </summary>
  52. private PlatingCellDevice _platingCellDevice;
  53. /// <summary>
  54. /// 槽体对象
  55. /// </summary>
  56. private ReservoirDevice _reservoirDevice;
  57. /// <summary>
  58. /// Reservoir Recipe
  59. /// </summary>
  60. private ResRecipe _resRecipe;
  61. /// <summary>
  62. /// vetical entity
  63. /// </summary>
  64. private PlatingCellVerticalEntity _verticalEntity;
  65. /// <summary>
  66. /// Rotation axis
  67. /// </summary>
  68. private JetAxisBase _rotationAxis;
  69. /// <summary>
  70. /// _flowFaultHoldOffTime 单位ms
  71. /// </summary>
  72. private int _flowFaultHoldOffTime = 1000;
  73. /// <summary>
  74. /// Cell Flow Start Low Limit
  75. /// </summary>
  76. private double _cellFlowStartLowLimit = 3.0;
  77. /// <summary>
  78. /// Anode flow start low limit
  79. /// </summary>
  80. private double _anFlowStartLowLimit = 0.5;
  81. /// <summary>
  82. /// Rinse Drip Idle Period
  83. /// </summary>
  84. private int _rinseDripIdlePeriod = 1000;
  85. #endregion
  86. /// <summary>
  87. /// 构造函数
  88. /// </summary>
  89. /// <param name="module"></param>
  90. public PlatingCellInitializeRoutine(string module) : base(module)
  91. {
  92. }
  93. /// <summary>
  94. /// 中止
  95. /// </summary>
  96. public void Abort()
  97. {
  98. Runner.Stop("Manual Abort");
  99. }
  100. /// <summary>
  101. /// 监控
  102. /// </summary>
  103. /// <returns></returns>
  104. public RState Monitor()
  105. {
  106. Runner.Run(InitializeStep.CheckPowerSupplierConnected, CheckPowerSupplierStatus, _delay_1ms)
  107. .Run(InitializeStep.CheckClamShellClosed, () => _platingCellDevice.ClamShellClose(), CheckClamShellClosed, _delay_1ms)
  108. .Run(InitializeStep.VerticalGotoLoad, VerticalGotoLoad,100)
  109. .WaitWithStopCondition(InitializeStep.VerticalGotoLoadCheck, CheckVerticalPositionStatus, CheckVerticalPositionRunStop)
  110. .Run(InitializeStep.RotationHome, RotationGotoHome, 100)
  111. .WaitWithStopCondition(InitializeStep.RotationHomeCheck, CheckRotationPositionStatus, CheckRotationPositionRunStop)
  112. .Run(InitializeStep.AngleEntryTilt, () => _platingCellDevice.HeadtTiltAction(), CheckAngleTilt, _delay_1ms)
  113. .Run(InitializeStep.AngleEntryVertical, () => _platingCellDevice.HeadtVerticalAction(), CheckAngleVertical, _delay_1ms)
  114. .Run(InitializeStep.CheckClamShellClosed, () => _platingCellDevice.ClamShellOpen(), CheckClamShellOpen, _delay_1ms)
  115. .Run(InitializeStep.OpenCAAndANIsoltaionValve, OpenReservoirIsolationValve,_delay_1ms)
  116. .Delay(InitializeStep.CheckCellFlowWait, _flowFaultHoldOffTime)
  117. .Run(InitializeStep.CheckCellFlow, CheckCellFlow, _delay_1ms)
  118. .Run(InitializeStep.OpenCCRAndRinseValve, OpenCCRAndRinseValve, _delay_1ms)
  119. .Delay(InitializeStep.RinseDripIdleDelay, _rinseDripIdlePeriod)
  120. .Run(InitializeStep.CloseCCRAndRinseValve, CloseCCRAndRinseValve, _delay_1ms)
  121. .End(InitializeStep.End, NullFun, _delay_1ms);
  122. return Runner.Status;
  123. }
  124. /// <summary>
  125. /// 检查cell flow
  126. /// </summary>
  127. /// <returns></returns>
  128. private bool CheckCellFlow()
  129. {
  130. if ("Manual".Equals(_persistentValue.OperatingMode))
  131. {
  132. if(_reservoirDevice.ReservoirData.CaFlow < _cellFlowStartLowLimit)
  133. {
  134. LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"CA flow{_reservoirDevice.ReservoirData.CaFlow} is lower than cellFlowStartLowLimit{_cellFlowStartLowLimit}");
  135. _reservoirDevice.CAIsolationOff();
  136. return false;
  137. }
  138. if (_reservoirDevice.ReservoirData.AnFlow < _anFlowStartLowLimit)
  139. {
  140. LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"AN flow{_reservoirDevice.ReservoirData.AnFlow} is lower than cellFlowStartLowLimit{_anFlowStartLowLimit}");
  141. _reservoirDevice.ANIsolationOff();
  142. return false;
  143. }
  144. }
  145. else
  146. {
  147. if (_reservoirDevice.ReservoirData.CaFlow < _resRecipe.CAFlowRateErrorLow)
  148. {
  149. LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"CA flow{_reservoirDevice.ReservoirData.CaFlow} is lower than resRecipe CAFlowRateErrorLow{_resRecipe.CAFlowRateErrorLow}");
  150. return false;
  151. }
  152. if (_reservoirDevice.ReservoirData.AnFlow < _resRecipe.ANFlowRateErrorLow)
  153. {
  154. LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"AN flow{_reservoirDevice.ReservoirData.AnFlow} is lower than resRecipe ANFlowRateErrorLow{_resRecipe.ANFlowRateErrorLow}");
  155. return false;
  156. }
  157. }
  158. return true;
  159. }
  160. /// <summary>
  161. /// 打开reservoir Isolation valve
  162. /// </summary>
  163. /// <returns></returns>
  164. private bool OpenReservoirIsolationValve()
  165. {
  166. return _reservoirDevice.ANIsolationOn() && _reservoirDevice.ANIsolationOn();
  167. }
  168. /// <summary>
  169. /// 打开CCR/Rinse valve
  170. /// </summary>
  171. /// <returns></returns>
  172. private bool OpenCCRAndRinseValve()
  173. {
  174. return _platingCellDevice.CCREnableAction() && _platingCellDevice.RinseEnableAction();
  175. }
  176. /// <summary>
  177. /// 关闭CCR/Rinse valve
  178. /// </summary>
  179. /// <returns></returns>
  180. private bool CloseCCRAndRinseValve()
  181. {
  182. return _platingCellDevice.CCRDisableAction() && _platingCellDevice.RinseDisableAction();
  183. }
  184. /// <summary>
  185. /// vertical 运动到Load位置
  186. /// </summary>
  187. /// <returns></returns>
  188. private bool VerticalGotoLoad()
  189. {
  190. if(_verticalEntity != null )
  191. {
  192. return _verticalEntity.CheckToPostMessage<PlatingCellVerticalState,PlatingCellVerticalEntity.VerticalMsg>(eEvent.INFO_PLATINGCELL, Module, (int)PlatingCellVerticalEntity.VerticalMsg.Initialize);
  193. }
  194. else
  195. {
  196. LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "vertical axis is null");
  197. return false;
  198. }
  199. }
  200. /// <summary>
  201. /// rotation home
  202. /// </summary>
  203. /// <returns></returns>
  204. private bool RotationGotoHome()
  205. {
  206. if (_rotationAxis != null)
  207. {
  208. if (!_rotationAxis.IsSwitchOn)
  209. {
  210. LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Roation is not Power On");
  211. return false;
  212. }
  213. return _rotationAxis.Home();
  214. }
  215. else
  216. {
  217. LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "Rotation axis is null");
  218. return false;
  219. }
  220. }
  221. /// <summary>
  222. /// 检查ClamShell是否closed
  223. /// </summary>
  224. /// <returns></returns>
  225. private bool CheckClamShellClosed()
  226. {
  227. return _platingCellDevice.PlatingCellDeviceData.ClamShellClose;
  228. }
  229. /// <summary>
  230. /// 检查ClamShell是否Open
  231. /// </summary>
  232. /// <returns></returns>
  233. private bool CheckClamShellOpen()
  234. {
  235. return !_platingCellDevice.PlatingCellDeviceData.ClamShellClose;
  236. }
  237. /// <summary>
  238. /// 检查Angle是否Tilt
  239. /// </summary>
  240. /// <returns></returns>
  241. private bool CheckAngleTilt()
  242. {
  243. return _platingCellDevice.PlatingCellDeviceData.HeadTilt;
  244. }
  245. /// <summary>
  246. /// 检查Angle是否Vertical
  247. /// </summary>
  248. /// <returns></returns>
  249. private bool CheckAngleVertical()
  250. {
  251. return !_platingCellDevice.PlatingCellDeviceData.HeadTilt;
  252. }
  253. /// <summary>
  254. /// 检验Metal A/B 面PowerSupplier通讯状况
  255. /// </summary>
  256. /// <returns></returns>
  257. private bool CheckPowerSupplierStatus()
  258. {
  259. if (!_platingCellDevice.PowerSupplier.IsConnected)
  260. {
  261. LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "power is not connected");
  262. return false;
  263. }
  264. return true;
  265. }
  266. /// <summary>
  267. /// 检验Vertical移动状态
  268. /// </summary>
  269. /// <returns></returns>
  270. private bool CheckVerticalPositionStatus()
  271. {
  272. return _verticalEntity.IsIdle;
  273. }
  274. /// <summary>
  275. /// 检验Vertical是否还在运动
  276. /// </summary>
  277. /// <returns></returns>
  278. private bool CheckVerticalPositionRunStop()
  279. {
  280. return _verticalEntity.IsError;
  281. }
  282. /// <summary>
  283. /// 检验Rotation home是否完成
  284. /// </summary>
  285. /// <returns></returns>
  286. private bool CheckRotationPositionStatus()
  287. {
  288. return _rotationAxis.Status == RState.End;
  289. }
  290. /// <summary>
  291. /// 检验Rotaion 是否home 失败
  292. /// </summary>
  293. /// <returns></returns>
  294. private bool CheckRotationPositionRunStop()
  295. {
  296. return _rotationAxis.Status == RState.Failed || _rotationAxis.Status == RState.Timeout;
  297. }
  298. /// <summary>
  299. /// 获取Reservoir设备
  300. /// </summary>
  301. /// <returns></returns>
  302. private ReservoirDevice GetReservoirDevice()
  303. {
  304. string reservoir = ReservoirItemManager.Instance.GetReservoirByPlatingCell(Module.ToString());
  305. return DEVICE.GetDevice<ReservoirDevice>(reservoir);
  306. }
  307. /// <summary>
  308. /// 启动
  309. /// </summary>
  310. /// <param name="objs"></param>
  311. /// <returns></returns>
  312. public RState Start(params object[] objs)
  313. {
  314. _persistentValue = (PlatingCellPersistentValue)objs[0];
  315. _platingCellDevice = DEVICE.GetDevice<PlatingCellDevice>(Module);
  316. _reservoirDevice = GetReservoirDevice();
  317. _flowFaultHoldOffTime = SC.GetValue<int>("PlatingCell.FlowFaultHoldOffTime");
  318. _rinseDripIdlePeriod = SC.GetValue<int>("PlatingCell.RinseDripIdlePeriod");
  319. _cellFlowStartLowLimit = SC.GetValue<double>("PlatingCell.CellFlowStartLowLimit");
  320. _anFlowStartLowLimit = SC.GetValue<double>("PlatingCell.ANFlowStartLowLimit");
  321. string verticalModule = ModuleMatcherManager.Instance.GetPlatingVerticalByCell(Module);
  322. _verticalEntity=Singleton<RouteManager>.Instance.GetModule<PlatingCellVerticalEntity>(verticalModule);
  323. _rotationAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Rotation");
  324. string reservoir = ReservoirItemManager.Instance.GetReservoirByPlatingCell(Module.ToString());
  325. ReservoirDevice reservoirDevice = DEVICE.GetDevice<ReservoirDevice>(reservoir);
  326. if (reservoirDevice == null)
  327. {
  328. LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"{reservoir} device is null");
  329. return RState.Failed;
  330. }
  331. if (reservoirDevice.Recipe == null)
  332. {
  333. LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"{reservoir} current recipe is null");
  334. return RState.Failed;
  335. }
  336. _resRecipe = reservoirDevice.Recipe;
  337. return Runner.Start(Module, "Start Reservoir Initialize");
  338. }
  339. }
  340. }