SRDAWCCycleRoutine.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. using Aitex.Core.Common;
  2. using Aitex.Core.RT.Device;
  3. using Aitex.Core.RT.Log;
  4. using Aitex.Core.RT.Routine;
  5. using Aitex.Core.Util;
  6. using Aitex.Sorter.Common;
  7. using CyberX8_Core;
  8. using CyberX8_RT.Devices.EFEM;
  9. using MECF.Framework.Common.Equipment;
  10. using MECF.Framework.Common.Schedulers;
  11. using MECF.Framework.Common.SubstrateTrackings;
  12. using System;
  13. using System.Collections.Generic;
  14. using System.Runtime.InteropServices;
  15. namespace CyberX8_RT.Modules.SRD
  16. {
  17. internal class SRDAWCCycleRoutine : ModuleRoutineBase, IRoutine
  18. {
  19. private enum AWCStep
  20. {
  21. Ready,
  22. Speed50Percent,
  23. WaitSpeed50Percent,
  24. Speed80Percent,
  25. WaitSpeed80Percent,
  26. PickfromSRD,
  27. WaitPickfromSRD,
  28. LoopDelayPickSRD,
  29. PlacetoAligner0,
  30. WaitPlacetoAligner0,
  31. LoopDelayPlaceAligner0,
  32. Align0Degree,
  33. WaitAlign0Degree,
  34. LoopDelayAligner0,
  35. PickfromAligner0,
  36. WaitPickfromAligner0,
  37. LoopDelayPickAligner0,
  38. PlacetoAligner120,
  39. WaitPlacetoAligner120,
  40. LoopDelayPlaceAligner120,
  41. Align120Degree,
  42. WaitAlign120Degree,
  43. LoopDelayAligner120,
  44. PickfromAligner120,
  45. WaitPickfromAligner120,
  46. LoopDelayPickAligner120,
  47. PlacetoAligner240,
  48. WaitPlacetoAligner240,
  49. LoopDelayPlaceAligner240,
  50. Align240Degree,
  51. WaitAlign240Degree,
  52. LoopDelayAligner240,
  53. PickfromAligner240,
  54. WaitPickfromAligner240,
  55. LoopDelayPickAligner240,
  56. PlacetoSRD,
  57. WaitPlacetoSRD,
  58. LoopDelayPlaceSRD,
  59. HomeSRD,
  60. WaitHomeSRD,
  61. CycleEnd,
  62. End
  63. }
  64. #region 内部变量
  65. /// <summary>
  66. /// 次数
  67. /// </summary>
  68. private int _cycleCount = 0;
  69. /// <summary>
  70. /// 超时时间
  71. /// </summary>
  72. private int _timeOut = 2000;
  73. /// <summary>
  74. /// Efem Enitity
  75. /// </summary>
  76. private EfemEntity _efemEntity;
  77. /// <summary>
  78. /// Efem Device
  79. /// </summary>
  80. private EfemBase _efemDevice;
  81. /// <summary>
  82. /// SRD Module Name
  83. /// </summary>
  84. private ModuleName _srdModuleName;
  85. /// <summary>
  86. /// SRD Entity
  87. /// </summary>
  88. private SRDEntity _srdEntity;
  89. #endregion
  90. #region 属性
  91. /// <summary>
  92. /// 当前子状态机
  93. /// </summary>
  94. public string CurrentStateMachine
  95. {
  96. get { return Runner.CurrentStep.ToString(); }
  97. }
  98. #endregion
  99. /// <summary>
  100. /// 构造函数
  101. /// </summary>
  102. /// <param name="module"></param>
  103. public SRDAWCCycleRoutine(ModuleName module) : base(module)
  104. {
  105. Name = "AWCCycle";
  106. _srdModuleName = module;
  107. }
  108. /// <summary>
  109. /// Abort
  110. /// </summary>
  111. public void Abort()
  112. {
  113. Runner.Stop("SRD AWC Cycle Abort");
  114. }
  115. /// <summary>
  116. /// Monitor
  117. /// </summary>
  118. /// <returns></returns>
  119. public RState Monitor()
  120. {
  121. Runner.LoopStart(AWCStep.Ready, "AWC Cycle", _cycleCount, NullFun, CheckReady, _timeOut)
  122. //Robot speed 50% and pick wafer from SRD
  123. .LoopRun(AWCStep.Speed50Percent, ()=> { return RobotSpeed(50); }, _delay_2s)
  124. .LoopRunWithStopStatus(AWCStep.WaitSpeed50Percent, CheckOperationComplete, CheckOperationError)
  125. .LoopRun(AWCStep.PickfromSRD, PickFromSRD, _delay_50ms)
  126. .LoopRunWithStopStatus(AWCStep.WaitPickfromSRD, CheckOperationComplete, CheckOperationError)
  127. .LoopDelay(AWCStep.LoopDelayPickSRD, _delay_2s)
  128. //Robot place wafer to Aligner, Align wafer 0 deg, pick from Aligner
  129. .LoopRun(AWCStep.PlacetoAligner0, PlacetoAligner, _delay_50ms)
  130. .LoopRunWithStopStatus(AWCStep.WaitPlacetoAligner0, CheckOperationComplete, CheckOperationError)
  131. .LoopDelay(AWCStep.LoopDelayPlaceAligner0, _delay_2s)
  132. .LoopRun(AWCStep.Align0Degree, () => { return Align(0); }, _delay_50ms)
  133. .LoopRunWithStopStatus(AWCStep.WaitAlign0Degree, CheckOperationComplete, CheckOperationError)
  134. .LoopDelay(AWCStep.LoopDelayAligner0, _delay_2s)
  135. .LoopRun(AWCStep.PickfromAligner0, PickfromAligner, _delay_50ms)
  136. .LoopRunWithStopStatus(AWCStep.WaitPickfromAligner0, CheckOperationComplete, CheckOperationError)
  137. .LoopDelay(AWCStep.LoopDelayPickAligner0, _delay_2s)
  138. //Robot place wafer to Aligner, Align wafer 120 deg, pick from Aligner
  139. .LoopRun(AWCStep.PlacetoAligner120, PlacetoAligner, _delay_50ms)
  140. .LoopRunWithStopStatus(AWCStep.WaitPlacetoAligner120, CheckOperationComplete, CheckOperationError)
  141. .LoopDelay(AWCStep.LoopDelayPlaceAligner120, _delay_2s)
  142. .LoopRun(AWCStep.Align120Degree, () => { return Align(120); }, _delay_50ms)
  143. .LoopRunWithStopStatus(AWCStep.WaitAlign120Degree, CheckOperationComplete, CheckOperationError)
  144. .LoopDelay(AWCStep.LoopDelayAligner120, _delay_2s)
  145. .LoopRun(AWCStep.PickfromAligner120, PickfromAligner, _delay_50ms)
  146. .LoopRunWithStopStatus(AWCStep.WaitPickfromAligner120, CheckOperationComplete, CheckOperationError)
  147. .LoopDelay(AWCStep.LoopDelayPickAligner120, _delay_2s)
  148. //Robot place wafer to Aligner, Align wafer 240 deg, pick from Aligner
  149. .LoopRun(AWCStep.PlacetoAligner240, PlacetoAligner, _delay_50ms)
  150. .LoopRunWithStopStatus(AWCStep.WaitPlacetoAligner240, CheckOperationComplete, CheckOperationError)
  151. .LoopDelay(AWCStep.LoopDelayPlaceAligner240, _delay_2s)
  152. .LoopRun(AWCStep.Align240Degree, () => { return Align(240); }, _delay_50ms)
  153. .LoopRunWithStopStatus(AWCStep.WaitAlign240Degree, CheckOperationComplete, CheckOperationError)
  154. .LoopDelay(AWCStep.LoopDelayAligner240, _delay_2s)
  155. .LoopRun(AWCStep.PickfromAligner240, PickfromAligner, _delay_50ms)
  156. .LoopRunWithStopStatus(AWCStep.WaitPickfromAligner240, CheckOperationComplete, CheckOperationError)
  157. .LoopDelay(AWCStep.LoopDelayPickAligner240, _delay_2s)
  158. //Robot speed80% place wafer to SRD
  159. .LoopRun(AWCStep.Speed80Percent, () => { return RobotSpeed(80); }, _delay_2s)
  160. .LoopRunWithStopStatus(AWCStep.WaitSpeed80Percent, CheckOperationComplete, CheckOperationError)
  161. .LoopRun(AWCStep.PlacetoSRD, PlacetoSRD, _delay_50ms)
  162. .LoopRunWithStopStatus(AWCStep.WaitPlacetoSRD, CheckOperationComplete, CheckOperationError)
  163. .LoopDelay(AWCStep.LoopDelayPlaceSRD, _delay_2s)
  164. .LoopRun(AWCStep.HomeSRD, HomeSRD, _delay_50ms)
  165. .LoopRunWithStopStatus(AWCStep.WaitHomeSRD, CheckHomeSRDComplete, CheckHomeSRDError)
  166. .LoopEnd(AWCStep.CycleEnd, NullFun, CheckOperationComplete)
  167. .End(AWCStep.End, NullFun, _delay_1ms);
  168. return Runner.Status;
  169. }
  170. /// <summary>
  171. /// 检验Ready状态
  172. /// </summary>
  173. /// <returns></returns>
  174. private bool CheckReady()
  175. {
  176. //检查是否有Wafer
  177. if (!WaferManager.Instance.CheckHasWafer(_srdModuleName, 0))
  178. {
  179. LOG.Write(eEvent.ERR_SRD, Module, $"{Module} don't have wafer, can't do AWC Cycle");
  180. return false;
  181. }
  182. _srdEntity = Singleton<RouteManager>.Instance.GetModule<SRDEntity>(Module.ToString());
  183. //检查SRD Home
  184. if (!_srdEntity.IsHomed)
  185. {
  186. LOG.Write(eEvent.ERR_SRD, Module, $"{Module} is not homed, can't do AWC Cycle. Please home it first");
  187. return false;
  188. }
  189. //检查SRD门是否关闭
  190. if (_srdEntity.IsSrdDoorClosed)
  191. {
  192. LOG.Write(eEvent.ERR_SRD, Module, $"{Module} door closed, can't do AWC Cycle");
  193. return false;
  194. }
  195. //检查SRD真空是否开启
  196. if (!_srdEntity.IsSrdChuckVacuum)
  197. {
  198. LOG.Write(eEvent.ERR_SRD, Module, $"{Module} Vacuum on, can't do AWC Cycle");
  199. return false;
  200. }
  201. //检查EFEM状态
  202. if (_efemEntity.IsIdle) return true;
  203. return false;
  204. }
  205. /// <summary>
  206. /// Robot speed
  207. /// </summary>
  208. /// <returns></returns>
  209. private bool RobotSpeed(int speed)
  210. {
  211. _efemEntity.CheckToPostMessage<EfemEntity.STATE, EfemEntity.MSG>(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EFEM.ToString(), (int)EfemEntity.MSG.SetRobotSpeed, speed);
  212. return true;
  213. }
  214. /// <summary>
  215. /// Pick from SRD
  216. /// </summary>
  217. /// <returns></returns>
  218. private bool PickFromSRD()
  219. {
  220. Queue<MoveItem> moveItems = new Queue<MoveItem>();
  221. MoveItem moveItem = new MoveItem(_srdModuleName, 0, ModuleName.EfemRobot, 0, Hand.Blade1);
  222. moveItems.Enqueue(moveItem);
  223. return _efemEntity.CheckToPostMessage<EfemEntity.STATE, EfemEntity.MSG>(eEvent.ERR_EFEM_COMMON_FAILED, "EFEM", (int)EfemEntity.MSG.Pick, moveItems);
  224. }
  225. /// <summary>
  226. /// Place to SRD
  227. /// </summary>
  228. /// <returns></returns>
  229. private bool PlacetoSRD()
  230. {
  231. Queue<MoveItem> moveItems = new Queue<MoveItem>();
  232. MoveItem moveItem = new MoveItem(ModuleName.EfemRobot, 0, _srdModuleName, 0, Hand.Blade1);
  233. moveItems.Enqueue(moveItem);
  234. return _efemEntity.CheckToPostMessage<EfemEntity.STATE, EfemEntity.MSG>(eEvent.ERR_EFEM_COMMON_FAILED, "EFEM", (int)EfemEntity.MSG.Place, moveItems);
  235. }
  236. /// <summary>
  237. /// Pick from Aligner
  238. /// </summary>
  239. /// <returns></returns>
  240. private bool PickfromAligner()
  241. {
  242. Queue<MoveItem> moveItems = new Queue<MoveItem>();
  243. MoveItem moveItem = new MoveItem(ModuleName.Aligner1, 0, ModuleName.EfemRobot, 0, Hand.Blade1);
  244. moveItems.Enqueue(moveItem);
  245. return _efemEntity.CheckToPostMessage<EfemEntity.STATE, EfemEntity.MSG>(eEvent.ERR_EFEM_COMMON_FAILED, "EFEM", (int)EfemEntity.MSG.Pick, moveItems);
  246. }
  247. /// <summary>
  248. /// Place to Aligner
  249. /// </summary>
  250. /// <returns></returns>
  251. private bool PlacetoAligner()
  252. {
  253. Queue<MoveItem> moveItems = new Queue<MoveItem>();
  254. MoveItem moveItem = new MoveItem(ModuleName.EfemRobot, 0, ModuleName.Aligner1, 0, Hand.Blade1);
  255. moveItems.Enqueue(moveItem);
  256. return _efemEntity.CheckToPostMessage<EfemEntity.STATE, EfemEntity.MSG>(eEvent.ERR_EFEM_COMMON_FAILED, "EFEM", (int)EfemEntity.MSG.Place, moveItems);
  257. }
  258. /// <summary>
  259. /// Align to target degree
  260. /// </summary>
  261. /// <param name="degree"></param>
  262. /// <returns></returns>
  263. private bool Align(int degree)
  264. {
  265. return _efemEntity.CheckToPostMessage<EfemEntity.STATE, EfemEntity.MSG>(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EFEM.ToString(), (int)EfemEntity.MSG.Align, ModuleName.Aligner1, 0, degree); ;
  266. }
  267. /// <summary>
  268. /// 检查Operation是否完成
  269. /// </summary>
  270. /// <returns></returns>
  271. private bool CheckOperationComplete()
  272. {
  273. if (_efemEntity.IsIdle && _efemEntity.RobotStatus == RState.End)
  274. {
  275. //LOG.WriteLog(eEvent.ERR_PREWET, _srdModuleName.ToString(), $"Efem RSstate is {_efemEntity.RobotStatus}");
  276. return true;
  277. }
  278. return false;
  279. }
  280. /// <summary>
  281. /// 检查是Operation是否报错
  282. /// </summary>
  283. /// <returns></returns>
  284. private bool CheckOperationError()
  285. {
  286. if (_efemEntity.IsError || _efemEntity.RobotStatus == RState.Failed || _efemEntity.RobotStatus == RState.Timeout)
  287. {
  288. _srdEntity.SetIsAWCCycling(false);
  289. LOG.WriteLog(eEvent.ERR_SRD, _srdModuleName.ToString(), $"Step {Runner.CurrentStep} is Error");
  290. return true;
  291. }
  292. return false;
  293. }
  294. /// <summary>
  295. /// Home SRD
  296. /// </summary>
  297. /// <returns></returns>
  298. private bool HomeSRD()
  299. {
  300. return _srdEntity.CheckToPostMessage<SRDState, SRDMSG>(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.HomeAll);
  301. }
  302. /// <summary>
  303. /// 检查SRD Home是否完成
  304. /// </summary>
  305. /// <returns></returns>
  306. private bool CheckHomeSRDComplete()
  307. {
  308. if(_srdEntity.IsHomed) return true;
  309. return false;
  310. }
  311. /// <summary>
  312. /// 检查SRD Home是否报错
  313. /// </summary>
  314. /// <returns></returns>
  315. private bool CheckHomeSRDError()
  316. {
  317. if (_srdEntity.IsError)
  318. {
  319. _srdEntity.SetIsAWCCycling(false);
  320. LOG.WriteLog(eEvent.ERR_SRD, _srdModuleName.ToString(), $"Step {Runner.CurrentStep} is Error");
  321. return true;
  322. }
  323. return false;
  324. }
  325. /// <summary>
  326. /// Start
  327. /// </summary>
  328. /// <param name="objs"></param>
  329. /// <returns></returns>
  330. public RState Start(params object[] objs)
  331. {
  332. _cycleCount = (int)objs[0];
  333. _efemEntity = Singleton<RouteManager>.Instance.GetModule<EfemEntity>(ModuleName.EFEM.ToString());
  334. _efemDevice = _efemEntity.EfemDevice;
  335. Runner.Start(Module, Name);
  336. return RState.Running;
  337. }
  338. }
  339. }