PickRoutineInter.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. using System;
  2. using Aitex.Core.Common;
  3. using Aitex.Core.RT.Device;
  4. using Aitex.Core.RT.Device.Unit;
  5. using Aitex.Core.RT.Event;
  6. using Aitex.Core.RT.Routine;
  7. using Aitex.Core.RT.SCCore;
  8. using Aitex.Core.Util;
  9. using EFEM.RT.Devices;
  10. using EFEM.RT.Modules;
  11. using Aitex.Sorter.Common;
  12. using MECF.Framework.Common.Equipment;
  13. using MECF.Framework.Common.SubstrateTrackings;
  14. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts;
  15. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase;
  16. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots;
  17. namespace EFEM.RT.Routines
  18. {
  19. public class PickRoutineInter : CommonRoutine, IRoutine, IEfemPickRoutine
  20. {
  21. enum Pick
  22. {
  23. QueryState,
  24. CheckBeforePick,
  25. OpenLoadLockDoor,
  26. SetWaferSizeParameter0000,
  27. SetWaferSizeParameter0114,
  28. PickWafer,
  29. WaitPick,
  30. XMove,
  31. CloseLoadLockDoor,
  32. RobotTurnToReadyPosition,
  33. WaitRobotTurn,
  34. CheckAfterPick,
  35. }
  36. protected bool MultiWaferSize = DeviceDefineManager.Instance.GetValue<bool>("MultiWaferSize") ?? false;
  37. private SCConfigItem _scPickTimeout = null;
  38. private int _timeout = 0;
  39. private int _axisTimeout = 0;
  40. private int _axisSpeed = 0;
  41. public PickRoutineInter(string module, string name)
  42. {
  43. Module = module;
  44. name = "Pick";
  45. }
  46. public bool Initalize()
  47. {
  48. _scPickTimeout = SC.GetConfigItem(SorterCommon.ScPathName.Robot_TimeLimitForPickWafer);
  49. if (HaveMotionAxis)
  50. {
  51. _axisTimeout = SC.GetValue<int>("MotionAxis.MoveTimeout");
  52. _axisSpeed = SC.GetValue<int>("MotionAxis.AutoSpeed");
  53. }
  54. return true;
  55. }
  56. public ModuleName Source { get; set; }
  57. public int Slot { get; set; }
  58. public Hand Blade { get; set; }
  59. private LoadPortBaseDevice _lpDevice;
  60. public Result Start(params object[] objs)
  61. {
  62. Reset();
  63. _timeout = _scPickTimeout.IntValue;
  64. Name = "Pick";
  65. Reset();
  66. EV.PostMessage(ModuleName.System.ToString(), EventEnum.PickingWaferFromChamberBegins, string.Format("{0}{1:D2} by {2}", Source.ToString(), Slot + 1, Blade.ToString()));
  67. _lpDevice = DEVICE.GetDevice<LoadPortBaseDevice>(Source.ToString());
  68. //获取offset(两种情况)
  69. if (ModuleHelper.IsLoadLock(Source))
  70. {
  71. if (!RobotOffsetConfig.Instance.GetOffset(Source, RobotOffsetConfig.MotionName.GET, ref OffsetX, ref OffsetY, ref OffsetZ, out string reason))
  72. {
  73. EV.PostAlarmLog(ModuleName.System.ToString(), $"Can not {Name}, {reason}");
  74. return Result.FAIL;
  75. }
  76. }
  77. else
  78. {
  79. if (!RobotOffsetConfig.Instance.GetOffset(Source, ref OffsetX, ref OffsetY, ref OffsetZ, out string reason))
  80. {
  81. EV.PostAlarmLog(ModuleName.System.ToString(), $"Can not {Name}, {reason}");
  82. return Result.FAIL;
  83. }
  84. }
  85. return Result.RUN;
  86. }
  87. public Result Monitor()
  88. {
  89. try
  90. {
  91. //if (ModuleHelper.IsLoadPort(Source))
  92. // QueryLoadportState((int)Pick.QueryState, Source.ToString(), _timeout);
  93. if (ModuleHelper.IsLoadLock(Source) && LoadLockDoorControlByStation && !Singleton<EfemEntity>.Instance.IsOnlineMode)
  94. {
  95. LoadLockOpenAtmDoor((int)Pick.OpenLoadLockDoor, DEVICE.GetDevice<LoadLockDevice>(Source.ToString()), "Wait Atm Door Open", _timeout, Notify, Stop);
  96. }
  97. CheckBeforePick((int)Pick.CheckBeforePick, "Check wafer information", Source, Slot, Blade, Notify, Stop);
  98. if (ModuleHelper.IsLoadPort(Source) && MultiWaferSize)
  99. {
  100. SetWaferSize((int)Pick.SetWaferSizeParameter0000, "Set Wafer Size Parameter 0000", 0000, Source, Slot, _timeout, Notify, Stop);
  101. SetWaferSize((int)Pick.SetWaferSizeParameter0114, "Set Wafer Size Parameter 0114", 0114, Source, Slot, _timeout, Notify, Stop);
  102. }
  103. PickWafer((int)Pick.PickWafer, "Pick wafer", Source, Slot, Blade, OffsetX, OffsetY, OffsetZ, Notify, Stop);
  104. this.WaitRobotMotion((int)Pick.WaitPick, robot, "Wait picked", _timeout, Notify, Stop);
  105. if (ModuleHelper.IsLoadLock(Source) && LoadLockDoorControlByStation && !Singleton<EfemEntity>.Instance.IsOnlineMode)
  106. {
  107. LoadLockCloseAtmDoor((int)Pick.CloseLoadLockDoor, DEVICE.GetDevice<LoadLockDevice>(Source.ToString()), "Wait Atm Door Close", _timeout, Notify, Stop);
  108. }
  109. if (ModuleHelper.IsLoadLock(Source))
  110. {
  111. RobotMoveToPickReadyPosition((int)Pick.RobotTurnToReadyPosition, "Robot turn to ready position", ModuleName.LP1, 22, Blade, Notify, Stop);
  112. WaitRobotMotion((int)Pick.WaitRobotTurn, robot, "Wait robot turn", _timeout, Notify, Stop);
  113. }
  114. CheckAfterPick((int)Pick.CheckAfterPick, "Check wafer information", Source, Slot, Blade, Notify, Stop);
  115. }
  116. catch (RoutineBreakException)
  117. {
  118. return Result.RUN;
  119. }
  120. catch (RoutineFaildException)
  121. {
  122. return Result.FAIL;
  123. }
  124. EV.PostMessage(ModuleName.System.ToString(), EventEnum.PickingWaferFromChamberEnds, string.Format("{0}{1:D2} by {2}.", Source.ToString(), Slot + 1, Blade.ToString()));
  125. return Result.DONE;
  126. }
  127. public void RobotMoveToPickReadyPosition(int id, string name, ModuleName chamber, int slot, Hand blade, Action<string> notify, Action<string> error)
  128. {
  129. Tuple<bool, Result> ret = Execute(id, () =>
  130. {
  131. notify(String.Format("Pick ready position at {0}", chamber.ToString()));
  132. string reason = string.Empty;
  133. return robot.GoTo((RobotArmEnum)blade, chamber.ToString(), slot, RobotPostionEnum.PickReady);
  134. });
  135. if (ret.Item1)
  136. {
  137. if (ret.Item2 == Result.FAIL)
  138. {
  139. throw (new RoutineFaildException());
  140. }
  141. }
  142. }
  143. public void CheckBeforePick(int id, string name, ModuleName chamber, int slot, Hand blade, Action<string> notify, Action<string> error)
  144. {
  145. Tuple<bool, Result> ret = Execute(id, () =>
  146. {
  147. notify(name);
  148. string reason = string.Empty;
  149. if (!CheckRobotMotionInterlock(chamber, slot, out reason))
  150. {
  151. EV.PostMessage(ModuleName.System.ToString(), EventEnum.TransferPrepareFailed, String.Format("target {0}{1:D2},{2}", chamber.ToString(), slot + 1, reason));
  152. return false;
  153. }
  154. notify(String.Format("Check {0}{1:D2} wafer information", chamber.ToString(), slot));
  155. if (blade == Hand.Blade1)
  156. {
  157. if (ModuleHelper.IsLoadLock(chamber) && Singleton<EfemEntity>.Instance.IsOnlineMode)
  158. {
  159. //online mode, CreateWafer in LoadLock
  160. WaferManager.Instance.CreateWafer(chamber, slot, WaferStatus.Normal);
  161. }
  162. else
  163. {
  164. bool bHasWafer = WaferManager.Instance.CheckWafer(chamber, slot, WaferStatus.Normal);
  165. if (!bHasWafer)
  166. {
  167. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferAbsentWithoutRecord, String.Format("target {0}{1:D2}", chamber.ToString(), slot + 1));
  168. return false;
  169. }
  170. }
  171. bool bNoWafer = WaferManager.Instance.CheckWafer(ModuleName.Robot, 0, WaferStatus.Empty);
  172. if (!bNoWafer)
  173. {
  174. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick);
  175. return false;
  176. }
  177. bNoWafer = CheckSensorNoWafer(ModuleName.Robot, 0); //check sensor
  178. if (!bNoWafer)
  179. {
  180. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick);
  181. return false;
  182. }
  183. if (ModuleHelper.IsBuffer(chamber))
  184. {
  185. bool bHasWafer = CheckSeneorHasWafer(chamber, slot); //check sensor
  186. if (!bHasWafer)
  187. {
  188. EV.PostWarningLog(chamber.ToString(), "Can not pick wafer from buffer, Buffer slot has no wafer.");
  189. return false;
  190. }
  191. }
  192. }
  193. else if (blade == Hand.Blade2)
  194. {
  195. bool bHasWafer = true;
  196. for (int i = 0; i < robot.Blade2Slots; i++)
  197. {
  198. if (ModuleHelper.IsLoadLock(chamber) && Singleton<EfemEntity>.Instance.IsOnlineMode)
  199. {
  200. //online mode, CreateWafer in LoadLock
  201. WaferManager.Instance.CreateWafer(chamber, slot, WaferStatus.Normal);
  202. }
  203. else
  204. bHasWafer = WaferManager.Instance.CheckWafer(chamber, slot + i, WaferStatus.Normal);
  205. bool bNoWafer = WaferManager.Instance.CheckWafer(ModuleName.Robot, (int)blade + i, WaferStatus.Empty);
  206. if (!bNoWafer)
  207. {
  208. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick);
  209. return false;
  210. }
  211. bNoWafer = CheckSensorNoWafer(ModuleName.Robot, (int)blade + i); //check sensor
  212. if (!bNoWafer)
  213. {
  214. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick);
  215. return false;
  216. }
  217. if (ModuleHelper.IsBuffer(chamber))
  218. {
  219. bHasWafer = CheckSeneorHasWafer(chamber, slot + i); //check sensor
  220. if (!bHasWafer)
  221. {
  222. EV.PostWarningLog(chamber.ToString(), "Can not pick wafer from buffer, Buffer slot has no wafer.");
  223. return false;
  224. }
  225. }
  226. }
  227. if (!bHasWafer)
  228. {
  229. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferAbsentWithoutRecord, String.Format("target {0}{1:D2}", chamber.ToString(), slot + 1));
  230. return false;
  231. }
  232. }
  233. else
  234. {
  235. bool bHasWafer = true;
  236. for (int i = 0; i < robot.Blade2Slots + 1; i++)
  237. {
  238. if (ModuleHelper.IsLoadLock(chamber) && Singleton<EfemEntity>.Instance.IsOnlineMode)
  239. {
  240. //online mode, CreateWafer in LoadLock
  241. WaferManager.Instance.CreateWafer(chamber, slot, WaferStatus.Normal);
  242. }
  243. else
  244. bHasWafer = WaferManager.Instance.CheckWafer(chamber, slot, WaferStatus.Normal);
  245. bool bNoWafer = WaferManager.Instance.CheckWafer(ModuleName.Robot, (int)Hand.Blade1 + i, WaferStatus.Empty);
  246. if (!bNoWafer)
  247. {
  248. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick);
  249. return false;
  250. }
  251. bNoWafer = CheckSensorNoWafer(ModuleName.Robot, (int)Hand.Blade1 + i); //check sensor
  252. if (!bNoWafer)
  253. {
  254. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick);
  255. return false;
  256. }
  257. if (ModuleHelper.IsBuffer(chamber) && blade == Hand.Both)
  258. {
  259. bHasWafer &= CheckSeneorHasWafer(chamber, slot + i); //check sensor
  260. if (!bHasWafer)
  261. {
  262. EV.PostWarningLog(chamber.ToString(), "Can not pick wafer from buffer, Buffer slot has no wafer.");
  263. return false;
  264. }
  265. }
  266. }
  267. if (!bHasWafer)
  268. {
  269. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferAbsentWithoutRecord, String.Format("target {0}{1:D2}", chamber.ToString(), slot));
  270. return false;
  271. }
  272. }
  273. if (ModuleHelper.IsCoolingBuffer(chamber))
  274. {
  275. IoCoolingBuffer buffer = DEVICE.GetDevice<IoCoolingBuffer>(chamber.ToString());
  276. if (!buffer.CheckPinUp())
  277. {
  278. EV.PostWarningLog(chamber.ToString(), "Can not pick wafer from buffer, buffer isn't pick position.");
  279. return false;
  280. }
  281. }
  282. return true;
  283. });
  284. if (ret.Item1)
  285. {
  286. if (ret.Item2 == Result.FAIL)
  287. {
  288. error(String.Format("Failed to check wafer information."));
  289. throw (new RoutineFaildException());
  290. }
  291. }
  292. }
  293. public void CheckAfterPick(int id, string name, ModuleName chamber, int slot, Hand blade, Action<string> notify, Action<string> error)
  294. {
  295. Tuple<bool, Result> ret = Execute(id, () =>
  296. {
  297. notify(name);
  298. if (blade == Hand.Blade1)
  299. {
  300. bool bHasWafer = CheckSeneorHasWafer(ModuleName.Robot, (int)blade);
  301. if (!bHasWafer)
  302. {
  303. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferNotDetectedAfterPick);
  304. return false;
  305. }
  306. }
  307. else if (blade == Hand.Blade2)
  308. {
  309. for (int i = 0; i < robot.Blade2Slots; i++)
  310. {
  311. bool bHasWafer = CheckSeneorHasWafer(ModuleName.Robot, (int)Hand.Blade2 + i);
  312. if (!bHasWafer)
  313. {
  314. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferNotDetectedAfterPick);
  315. return false;
  316. }
  317. }
  318. }
  319. else
  320. {
  321. for (int i = 0; i < robot.Blade2Slots + 1; i++)
  322. {
  323. bool bHasWafer = CheckSeneorHasWafer(ModuleName.Robot, (int)Hand.Blade1 + i);
  324. if (!bHasWafer)
  325. {
  326. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferNotDetectedAfterPick);
  327. return false;
  328. }
  329. }
  330. }
  331. return true;
  332. });
  333. if (ret.Item1)
  334. {
  335. if (ret.Item2 == Result.FAIL)
  336. {
  337. error(String.Format("Failed to check wafer information."));
  338. throw (new RoutineFaildException());
  339. }
  340. }
  341. }
  342. }
  343. }