PlatingCellCCRRoutine.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  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 MECF.Framework.Common.Beckhoff.AxisProvider;
  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 MECF.Framework.Common.Utilities;
  11. using PunkHPX8_Core;
  12. using PunkHPX8_RT.Devices.AXIS;
  13. using PunkHPX8_RT.Devices.PlatingCell;
  14. using PunkHPX8_RT.Devices.Reservoir;
  15. using System;
  16. using System.Collections.Generic;
  17. using System.Linq;
  18. using System.Text;
  19. using System.Threading.Tasks;
  20. namespace PunkHPX8_RT.Modules.PlatingCell
  21. {
  22. public class PlatingCellCCRRoutine : RoutineBase, IRoutine
  23. {
  24. private enum CCRStep
  25. {
  26. CSRStart,
  27. CSRClamshellClose,
  28. CSROpenRinseValve,
  29. CSRStartRotation,
  30. CSRRinseMonitor,
  31. CSRCloseRinseValve,
  32. CSRSetDryRotationSpeed,
  33. CSRCheckRotationStoped,
  34. CCR1Start,
  35. CCR1ClamshellOpen,
  36. OpenCCR1Valve,
  37. CCR1StartRotation,
  38. CCR1CCRMonitor,
  39. CCR1CloseCCRValve,
  40. CCR1SetDryRotationSpeed,
  41. CCR1CheckRotationStoped,
  42. CCR2Start,
  43. CCR2ClamshellOpen,
  44. OpenCCR2Valve,
  45. CCR2StartRotation,
  46. CCR2CCRMonitor,
  47. CCR2CloseCCRValve,
  48. CCR2SetDryRotationSpeed,
  49. CCR2CheckRotationStoped,
  50. End
  51. }
  52. #region 常量
  53. /// <summary>
  54. /// ROTATION电机转速比例
  55. /// </summary>
  56. private const int SPEED_RATIO = 1;
  57. #endregion
  58. #region 内部变量
  59. /// <summary>
  60. /// 设备对象
  61. /// </summary>
  62. private PlatingCellDevice _platingCellDevice;
  63. /// <summary>
  64. /// Rotation axis
  65. /// </summary>
  66. private JetAxisBase _rotationAxis;
  67. /// <summary>
  68. /// SRD rotation Provider对象
  69. /// </summary>
  70. private BeckhoffProviderAxis _rotationProviderAxis;
  71. /// <summary>
  72. /// startRotationTime,用于控制速度改变
  73. /// </summary>
  74. private int _startRotationTime;
  75. /// <summary>
  76. /// 当前执行到哪一步的显示
  77. /// </summary>
  78. private string _currentStep;
  79. /// <summary>
  80. /// 当前执行到哪一步的剩余时间
  81. /// </summary>
  82. private double _timeRemain;
  83. private bool _cSREnable;
  84. private bool _cCR1Enable;
  85. private bool _cCR2Enable;
  86. private int _cSRRinseSpeed;
  87. private int _cSRDrySpeed;
  88. private double _cSRRinseTime;
  89. private double _cSRDryTime;
  90. private int _cCR1RinseSpeed;
  91. private int _cCR1DrySpeed;
  92. private double _cCR1RinseTime;
  93. private double _cCR1DryTime;
  94. private int _cCR2RinseSpeed;
  95. private int _cCR2DrySpeed;
  96. private double _cCR2RinseTime;
  97. private double _cCR2DryTime;
  98. /// <summary>
  99. /// CCR小步骤的启动时间
  100. /// </summary>
  101. private DateTime _cSRStartTime;
  102. private DateTime _cCR1StartTime;
  103. private DateTime _cCR2StartTime;
  104. #endregion
  105. /// <summary>
  106. /// 构造函数
  107. /// </summary>
  108. /// <param name="module"></param>
  109. public PlatingCellCCRRoutine(string module) : base(module)
  110. {
  111. }
  112. /// <summary>
  113. /// 中止
  114. /// </summary>
  115. public void Abort()
  116. {
  117. Runner.Stop("CCR Manual Abort");
  118. }
  119. /// <summary>
  120. /// 监控
  121. /// </summary>
  122. /// <returns></returns>
  123. public RState Monitor()
  124. {
  125. CheckCurrentStepAndTimeRemain();
  126. _platingCellDevice.UpdateStatus(_currentStep);
  127. Runner.RunIf(CCRStep.CSRStart, _cSREnable , () => RecordCCRStepStartTime(out _cSRStartTime), _delay_1ms)
  128. .RunIf(CCRStep.CSRClamshellClose, _cSREnable , () => _platingCellDevice.ClamShellClose(), CheckClamShellClosed, _delay_1ms)
  129. .RunIf(CCRStep.CSROpenRinseValve, _cSREnable, OpenRinseValve, _delay_1ms)
  130. .RunIf(CCRStep.CSRStartRotation, _cSREnable, () => CSRStartRotation(), _delay_1ms)
  131. .WaitIf(CCRStep.CSRRinseMonitor, _cSREnable, MonitorCSRRinseRotationEndStatus)
  132. .RunIf(CCRStep.CSRCloseRinseValve, _cSREnable, CloseRinseValve, _delay_1ms)
  133. .RunIf(CCRStep.CSRSetDryRotationSpeed, _cSREnable, () => ChangeRotationSpeed(_cSRDrySpeed), _delay_1ms)
  134. .WaitWithStopConditionIf(CCRStep.CSRCheckRotationStoped, _cSREnable, CheckRotationEndStatus, CheckRotationStopStatus)
  135. .RunIf(CCRStep.CCR1Start, _cCR1Enable, () => RecordCCRStepStartTime(out _cCR1StartTime), _delay_1ms)
  136. .RunIf(CCRStep.CCR1ClamshellOpen, _cCR1Enable, () => _platingCellDevice.ClamShellOpen(), CheckClamShellOpen, _delay_1ms)
  137. .RunIf(CCRStep.OpenCCR1Valve, _cCR1Enable, OpenCCRValve, _delay_1ms)
  138. .RunIf(CCRStep.CCR1StartRotation, _cCR1Enable, () => CCR1StartRotation(), _delay_1ms)
  139. .WaitIf(CCRStep.CCR1CCRMonitor, _cCR1Enable, MonitorCCR1RotationEndStatus)
  140. .RunIf(CCRStep.CCR1CloseCCRValve, _cCR1Enable, CloseCCRValve, _delay_1ms)
  141. .RunIf(CCRStep.CCR1SetDryRotationSpeed, _cCR1Enable, () => ChangeRotationSpeed(_cCR1DrySpeed), _delay_1ms)
  142. .WaitWithStopConditionIf(CCRStep.CCR1CheckRotationStoped, _cCR1Enable, CheckRotationEndStatus, CheckRotationStopStatus)
  143. .RunIf(CCRStep.CCR2Start, _cCR2Enable, () => RecordCCRStepStartTime(out _cCR2StartTime), _delay_1ms)
  144. .RunIf(CCRStep.CCR2ClamshellOpen, _cCR2Enable, () => _platingCellDevice.ClamShellOpen(), CheckClamShellOpen, _delay_1ms)
  145. .RunIf(CCRStep.OpenCCR2Valve, _cCR2Enable, OpenCCRValve, _delay_1ms)
  146. .RunIf(CCRStep.CCR2StartRotation, _cCR2Enable, () => CCR2StartRotation(), _delay_1ms)
  147. .WaitIf(CCRStep.CCR2CCRMonitor, _cCR2Enable, MonitorCCR2RotationEndStatus)
  148. .RunIf(CCRStep.CCR2CloseCCRValve, _cCR2Enable, CloseCCRValve, _delay_1ms)
  149. .RunIf(CCRStep.CCR2SetDryRotationSpeed, _cCR2Enable, () => ChangeRotationSpeed(_cCR2DrySpeed), _delay_1ms)
  150. .WaitWithStopConditionIf(CCRStep.CCR2CheckRotationStoped, _cCR2Enable, CheckRotationEndStatus, CheckRotationStopStatus)
  151. .End(CCRStep.End, NullFun, _delay_1ms);
  152. return Runner.Status;
  153. }
  154. /// <summary>
  155. /// 记录ccr step 起始时间
  156. /// </summary>
  157. /// <param name="dateTime"></param>
  158. /// <returns></returns>
  159. private bool RecordCCRStepStartTime(out DateTime dateTime)
  160. {
  161. dateTime = DateTime.Now;
  162. return true;
  163. }
  164. /// <summary>
  165. /// 判断当前处于ccr的哪一步
  166. /// </summary>
  167. private void CheckCurrentStepAndTimeRemain()
  168. {
  169. string currentStep = Runner.CurrentStep.ToString();
  170. if (currentStep.Contains("CSR"))
  171. {
  172. _currentStep ="CSR Rinse/Dry";
  173. _timeRemain = _cSRRinseTime + _cSRDryTime - (DateTime.Now - _cSRStartTime).TotalSeconds > 0 ? _cSRRinseTime + _cSRDryTime - (DateTime.Now - _cSRStartTime).TotalSeconds : 0;
  174. }
  175. else if (currentStep.Contains("CCR1"))
  176. {
  177. _currentStep = "CCR Cycle1 Rinse/Dry";
  178. _timeRemain = _cCR1RinseTime + _cCR1DryTime - (DateTime.Now - _cCR1StartTime).TotalSeconds > 0 ? _cCR1RinseTime + _cCR1DryTime - (DateTime.Now - _cCR1StartTime).TotalSeconds : 0;
  179. }
  180. else if (currentStep.Contains("CCR2"))
  181. {
  182. _currentStep = "CCR Cycle2 Rinse/Dry";
  183. _timeRemain = _cCR2RinseTime + _cCR2DryTime - (DateTime.Now - _cCR2StartTime).TotalSeconds > 0 ? _cCR2RinseTime + _cCR2DryTime - (DateTime.Now - _cCR2StartTime).TotalSeconds : 0;
  184. }
  185. else
  186. {
  187. _currentStep = "End";
  188. _timeRemain = 0;
  189. }
  190. _platingCellDevice.UpdateCCRTimeRemain(_timeRemain);
  191. }
  192. /// <summary>
  193. /// 打开CCR valve
  194. /// </summary>
  195. /// <returns></returns>
  196. private bool OpenCCRValve()
  197. {
  198. return _platingCellDevice.CCREnableAction();
  199. }
  200. /// <summary>
  201. /// 关闭CCR valve
  202. /// </summary>
  203. /// <returns></returns>
  204. private bool CloseCCRValve()
  205. {
  206. return _platingCellDevice.CCRDisableAction();
  207. }
  208. /// <summary>
  209. /// 打开Rinse valve
  210. /// </summary>
  211. /// <returns></returns>
  212. private bool OpenRinseValve()
  213. {
  214. return _platingCellDevice.RinseEnableAction();
  215. }
  216. /// <summary>
  217. /// 关闭Rinse valve
  218. /// </summary>
  219. /// <returns></returns>
  220. private bool CloseRinseValve()
  221. {
  222. return _platingCellDevice.RinseDisableAction();
  223. }
  224. /// <summary>
  225. /// 检查ClamShell是否closed
  226. /// </summary>
  227. /// <returns></returns>
  228. private bool CheckClamShellClosed()
  229. {
  230. return _platingCellDevice.PlatingCellDeviceData.ClamShellClose;
  231. }
  232. /// <summary>
  233. /// 检查ClamShell是否Open
  234. /// </summary>
  235. /// <returns></returns>
  236. private bool CheckClamShellOpen()
  237. {
  238. return !_platingCellDevice.PlatingCellDeviceData.ClamShellClose;
  239. }
  240. /// <summary>
  241. /// 检验Rotation是否停止
  242. /// </summary>
  243. /// <returns></returns>
  244. private bool CheckRotationEndStatus()
  245. {
  246. if (!_rotationAxis.IsRun && _rotationAxis.Status == RState.End)
  247. {
  248. return true;
  249. }
  250. return false;
  251. }
  252. /// <summary>
  253. /// 检验Rotation停止状态
  254. /// </summary>
  255. /// <returns></returns>
  256. private bool CheckRotationStopStatus()
  257. {
  258. if (_rotationAxis.Status == RState.Failed || _rotationAxis.Status == RState.Timeout)
  259. {
  260. NotifyError(eEvent.ERR_PLATINGCELL, $"{Module}.Rotation is failed", 0);
  261. return true;
  262. }
  263. return false;
  264. }
  265. /// <summary>
  266. /// CSR阶段rotation开始旋转
  267. /// </summary>
  268. /// <param name="param"></param>
  269. /// <returns></returns>
  270. private bool CSRStartRotation()
  271. {
  272. double _scale = _rotationProviderAxis.ScaleFactor;
  273. //rinse 目标位置
  274. double rinsePosition = _cSRRinseTime * BeckhoffVelocityUtil.ConvertVelocityToDegPerSecondByRPM(_cSRRinseSpeed);
  275. //dry目标位置
  276. double dryPosition = BeckhoffVelocityUtil.ConvertVelocityToDegPerSecondByRPM(_cSRDrySpeed) * _cSRDryTime;
  277. int targetPosition = (int)Math.Round((rinsePosition + dryPosition ) * _scale, 0);
  278. int rotationSpeed = (int)Math.Round(_scale * BeckhoffVelocityUtil.ConvertVelocityToDegPerSecondByRPM(_cSRRinseSpeed), 0);
  279. //启动先用rinse的speed,时间到了转成用dry的speed
  280. bool result = _rotationAxis.ProfilePosition(targetPosition, rotationSpeed * SPEED_RATIO, 0, 0);
  281. if (!result)
  282. {
  283. NotifyError(eEvent.ERR_PLATINGCELL, "Start Rotation is failed", 0);
  284. return false;
  285. }
  286. LOG.WriteLog(eEvent.INFO_PLATINGCELL, Module, "Start CSR Step Rinse Rotation");
  287. //Rinse开始时间
  288. _startRotationTime = Environment.TickCount;
  289. return true;
  290. }
  291. /// <summary>
  292. /// WaterFlow End Monitor
  293. /// </summary>
  294. /// <returns></returns>
  295. private bool MonitorCSRRinseRotationEndStatus()
  296. {
  297. int ticks = Environment.TickCount - _startRotationTime;
  298. if (ticks >= _cSRRinseTime * 1000)
  299. {
  300. return true;
  301. }
  302. return false;
  303. }
  304. /// <summary>
  305. /// CCR1阶段rotation开始旋转
  306. /// </summary>
  307. /// <param name="param"></param>
  308. /// <returns></returns>
  309. private bool CCR1StartRotation()
  310. {
  311. double _scale = _rotationProviderAxis.ScaleFactor;
  312. //rinse 目标位置
  313. double rinsePosition = _cCR1RinseTime * BeckhoffVelocityUtil.ConvertVelocityToDegPerSecondByRPM(_cCR1RinseSpeed);
  314. //dry目标位置
  315. double dryPosition = BeckhoffVelocityUtil.ConvertVelocityToDegPerSecondByRPM(_cCR1DrySpeed) * _cCR1DryTime;
  316. int targetPosition = (int)Math.Round((rinsePosition + dryPosition) * _scale, 0);
  317. int rotationSpeed = (int)Math.Round(_scale * BeckhoffVelocityUtil.ConvertVelocityToDegPerSecondByRPM(_cCR1RinseSpeed), 0);
  318. //启动先用rinse的speed,时间到了转成用dry的speed
  319. bool result = _rotationAxis.ProfilePosition(targetPosition, rotationSpeed * SPEED_RATIO, 0, 0);
  320. if (!result)
  321. {
  322. NotifyError(eEvent.ERR_PLATINGCELL, "Start Rotation is failed", 0);
  323. return false;
  324. }
  325. LOG.WriteLog(eEvent.INFO_PLATINGCELL, Module, "Start CCR1 Step Rinse Rotation");
  326. //Rinse开始时间
  327. _startRotationTime = Environment.TickCount;
  328. return true;
  329. }
  330. /// <summary>
  331. /// CCR1 WaterFlow End Monitor
  332. /// </summary>
  333. /// <returns></returns>
  334. private bool MonitorCCR1RotationEndStatus()
  335. {
  336. int ticks = Environment.TickCount - _startRotationTime;
  337. if (ticks >= _cCR1RinseTime * 1000)
  338. {
  339. return true;
  340. }
  341. return false;
  342. }
  343. /// <summary>
  344. /// CCR2阶段rotation开始旋转
  345. /// </summary>
  346. /// <param name="param"></param>
  347. /// <returns></returns>
  348. private bool CCR2StartRotation()
  349. {
  350. double _scale = _rotationProviderAxis.ScaleFactor;
  351. //rinse 目标位置
  352. double rinsePosition = _cCR2RinseTime * BeckhoffVelocityUtil.ConvertVelocityToDegPerSecondByRPM(_cCR2RinseSpeed);
  353. //dry目标位置
  354. double dryPosition = BeckhoffVelocityUtil.ConvertVelocityToDegPerSecondByRPM(_cCR2DrySpeed) * _cCR2DryTime;
  355. int targetPosition = (int)Math.Round((rinsePosition + dryPosition) * _scale, 0);
  356. int rotationSpeed = (int)Math.Round(_scale * BeckhoffVelocityUtil.ConvertVelocityToDegPerSecondByRPM(_cCR2RinseSpeed), 0);
  357. //启动先用rinse的speed,时间到了转成用dry的speed
  358. bool result = _rotationAxis.ProfilePosition(targetPosition, rotationSpeed * SPEED_RATIO, 0, 0);
  359. if (!result)
  360. {
  361. NotifyError(eEvent.ERR_PLATINGCELL, "Start Rotation is failed", 0);
  362. return false;
  363. }
  364. LOG.WriteLog(eEvent.INFO_PLATINGCELL, Module, "Start CCR2 Step Rinse Rotation");
  365. //Rinse开始时间
  366. _startRotationTime = Environment.TickCount;
  367. return true;
  368. }
  369. /// <summary>
  370. /// CCR2 WaterFlow End Monitor
  371. /// </summary>
  372. /// <returns></returns>
  373. private bool MonitorCCR2RotationEndStatus()
  374. {
  375. int ticks = Environment.TickCount - _startRotationTime;
  376. if (ticks >= _cCR2RinseTime * 1000)
  377. {
  378. return true;
  379. }
  380. return false;
  381. }
  382. /// <summary>
  383. /// 改变速度
  384. /// </summary>
  385. /// <param name="speed"></param>
  386. /// <returns></returns>
  387. private bool ChangeRotationSpeed(int speed)
  388. {
  389. double _scale = _rotationProviderAxis.ScaleFactor;
  390. speed = (int)Math.Round(_scale * BeckhoffVelocityUtil.ConvertVelocityToDegPerSecondByRPM(speed), 0);
  391. return _rotationAxis.ChangeSpeed(speed);
  392. }
  393. /// <summary>
  394. /// 启动
  395. /// </summary>
  396. /// <param name="objs"></param>
  397. /// <returns></returns>
  398. public RState Start(params object[] objs)
  399. {
  400. _platingCellDevice = DEVICE.GetDevice<PlatingCellDevice>(Module);
  401. _cSREnable = SC.GetValue<bool>("PlatingCell.CSR.CSREnable");
  402. _cCR1Enable = SC.GetValue<bool>("PlatingCell.CCR1.CCR1Enable");
  403. _cCR2Enable = SC.GetValue<bool>("PlatingCell.CCR2.CCR2Enable");
  404. _cSRRinseSpeed = SC.GetValue<int>("PlatingCell.CSR.RinseSpeed");
  405. _cSRDrySpeed = SC.GetValue<int>("PlatingCell.CSR.DrySpeed");
  406. _cSRRinseTime = SC.GetValue<double>("PlatingCell.CSR.RinseTime");
  407. _cSRDryTime = SC.GetValue<double>("PlatingCell.CSR.DryTime");
  408. _cCR1RinseSpeed = SC.GetValue<int>("PlatingCell.CCR1.RinseSpeed");
  409. _cCR1DrySpeed = SC.GetValue<int>("PlatingCell.CCR1.DrySpeed");
  410. _cCR1RinseTime = SC.GetValue<double>("PlatingCell.CCR1.RinseTime");
  411. _cCR1DryTime = SC.GetValue<double>("PlatingCell.CCR1.DryTime");
  412. _cCR2RinseSpeed = SC.GetValue<int>("PlatingCell.CCR2.RinseSpeed");
  413. _cCR2DrySpeed = SC.GetValue<int>("PlatingCell.CCR2.DrySpeed");
  414. _cCR2RinseTime = SC.GetValue<double>("PlatingCell.CCR2.RinseTime");
  415. _cCR2DryTime = SC.GetValue<double>("PlatingCell.CCR2.DryTime");
  416. _rotationAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Rotation");
  417. _rotationProviderAxis = BeckhoffAxisProviderManager.Instance.GetAxisProvider($"{Module}.Rotation");
  418. if (_rotationProviderAxis == null)
  419. {
  420. NotifyError(eEvent.ERR_SRD, $"{Module}.Rotation Provider is not exist", 0);
  421. return RState.Failed;
  422. }
  423. return Runner.Start(Module, "Start Reservoir Initialize");
  424. }
  425. }
  426. }