TMPickRoutine.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. using System;
  2. using Aitex.Core.RT.Device;
  3. using Aitex.Core.RT.Device.Unit;
  4. using Aitex.Core.RT.Event;
  5. using Aitex.Core.RT.Routine;
  6. using Aitex.Core.RT.SCCore;
  7. using Aitex.Sorter.Common;
  8. using MECF.Framework.Common.Equipment;
  9. using MECF.Framework.Common.Schedulers;
  10. using MECF.Framework.Common.SubstrateTrackings;
  11. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots;
  12. using MECF.Framework.RT.EquipmentLibrary.LogicUnits;
  13. using MECF.Framework.RT.ModuleLibrary.PMModules;
  14. using MECF.Framework.RT.ModuleLibrary.SystemModules;
  15. namespace JetMainframe.TMs
  16. {
  17. public class TMPickRoutine : ModuleRoutine, IRoutine
  18. {
  19. enum RoutineStep
  20. {
  21. PrepareTransfer,
  22. CheckBeforePick,
  23. PickWafer,
  24. CheckBeforePick2,
  25. PickWafer2,
  26. TransferHandoff,
  27. PickRetract,
  28. PostTransfer,
  29. }
  30. private int _pickTimeout;
  31. private ModuleName _source;
  32. private int _sourceSlot;
  33. private Hand _hand;
  34. private bool _autoHand;
  35. private double _TargetTemp1 = 0.0f;
  36. private double _TargetTemp2 = 0.0f;
  37. private bool _enableCheck = false;
  38. private TMModule _robotModule;
  39. private ITransferTarget _target;
  40. private int _postTransferTimeout;
  41. public TMPickRoutine(TMModule robotModule)
  42. {
  43. Module = "TM";
  44. Name = "Pick";
  45. _robotModule = robotModule;
  46. }
  47. public Result Start(params object[] objs)
  48. {
  49. _pickTimeout = SC.GetValue<int>("TM.TMRobot.PickTimeout");
  50. Reset();
  51. if (!DEVICE.GetDevice<IoSensor>($"System.SensorTMInSafety").Value)
  52. {
  53. EV.PostAlarmLog(Module, $"Can not pick, Sensor TMInSafety is false");
  54. return Result.FAIL;
  55. }
  56. if (_source == ModuleName.LLA && DEVICE.GetDevice<IoSensor>($"System.SensorBufferABigWaferProtrusion").Value)
  57. {
  58. EV.PostAlarmLog(Module, $"Can not pick, Sensor BufferABigWaferProtrusion is false");
  59. return Result.FAIL;
  60. }
  61. if (_source == ModuleName.LLB && DEVICE.GetDevice<IoSensor>($"System.SensorBufferBBigWaferProtrusion").Value)
  62. {
  63. EV.PostAlarmLog(Module, $"Can not pick, Sensor BufferBBigWaferProtrusion is false");
  64. return Result.FAIL;
  65. }
  66. if (_autoHand)
  67. {
  68. if (WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0))
  69. {
  70. _hand = Hand.Blade1;
  71. }
  72. else if (WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 1))
  73. {
  74. _hand = Hand.Blade2;
  75. }
  76. else
  77. {
  78. EV.PostWarningLog(Module, $"Can not pick, Robot both arm has wafer");
  79. return Result.FAIL;
  80. }
  81. }
  82. if (_hand == Hand.Both)
  83. {
  84. if (!SC.GetValueOrDefault<bool>("TM.TMRobot.LowerBladeEnable"))
  85. {
  86. EV.PostAlarmLog(Module, $"Can not pick, Lower Blade is Disabled");
  87. return Result.FAIL;
  88. }
  89. if (!SC.GetValueOrDefault<bool>("TM.TMRobot.UpperBladeEnable"))
  90. {
  91. EV.PostAlarmLog(Module, $"Can not pick, Upper Blade is Disabled");
  92. return Result.FAIL;
  93. }
  94. if (WaferManager.Instance.GetWafers(_source).Length < 2)
  95. {
  96. EV.PostWarningLog(Module, $"Can not pick use both arm, Only one slot at {_source}");
  97. return Result.FAIL;
  98. }
  99. if (!WaferManager.Instance.CheckHasWafer(_source, _sourceSlot))
  100. {
  101. EV.PostWarningLog(Module, $"Can not pick, No wafer at {_source}, {_sourceSlot + 1}");
  102. return Result.FAIL;
  103. }
  104. if (!WaferManager.Instance.CheckHasWafer(_source, _sourceSlot + 1))
  105. {
  106. EV.PostWarningLog(Module, $"Can not pick, No wafer at {_source}, {_sourceSlot + 1 + 1}");
  107. return Result.FAIL;
  108. }
  109. if (!WaferManager.Instance.CheckNoWafer(Module, (int)Hand.Blade1))
  110. {
  111. EV.PostWarningLog(Module, $"Can not pick, Robot arm 1 has wafer");
  112. return Result.FAIL;
  113. }
  114. if (!WaferManager.Instance.CheckNoWafer(Module, (int)Hand.Blade2))
  115. {
  116. EV.PostWarningLog(Module, $"Can not pick, Robot arm 2 has wafer");
  117. return Result.FAIL;
  118. }
  119. }
  120. else
  121. {
  122. if (_hand == Hand.Blade1 && !SC.GetValueOrDefault<bool>("TM.TMRobot.LowerBladeEnable"))
  123. {
  124. EV.PostAlarmLog(Module, $"Can not pick, Lower Blade is Disabled");
  125. return Result.FAIL;
  126. }
  127. if (_hand == Hand.Blade2 && !SC.GetValueOrDefault<bool>("TM.TMRobot.UpperBladeEnable"))
  128. {
  129. EV.PostAlarmLog(Module, $"Can not pick, Upper Blade is Disabled");
  130. return Result.FAIL;
  131. }
  132. if (!WaferManager.Instance.CheckHasWafer(_source, _sourceSlot))
  133. {
  134. EV.PostWarningLog(Module, $"Can not pick, No wafer at {_source}, {_sourceSlot + 1}");
  135. return Result.FAIL;
  136. }
  137. if (!WaferManager.Instance.CheckNoWafer(Module, (int)_hand))
  138. {
  139. EV.PostWarningLog(Module, $"Can not pick, Robot arm {(int)_hand + 1} has wafer");
  140. return Result.FAIL;
  141. }
  142. }
  143. Notify($"Start, Pick from {_source} slot {_sourceSlot + 1}, by {_hand}");
  144. return Result.RUN;
  145. }
  146. public void Init(ModuleName source, int slot, Hand hand, double temp1, double temp2, bool enableCheckTemp)
  147. {
  148. _autoHand = false;
  149. _TargetTemp1 = temp1;
  150. _TargetTemp2 = temp2;
  151. _enableCheck = enableCheckTemp;
  152. _source = source;
  153. _sourceSlot = slot;
  154. _hand = hand;
  155. if (ModuleHelper.IsPm(source))
  156. _postTransferTimeout = SC.GetValue<int>($"{source}.PostTransferTimeout");
  157. _target = EquipmentManager.Modules[source] as ITransferTarget;
  158. }
  159. public void Init(ModuleName source, int slot, double temp1, double temp2, bool enableCheckTemp)
  160. {
  161. _autoHand = true;
  162. _TargetTemp1 = temp1;
  163. _TargetTemp2 = temp2;
  164. _enableCheck = enableCheckTemp;
  165. _source = source;
  166. _sourceSlot = slot;
  167. if (ModuleHelper.IsPm(source))
  168. _postTransferTimeout = SC.GetValue<int>($"{source}.PostTransferTimeout");
  169. _target = EquipmentManager.Modules[source] as ITransferTarget;
  170. }
  171. public void Abort()
  172. {
  173. if (_target != null)
  174. {
  175. _target.NoteTransferStop(ModuleName.TMRobot, Hand.Blade1, 0, EnumTransferType.Pick);
  176. }
  177. _target = null;
  178. Notify("Abort");
  179. }
  180. public Result Monitor()
  181. {
  182. try
  183. {
  184. if (ModuleHelper.IsPm(_source))
  185. {
  186. PrepareTransfer((int)RoutineStep.PrepareTransfer, _target as PMModuleBase, _hand, _sourceSlot, EnumTransferType.Pick, _postTransferTimeout, _TargetTemp1, _TargetTemp2, _enableCheck);
  187. }
  188. CheckBeforePick((int)RoutineStep.CheckBeforePick, _source, _sourceSlot, _hand, _postTransferTimeout);
  189. PickWafer((int)RoutineStep.PickWafer, _source, _sourceSlot, _hand, _pickTimeout);
  190. if (ModuleHelper.IsPm(_source))
  191. {
  192. TransferHandoff((int)RoutineStep.TransferHandoff, _target as PMModuleBase, _hand, _sourceSlot, EnumTransferType.Pick, _postTransferTimeout);
  193. PickRetract((int)RoutineStep.PickRetract, _source, _sourceSlot, _hand, _pickTimeout);
  194. PostTransfer((int)RoutineStep.PostTransfer, _target as PMModuleBase, _hand, _sourceSlot, EnumTransferType.Pick, _postTransferTimeout);
  195. }
  196. }
  197. catch (RoutineBreakException)
  198. {
  199. return Result.RUN;
  200. }
  201. catch (RoutineFaildException)
  202. {
  203. return Result.FAIL;
  204. }
  205. _target.NoteTransferStop(ModuleName.TMRobot, Hand.Blade1, 0, EnumTransferType.Pick);
  206. //WaferManager.Instance.WaferMoved(_source, _sourceSlot, ModuleName.TMRobot, (int)_hand);
  207. Notify($"Finish, Pick from {_source} slot {_sourceSlot + 1}, by {_hand}");
  208. return Result.DONE;
  209. }
  210. public void CheckBeforePick(int id, ModuleName source, int slot, Hand blade, int timeout)
  211. {
  212. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  213. {
  214. Notify("Check pick is enabled");
  215. string reason = string.Empty;
  216. if (!WaferManager.Instance.CheckHasWafer(source, slot))
  217. {
  218. Stop("Source no wafer");
  219. return false;
  220. }
  221. if (!WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, (int)blade))
  222. {
  223. Stop("Blade has wafer");
  224. return false;
  225. }
  226. return true;
  227. }, () =>
  228. {
  229. if (_robotModule.RobotDevice.IsError)
  230. return null;
  231. if (_target.CheckReadyForTransfer(ModuleName.TMRobot, _hand, _sourceSlot, EnumTransferType.Pick, out _))
  232. {
  233. return true;
  234. }
  235. return false;
  236. }, timeout * 1000);
  237. if (ret.Item1)
  238. {
  239. if (ret.Item2 == Result.FAIL)
  240. {
  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 PickWafer(int id, ModuleName chamber, int slot, Hand hand, int timeout)
  253. {
  254. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  255. {
  256. Notify("robot execute pick command");
  257. _target.NoteTransferStart(ModuleName.TMRobot, hand, slot, EnumTransferType.Pick);
  258. if (!_robotModule.RobotDevice.Pick((RobotArmEnum)(int)hand, chamber.ToString(), slot))
  259. {
  260. return false;
  261. }
  262. return true;
  263. }, () =>
  264. {
  265. if (_robotModule.RobotDevice.IsError)
  266. return null;
  267. if (_robotModule.RobotDevice.IsIdle)
  268. return true;
  269. return false;
  270. }, timeout * 1000);
  271. if (ret.Item1)
  272. {
  273. if (ret.Item2 == Result.FAIL)
  274. {
  275. Stop(string.Format("failed."));
  276. throw new RoutineFaildException();
  277. }
  278. else if (ret.Item2 == Result.TIMEOUT) //timeout
  279. {
  280. Stop(string.Format("timeout, can not complete in {0} seconds", timeout));
  281. throw new RoutineFaildException();
  282. }
  283. else
  284. throw new RoutineBreakException();
  285. }
  286. }
  287. public void PickRetract(int id, ModuleName chamber, int slot, Hand hand, int timeout)
  288. {
  289. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  290. {
  291. Notify("robot execute pick retract command");
  292. _target.NoteTransferStart(ModuleName.TMRobot, hand, slot, EnumTransferType.Pick);
  293. if (!_robotModule.RobotDevice.PickRetract((RobotArmEnum)(int)hand, chamber.ToString(), slot))
  294. {
  295. return false;
  296. }
  297. return true;
  298. }, () =>
  299. {
  300. if (_robotModule.RobotDevice.IsError)
  301. return null;
  302. if (_robotModule.RobotDevice.IsIdle)
  303. return true;
  304. return false;
  305. }, timeout * 1000);
  306. if (ret.Item1)
  307. {
  308. if (ret.Item2 == Result.FAIL)
  309. {
  310. Stop(string.Format("failed."));
  311. throw new RoutineFaildException();
  312. }
  313. else if (ret.Item2 == Result.TIMEOUT) //timeout
  314. {
  315. Stop(string.Format("timeout, can not complete in {0} seconds", timeout));
  316. throw new RoutineFaildException();
  317. }
  318. else
  319. throw new RoutineBreakException();
  320. }
  321. }
  322. public void PrepareTransfer(int id, PMModuleBase pm, Hand hand, int slot, EnumTransferType type, int timeout, double temp1, double temp2, bool enableCheckTemp)
  323. {
  324. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  325. {
  326. Notify($"{pm.Name} prepare transfer ");
  327. if (!pm.PrepareTransfer(ModuleName.TMRobot, hand, slot, type, temp1, temp2, enableCheckTemp, out string reason))
  328. {
  329. Stop(reason);
  330. return false;
  331. }
  332. return true;
  333. }, () =>
  334. {
  335. if (pm.IsError)
  336. {
  337. return null;
  338. }
  339. return pm.IsReady;
  340. }, timeout * 1000);
  341. if (ret.Item1)
  342. {
  343. if (ret.Item2 == Result.FAIL)
  344. {
  345. Stop($"{pm.Name} error");
  346. throw new RoutineFaildException();
  347. }
  348. else if (ret.Item2 == Result.TIMEOUT) //timeout
  349. {
  350. Stop($"{pm.Name} prepare transfer timeout, over {timeout} seconds");
  351. throw new RoutineFaildException();
  352. }
  353. else
  354. throw new RoutineBreakException();
  355. }
  356. }
  357. public void TransferHandoff(int id, PMModuleBase pm, Hand hand, int slot, EnumTransferType type, int timeout)
  358. {
  359. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  360. {
  361. Notify($"{pm.Name} transfer handoff");
  362. if (!pm.TransferHandoff(ModuleName.TMRobot, hand, slot, type, out string reason))
  363. {
  364. Stop(reason);
  365. return false;
  366. }
  367. return true;
  368. }, () =>
  369. {
  370. if (pm.IsError)
  371. {
  372. return null;
  373. }
  374. return pm.IsReady;
  375. }, timeout * 1000);
  376. if (ret.Item1)
  377. {
  378. if (ret.Item2 == Result.FAIL)
  379. {
  380. Stop($"{pm.Name} error");
  381. throw new RoutineFaildException();
  382. }
  383. else if (ret.Item2 == Result.TIMEOUT) //timeout
  384. {
  385. Stop($"{pm.Name} transfer handoff timeout, over {timeout} seconds");
  386. throw new RoutineFaildException();
  387. }
  388. else
  389. throw new RoutineBreakException();
  390. }
  391. }
  392. public void PostTransfer(int id, PMModuleBase pm, Hand hand, int slot, EnumTransferType type, int timeout)
  393. {
  394. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  395. {
  396. Notify($"{pm.Name} post transfer ");
  397. if (!pm.PostTransfer(ModuleName.TMRobot, hand, slot, type, out string reason))
  398. {
  399. Stop(reason);
  400. return false;
  401. }
  402. return true;
  403. }, () =>
  404. {
  405. if (pm.IsError)
  406. {
  407. return null;
  408. }
  409. return pm.IsReady;
  410. }, timeout * 1000);
  411. if (ret.Item1)
  412. {
  413. if (ret.Item2 == Result.FAIL)
  414. {
  415. Stop($"{pm.Name} error");
  416. throw new RoutineFaildException();
  417. }
  418. else if (ret.Item2 == Result.TIMEOUT) //timeout
  419. {
  420. Stop($"{pm.Name} post transfer timeout, over {timeout} seconds");
  421. throw new RoutineFaildException();
  422. }
  423. else
  424. throw new RoutineBreakException();
  425. }
  426. }
  427. }
  428. }