PrewetProcessStateMachine.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. using Aitex.Core.RT.Device;
  2. using Aitex.Core.RT.Fsm;
  3. using Aitex.Core.RT.Log;
  4. using Aitex.Core.Utilities;
  5. using MECF.Framework.Common.RecipeCenter;
  6. using CyberX8_Core;
  7. using CyberX8_RT.Devices.LinMot;
  8. using CyberX8_RT.Devices.Prewet;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.Linq;
  12. using System.Text;
  13. using System.Threading.Tasks;
  14. using System.Windows.Markup;
  15. using MECF.Framework.Common.CommonData.Prewet;
  16. using static CyberX8_RT.Modules.Prewet.PrewetKeepWetStateMachine;
  17. namespace CyberX8_RT.Modules.Prewet
  18. {
  19. public class PrewetProcessStateMachine : Entity, IEntity
  20. {
  21. #region 内部变量
  22. /// <summary>
  23. /// 模块名称
  24. /// </summary>
  25. private string _module;
  26. /// <summary>
  27. /// prewet设备
  28. /// </summary>
  29. private PrewetDevice _prewetDevice;
  30. /// <summary>
  31. /// linmot axis
  32. /// </summary>
  33. private LinMotAxis _linMotAxis;
  34. /// <summary>
  35. /// Prewet recipe
  36. /// </summary>
  37. private PwtRecipe _recipe;
  38. #endregion
  39. #region 属性
  40. /// <summary>
  41. /// 状态
  42. /// </summary>
  43. public string State { get { return ((PrewetProcessState)fsm.State).ToString(); } }
  44. #endregion
  45. /// <summary>
  46. /// 构造函数
  47. /// </summary>
  48. /// <param name="module"></param>
  49. public PrewetProcessStateMachine(string module,LinMotAxis linMotAxis)
  50. {
  51. _module = module;
  52. _prewetDevice = DEVICE.GetDevice<PrewetDevice>(module);
  53. _linMotAxis = linMotAxis;
  54. this.fsm = new StateMachine($"{module}_ProcessStateMachine", (int)PrewetProcessState.Idle, 10);
  55. fsm.EnableRepeatedMsg(true);
  56. AnyStateTransition(PrewetProcessMsg.Error, EnterError, PrewetProcessState.Error);
  57. Transition(PrewetProcessState.Error, PrewetProcessState.Process_Start, EnterProcessStartStatus, PrewetProcessState.Process_Start);
  58. Transition(PrewetProcessState.Idle, PrewetProcessMsg.ProcessStart, EnterProcessStartStatus, PrewetProcessState.Process_Start);
  59. Transition(PrewetProcessState.Process_Start,FSM_MSG.TIMER, NullFunc, PrewetProcessState.Process_StartScanning);
  60. Transition(PrewetProcessState.Process_StartScanning,FSM_MSG.TIMER, ProcessStartScan, WaitProcessStartStatus, PrewetProcessState.Process_WaitFirstScanComplete);
  61. Transition(PrewetProcessState.Process_WaitFirstScanComplete, FSM_MSG.TIMER, StartScan, PrewetProcessState.Process_WaitScanComplete);
  62. Transition(PrewetProcessState.Process_WaitScanComplete, FSM_MSG.TIMER, WaitScanComplete, PrewetProcessState.Process_Complete);
  63. Transition(PrewetProcessState.Process_Complete, FSM_MSG.TIMER, ProcessComplete, PrewetProcessState.Idle);
  64. EnumLoop<PrewetProcessState>.ForEach((item) => { fsm.MapState((int)item, item.ToString()); });
  65. EnumLoop<PrewetProcessMsg>.ForEach((item) => { fsm.MapMessage((int)item, item.ToString()); });
  66. }
  67. /// <summary>
  68. /// 进入启动状态
  69. /// </summary>
  70. /// <param name="param"></param>
  71. private bool EnterProcessStartStatus(object param)
  72. {
  73. object[] objects = param as object[];
  74. PwtRecipe pwtRecipe = (PwtRecipe)objects[0];
  75. if(pwtRecipe == null)
  76. {
  77. LOG.WriteLog(eEvent.ERR_PREWET, _module, "recipe is null error");
  78. PostMsg(PrewetProcessMsg.Error);
  79. return false;
  80. }
  81. _recipe = pwtRecipe;
  82. return true;
  83. }
  84. /// <summary>
  85. /// 进入Error状态
  86. /// </summary>
  87. /// <param name="param"></param>
  88. /// <returns></returns>
  89. private bool EnterError(object param)
  90. {
  91. if(_linMotAxis.Status==RState.Running)
  92. {
  93. _linMotAxis.AbortCurrentRoutine();
  94. }
  95. if(_prewetDevice.Status==RState.Running)
  96. {
  97. _prewetDevice.AbortCurrentRoutine();
  98. }
  99. return true;
  100. }
  101. #region process
  102. /// <summary>
  103. /// Process Start Scan
  104. /// </summary>
  105. /// <returns></returns>
  106. private bool ProcessStartScan(object param)
  107. {
  108. bool result = _linMotAxis.ResetOperation("", false);
  109. if (!result)
  110. {
  111. LOG.WriteLog(eEvent.ERR_PREWET, _module, "reset linmot error");
  112. PostMsg(PrewetProcessMsg.Error);
  113. return false;
  114. }
  115. _prewetDevice.PrewetPumpData.PumpSpeedAuto = true;
  116. //更新Pump status状态
  117. string statusContent = _prewetDevice.PrewetPumpData.PumpStatus ? "On" : "Off";
  118. _prewetDevice.PrewetPumpData.PumpModel = "Auto";
  119. _prewetDevice.PrewetPumpData.PumpStatusContent = $"{_prewetDevice.PrewetPumpData.PumpModel}: {statusContent}";
  120. result = _prewetDevice.PumpSpeed();
  121. if(!result)
  122. {
  123. LOG.WriteLog(eEvent.ERR_PREWET, _module, "pump speed error");
  124. PostMsg(PrewetProcessMsg.Error);
  125. return false;
  126. }
  127. bool pumpEnableResult = _prewetDevice.PumpEnableOperation("", null);
  128. if (!pumpEnableResult)
  129. {
  130. LOG.WriteLog(eEvent.ERR_PREWET, _module, "pump enable error");
  131. PostMsg(PrewetProcessMsg.Error);
  132. return false;
  133. }
  134. return true;
  135. }
  136. /// <summary>
  137. /// 等待start process状态
  138. /// </summary>
  139. /// <returns></returns>
  140. private bool WaitProcessStartStatus(object param)
  141. {
  142. if(_prewetDevice.Status==RState.Failed)
  143. {
  144. LOG.WriteLog(eEvent.ERR_PREWET, _module, "prewet device status is error");
  145. PostMsg(PrewetProcessMsg.Error);
  146. return false;
  147. }
  148. if (_linMotAxis.Status == RState.Failed)
  149. {
  150. LOG.WriteLog(eEvent.ERR_PREWET, _module, "linmot status is error");
  151. PostMsg(PrewetProcessMsg.Error);
  152. return false;
  153. }
  154. if (_prewetDevice.Status == RState.End && _linMotAxis.Status == RState.End)
  155. {
  156. return true;
  157. }
  158. return false;
  159. }
  160. /// <summary>
  161. /// 开始Scan
  162. /// </summary>
  163. /// <param name="param"></param>
  164. /// <returns></returns>
  165. private bool StartScan(object param)
  166. {
  167. if (!_linMotAxis.IsHomed)
  168. {
  169. LOG.WriteLog(eEvent.ERR_PREWET, _module, "limot is not ready");
  170. PostMsg(PrewetProcessMsg.Error);
  171. return false;
  172. }
  173. if(!_prewetDevice.PrewetPumpData.PumpStatus)
  174. {
  175. LOG.WriteLog(eEvent.ERR_PREWET, _module, "pump status if off");
  176. PostMsg(PrewetProcessMsg.Error);
  177. return false;
  178. }
  179. bool result = _linMotAxis.StartPosition("", new object[] { _recipe.NumberOfScans });
  180. if(!result)
  181. {
  182. LOG.WriteLog(eEvent.ERR_PREWET, _module, "linmot start scan error");
  183. PostMsg(PrewetProcessMsg.Error);
  184. return false;
  185. }
  186. return true;
  187. }
  188. /// <summary>
  189. /// 等待Scan结束
  190. /// </summary>
  191. /// <param name="param"></param>
  192. /// <returns></returns>
  193. private bool WaitScanComplete(object param)
  194. {
  195. if (_prewetDevice.PrewetPumpData.PumpFlowData.IsWarning)
  196. {
  197. LOG.WriteLog(eEvent.WARN_PREWET, _module, $"pump flow status {_prewetDevice.PrewetPumpData.PumpFlowData.Value} is in warning");
  198. }
  199. if (_prewetDevice.PrewetPumpData.PumpFlowData.IsError)
  200. {
  201. LOG.WriteLog(eEvent.ERR_PREWET, _module, $"pump flow status {_prewetDevice.PrewetPumpData.PumpFlowData.Value} is in error");
  202. PostMsg(PrewetProcessMsg.Error);
  203. return false;
  204. }
  205. if (_prewetDevice.PrewetPumpData.PumpPressureData.IsWarning)
  206. {
  207. LOG.WriteLog(eEvent.WARN_PREWET, _module, $"pump pressure status is {_prewetDevice.PrewetPumpData.PumpPressureData.Value} in warning");
  208. }
  209. if (_prewetDevice.PrewetPumpData.PumpPressureData.IsError)
  210. {
  211. LOG.WriteLog(eEvent.ERR_PREWET, _module, $"pump pressure status {_prewetDevice.PrewetPumpData.PumpPressureData.Value} is in error");
  212. PostMsg(PrewetProcessMsg.Error);
  213. return false;
  214. }
  215. //linmot完成一次scan
  216. if (_linMotAxis.Status == RState.End)
  217. {
  218. return true;
  219. }
  220. if (_linMotAxis.Status == RState.Failed)
  221. {
  222. PostMsg(PrewetProcessMsg.Error);
  223. return false;
  224. }
  225. return false;
  226. }
  227. /// <summary>
  228. /// Process scan完成
  229. /// </summary>
  230. /// <param name="param"></param>
  231. /// <returns></returns>
  232. private bool ProcessComplete(object param)
  233. {
  234. bool result = _prewetDevice.PumpDisableOperation("pump disable", null);
  235. if (!result)
  236. {
  237. LOG.WriteLog(eEvent.ERR_PREWET, _module, "pump disable error");
  238. PostMsg(PrewetKeepWetMsg.Error);
  239. return false;
  240. }
  241. result = _linMotAxis.SwitchOff();
  242. if (!result)
  243. {
  244. LOG.WriteLog(eEvent.ERR_PREWET, _module, "linmot disable error");
  245. PostMsg(PrewetProcessMsg.Error);
  246. return false;
  247. }
  248. return true;
  249. }
  250. #endregion
  251. public bool Check(int msg, out string reason, params object[] args)
  252. {
  253. reason = "";
  254. return true;
  255. }
  256. public enum PrewetProcessState
  257. {
  258. Error,
  259. Idle,
  260. Process_Start,
  261. Process_StartScanning,
  262. Process_WaitFirstScanComplete,
  263. Process_WaitScanComplete,
  264. Process_Complete
  265. }
  266. public enum PrewetProcessMsg
  267. {
  268. Error,
  269. ProcessStart
  270. }
  271. }
  272. }