EfemPickRoutine.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. using System;
  2. using Aitex.Core.Common;
  3. using Aitex.Core.RT.Event;
  4. using Aitex.Core.RT.Routine;
  5. using Aitex.Core.RT.SCCore;
  6. using Aitex.Core.Util;
  7. using Aitex.Sorter.Common;
  8. using MECF.Framework.Common.Equipment;
  9. using MECF.Framework.Common.Routine;
  10. using MECF.Framework.Common.Schedulers;
  11. using MECF.Framework.Common.SubstrateTrackings;
  12. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.PMs;
  13. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots;
  14. using MECF.Framework.RT.EquipmentLibrary.LogicUnits;
  15. using MECF.Framework.RT.ModuleLibrary.AlignerModules;
  16. using MECF.Framework.RT.ModuleLibrary.PMModules;
  17. using MECF.Framework.RT.ModuleLibrary.SystemModules;
  18. namespace JetEfemLib.Efems
  19. {
  20. public class EfemPickRoutine : ModuleRoutineBase, IStepRoutine
  21. {
  22. enum RoutineStep
  23. {
  24. CheckBeforePick,
  25. PickWafer,
  26. CheckBeforePick2,
  27. PickWafer2,
  28. PostTransfer,
  29. PrepareTransfer,
  30. PickExtend,
  31. PickRetract,
  32. LiftMove,
  33. End,
  34. }
  35. private int _pickTimeout;
  36. private ModuleName _source;
  37. private int _sourceSlot;
  38. private Hand _hand;
  39. private bool _autoHand;
  40. private EfemModule _robotModule;
  41. private ITransferTarget _target;
  42. private int _postTransferTimeout;
  43. private WaferSize _waferSize = WaferSize.WS0;
  44. public EfemPickRoutine(EfemModule robotModule) : base(ModuleName.EFEM.ToString())
  45. {
  46. Name = "Pick";
  47. _robotModule = robotModule;
  48. }
  49. public RState Start(params object[] objs)
  50. {
  51. if (!_robotModule.EfemDevice.IsInitialized)
  52. {
  53. EV.PostAlarmLog(Module, $"EFEM is not homed, please home it first");
  54. return RState.Failed;
  55. }
  56. _pickTimeout = SC.GetValue<int>("EFEM.EfemRobot.PickTimeout");
  57. Reset();
  58. if (_autoHand)
  59. {
  60. if (WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 0))
  61. {
  62. _hand = Hand.Blade1;
  63. }
  64. else if (WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 1))
  65. {
  66. _hand = Hand.Blade2;
  67. }
  68. else
  69. {
  70. EV.PostWarningLog(Module, $"Can not pick, Robot both arm has wafer");
  71. return RState.Failed;
  72. }
  73. }
  74. if (_hand == Hand.Both)
  75. {
  76. if (!SC.GetValueOrDefault<bool>("EFEM.EfemRobot.LowerBladeEnable"))
  77. {
  78. EV.PostAlarmLog(Module, $"Can not pick, Lower Blade is Disabled");
  79. return RState.Failed;
  80. }
  81. if (!SC.GetValueOrDefault<bool>("EFEM.EfemRobot.UpperBladeEnable"))
  82. {
  83. EV.PostAlarmLog(Module, $"Can not pick, Upper Blade is Disabled");
  84. return RState.Failed;
  85. }
  86. if (WaferManager.Instance.GetWafers(_source).Length < 2)
  87. {
  88. EV.PostWarningLog(Module, $"Can not pick use both arm, Only one slot at {_source}");
  89. return RState.Failed;
  90. }
  91. if (!WaferManager.Instance.CheckHasWafer(_source, _sourceSlot))
  92. {
  93. EV.PostWarningLog(Module, $"Can not pick, No wafer at {_source}, {_sourceSlot + 1}");
  94. return RState.Failed;
  95. }
  96. if (!WaferManager.Instance.CheckHasWafer(_source, _sourceSlot + 1))
  97. {
  98. EV.PostWarningLog(Module, $"Can not pick, No wafer at {_source}, {_sourceSlot + 1 + 1}");
  99. return RState.Failed;
  100. }
  101. if (!WaferManager.Instance.CheckNoWafer(Module, (int)Hand.Blade1))
  102. {
  103. EV.PostWarningLog(Module, $"Can not pick, Robot arm 1 has wafer");
  104. return RState.Failed;
  105. }
  106. if (!WaferManager.Instance.CheckNoWafer(Module, (int)Hand.Blade2))
  107. {
  108. EV.PostWarningLog(Module, $"Can not pick, Robot arm 2 has wafer");
  109. return RState.Failed;
  110. }
  111. }
  112. else
  113. {
  114. if (_hand == Hand.Blade1 && !SC.GetValueOrDefault<bool>("EFEM.EfemRobot.LowerBladeEnable"))
  115. {
  116. EV.PostAlarmLog(Module, $"Can not pick, Lower Blade is Disabled");
  117. return RState.Failed;
  118. }
  119. if (_hand == Hand.Blade2 && !SC.GetValueOrDefault<bool>("EFEM.EfemRobot.UpperBladeEnable"))
  120. {
  121. EV.PostAlarmLog(Module, $"Can not pick, Upper Blade is Disabled");
  122. return RState.Failed;
  123. }
  124. if (!WaferManager.Instance.CheckHasWafer(_source, _sourceSlot))
  125. {
  126. EV.PostWarningLog(Module, $"Can not pick, No wafer at {_source}, {_sourceSlot + 1}");
  127. return RState.Failed;
  128. }
  129. if (!WaferManager.Instance.CheckNoWafer(Module, (int)_hand))
  130. {
  131. EV.PostWarningLog(Module, $"Can not pick, Robot arm {(int)_hand + 1} has wafer");
  132. return RState.Failed;
  133. }
  134. }
  135. _waferSize = WaferManager.Instance.GetWafer(_source, _sourceSlot).Size;
  136. Notify($"Start, Pick from {_source} slot {_sourceSlot + 1}, by {_hand}");
  137. return Runner.Start(ModuleName.EFEM.ToString(), Name);
  138. }
  139. public void Init(ModuleName source, int slot, Hand hand)
  140. {
  141. _autoHand = false;
  142. _source = source;
  143. _sourceSlot = slot;
  144. _hand = hand;
  145. if (ModuleHelper.IsPm(source))
  146. _postTransferTimeout = SC.GetValue<int>($"PM.PostTransferTimeout");
  147. _target = EquipmentManager.Modules[source] as ITransferTarget;
  148. }
  149. public void Init(ModuleName source, int slot)
  150. {
  151. _autoHand = true;
  152. _source = source;
  153. _sourceSlot = slot;
  154. if (ModuleHelper.IsPm(source))
  155. _postTransferTimeout = SC.GetValue<int>($"PM.PostTransferTimeout");
  156. _target = EquipmentManager.Modules[source] as ITransferTarget;
  157. }
  158. public void Abort()
  159. {
  160. if (_target != null)
  161. {
  162. _target.NoteTransferStop(ModuleName.EfemRobot, Hand.Blade1, 0, EnumTransferType.Pick);
  163. }
  164. _target = null;
  165. Notify("Abort");
  166. }
  167. public RState Monitor()
  168. {
  169. if (_hand == Hand.Both)
  170. {
  171. Runner.Run(RoutineStep.PrepareTransfer, PrepareTransfer, CheckPrepareTransfer, _postTransferTimeout * 1000)
  172. .Wait(RoutineStep.CheckBeforePick, HOFs.Apply(CheckBeforePick, _source, _sourceSlot, Hand.Blade1))
  173. .Run(RoutineStep.PickWafer, HOFs.Apply(PickWafer, _source, _sourceSlot, Hand.Blade1), CheckPickWafer, _pickTimeout * 1000)
  174. .Wait(RoutineStep.CheckBeforePick2, HOFs.Apply(CheckBeforePick, _source, _sourceSlot + 1, Hand.Blade2))
  175. .Run(RoutineStep.PickWafer2, HOFs.Apply(PickWafer, _source, _sourceSlot + 1, Hand.Blade2), CheckPickWafer, _pickTimeout * 1000)
  176. .Run(RoutineStep.PostTransfer, PostTransfer, CheckPostTransfer, _postTransferTimeout * 1000)
  177. .Run(RoutineStep.LiftMove, LiftMove, CheckLiftMove, _pickTimeout * 1000)
  178. .End(RoutineStep.End, NullFun, _delay_0s);
  179. }
  180. else
  181. {
  182. Runner.Run(RoutineStep.PrepareTransfer, PrepareTransfer, CheckPrepareTransfer, _postTransferTimeout * 1000)
  183. .Wait(RoutineStep.CheckBeforePick, HOFs.Apply(CheckBeforePick, _source, _sourceSlot, _hand))
  184. .Run(RoutineStep.PickWafer, HOFs.Apply(PickWafer, _source, _sourceSlot, _hand), CheckPickWafer, _pickTimeout * 1000)
  185. .Run(RoutineStep.PostTransfer, PostTransfer, CheckPostTransfer, _postTransferTimeout * 1000)
  186. .Run(RoutineStep.LiftMove, LiftMove, CheckLiftMove, _pickTimeout * 1000)
  187. .End(RoutineStep.End, NullFun, _delay_0s);
  188. }
  189. if (Runner.Status == RState.End)
  190. {
  191. _target.NoteTransferStop(ModuleName.EfemRobot, Hand.Blade1, 0, EnumTransferType.Pick);
  192. Notify($"Finish, Pick from {_source} slot {_sourceSlot + 1}, by {_hand}");
  193. }
  194. return Runner.Status;
  195. }
  196. bool PrepareTransfer()
  197. {
  198. if(ModuleHelper.IsPm(_source) && !_target.CheckReadyForTransfer(ModuleName.EfemRobot, _hand, _sourceSlot, EnumTransferType.Pick, out _))
  199. {
  200. var pm = _target as PMModuleBase;
  201. var type = EnumTransferType.Pick;
  202. Notify($"{pm.Name} Prepare transfer ");
  203. if (!pm.PrepareTransfer(ModuleName.EfemRobot, Hand.Blade1, new int[] { 0 }, type, 0, 0, false, out string reason))
  204. {
  205. Stop(reason);
  206. return false;
  207. }
  208. return true;
  209. }
  210. return true;
  211. }
  212. bool CheckPrepareTransfer()
  213. {
  214. if (ModuleHelper.IsPm(_source) && !_target.CheckReadyForTransfer(ModuleName.EfemRobot, _hand, _sourceSlot, EnumTransferType.Pick, out _))
  215. {
  216. var pm = _target as PMModuleBase;
  217. return !pm.IsError && pm.IsReady && pm.IsPrepareTransferReady(EnumTransferType.Pick, (EnumDualPM)(_sourceSlot + 1), _waferSize); ;
  218. }
  219. return true;
  220. }
  221. bool CheckBeforePick(ModuleName source, int slot, Hand blade)
  222. {
  223. Notify("Check pick is enabled");
  224. string reason = string.Empty;
  225. if (!_target.CheckReadyForTransfer(ModuleName.EfemRobot, _hand, _sourceSlot, EnumTransferType.Pick, out reason))
  226. {
  227. Stop(reason);
  228. return false;
  229. }
  230. if (blade == Hand.Blade1)
  231. {
  232. if (!WaferManager.Instance.CheckHasWafer(source, slot))
  233. {
  234. Stop("Source no wafer");
  235. return false;
  236. }
  237. if (!WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 0))
  238. {
  239. Stop("Blade has wafer");
  240. return false;
  241. }
  242. }
  243. else if (blade == Hand.Blade2)
  244. {
  245. if (!WaferManager.Instance.CheckHasWafer(source, slot))
  246. {
  247. Stop("Source no wafer");
  248. return false;
  249. }
  250. if (!WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 1))
  251. {
  252. Stop("Blade has wafer");
  253. return false;
  254. }
  255. }
  256. else
  257. {
  258. for (int i = 0; i < 2; i++)
  259. {
  260. if (!WaferManager.Instance.CheckHasWafer(source, slot + i))
  261. {
  262. Stop("Source no wafer");
  263. return false;
  264. }
  265. if (!WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, i))
  266. {
  267. Stop("Blade has wafer");
  268. return false;
  269. }
  270. }
  271. }
  272. return true;
  273. }
  274. bool PickWafer(ModuleName chamber, int slot, Hand hand)
  275. {
  276. Notify("robot execute pick command");
  277. _target.NoteTransferStart(ModuleName.EfemRobot, hand, slot, EnumTransferType.Pick);
  278. string reason;
  279. if (!_robotModule.RobotDevice.Pick(chamber, hand, slot, out reason))
  280. {
  281. Stop(reason);
  282. return false;
  283. }
  284. return true;
  285. }
  286. bool CheckPickWafer()
  287. {
  288. return !_robotModule.RobotDevice.IsError && _robotModule.RobotDevice.IsIdle;
  289. }
  290. bool PostTransfer()
  291. {
  292. if(ModuleHelper.IsPm(_source))
  293. {
  294. var pm = _target as PMModuleBase;
  295. var type = EnumTransferType.Pick;
  296. Notify($"{pm.Name} post transfer ");
  297. if (!pm.PostTransfer(ModuleName.EfemRobot, _hand, new int[] { _sourceSlot }, type, out string reason))
  298. {
  299. Stop(reason);
  300. return false;
  301. }
  302. return true;
  303. }
  304. return true;
  305. }
  306. bool CheckPostTransfer()
  307. {
  308. if (ModuleHelper.IsPm(_source))
  309. {
  310. var pm = _target as PMModuleBase;
  311. return !pm.IsError && pm.IsReady;
  312. }
  313. return true;
  314. }
  315. bool LiftMove()
  316. {
  317. if(ModuleHelper.IsCooling(_source) || ModuleHelper.IsAligner(_source))
  318. {
  319. var aligner = _target as AlignerModuleBase;
  320. Notify($"{aligner.Name} lift pin up ");
  321. //if (!pm.ChamberLiftPin.MoveUp(out string reason))
  322. //{
  323. // Stop(reason);
  324. // return false;
  325. //}
  326. return aligner.Lift(true);
  327. }
  328. return true;
  329. }
  330. bool CheckLiftMove()
  331. {
  332. if (ModuleHelper.IsCooling(_source) || ModuleHelper.IsAligner(_source))
  333. {
  334. var aligner = _target as AlignerModuleBase;
  335. return aligner.IsReady;
  336. }
  337. return true;
  338. }
  339. }
  340. }