PlatingCellDepositionRoutine.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. using Aitex.Core.RT.Device;
  2. using Aitex.Core.RT.Log;
  3. using Aitex.Core.RT.Routine;
  4. using Aitex.Core.Util;
  5. using MECF.Framework.Common.Beckhoff.Station;
  6. using MECF.Framework.Common.CommonData.PowerSupplier;
  7. using MECF.Framework.Common.RecipeCenter;
  8. using MECF.Framework.Common.Routine;
  9. using MECF.Framework.Common.Utilities;
  10. using PunkHPX8_Core;
  11. using PunkHPX8_RT.Devices.AXIS;
  12. using PunkHPX8_RT.Devices.PlatingCell;
  13. using System;
  14. using System.Collections.Generic;
  15. using System.Linq;
  16. using System.Text;
  17. using System.Threading.Tasks;
  18. namespace PunkHPX8_RT.Modules.PlatingCell
  19. {
  20. public class PlatingCellDepositionRoutine : RoutineBase, IRoutine
  21. {
  22. private enum RunRecipeStep
  23. {
  24. RunPowerStep,
  25. RunPowerStepWait,
  26. LoopRotationStart,
  27. LoopVerticalGotoOffSet,
  28. LoopVerticalGotoOffSetCheck,
  29. LoopRotationStartIfCurrentIsStoped,//如果当前电机是停止状态,启动起来
  30. LoopRotationChangeSpeed,
  31. LoopRotationDelay,
  32. LoopRotationStopIfCurrentIsRuning, //如果当前电机是启动状态,则停止
  33. LoopROtationStopCheck,
  34. LoopRotationBiRotation,
  35. LoopRotationBiRotationCheck,
  36. LoopUpdateDepositionIndex,
  37. LoopEnd,
  38. RotationStartIfCurrentIsStoped,
  39. End
  40. }
  41. #region 常量
  42. /// <summary>
  43. /// ROTATION电机转速比例
  44. /// </summary>
  45. private const int SPEED_RATIO = 1;
  46. private const int ROTATION_FAR_POSITION = 12 * 60 * 60 * 500 * 6; //以500rmp 运行12个小时的位置
  47. #endregion
  48. /// <summary>
  49. /// recipe
  50. /// </summary>
  51. private DepRecipe _recipe;
  52. /// <summary>
  53. /// Rotation axis
  54. /// </summary>
  55. private JetAxisBase _rotationAxis;
  56. /// <summary>
  57. /// Platingcell device
  58. /// </summary>
  59. private PlatingCellDevice _device;
  60. /// <summary>
  61. /// vertical axis entity
  62. /// </summary>
  63. private PlatingCellVerticalEntity _verticalEntity;
  64. /// <summary>
  65. /// vertical 轴的位置数据
  66. /// </summary>
  67. private BeckhoffStationAxis _verticalBeckhoffStation;
  68. /// <summary>
  69. /// 不通电
  70. /// </summary>
  71. private bool _isZeroCurrent = false;
  72. /// <summary>
  73. /// 是否双有双向旋转
  74. /// </summary>
  75. private bool _isBiRotation = false;
  76. /// <summary>
  77. /// 是否启动smart spin
  78. /// </summary>
  79. private bool _isSmartSpin = false;
  80. /// <summary>
  81. /// Power step集合
  82. /// </summary>
  83. List<PowerSupplierStepPeriodData> _powerSupplierStepPeriodDatas = new List<PowerSupplierStepPeriodData>();
  84. /// <summary>
  85. /// 双向旋转routine
  86. /// </summary>
  87. private RotationBiDirectionRoutine _rotationBiDirectionRoutine;
  88. /// <summary>
  89. /// Plating启动时间
  90. /// </summary>
  91. private DateTime _platingStartTime;
  92. /// <summary>
  93. /// 当前执行到电镀步骤的索引
  94. /// </summary>
  95. private int _depositionStepIndex = 0;
  96. /// <summary>
  97. /// 构造函数
  98. /// </summary>
  99. /// <param name="module"></param>
  100. public PlatingCellDepositionRoutine(string module) : base(module)
  101. {
  102. _rotationBiDirectionRoutine = new RotationBiDirectionRoutine(module);
  103. }
  104. /// <summary>
  105. /// 中止
  106. /// </summary>
  107. public void Abort()
  108. {
  109. Runner.Stop("Manual Abort");
  110. }
  111. /// <summary>
  112. /// 监控
  113. /// </summary>
  114. /// <returns></returns>
  115. public RState Monitor()
  116. {
  117. Runner //没有上电保护,此刻给电
  118. .RunIf(RunRecipeStep.RunPowerStep, _recipe.IsEntryTypeCold, StartPowerStep, _delay_1ms)
  119. .LoopStart(RunRecipeStep.LoopRotationStart, "Start rotation cycle",_recipe.DepStepCount,NullFun)
  120. //vertical 调整位置
  121. .LoopRunIf(RunRecipeStep.LoopVerticalGotoOffSet, _recipe.DepSteps[_depositionStepIndex].PlatingZoffset!=0, () => StartVertical("Plate", _recipe.DepSteps[_depositionStepIndex].PlatingZoffset),_delay_1ms)
  122. .LoopRunIf(RunRecipeStep.LoopVerticalGotoOffSetCheck, _recipe.DepSteps[_depositionStepIndex].PlatingZoffset!=0, CheckVerticalEnd, CheckVerticalError)
  123. //不带双向旋转,时间到了直接变速(如果当前电机是停止状态,启动起来)
  124. .LoopRunIf(RunRecipeStep.LoopRotationStartIfCurrentIsStoped, CheckRotationIsIdle() && !_recipe.DepSteps[_depositionStepIndex].BiDireaction,
  125. () => { return StartRotation(ROTATION_FAR_POSITION); }, _delay_1ms)
  126. .LoopRunIf(RunRecipeStep.LoopRotationChangeSpeed, !_recipe.DepSteps[_depositionStepIndex].BiDireaction,() => ChangeRotationSpeed(_recipe.DepSteps[_depositionStepIndex].PlatingSpeed),_delay_1ms)
  127. .LoopDelayIf(RunRecipeStep.LoopRotationDelay, !_recipe.DepSteps[_depositionStepIndex].BiDireaction, _recipe.DepSteps[_depositionStepIndex].DurartionSeconds *1000)
  128. //带双向旋转,启动双向旋转的routine(如果当前电机是启动状态,则停止)
  129. .LoopRunIf(RunRecipeStep.LoopRotationStopIfCurrentIsRuning, checkRotationIsRunning() && _recipe.DepSteps[_depositionStepIndex].BiDireaction,
  130. _rotationAxis.StopPositionOperation, _delay_1ms)
  131. .LoopRunIfWithStopStatus(RunRecipeStep.LoopROtationStopCheck, checkRotationIsRunning() && _recipe.DepSteps[_depositionStepIndex].BiDireaction,
  132. CheckRotationIsIdle, CheckRotationPositionRunStop)
  133. .LoopRunIf(RunRecipeStep.LoopRotationBiRotation, _recipe.DepSteps[_depositionStepIndex].BiDireaction,
  134. () => _rotationBiDirectionRoutine.Start(_recipe.DepSteps[_depositionStepIndex].DurartionSeconds, _recipe.DepSteps[_depositionStepIndex].BiDFrequency, _recipe.DepSteps[_depositionStepIndex].PlatingSpeed) == RState.Running,_delay_1ms)
  135. .LoopRunIfWithStopStatus(RunRecipeStep.LoopRotationBiRotationCheck, _recipe.DepSteps[_depositionStepIndex].BiDireaction,
  136. () => CommonFunction.CheckRoutineEndState(_rotationBiDirectionRoutine),
  137. () => CommonFunction.CheckRoutineStopState(_rotationBiDirectionRoutine))
  138. .LoopRun(RunRecipeStep.LoopUpdateDepositionIndex, UpdateDepositionIndex, _delay_1ms)
  139. .LoopEnd(RunRecipeStep.LoopEnd,NullFun,_delay_1ms)
  140. //检验步阶电流是否完成
  141. .WaitWithStopCondition(RunRecipeStep.RunPowerStepWait, CheckRecipeStepEndStatus, CheckRecipeStepStopStatus, _delay_1ms)
  142. //如果电镀最后一步带双向旋转,后续电机会停止,需要再把电机启动起来
  143. .RunIf(RunRecipeStep.RotationStartIfCurrentIsStoped, CheckRotationIsIdle(), () => { return StartRotation(ROTATION_FAR_POSITION); }, _delay_1ms)
  144. .End(RunRecipeStep.End, NullFun);
  145. return Runner.Status;
  146. }
  147. /// <summary>
  148. /// 判断当前电机是否在转
  149. /// </summary>
  150. /// <returns></returns>
  151. private bool checkRotationIsRunning()
  152. {
  153. return _rotationAxis.Status == RState.Running;
  154. }
  155. /// <summary>
  156. /// 判断电机当前状态是否停止
  157. /// </summary>
  158. /// <returns></returns>
  159. private bool CheckRotationIsIdle()
  160. {
  161. return _rotationAxis.Status == RState.End;
  162. }
  163. /// <summary>
  164. /// 检验Rotation是否运动失败
  165. /// </summary>
  166. /// <returns></returns>
  167. private bool CheckRotationPositionRunStop()
  168. {
  169. return _rotationAxis.Status == RState.Failed || _rotationAxis.Status == RState.Timeout;
  170. }
  171. /// <summary>
  172. /// 更新电镀步骤索引
  173. /// </summary>
  174. /// <returns></returns>
  175. private bool UpdateDepositionIndex()
  176. {
  177. _depositionStepIndex++;
  178. return true;
  179. }
  180. /// <summary>
  181. /// 启动PowerSupplier
  182. /// </summary>
  183. /// <returns></returns>
  184. private bool StartPowerStep()
  185. {
  186. bool result = _device.PowerSupplier.StartSetStepPeriodNoWaitEnd(_powerSupplierStepPeriodDatas);
  187. if (!result)
  188. {
  189. _device.PowerSupplier.DisableOperation("", null);
  190. return false;
  191. }
  192. _platingStartTime = DateTime.Now;
  193. return true;
  194. }
  195. /// <summary>
  196. /// 检验Powerstep是否启动完成
  197. /// </summary>
  198. /// <returns></returns>
  199. private bool CheckRecipeStepEndStatus()
  200. {
  201. if (_isZeroCurrent)
  202. {
  203. return true;
  204. }
  205. return _device.PowerSupplier.Status == RState.End;
  206. }
  207. /// <summary>
  208. /// 检验Powerstep是否启动失败
  209. /// </summary>
  210. /// <returns></returns>
  211. private bool CheckRecipeStepStopStatus()
  212. {
  213. if (_isZeroCurrent)
  214. {
  215. return false;
  216. }
  217. return _device.PowerSupplier.Status == RState.Failed || _device.PowerSupplier.Status == RState.Timeout;
  218. }
  219. /// <summary>
  220. /// rotation开始旋转
  221. /// </summary>
  222. /// <param name="param"></param>
  223. /// <returns></returns>
  224. private bool StartRotation(int targetPosition)
  225. {
  226. bool result = _rotationAxis.ProfilePosition(targetPosition, _recipe.IntervalRinseSpeed * SPEED_RATIO * 6, 0, 0); //rpm->deg/s
  227. if (!result)
  228. {
  229. NotifyError(eEvent.ERR_PLATINGCELL, "Start Rotation is failed", 0);
  230. return false;
  231. }
  232. return true;
  233. }
  234. /// <summary>
  235. /// rotation改变速度
  236. /// </summary>
  237. /// <param name="speed"></param>
  238. /// <returns></returns>
  239. private bool ChangeRotationSpeed(int speed)
  240. {
  241. double _scale = _rotationAxis.ScaleFactor;
  242. speed = (int)Math.Round(_scale * BeckhoffVelocityUtil.ConvertVelocityToDegPerSecondByRPM(speed), 0);
  243. return _rotationAxis.ChangeSpeed(speed);
  244. }
  245. /// <summary>
  246. /// vertical 运行
  247. /// </summary>
  248. /// <param name="positionName"></param> 目标位置名称
  249. /// <param name="offset"></param> 偏移量
  250. /// <returns></returns>
  251. private bool StartVertical(string positionName, double offset)
  252. {
  253. return _verticalEntity.CheckToPostMessage<PlatingCellVerticalState, PlatingCellVerticalEntity.VerticalMsg>(Aitex.Core.RT.Log.eEvent.INFO_PLATINGCELL,
  254. Module, (int)PlatingCellVerticalEntity.VerticalMsg.Position, positionName, offset);
  255. }
  256. /// <summary>
  257. /// 检验垂直电机是否运动完成
  258. /// </summary>
  259. /// <returns></returns>
  260. private bool CheckVerticalEnd()
  261. {
  262. return _verticalEntity.IsIdle;
  263. }
  264. /// <summary>
  265. /// 检验垂直是否出现错误
  266. /// </summary>
  267. /// <returns></returns>
  268. private bool CheckVerticalError()
  269. {
  270. return _verticalEntity.IsError;
  271. }
  272. /// <summary>
  273. /// 启动
  274. /// </summary>
  275. /// <param name="objs"></param>
  276. /// <returns></returns>
  277. public RState Start(params object[] objs)
  278. {
  279. _recipe = (DepRecipe)objs[0];
  280. _isZeroCurrent = (bool)objs[1];
  281. _isBiRotation = (bool)objs[2];
  282. _powerSupplierStepPeriodDatas = (List<PowerSupplierStepPeriodData>)objs[3];
  283. _platingStartTime = (DateTime)objs[4];
  284. _rotationAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Rotation");
  285. _device = DEVICE.GetDevice<PlatingCellDevice>(Module);
  286. _depositionStepIndex = 0;
  287. //获取vertical entity
  288. string vertical = ModuleMatcherManager.Instance.GetPlatingVerticalByCell(Module);
  289. _verticalEntity = Singleton<RouteManager>.Instance.GetModule<PlatingCellVerticalEntity>(vertical);
  290. //获取vertical station信息对象
  291. _verticalBeckhoffStation = BeckhoffStationLocationManager.Instance.GetStationAxis($"{_verticalEntity.Module}", "Vertical");
  292. return Runner.Start(Module, "start intervale rinse");
  293. }
  294. }
  295. }