EfemPickAndPlaceRoutine.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. using System;
  2. using Aitex.Core.RT.Event;
  3. using Aitex.Core.RT.Routine;
  4. using Aitex.Core.RT.SCCore;
  5. using Aitex.Core.Util;
  6. using Aitex.Sorter.Common;
  7. using MECF.Framework.Common.Equipment;
  8. using MECF.Framework.Common.Schedulers;
  9. using MECF.Framework.Common.SubstrateTrackings;
  10. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots;
  11. using MECF.Framework.RT.EquipmentLibrary.LogicUnits;
  12. using MECF.Framework.RT.ModuleLibrary.PMModules;
  13. using MECF.Framework.RT.ModuleLibrary.SystemModules;
  14. namespace FutureEfemLib.Efems
  15. {
  16. public class EfemPickAndPlaceRoutine : ModuleRoutine, IRoutine
  17. {
  18. enum RoutineStep
  19. {
  20. CheckBeforePick,
  21. PickWafer,
  22. CheckBeforePlace,
  23. PlaceWafer,
  24. PostTransfer,
  25. PickExtend,
  26. PickRetract,
  27. PlaceExtend,
  28. PlaceRetract,
  29. PickLiftUp,
  30. PickLiftDown,
  31. PlaceLiftUp,
  32. PlaceLiftDown,
  33. }
  34. private EfemModule _robotModule;
  35. private ITransferTarget _target;
  36. private Hand _pickBlade;
  37. private Hand _placeBlade;
  38. private ModuleName _targetModule;
  39. private int _pickSlot;
  40. private int _placeSlot;
  41. private int _pickTimeout;
  42. private int _placeTimeout;
  43. private int _postTransferTimeout;
  44. public EfemPickAndPlaceRoutine(EfemModule robotModule)
  45. {
  46. Module = "EfemRobot";
  47. Name = "Pick";
  48. _robotModule = robotModule;
  49. }
  50. public Result Start(params object[] objs)
  51. {
  52. _pickTimeout = SC.GetValue<int>("EFEM.EfemRobot.PickTimeout");
  53. _placeTimeout = SC.GetValue<int>("EFEM.EfemRobot.PlaceTimeout");
  54. if (ModuleHelper.IsPm(_targetModule))
  55. {
  56. _postTransferTimeout = SC.GetValue<int>($"PM.PostTransferTimeout");
  57. }
  58. Reset();
  59. if (!WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, (int)_pickBlade))
  60. {
  61. EV.PostWarningLog(Module, $"Can not pick by {_pickBlade}, found wafer on");
  62. return Result.FAIL;
  63. }
  64. if (!WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, (int)_placeBlade))
  65. {
  66. EV.PostWarningLog(Module, $"Can not place by {_placeBlade}, no wafer on");
  67. return Result.FAIL;
  68. }
  69. if (_pickSlot != _placeSlot)
  70. {
  71. if (!WaferManager.Instance.CheckHasWafer(_targetModule, _pickSlot))
  72. {
  73. EV.PostWarningLog(Module, $"Can not pick from {_targetModule} slot {_pickSlot + 1}, no wafer on");
  74. return Result.FAIL;
  75. }
  76. if (!WaferManager.Instance.CheckNoWafer(_targetModule, _placeSlot))
  77. {
  78. EV.PostWarningLog(Module, $"Can not place to {_targetModule} slot {_placeSlot + 1}, found wafer on");
  79. return Result.FAIL;
  80. }
  81. }
  82. else
  83. {
  84. if (!WaferManager.Instance.CheckHasWafer(_targetModule, _placeSlot))
  85. {
  86. {
  87. EV.PostWarningLog(Module, $"Can not pick&place from {_targetModule} slot {_placeSlot + 1}, no wafer on");
  88. return Result.FAIL;
  89. }
  90. }
  91. }
  92. Notify($"Start, swap wafer,pick: {_pickBlade} slot {_pickSlot + 1}, place: {_placeBlade} slot {_placeSlot+1}");
  93. return Result.RUN;
  94. }
  95. public void Init(ModuleName targetModule, Hand pickBlade, int pickSlot, Hand placeBlade, int placeSlot)
  96. {
  97. _pickBlade = pickBlade;
  98. _placeBlade = placeBlade;
  99. _targetModule = targetModule;
  100. _pickSlot = pickSlot;
  101. _placeSlot = placeSlot;
  102. //_target = Singleton<EquipmentManager>.Instance.Modules[targetModule] as ITransferTarget;
  103. }
  104. public void Abort()
  105. {
  106. if (_target != null)
  107. {
  108. _target.NoteTransferStop(ModuleName.EfemRobot, Hand.Blade1, 0, EnumTransferType.Pick);
  109. }
  110. _target = null;
  111. Notify("Abort");
  112. }
  113. public Result Monitor()
  114. {
  115. try
  116. {
  117. CheckBeforePick((int)RoutineStep.CheckBeforePick, _targetModule, _pickSlot, _pickBlade);
  118. if (ModuleHelper.IsPm(_targetModule))
  119. {
  120. RobotExtend((int)RoutineStep.PickExtend, _targetModule, _pickSlot, _pickBlade, RobotPostionEnum.PickExtendLow, _pickTimeout);
  121. MovePinDown((int)RoutineStep.PickLiftDown, _target as PMModuleBase, EnumTransferType.Extend, _pickTimeout);
  122. RobotRetract((int)RoutineStep.PickRetract, _targetModule, _pickSlot, _pickBlade, RobotPostionEnum.PickRetracted, _pickTimeout);
  123. //MovePinDown((int)RoutineStep.PickLiftDown, _target as PMModuleBase, EnumTransferType.Retract, _pickTimeout);
  124. RobotExtend((int)RoutineStep.PlaceExtend, _targetModule, _placeSlot, _placeBlade, RobotPostionEnum.PlaceExtendUp, _pickTimeout);
  125. MovePinUp((int)RoutineStep.PlaceLiftUp, _target as PMModuleBase, EnumTransferType.Extend, _pickTimeout);
  126. RobotRetract((int)RoutineStep.PlaceRetract, _targetModule, _placeSlot, _placeBlade, RobotPostionEnum.PlaceRetract, _pickTimeout);
  127. //LiftPinDown((int)RoutineStep.PlaceLiftDown, _target as PMModuleBase, EnumTransferType.Retract, _pickTimeout);
  128. }
  129. else
  130. {
  131. PickWafer((int)RoutineStep.PickWafer, _targetModule, _pickSlot, _pickBlade, _pickTimeout);
  132. CheckBeforePlace((int)RoutineStep.CheckBeforePlace, _targetModule, _placeSlot, _placeBlade);
  133. PlaceWafer((int)RoutineStep.PlaceWafer, _targetModule, _placeSlot, _placeBlade, _pickTimeout);
  134. }
  135. if (ModuleHelper.IsPm(_targetModule))
  136. {
  137. PostTransfer((int)RoutineStep.PostTransfer, _target as PMModuleBase, EnumTransferType.Place, _postTransferTimeout);
  138. }
  139. }
  140. catch (RoutineBreakException)
  141. {
  142. return Result.RUN;
  143. }
  144. catch (RoutineFaildException)
  145. {
  146. return Result.FAIL;
  147. }
  148. _target.NoteTransferStop(ModuleName.EfemRobot, Hand.Blade1, 0, EnumTransferType.Pick);
  149. Notify($"complete, swap wafer,pick: {_pickBlade} slot {_pickSlot + 1}, place: {_placeBlade} slot {_placeSlot + 1}");
  150. return Result.DONE;
  151. }
  152. public void CheckBeforePick(int id, ModuleName source, int slot, Hand blade)
  153. {
  154. Tuple<bool, Result> ret = Execute(id, () =>
  155. {
  156. Notify("Check pick is enabled");
  157. string reason = string.Empty;
  158. if (!_target.CheckReadyForTransfer(ModuleName.EfemRobot, blade, slot, EnumTransferType.Pick, out reason))
  159. {
  160. Stop(reason);
  161. return false;
  162. }
  163. if (blade == Hand.Blade1)
  164. {
  165. if (!WaferManager.Instance.CheckHasWafer(source, slot))
  166. {
  167. Stop("Source no wafer");
  168. return false;
  169. }
  170. if (!WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 0))
  171. {
  172. Stop("Blade has wafer");
  173. return false;
  174. }
  175. }
  176. else if (blade == Hand.Blade2)
  177. {
  178. if (!WaferManager.Instance.CheckHasWafer(source, slot))
  179. {
  180. Stop("Source no wafer");
  181. return false;
  182. }
  183. if (!WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 1))
  184. {
  185. Stop("Blade has wafer");
  186. return false;
  187. }
  188. }
  189. else
  190. {
  191. for (int i = 0; i < 2; i++)
  192. {
  193. if (!WaferManager.Instance.CheckHasWafer(source, slot + i))
  194. {
  195. Stop("Source no wafer");
  196. return false;
  197. }
  198. if (!WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, i))
  199. {
  200. Stop("Blade has wafer");
  201. return false;
  202. }
  203. }
  204. }
  205. return true;
  206. });
  207. if (ret.Item1)
  208. {
  209. if (ret.Item2 == Result.FAIL)
  210. {
  211. throw (new RoutineFaildException());
  212. }
  213. }
  214. }
  215. public void PickWafer(int id, ModuleName chamber, int slot, Hand hand, int timeout)
  216. {
  217. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  218. {
  219. Notify("robot execute pick command");
  220. _target.NoteTransferStart(ModuleName.EfemRobot, hand, slot, EnumTransferType.Pick);
  221. string reason;
  222. if (!_robotModule.RobotDevice.Pick(chamber, hand, slot, out reason))
  223. {
  224. Stop(reason);
  225. return false;
  226. }
  227. return true;
  228. }, () =>
  229. {
  230. if (_robotModule.RobotDevice.IsError)
  231. return null;
  232. if (_robotModule.RobotDevice.IsIdle)
  233. return true;
  234. return false;
  235. }, timeout * 1000);
  236. if (ret.Item1)
  237. {
  238. if (ret.Item2 == Result.FAIL)
  239. {
  240. Stop(string.Format("failed."));
  241. throw (new RoutineFaildException());
  242. }
  243. else if (ret.Item2 == Result.TIMEOUT) //timeout
  244. {
  245. Stop(string.Format("timeout, can not complete in {0} seconds", timeout));
  246. throw (new RoutineFaildException());
  247. }
  248. else
  249. throw (new RoutineBreakException());
  250. }
  251. }
  252. public void CheckBeforePlace(int id, ModuleName source, int slot, Hand blade)
  253. {
  254. Tuple<bool, Result> ret = Execute(id, () =>
  255. {
  256. Notify("Check place condition");
  257. string reason = string.Empty;
  258. if (!_target.CheckReadyForTransfer(ModuleName.EfemRobot, blade, slot, EnumTransferType.Place, out reason))
  259. {
  260. Stop(reason);
  261. return false;
  262. }
  263. if (blade == Hand.Blade1)
  264. {
  265. if (!WaferManager.Instance.CheckNoWafer(source, slot))
  266. {
  267. Stop("Source has wafer");
  268. return false;
  269. }
  270. if (!WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 0))
  271. {
  272. Stop("Blade 1 no wafer");
  273. return false;
  274. }
  275. }
  276. else if (blade == Hand.Blade2)
  277. {
  278. if (!WaferManager.Instance.CheckNoWafer(source, slot))
  279. {
  280. Stop("Source has wafer");
  281. return false;
  282. }
  283. if (!WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 1))
  284. {
  285. Stop("Blade no wafer");
  286. return false;
  287. }
  288. }
  289. else
  290. {
  291. for (int i = 0; i < 2; i++)
  292. {
  293. if (!WaferManager.Instance.CheckNoWafer(source, slot + i))
  294. {
  295. Stop("Source has wafer");
  296. return false;
  297. }
  298. if (!WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, i))
  299. {
  300. Stop("Blade no wafer");
  301. return false;
  302. }
  303. }
  304. }
  305. return true;
  306. });
  307. if (ret.Item1)
  308. {
  309. if (ret.Item2 == Result.FAIL)
  310. {
  311. throw (new RoutineFaildException());
  312. }
  313. }
  314. }
  315. public void PlaceWafer(int id, ModuleName chamber, int slot, Hand hand, int timeout)
  316. {
  317. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  318. {
  319. Notify("robot start execute place command");
  320. string reason;
  321. _target.NoteTransferStart(ModuleName.EfemRobot, hand, slot, EnumTransferType.Place);
  322. if (!_robotModule.RobotDevice.Place(chamber, hand, slot, out reason))
  323. {
  324. Stop(reason);
  325. return false;
  326. }
  327. return true;
  328. }, () =>
  329. {
  330. if (_robotModule.RobotDevice.IsError)
  331. return null;
  332. if (_robotModule.RobotDevice.IsIdle)
  333. return true;
  334. return false;
  335. }, timeout * 1000);
  336. if (ret.Item1)
  337. {
  338. if (ret.Item2 == Result.FAIL)
  339. {
  340. throw (new RoutineFaildException());
  341. }
  342. else if (ret.Item2 == Result.TIMEOUT) //timeout
  343. {
  344. Stop(string.Format("timeout, can not complete in {0} seconds", timeout));
  345. throw (new RoutineFaildException());
  346. }
  347. else
  348. throw (new RoutineBreakException());
  349. }
  350. }
  351. public void PostTransfer(int id, PMModuleBase pm, EnumTransferType type, int timeout)
  352. {
  353. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  354. {
  355. Notify($"{pm.Name} post transfer ");
  356. if (!pm.PostTransfer(ModuleName.EfemRobot, Hand.Blade1, 0, type, out string reason))
  357. {
  358. Stop(reason);
  359. return false;
  360. }
  361. return true;
  362. }, () =>
  363. {
  364. if (pm.IsError)
  365. {
  366. return null;
  367. }
  368. return pm.IsReady;
  369. }, timeout * 1000);
  370. if (ret.Item1)
  371. {
  372. if (ret.Item2 == Result.FAIL)
  373. {
  374. Stop($"{pm.Name} error");
  375. throw (new RoutineFaildException());
  376. }
  377. else if (ret.Item2 == Result.TIMEOUT) //timeout
  378. {
  379. Stop($"{pm.Name} post transfer timeout, over {timeout} seconds");
  380. throw (new RoutineFaildException());
  381. }
  382. else
  383. throw (new RoutineBreakException());
  384. }
  385. }
  386. public void RobotExtend(int id, ModuleName chamber, int slot, Hand hand, RobotPostionEnum robotPostion, int timeout)
  387. {
  388. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  389. {
  390. Notify("robot execute goto command");
  391. //string reason;
  392. //if (!_robotModule.RobotDevice.GotoRE(chamber, hand, slot, robotPostion, out reason))
  393. //{
  394. // Stop(reason);
  395. // return false;
  396. //}
  397. return true;
  398. }, () =>
  399. {
  400. if (_robotModule.RobotDevice.IsError)
  401. return null;
  402. if (_robotModule.RobotDevice.IsIdle)
  403. return true;
  404. return false;
  405. }, timeout * 1000);
  406. if (ret.Item1)
  407. {
  408. if (ret.Item2 == Result.FAIL)
  409. {
  410. Stop(string.Format("failed."));
  411. throw (new RoutineFaildException());
  412. }
  413. else if (ret.Item2 == Result.TIMEOUT) //timeout
  414. {
  415. Stop(string.Format("timeout, can not complete in {0} seconds", timeout));
  416. throw (new RoutineFaildException());
  417. }
  418. else
  419. throw (new RoutineBreakException());
  420. }
  421. }
  422. public void RobotRetract(int id, ModuleName chamber, int slot, Hand hand, RobotPostionEnum robotPostion, int timeout)
  423. {
  424. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  425. {
  426. Notify("robot execute goto command");
  427. //string reason;
  428. //if (!_robotModule.RobotDevice.GotoRE(chamber, hand, slot, robotPostion, out reason))
  429. //{
  430. // Stop(reason);
  431. // return false;
  432. //}
  433. return true;
  434. }, () =>
  435. {
  436. if (_robotModule.RobotDevice.IsError)
  437. return null;
  438. if (_robotModule.RobotDevice.IsIdle)
  439. return true;
  440. return false;
  441. }, timeout * 1000);
  442. if (ret.Item1)
  443. {
  444. if (ret.Item2 == Result.FAIL)
  445. {
  446. Stop(string.Format("failed."));
  447. throw (new RoutineFaildException());
  448. }
  449. else if (ret.Item2 == Result.TIMEOUT) //timeout
  450. {
  451. Stop(string.Format("timeout, can not complete in {0} seconds", timeout));
  452. throw (new RoutineFaildException());
  453. }
  454. else
  455. throw (new RoutineBreakException());
  456. }
  457. }
  458. public void MovePinUp(int id, PMModuleBase pm, EnumTransferType type, int timeout)
  459. {
  460. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  461. {
  462. Notify($"{pm.Name} lift pin up ");
  463. //if (!pm.ChamberLiftPin.MoveUp(out string reason))
  464. //{
  465. // Stop(reason);
  466. // return false;
  467. //}
  468. return true;
  469. }, () =>
  470. {
  471. //if (pm.ChamberLiftPin.IsUp)
  472. // return true;
  473. return false;
  474. }, timeout * 1000);
  475. if (ret.Item1)
  476. {
  477. if (ret.Item2 == Result.FAIL)
  478. {
  479. throw (new RoutineFaildException());
  480. }
  481. else if (ret.Item2 == Result.TIMEOUT) //timeout
  482. {
  483. Stop($"{pm.Name} move lift pin up timeout, over {timeout} seconds");
  484. throw (new RoutineFaildException());
  485. }
  486. else
  487. throw (new RoutineBreakException());
  488. }
  489. }
  490. public void MovePinDown(int id, PMModuleBase pm, EnumTransferType type, int timeout)
  491. {
  492. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  493. {
  494. Notify($"{pm.Name} lift pin down");
  495. //if (!pm.ChamberLiftPin.MoveDown(out string reason))
  496. //{
  497. // Stop(reason);
  498. // return false;
  499. //}
  500. return true;
  501. }, () =>
  502. {
  503. //if (pm.ChamberLiftPin.IsDown)
  504. // return true;
  505. return false;
  506. }, timeout * 1000);
  507. if (ret.Item1)
  508. {
  509. if (ret.Item2 == Result.FAIL)
  510. {
  511. throw (new RoutineFaildException());
  512. }
  513. else if (ret.Item2 == Result.TIMEOUT) //timeout
  514. {
  515. Stop($"{pm.Name} move down lift pin timeout, over {timeout} seconds");
  516. throw (new RoutineFaildException());
  517. }
  518. else
  519. throw (new RoutineBreakException());
  520. }
  521. }
  522. }
  523. }