UnloadingStateMachine.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. using Aitex.Core.RT.Device;
  2. using Aitex.Core.RT.Fsm;
  3. using Aitex.Core.RT.Log;
  4. using Aitex.Core.RT.SCCore;
  5. using Aitex.Core.Utilities;
  6. using MECF.Framework.Common.Beckhoff.AxisProvider;
  7. using MECF.Framework.Common.Utilities;
  8. using CyberX8_Core;
  9. using CyberX8_RT.Devices.AXIS;
  10. using CyberX8_RT.Devices.SRD;
  11. using System;
  12. using System.Collections.Generic;
  13. using System.Linq;
  14. using System.Runtime.InteropServices;
  15. using System.Text;
  16. using System.Threading.Tasks;
  17. namespace CyberX8_RT.Modules.SRD
  18. {
  19. internal class UnloadingStateMachine : Entity, IEntity
  20. {
  21. #region 常量
  22. /// <summary>
  23. /// Arm Home最大retry次数
  24. /// </summary>
  25. private const int MAX_ARM_HOME_RETRIES = 3;
  26. /// <summary>
  27. /// Rotation Home最大retry次数
  28. /// </summary>
  29. private const int MAX_ROTATION_HOME_RETRIES = 3;
  30. /// <summary>
  31. /// 旋转增加时长
  32. /// </summary>
  33. private const int ROTATION_PLUS_TIME = 10;
  34. #endregion
  35. #region 内部变量
  36. /// <summary>
  37. /// 模块名称
  38. /// </summary>
  39. private string _module;
  40. /// <summary>
  41. /// SRD Common
  42. /// </summary>
  43. private SrdCommonDevice _srdCommon;
  44. /// <summary>
  45. /// Arm Axis
  46. /// </summary>
  47. private JetAxisBase _armAxis;
  48. /// <summary>
  49. /// Rotation Axis
  50. /// </summary>
  51. private JetAxisBase _rotationAxis;
  52. /// <summary>
  53. /// Arm重试次数
  54. /// </summary>
  55. private int _armRetryTimes = 0;
  56. /// <summary>
  57. /// Rotation重试次数
  58. /// </summary>
  59. private int _rotationRetryTimes = 0;
  60. /// <summary>
  61. /// ARM正在执行Home
  62. /// </summary>
  63. private bool _armHoming = false;
  64. /// <summary>
  65. /// Rotation正在执行Home
  66. /// </summary>
  67. private bool _rotationHoming = false;
  68. #endregion
  69. #region 属性
  70. /// <summary>
  71. /// 状态
  72. /// </summary>
  73. public string State { get { return ((UnloadingState)fsm.State).ToString(); } }
  74. #endregion
  75. /// <summary>
  76. /// 构造函数
  77. /// </summary>
  78. /// <param name="module"></param>
  79. public UnloadingStateMachine(string module)
  80. {
  81. _module = module;
  82. this.fsm = new StateMachine($"{module}_UnloadingStateMachine", (int)UnloadingState.Unloading_Complete, 10);
  83. fsm.EnableRepeatedMsg(true);
  84. AnyStateTransition(UnloadingMsg.Init, EnterUnloadingStart, UnloadingState.Unloading_Start);
  85. AnyStateTransition(UnloadingMsg.Error, EnterError, UnloadingState.Error);
  86. //Transition(UnloadingState.Unloading_Complete, UnloadingMsg.Unloading_Start, EnterUnloadingStart, UnloadingState.Unloading_Start);
  87. Transition(UnloadingState.Unloading_Start, UnloadingMsg.Unloading_Start, UnloadingCheckStatus, UnloadingState.Unloading_CheckRotationStopped);
  88. Transition(UnloadingState.Unloading_CheckRotationStopped, FSM_MSG.TIMER, CheckRotationStopped, UnloadingState.Unloading_WaferPresent);
  89. Transition(UnloadingState.Unloading_WaferPresent, FSM_MSG.TIMER, CheckWaferPresent, UnloadingState.Unloading_OpenDoor);
  90. Transition(UnloadingState.Unloading_OpenDoor, FSM_MSG.TIMER, OpenDoor, UnloadingState.Unloading_CheckDoorOpened);
  91. Transition(UnloadingState.Unloading_CheckDoorOpened, FSM_MSG.TIMER, CheckDoorOpened, UnloadingState.Unloading_ReleaseChuckVacuum);
  92. Transition(UnloadingState.Unloading_ReleaseChuckVacuum, FSM_MSG.TIMER, ReleaseChuckVacuum, UnloadingState.Unloading_CheckVacuum);
  93. Transition(UnloadingState.Unloading_CheckVacuum, FSM_MSG.TIMER, CheckVacuum, UnloadingState.Unloading_Complete);
  94. EnumLoop<UnloadingState>.ForEach((item) => { fsm.MapState((int)item, item.ToString()); });
  95. EnumLoop<UnloadingMsg>.ForEach((item) => { fsm.MapMessage((int)item, item.ToString()); });
  96. }
  97. /// <summary>
  98. /// Enter Error
  99. /// </summary>
  100. /// <param name="param"></param>
  101. /// <returns></returns>
  102. private bool EnterError(object param)
  103. {
  104. return true;
  105. }
  106. /// <summary>
  107. /// Enter Unloading_Start
  108. /// </summary>
  109. /// <param name="param"></param>
  110. /// <returns></returns>
  111. private bool EnterUnloadingStart(object param)
  112. {
  113. return true;
  114. }
  115. #region 状态方法
  116. /// <summary>
  117. /// 启动
  118. /// </summary>
  119. /// <param name="param"></param>
  120. /// <returns></returns>
  121. private bool UnloadingCheckStatus(object param)
  122. {
  123. _armAxis = DEVICE.GetDevice<JetAxisBase>($"{_module}.Arm");
  124. _rotationAxis = DEVICE.GetDevice<JetAxisBase>($"{_module}.Rotation");
  125. _srdCommon = DEVICE.GetDevice<SrdCommonDevice>($"{_module}.Common");
  126. return true;
  127. }
  128. /// <summary>
  129. /// 检查Rotation与Arm是否home
  130. /// </summary>
  131. /// <param name="param"></param>
  132. /// <returns></returns>
  133. private bool CheckRotationStopped(object param)
  134. {
  135. CheckArmHome();
  136. CheckRotationHome();
  137. return _srdCommon.Status == RState.End;
  138. }
  139. /// <summary>
  140. /// 检验Arm home,发现失败则重试
  141. /// </summary>
  142. /// <param name="param"></param>
  143. /// <returns></returns>
  144. private bool CheckArmHome()
  145. {
  146. if (_armAxis.IsHomed)
  147. {
  148. return true;
  149. }
  150. else
  151. {
  152. if (_armRetryTimes < MAX_ARM_HOME_RETRIES)
  153. {
  154. if (!_armHoming)
  155. {
  156. LOG.WriteLog(eEvent.INFO_SRD, _module, $"Arm Home Retry Home {_armRetryTimes + 1} times");
  157. bool result = _armAxis.Home(false);
  158. if (result)
  159. {
  160. _armHoming = true;
  161. }
  162. _armRetryTimes++;
  163. return false;
  164. }
  165. else
  166. {
  167. if (_armAxis.IsHomed && _armAxis.Status == RState.End)
  168. {
  169. _armRetryTimes = 0;
  170. _armHoming = false;
  171. return true;
  172. }
  173. return false;
  174. }
  175. }
  176. else
  177. {
  178. LOG.WriteLog(eEvent.ERR_SRD, _module, $"Arm Home Retry Home {_armRetryTimes + 1} times is over {MAX_ARM_HOME_RETRIES}");
  179. PostMsg(UnloadingMsg.Error);
  180. return false;
  181. }
  182. }
  183. }
  184. /// <summary>
  185. /// 检验Rotation home,发现失败则重试
  186. /// </summary>
  187. /// <param name="param"></param>
  188. /// <returns></returns>
  189. private bool CheckRotationHome()
  190. {
  191. if (_rotationAxis.IsHomed)
  192. {
  193. return true;
  194. }
  195. else
  196. {
  197. if (_rotationRetryTimes < MAX_ROTATION_HOME_RETRIES)
  198. {
  199. if (!_rotationHoming)
  200. {
  201. LOG.WriteLog(eEvent.INFO_SRD, _module, $"Rotation Home Retry Home {_rotationRetryTimes + 1} times");
  202. bool result = _rotationAxis.Home(false);
  203. if (result)
  204. {
  205. _rotationHoming = true;
  206. }
  207. _rotationRetryTimes++;
  208. return false;
  209. }
  210. else
  211. {
  212. if (_rotationAxis.IsHomed && _rotationAxis.Status == RState.End)
  213. {
  214. _rotationRetryTimes = 0;
  215. _rotationHoming = false;
  216. return true;
  217. }
  218. return false;
  219. }
  220. }
  221. else
  222. {
  223. LOG.WriteLog(eEvent.ERR_SRD, _module, $"Rotation Home Retry Home {_rotationRetryTimes + 1} times is over {MAX_ROTATION_HOME_RETRIES}");
  224. PostMsg(UnloadingMsg.Error);
  225. return false;
  226. }
  227. }
  228. }
  229. /// <summary>
  230. /// Check Wafer Present
  231. /// </summary>
  232. /// <param name="param"></param>
  233. /// <returns></returns>
  234. private bool CheckWaferPresent(object param)
  235. {
  236. if (_srdCommon.IsWaferPresence)
  237. {
  238. if (_srdCommon.WaferPresence != "WellPlaced")
  239. {
  240. PostMsg(UnloadingMsg.Error);
  241. LOG.WriteLog(eEvent.ERR_SRD, _module, "Wafer Presence is not WellPlaced");
  242. return false;
  243. }
  244. }
  245. else
  246. {
  247. LOG.WriteLog(eEvent.INFO_SRD, _module, "CheckWaferPresent has been ignored");
  248. }
  249. return true;
  250. }
  251. /// <summary>
  252. /// Open Door
  253. /// </summary>
  254. /// <param name="param"></param>
  255. /// <returns></returns>
  256. private bool OpenDoor(object param)
  257. {
  258. bool result = _srdCommon.DoorOpenAction("", null);
  259. if (!result)
  260. {
  261. PostMsg(UnloadingMsg.Error);
  262. }
  263. return result;
  264. }
  265. /// <summary>
  266. /// 检验DoorOpened
  267. /// </summary>
  268. /// <param name="param"></param>
  269. /// <returns></returns>
  270. private bool CheckDoorOpened(object param)
  271. {
  272. if (_srdCommon.Status == RState.Failed || _srdCommon.Status == RState.Timeout)
  273. {
  274. PostMsg(UnloadingMsg.Error);
  275. return false;
  276. }
  277. return _srdCommon.Status == RState.End && _srdCommon.CommonData.DoorOpened;
  278. }
  279. /// <summary>
  280. /// 关闭Chuck Vacuum,并检查Vacuum Level
  281. /// </summary>
  282. /// <param name="param"></param>
  283. /// <returns></returns>
  284. private bool ReleaseChuckVacuum(object param)
  285. {
  286. if (_srdCommon.IsWaferPresence)
  287. {
  288. bool result = _srdCommon.ChuckVacuumOffAction("", null);
  289. if (!result)
  290. {
  291. PostMsg(UnloadingMsg.Error);
  292. }
  293. return result;
  294. }
  295. else
  296. {
  297. LOG.WriteLog(eEvent.INFO_SRD, _module, "ReleaseChuckVacuum has been ignored");
  298. return true;
  299. }
  300. }
  301. /// <summary>
  302. /// 检查真空状态
  303. /// </summary>
  304. /// <param name="param"></param>
  305. /// <returns></returns>
  306. private bool CheckVacuum(object param)
  307. {
  308. if (_srdCommon.IsWaferPresence)
  309. {
  310. if (_srdCommon.Status == RState.Failed || _srdCommon.Status == RState.Timeout)
  311. {
  312. PostMsg(UnloadingMsg.Error);
  313. return false;
  314. }
  315. bool result = _srdCommon.Status == RState.End && _srdCommon.CommonData.ChuckVacuum;
  316. return result;
  317. }
  318. else
  319. {
  320. LOG.WriteLog(eEvent.INFO_SRD, _module, "CheckVacuum has been ignored");
  321. return true;
  322. }
  323. }
  324. #endregion
  325. /// <summary>
  326. /// 停止
  327. /// </summary>
  328. public void Stop()
  329. {
  330. base.Terminate();
  331. }
  332. public bool Check(int msg, out string reason, params object[] args)
  333. {
  334. reason = "";
  335. return false;
  336. }
  337. #region State Msg枚举
  338. public enum UnloadingState
  339. {
  340. None,
  341. Error,
  342. Unloading_Start,
  343. Unloading_Complete,
  344. Unloading_CheckRotationStopped,
  345. Unloading_WaferPresent,
  346. Unloading_OpenDoor,
  347. Unloading_CheckDoorOpened,
  348. Unloading_ReleaseChuckVacuum,
  349. Unloading_CheckVacuum
  350. }
  351. public enum UnloadingMsg
  352. {
  353. Init,
  354. Error,
  355. Unloading_Start,
  356. Unloading_Complete,
  357. CheckRoationStopped,
  358. WaferPresent,
  359. OpenDoor,
  360. ReleaseChuckVacuum,
  361. Abort
  362. }
  363. #endregion
  364. }
  365. }