ReturnAllWafer.cs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Aitex.Core.Common;
  5. using Aitex.Core.RT.Event;
  6. using Aitex.Core.RT.Routine;
  7. using Aitex.Core.RT.SCCore;
  8. using Aitex.Sorter.Common;
  9. using MECF.Framework.Common.Equipment;
  10. using MECF.Framework.Common.Schedulers;
  11. using MECF.Framework.Common.SubstrateTrackings;
  12. using MECF.Framework.RT.ModuleLibrary.SystemModules;
  13. using EfemDualSchedulerLib.Schedulers;
  14. using Aitex.Core.Util;
  15. namespace EfemDualSchedulerLib
  16. {
  17. public class ReturnAllWafer : SchedulerModuleFactory, IRoutine
  18. {
  19. private bool _needCooling;
  20. private int _coolingTime;
  21. Dictionary<ModuleName, int> _checkPosition = new Dictionary<ModuleName, int>()
  22. {
  23. {ModuleName.EfemRobot, 2},
  24. {ModuleName.Aligner1, 1},
  25. {ModuleName.Aligner2, 1},
  26. {ModuleName.Cooling1, 1},
  27. {ModuleName.Cooling2, 1},
  28. {ModuleName.LLA, 8},
  29. {ModuleName.LLB, 8},
  30. {ModuleName.TMRobot, 2},
  31. {ModuleName.PMA, 2},
  32. {ModuleName.PMB, 2},
  33. };
  34. private List<SchedulerPM> _lstPms = new List<SchedulerPM>();
  35. private List<SchedulerLoadPort> _lstLps = new List<SchedulerLoadPort>();
  36. private List<SchedulerLoadLock> _lstLls = new List<SchedulerLoadLock>();
  37. private List<SchedulerAligner> _lstAligners = new List<SchedulerAligner>();
  38. private List<SchedulerAligner> _lstCoolings = new List<SchedulerAligner>();
  39. private R_TRIG _trigLLReturnWafer = new R_TRIG();
  40. private R_TRIG _trigLLNoInstall = new R_TRIG();
  41. Queue<Action> tmRobotActions = new Queue<Action>() { };
  42. public ReturnAllWafer(EquipmentManager equipment) : base()
  43. {
  44. _checkPosition.Where(p => p.Key != ModuleName.EfemRobot && p.Key != ModuleName.TMRobot && !SC.GetValueOrDefault<bool>($"System.SetUp.{p.Key.ToString()}.IsInstalled"))
  45. .ToList().ForEach(p => _checkPosition.Remove(p.Key));
  46. if (_checkPosition.ContainsKey(ModuleName.TMRobot) && SC.IsDoubleFork) _checkPosition[ModuleName.TMRobot] = 4;
  47. if (SC.GetValueOrDefault<bool>("System.SetUp.PMA.IsInstalled"))
  48. _lstPms.Add(_pm1);
  49. if (SC.GetValueOrDefault<bool>("System.SetUp.PMB.IsInstalled"))
  50. _lstPms.Add(_pm2);
  51. //if (SC.GetValueOrDefault<bool>("System.SetUp.PMC.IsInstalled"))
  52. // _lstPms.Add(_pm3);
  53. if (SC.GetValueOrDefault<bool>("System.SetUp.LLA.IsInstalled"))
  54. _lstLls.Add(_loadlockA);
  55. if (SC.GetValueOrDefault<bool>("System.SetUp.LLB.IsInstalled"))
  56. _lstLls.Add(_loadlockB);
  57. if (SC.GetValueOrDefault<bool>("System.SetUp.Aligner1.IsInstalled"))
  58. _lstAligners.Add(_aligner1);
  59. if (SC.GetValueOrDefault<bool>("System.SetUp.Aligner2.IsInstalled"))
  60. _lstAligners.Add(_aligner2);
  61. if (SC.GetValueOrDefault<bool>("System.SetUp.Cooling1.IsInstalled"))
  62. _lstCoolings.Add(_cooling1);
  63. if (SC.GetValueOrDefault<bool>("System.SetUp.Cooling2.IsInstalled"))
  64. _lstCoolings.Add(_cooling2);
  65. if (SC.GetValueOrDefault<bool>("System.SetUp.LP1.IsInstalled"))
  66. _lstLps.Add(_lp1);
  67. if (SC.GetValueOrDefault<bool>("System.SetUp.LP2.IsInstalled"))
  68. _lstLps.Add(_lp2);
  69. if (SC.GetValueOrDefault<bool>("System.SetUp.LP3.IsInstalled"))
  70. _lstLps.Add(_lp3);
  71. tmRobotActions.Enqueue(MonitorTMRobotPMATask);
  72. tmRobotActions.Enqueue(MonitorTMRobotPMBTask);
  73. tmRobotActions.Enqueue(MonitorTMRobotLoadLockTask);
  74. }
  75. public Result Start(params object[] objs)
  76. {
  77. if (objs.Length > 1)
  78. {
  79. _needCooling = (bool)objs[0];
  80. _coolingTime = (int)objs[1] > 1 ? (int)objs[1] : 1;
  81. }
  82. foreach (var positions in _checkPosition)
  83. {
  84. for (int i = 0; i < positions.Value; i++)
  85. {
  86. WaferInfo wafer = WaferManager.Instance.GetWafer(positions.Key, i);
  87. if (!wafer.IsEmpty)
  88. {
  89. ModuleName originLoadPort = (ModuleName)wafer.OriginStation;
  90. if (!ModuleHelper.IsLoadPort(originLoadPort))
  91. {
  92. EV.PostWarningLog("System", $"Wafer {positions.Key}.{i + 1} can not return, origin is not LP");
  93. return Result.FAIL;
  94. }
  95. if (wafer.Status == WaferStatus.Dummy)
  96. {
  97. EV.PostWarningLog("System", $"Wafer {positions.Key}.{i + 1} can not return, wafer is dummy");
  98. return Result.FAIL;
  99. }
  100. if (WaferManager.Instance.CheckHasWafer(originLoadPort, wafer.OriginSlot))
  101. {
  102. EV.PostWarningLog("System", $"Wafer {positions.Key}.{i + 1} can not return, origin has wafer");
  103. return Result.FAIL;
  104. }
  105. if (!(GetModule(originLoadPort.ToString()) as SchedulerLoadPort).IsReadyForPlace(ModuleName.EfemRobot, Hand.Blade1, wafer.OriginSlot))
  106. {
  107. EV.PostWarningLog("System", $"{originLoadPort} not ready to place Wafer");
  108. return Result.FAIL;
  109. }
  110. EV.PostInfoLog("System", $"Wafer return, {positions.Key}.{i + 1}=>{(ModuleName)wafer.OriginStation}.{wafer.OriginSlot + 1}");
  111. }
  112. }
  113. }
  114. _trigLLReturnWafer.RST = true;
  115. _trigLLNoInstall.RST = true;
  116. return Result.RUN;
  117. }
  118. public Result Monitor()
  119. {
  120. MonitorModuleTasks();
  121. if (MonitorTaskDone())
  122. {
  123. return Result.DONE;
  124. }
  125. return Result.RUN;
  126. }
  127. public void Clear()
  128. {
  129. }
  130. public void Abort()
  131. {
  132. _tmRobot?.ResetTask();
  133. _efem?.ResetTask();
  134. foreach (var pm in _lstPms)
  135. {
  136. pm.ResetTask();
  137. }
  138. foreach (var lp in _lstLps)
  139. {
  140. lp.ResetTask();
  141. }
  142. }
  143. public Result MonitorModuleTasks()
  144. {
  145. MonitorPMTask();
  146. MonitorLoadLockTask();
  147. MonitorCoolingTask();
  148. MonitorTMRobotTask();
  149. MonitorEfemRobotTask();
  150. return Result.RUN;
  151. }
  152. private void MonitorTMRobotTask()
  153. {
  154. if (!_tmRobot.IsAvailable)
  155. return;
  156. //_tmRobot is idle, release all the target
  157. foreach (var ll in _lstLls)
  158. {
  159. if (ll.IsWaitTransfer(ModuleName.TMRobot))
  160. ll.StopWaitTransfer(ModuleName.TMRobot);
  161. }
  162. foreach (var pm in _lstPms)
  163. {
  164. if (pm.IsWaitTransfer(ModuleName.TMRobot))
  165. pm.StopWaitTransfer(ModuleName.TMRobot);
  166. }
  167. if (!_tmRobot.IsAvailable)
  168. return;
  169. var act = tmRobotActions.Peek();
  170. act.Invoke();
  171. if (!_tmRobot.IsAvailable)
  172. return;
  173. if (act == MonitorTMRobotLoadLockTask && _lstLls.Any(x => !x.IsAvailable))
  174. return;
  175. tmRobotActions.Enqueue(tmRobotActions.Dequeue());
  176. //MonitorTMRobotPMATask();
  177. //if (!_tmRobot.IsAvailable)
  178. // return;
  179. //MonitorTMRobotPMBTask();
  180. //if (!_tmRobot.IsAvailable)
  181. // return;
  182. //MonitorTMRobotLoadLockTask();
  183. }
  184. private bool CheckReturnWaferByModule(ModuleName currentName)
  185. {
  186. var bufferIndex = SC.GetValueOrDefault<int>("System.Scheduler.ReturnWaferPath");
  187. const int enumOffset = 29;
  188. if (bufferIndex > 0)
  189. {
  190. ModuleName targetModule = (ModuleName)Enum.Parse(typeof(ModuleName), (bufferIndex + enumOffset).ToString());
  191. _trigLLNoInstall.CLK = !SC.GetValueOrDefault<bool>($"System.SetUp.{targetModule}.IsInstalled");
  192. if (_trigLLNoInstall.Q)
  193. {
  194. EV.PostWarningLog("System", $"Wafer can not return by {targetModule}, because of the {targetModule} is not installed");
  195. }
  196. if (_trigLLNoInstall.CLK)
  197. {
  198. return false;
  199. }
  200. _trigLLReturnWafer.CLK = targetModule != currentName;
  201. if(_trigLLReturnWafer.Q && !_lstLls.Any(p => p.Module == targetModule))
  202. {
  203. EV.PostWarningLog("System", $"Wafer can not return by {currentName}, because of the {currentName} is not set up ");
  204. }
  205. if(_trigLLReturnWafer.CLK)
  206. {
  207. return false;
  208. }
  209. }
  210. return true;
  211. }
  212. private void MonitorTMRobotLoadLockTask()
  213. {
  214. if (!_tmRobot.IsAvailable)
  215. return;
  216. if (SC.IsDoubleFork && _lstLls.Any(x => !x.IsAvailable))
  217. return;
  218. //place to loadlock
  219. {
  220. bool blade1HasWafer = _tmRobot.Blade1Enable && Converter.MapBladeToSlots(Hand.Blade1).Any(p=>WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, p));
  221. bool blade2HasWafer = _tmRobot.Blade2Enable && Converter.MapBladeToSlots(Hand.Blade2).Any(p=>WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, p));
  222. if (blade1HasWafer || blade2HasWafer)
  223. {
  224. Hand placeBlade = blade1HasWafer ? Hand.Blade1 : Hand.Blade2;
  225. foreach (var ll in _lstLls)
  226. {
  227. if (!ll.IsAvailable)
  228. continue;
  229. if (!CheckReturnWaferByModule(ll.Module))
  230. continue;
  231. var slots = GetSlotCouldBePlace(ll, placeBlade);
  232. if (slots != null && slots.Length > 0 )
  233. {
  234. if (_tmRobot.Place(ll.Module, Converter.MapPanToLLSlot(Converter.GetPanAndSlotFromPlace(placeBlade).Item1, slots), placeBlade, Converter.GetPanAndSlotFromPlace(placeBlade).Item1, 0, 0, false))
  235. {
  236. if (SC.IsDoubleFork)
  237. _lstLls.All(p => p.WaitTransfer(ModuleName.TMRobot));
  238. else
  239. ll.WaitTransfer(ModuleName.TMRobot);
  240. return;
  241. }
  242. }
  243. }
  244. }
  245. }
  246. }
  247. private void MonitorTMRobotPMATask()
  248. {
  249. if (!_tmRobot.IsAvailable)
  250. return;
  251. //pick from pm
  252. {
  253. bool blade1Empty = _tmRobot.Blade1Enable && Converter.MapBladeToSlots(Hand.Blade1).All(p=> WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, p));
  254. bool blade2Empty = _tmRobot.Blade2Enable && Converter.MapBladeToSlots(Hand.Blade2).All(p=> WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, p));
  255. if (blade1Empty || blade2Empty)
  256. {
  257. Hand pickBlade = blade1Empty ? Hand.Blade1 : Hand.Blade2;
  258. //foreach (var pm in _lstPms)
  259. {
  260. var pm = _pm1;
  261. if (!pm.IsAvailable)
  262. return;
  263. var slot = GetWaferCouldBeReturn(pm.Module);
  264. if (slot != null && slot.Length>0 /*&& pm.IsReadyForPick(ModuleName.TMRobot, pickBlade, (int)slot)*/)
  265. {
  266. if (_tmRobot.Pick(pm.Module, slot, pickBlade, Converter.GetPanAndSlotFromPick(pickBlade,slot).Item1, 0, 0, false))
  267. {
  268. pm.WaitTransfer(ModuleName.TMRobot);
  269. return;
  270. }
  271. }
  272. }
  273. }
  274. }
  275. }
  276. private void MonitorTMRobotPMBTask()
  277. {
  278. if (!_tmRobot.IsAvailable)
  279. return;
  280. //pick from pm
  281. {
  282. bool blade1Empty = _tmRobot.Blade1Enable && Converter.MapBladeToSlots(Hand.Blade1).All(p=> WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, p));
  283. bool blade2Empty = _tmRobot.Blade2Enable && Converter.MapBladeToSlots(Hand.Blade2).All(p => WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, p));
  284. if (blade1Empty || blade2Empty)
  285. {
  286. Hand pickBlade = blade1Empty ? Hand.Blade1 : Hand.Blade2;
  287. //foreach (var pm in _lstPms)
  288. {
  289. var pm = _pm2;
  290. if (!pm.IsAvailable)
  291. return;
  292. var slot = GetWaferCouldBeReturn(pm.Module);
  293. if (slot != null && slot.Length > 0 /*&& pm.IsReadyForPick(ModuleName.TMRobot, pickBlade, (int)slot)*/)
  294. {
  295. if (_tmRobot.Pick(pm.Module, slot, pickBlade, Converter.GetPanAndSlotFromPick(pickBlade, slot).Item1, 0, 0, false))
  296. {
  297. pm.WaitTransfer(ModuleName.TMRobot);
  298. return;
  299. }
  300. }
  301. }
  302. }
  303. }
  304. }
  305. private bool MonitorTaskDone()
  306. {
  307. foreach (var positions in _checkPosition)
  308. {
  309. for (int i = 0; i < positions.Value; i++)
  310. {
  311. if (CheckWaferCouldBeReturn(positions.Key, i))
  312. {
  313. return false;
  314. }
  315. }
  316. }
  317. foreach (var lp in _lstLps)
  318. {
  319. if (!lp.IsAvailable)
  320. return false;
  321. }
  322. if (!_tmRobot.IsAvailable)
  323. return false;
  324. if (!_efem.IsAvailable)
  325. return false;
  326. return true;
  327. }
  328. private void MonitorPMTask()
  329. {
  330. // foreach (var pm in _lstPms)
  331. // {
  332. // if (!pm.IsAvailable)
  333. // continue;
  334. // var wafers = WaferManager.Instance.GetWafers(pm.Module);
  335. // for (int i = 0; i < wafers.Length; i++)
  336. // {
  337. // if (!pm.IsAvailable)
  338. // break;
  339. // if (CheckWaferCouldBeReturn(pm.Module, i))
  340. // {
  341. // if (!pm.IsReadyForPick(ModuleName.TMRobot, Hand.Blade1, i))
  342. // {
  343. // pm.PrepareTransfer(ModuleName.TMRobot, EnumTransferType.Pick, i);
  344. // }
  345. // }
  346. // }
  347. // }
  348. }
  349. private void MonitorLoadLockTask()
  350. {
  351. foreach (var ll in _lstLls)
  352. {
  353. if (!ll.IsAvailable)
  354. continue;
  355. var wafers = WaferManager.Instance.GetWafers(ll.Module);
  356. for (int i = 0; i < wafers.Length; i++)
  357. {
  358. var wafer = wafers[i];
  359. if (!wafer.IsEmpty && wafer.NextStation != (int)ModuleName.LoadLock && ll.PostTransfer(ll.Module,EnumTransferType.Place,i))
  360. {
  361. wafer.NextStation = (int)ModuleName.LoadLock;
  362. }
  363. }
  364. }
  365. }
  366. private void MonitorCoolingTask()
  367. {
  368. foreach (var cooling in _lstCoolings)
  369. {
  370. if (!cooling.IsAvailable)
  371. continue;
  372. WaferInfo wafer = WaferManager.Instance.GetWafer(cooling.Module, 0);
  373. if (wafer.NextStation != (int)ModuleName.Cooling)
  374. {
  375. //int coolingTime = SC.GetValueOrDefault<int>("System.DefaultCoolingTime");
  376. if (cooling.Cooling(_coolingTime))
  377. {
  378. wafer.NextStation = (int)ModuleName.Cooling;
  379. }
  380. }
  381. }
  382. }
  383. private void MonitorEfemRobotTask()
  384. {
  385. if (!_efem.IsAvailable)
  386. return;
  387. //efem robot is idle, release all the target
  388. foreach (var ll in _lstLls)
  389. {
  390. if (ll.IsWaitTransfer(ModuleName.EfemRobot))
  391. ll.StopWaitTransfer(ModuleName.EfemRobot);
  392. }
  393. foreach (var al in _lstAligners)
  394. {
  395. if (al.IsWaitTransfer(ModuleName.EfemRobot))
  396. al.StopWaitTransfer(ModuleName.EfemRobot);
  397. }
  398. foreach (var bf in _lstCoolings)
  399. {
  400. if (bf.IsWaitTransfer(ModuleName.EfemRobot))
  401. bf.StopWaitTransfer(ModuleName.EfemRobot);
  402. }
  403. foreach (var lp in _lstLps)
  404. {
  405. if (lp.IsWaitTransfer(ModuleName.EfemRobot))
  406. lp.StopWaitTransfer(ModuleName.EfemRobot);
  407. }
  408. MonitorEfemRobotAlignerTask();
  409. if (!_efem.IsAvailable)
  410. return;
  411. MonitorEfemRobotLoadLockTask();
  412. MonitorEfemRobotCoolingTask();
  413. MonitorEfemRobotLoadPortTask();
  414. }
  415. private void MonitorEfemRobotLoadPortTask()
  416. {
  417. if (!_efem.IsAvailable)
  418. return;
  419. //place
  420. bool blade0HasWaferAndProcessed = _efem.Blade1Enable && CheckWaferCouldBeReturn(ModuleName.EfemRobot, 0);
  421. bool blade1HasWaferAndProcessed = _efem.Blade2Enable && CheckWaferCouldBeReturn(ModuleName.EfemRobot, 1);
  422. if (blade0HasWaferAndProcessed || blade1HasWaferAndProcessed)
  423. {
  424. Hand placeBlade = blade0HasWaferAndProcessed ? Hand.Blade1 : Hand.Blade2;
  425. if (blade0HasWaferAndProcessed && blade1HasWaferAndProcessed)
  426. {
  427. if (WaferManager.Instance.GetWafer(ModuleName.EfemRobot, 1).OriginSlot <
  428. WaferManager.Instance.GetWafer(ModuleName.EfemRobot, 0).OriginSlot)
  429. {
  430. placeBlade = Hand.Blade2;
  431. }
  432. }
  433. if (_needCooling && WaferManager.Instance.GetWafer(ModuleName.EfemRobot, (int)placeBlade).NextStation != (int)ModuleName.Cooling)
  434. return;
  435. SlotItem destination = GetWaferReturnLoadPort(ModuleName.EfemRobot, (int)placeBlade);
  436. if (destination != null)
  437. {
  438. SchedulerLoadPort lp = (SchedulerLoadPort)GetModule(destination.Module.ToString());
  439. if (lp.IsReadyForPlace(ModuleName.EfemRobot, Hand.Blade1, destination.Slot))
  440. {
  441. if (_efem.Place(destination.Module, destination.Slot, placeBlade))
  442. {
  443. WaferManager.Instance.GetWafer(ModuleName.EfemRobot, (int)placeBlade).NextStation = (int)ModuleName.System;
  444. lp.WaitTransfer(ModuleName.EfemRobot);
  445. return;
  446. }
  447. }
  448. }
  449. }
  450. }
  451. private void MonitorEfemRobotLoadLockTask()
  452. {
  453. if (!_efem.IsAvailable)
  454. return;
  455. if ((_cooling1.HasWafer(0) || _cooling2.HasWafer(0)) && (!_efem.Blade1Enable || !_efem.Blade2Enable))
  456. return;
  457. int waferCount = 0;
  458. if (_cooling1.HasWafer(0)) waferCount++;
  459. if (_cooling2.HasWafer(0)) waferCount++;
  460. if (_efem.HasWafer(0)) waferCount++;
  461. if (_efem.HasWafer(1)) waferCount++;
  462. if (waferCount >= 2)
  463. return;
  464. foreach (var ll in _lstLls)
  465. {
  466. if (!ll.IsAvailable)
  467. continue;
  468. {
  469. bool blade1Empty = _efem.Blade1Enable && WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 0);
  470. bool blade2Empty = _efem.Blade2Enable && WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 1);
  471. if (blade1Empty || blade2Empty)
  472. {
  473. Hand pickBlade = blade1Empty ? Hand.Blade1 : Hand.Blade2;
  474. var wafers = WaferManager.Instance.GetWafers(ll.Module);
  475. for (int i = 0; i < wafers.Length; i++)
  476. {
  477. if (CheckWaferCouldBeReturn(wafers[i]) && wafers[i].NextStation == (int)ModuleName.LoadLock)
  478. {
  479. if (ll.IsReadyForPick(ModuleName.EfemRobot, pickBlade, i))
  480. {
  481. if (_efem.Pick(ll.Module, i, pickBlade))
  482. {
  483. ll.WaitTransfer(ModuleName.EfemRobot);
  484. return;
  485. }
  486. }
  487. }
  488. }
  489. }
  490. }
  491. }
  492. }
  493. private void MonitorEfemRobotCoolingTask()
  494. {
  495. if (!_efem.IsAvailable)
  496. return;
  497. //pick from Cooling
  498. bool blade1EmptyAndEnable = _efem.Blade1Enable && WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 0);
  499. bool blade2EmptyAndEnable = _efem.Blade2Enable && WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 1);
  500. if (blade1EmptyAndEnable || blade2EmptyAndEnable)
  501. {
  502. Hand pickBlade = blade1EmptyAndEnable ? Hand.Blade1 : Hand.Blade2;
  503. foreach (var cooling in _lstCoolings)
  504. {
  505. if (!_efem.IsAvailable)
  506. return;
  507. if (!cooling.IsAvailable)
  508. continue;
  509. if (cooling.HasWafer(0) && cooling.GetWaferInfo(0).NextStation == (int)ModuleName.Cooling)
  510. {
  511. if (cooling.IsReadyForPick(ModuleName.EfemRobot, pickBlade, 0))
  512. {
  513. if (_efem.Pick(cooling.Module, 0, pickBlade))
  514. {
  515. cooling.WaitTransfer(ModuleName.EfemRobot);
  516. return;
  517. }
  518. }
  519. }
  520. }
  521. }
  522. //不需要cooling,返回
  523. if (!_needCooling)
  524. return;
  525. //place to Cooling
  526. bool blade1NeedCooling = _efem.Blade1Enable && WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 0) &&
  527. WaferManager.Instance.GetWafer(ModuleName.EfemRobot, 0).NextStation != (int)ModuleName.Cooling;
  528. bool blade2NeedCooling = _efem.Blade2Enable && WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 1) &&
  529. WaferManager.Instance.GetWafer(ModuleName.EfemRobot, 1).NextStation != (int)ModuleName.Cooling;
  530. if (blade1NeedCooling || blade2NeedCooling)
  531. {
  532. Hand placeBlade = blade1NeedCooling ? Hand.Blade1 : Hand.Blade2;
  533. foreach (var cooling in _lstCoolings)
  534. {
  535. if (!_efem.IsAvailable)
  536. return;
  537. if (!cooling.IsAvailable)
  538. continue;
  539. if (cooling.IsReadyForPlace(ModuleName.EfemRobot, placeBlade, 0))
  540. {
  541. if (_efem.Place(cooling.Module, 0, placeBlade))
  542. {
  543. cooling.WaitTransfer(ModuleName.EfemRobot);
  544. return;
  545. }
  546. }
  547. }
  548. }
  549. }
  550. private void MonitorEfemRobotAlignerTask()
  551. {
  552. if (!_efem.IsAvailable)
  553. return;
  554. //pick from aligner
  555. bool blade1EmptyAndEnable = _efem.Blade1Enable && WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 0);
  556. bool blade2EmptyAndEnable = _efem.Blade2Enable && WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 1);
  557. if (blade1EmptyAndEnable || blade2EmptyAndEnable)
  558. {
  559. Hand pickBlade = blade1EmptyAndEnable ? Hand.Blade1 : Hand.Blade2;
  560. foreach (var aligner in _lstAligners)
  561. {
  562. if (!_efem.IsAvailable)
  563. return;
  564. if (!aligner.IsAvailable)
  565. continue;
  566. if (aligner.HasWafer(0))
  567. {
  568. if (aligner.IsReadyForPick(ModuleName.EfemRobot, pickBlade, 0))
  569. {
  570. if (_efem.Pick(aligner.Module, 0, pickBlade))
  571. {
  572. aligner.WaitTransfer(ModuleName.EfemRobot);
  573. return;
  574. }
  575. }
  576. }
  577. }
  578. }
  579. }
  580. private int[] GetWaferCouldBeReturn(ModuleName module)
  581. {
  582. var wafers = WaferManager.Instance.GetWafers(module);
  583. List<int> slots = new List<int>();
  584. for (int i = 0; i < wafers.Length; i++)
  585. {
  586. if (CheckWaferCouldBeReturn(wafers[i]))
  587. {
  588. slots.Add(i);
  589. if(SC.IsDoubleFork)
  590. {
  591. var leftOrRightSlot = (i % 2 > 0) ? i - 1 : i + 1;
  592. var wafer = WaferManager.Instance.GetWafer(module, leftOrRightSlot);
  593. if(wafer != null && !wafer.IsEmpty && CheckWaferCouldBeReturn(wafer))
  594. {
  595. slots.Add(leftOrRightSlot);
  596. }
  597. }
  598. return slots.ToArray();
  599. }
  600. }
  601. return null;
  602. }
  603. private bool TryGetNextCanBeRetrunWafer(ModuleName module, int selectedSlot, out int nextSlot)
  604. {
  605. nextSlot = 0;
  606. if (!SC.IsDoubleFork) return false;
  607. nextSlot = (selectedSlot % 2 > 0) ? selectedSlot - 1 : selectedSlot + 1;
  608. var wafer = WaferManager.Instance.GetWafer(module, nextSlot);
  609. return !wafer.IsEmpty && CheckWaferCouldBeReturn(wafer);
  610. }
  611. private int[] GetSlotCouldBePlace(SchedulerLoadLock ll, Hand placeBlade)
  612. {
  613. var wafers = WaferManager.Instance.GetWafers(ll.Module);
  614. var isDoubleFork = SC.IsDoubleFork;
  615. for (int i = 0; i < wafers.Length; )
  616. {
  617. if(isDoubleFork)
  618. {
  619. if (wafers[i].IsEmpty && ll.IsReadyForPlace(ModuleName.TMRobot, placeBlade, i) &&
  620. wafers[i + 1].IsEmpty && ll.IsReadyForPlace(ModuleName.TMRobot, placeBlade, i + 1))
  621. {
  622. if (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, ((int)placeBlade) + 2))
  623. return new int[] { i, i + 1 };
  624. else
  625. return new int[] { i};
  626. }
  627. i += 2;
  628. }
  629. else
  630. {
  631. if (wafers[i].IsEmpty && ll.IsReadyForPlace(ModuleName.TMRobot, placeBlade, i))
  632. return new int[] {i};
  633. i += 1;
  634. }
  635. }
  636. return null;
  637. }
  638. private bool CheckWaferCouldBeReturn(WaferInfo wafer)
  639. {
  640. if (!wafer.IsEmpty)
  641. {
  642. return ModuleHelper.IsLoadPort((ModuleName)wafer.OriginStation)
  643. && wafer.Status != WaferStatus.Dummy
  644. && WaferManager.Instance.CheckNoWafer((ModuleName)wafer.OriginStation, wafer.OriginSlot);
  645. }
  646. return false;
  647. }
  648. private bool CheckWaferCouldBeReturn(ModuleName module, int slot)
  649. {
  650. WaferInfo wafer = WaferManager.Instance.GetWafer(module, slot);
  651. if (!wafer.IsEmpty)
  652. {
  653. return ModuleHelper.IsLoadPort((ModuleName)wafer.OriginStation)
  654. && wafer.Status != WaferStatus.Dummy
  655. && WaferManager.Instance.CheckNoWafer((ModuleName)wafer.OriginStation, wafer.OriginSlot);
  656. }
  657. return false;
  658. }
  659. private SlotItem GetWaferReturnLoadPort(ModuleName module, int slot)
  660. {
  661. WaferInfo wafer = WaferManager.Instance.GetWafer(module, slot);
  662. if (!wafer.IsEmpty)
  663. {
  664. return new SlotItem((ModuleName)wafer.OriginStation, wafer.OriginSlot);
  665. }
  666. return null;
  667. }
  668. }
  669. }