PlaceRoutine.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  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 EFEMSC;
  13. using MECF.Framework.Common.Equipment;
  14. using MECF.Framework.Common.SubstrateTrackings;
  15. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts;
  16. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots;
  17. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase;
  18. using Aitex.Core.RT.Log;
  19. namespace EFEM.RT.Routines
  20. {
  21. public class PlaceRoutine : CommonRoutine, IRoutine, IEfemPlaceRoutine
  22. {
  23. enum Place
  24. {
  25. QueryState,
  26. OpenLoadLockDoor,
  27. CoolBufferMoveUP,
  28. WaitCoolBufferMoveUP,
  29. CheckBeforePlace,
  30. QueryRobotParameter,
  31. RobotServoOff,
  32. WaitRobotServoOff,
  33. SetWaferSizeParameter0000,
  34. SetWaferSizeParameter0114,
  35. RobotServoOn,
  36. WaitRobotServoOn,
  37. PlaceWafer,
  38. WaitPlace,
  39. CloseLoadLockDoor,
  40. CoolBufferMoveDown,
  41. WaitCoolBufferMoveDown,
  42. CheckAfterPlace,
  43. XMove,
  44. PostMessage,
  45. RobotBusytoSimifOn,
  46. RobotBusytoSimifOff,
  47. PinDown,
  48. CheckWaferPrecense,
  49. WaitCheckWaferPrecense,
  50. CheckWaferPrecenseAfterPlace,
  51. QuerySignalStatus,
  52. RobotBladeGrip
  53. }
  54. protected bool MultiWaferSize = DeviceDefineManager.Instance.GetValue<bool>("MultiWaferSize") ?? false;
  55. protected bool EnableMoveInDiffSlotsNumLP
  56. {
  57. get
  58. {
  59. if (SC.ContainsItem("System.IsEnableMoveInDiffSlotsNumLP"))
  60. return SC.GetValue<bool>("System.IsEnableMoveInDiffSlotsNumLP");
  61. return false;
  62. }
  63. }
  64. private SCConfigItem _scPlaceTimeout = null;
  65. private int _timeout = 0;
  66. private int _axisTimeout = 0;
  67. private int _axisSpeed = 0;
  68. private int _alignerdelay = 0;
  69. private int _coolingdelay = 0;
  70. private int delaytime = 0;
  71. public PlaceRoutine(string module, string name)
  72. {
  73. Module = module;Name = name;
  74. _alignerdelay = SC.GetValue<int>("System.AlignerPinDownDelay");
  75. _coolingdelay = SC.GetValue<int>("System.CoolingPinDownDelay");
  76. _scPlaceTimeout = SC.GetConfigItem(SorterCommon.ScPathName.Robot_TimeLimitForPlaceWafer);
  77. if (HaveMotionAxis)
  78. {
  79. _axisTimeout = SC.GetValue<int>("MotionAxis.MoveTimeout");
  80. _axisSpeed = SC.GetValue<int>("MotionAxis.AutoSpeed");
  81. }
  82. }
  83. public bool Initalize()
  84. {
  85. IsStopped = true;
  86. return true;
  87. }
  88. public ModuleName Station { get; set; }
  89. public int Slot { get; set; }
  90. public Hand Blade { get; set; }
  91. public LoadPort _lpDevice;
  92. private bool _skipWait;
  93. public Result Start(params object[] objs)
  94. {
  95. IsStopped = false;
  96. Name = "Place";
  97. Reset();
  98. _timeout = robot.RobotCommandTimeout;
  99. if (ModuleHelper.IsCoolingBuffer(Station))
  100. delaytime = _coolingdelay*1000;
  101. else delaytime = _alignerdelay*1000;
  102. EV.PostMessage(ModuleName.System.ToString(), EventEnum.PuttingWaferToChamberBegins, string.Format("{0}{1:D2} by {2}", Station.ToString(), Slot + 1, Blade.ToString()));
  103. return Result.RUN;
  104. }
  105. public Result Monitor()
  106. {
  107. try
  108. {
  109. if (IsStopped) return Result.DONE;
  110. if (ModuleHelper.IsCoolingBuffer(Station)|| ModuleHelper.IsAligner(Station))
  111. {
  112. //QueryCoolBufferState((int)Place.QueryState, GetCoolBuffer(Station));
  113. CoolBufferMoveUP((int)Place.CoolBufferMoveUP, GetCoolBuffer(Station), WaferManager.Instance.GetWaferSize(ModuleName.Robot, 0), _timeout, Notify, Stop);
  114. WaitCoolBufferMoveUp((int)Place.WaitCoolBufferMoveUP, GetCoolBuffer(Station), "Wait CoolingBuffer Move Up...", _timeout, Notify, Stop);
  115. }
  116. CheckBladeWaferIsExist((int)Place.CheckWaferPrecense, robot, Blade, _timeout);
  117. // RobotSignalStatus((int)Place.QuerySignalStatus, robot, _timeout);
  118. WaitRobotMotion((int)Place.WaitCheckWaferPrecense, robot, "Wait finish check wafer", _timeout, Notify, Stop);
  119. CheckBeforePlace((int)Place.CheckBeforePlace, "Check wafer before place", Station, Slot, Blade, Notify, Stop);
  120. //GripRobotBlade((int)Place.RobotBladeGrip, Blade, robot, _timeout);
  121. if (!ModuleHelper.IsLoadLock(Station))
  122. {
  123. PlaceWafer((int)Place.PlaceWafer, "Place wafer", Station, Slot, Blade, OffsetX, OffsetY, OffsetZ, Notify, Stop);
  124. this.WaitRobotMotion((int)Place.WaitPlace, robot, "Wait wafer placed", _timeout, Notify, Stop);
  125. }
  126. if (LoadLockDoorControlByStation && ModuleHelper.IsLoadLock(Station) && !Singleton<EfemEntity>.Instance.IsOnlineMode)
  127. {
  128. LoadLockCloseAtmDoor((int)Place.CloseLoadLockDoor, DEVICE.GetDevice<LoadLockDevice>(Station.ToString()), "Wait Atm Door Close", _timeout, Notify, Stop);
  129. }
  130. //为了提高上位机调度效率,机械手放片在上面就认为place指令完成。pin落下的时间和指令从上位机发送
  131. //为了保持兼容性,暂时判断了是否上位机控制,需要等cycle功能做好,这里都统一成外部控制lift pin
  132. if (!Singleton<EfemEntity>.Instance.IsOnlineMode)
  133. {
  134. if (ModuleHelper.IsCoolingBuffer(Station) || ModuleHelper.IsAligner(Station))
  135. {
  136. TimeDelay((int)Place.PinDown, delaytime);
  137. CoolBufferMoveDown((int)Place.CoolBufferMoveDown, GetCoolBuffer(Station), WaferManager.Instance.GetWaferSize(Station, Slot), _timeout, Notify, Stop);
  138. WaitCoolBufferMoveDown((int)Place.WaitCoolBufferMoveDown, GetCoolBuffer(Station), "Wait CoolingBuffer Move Down...", _timeout, Notify, Stop);
  139. }
  140. }
  141. PostMessage((int)Place.PostMessage, string.Format("{0}{1:D2} by {2}", Station.ToString(), Slot + 1, Blade.ToString()));
  142. //CheckBladeWaferIsExist((int)Place.CheckWaferPrecenseAfterPlace, robot, Blade, _timeout);
  143. CheckAfterPlace((int)Place.CheckAfterPlace, "Check wafer information after wafer placed", Station, Slot, Blade, Notify, Stop);
  144. }
  145. catch (RoutineBreakException)
  146. {
  147. if (!IsActived(TokenId) && !_skipWait)
  148. {
  149. _skipWait = true;
  150. return Monitor();
  151. }
  152. return Result.RUN;
  153. }
  154. catch (RoutineFaildException)
  155. {
  156. IsStopped = true;
  157. return Result.FAIL;
  158. }
  159. IsStopped = true;
  160. return Result.DONE;
  161. }
  162. protected override void Notify(string message)
  163. {
  164. EV.PostMessage(Module, EventEnum.GeneralInfo, String.Format("Place sequence:{0}", message));
  165. }
  166. /// <summary>
  167. /// prepare process failed
  168. /// </summary>
  169. /// <param name="failReason"></param>
  170. /// <param name="reactor"></param>
  171. protected override void Stop(string failReason)
  172. {
  173. string reason = String.Empty;
  174. EV.PostMessage(ModuleName.System.ToString(), EventEnum.PlaceWaferFailed, Station.ToString(), Slot + 1, Blade.ToString(), failReason);
  175. }
  176. public void PlaceWafer(int id, string name, ModuleName chamber, int slot, Hand blade, Action<string> notify, Action<string> error)
  177. {
  178. Tuple<bool, Result> ret = Execute(id, () =>
  179. {
  180. notify(String.Format("Place wafer to {0}", chamber.ToString()));
  181. string reason = string.Empty;
  182. return robot.Place((RobotArmEnum)(int)blade, chamber.ToString(), slot);
  183. });
  184. if (ret.Item1)
  185. {
  186. if (ret.Item2 == Result.FAIL)
  187. {
  188. throw (new RoutineFaildException());
  189. }
  190. }
  191. }
  192. public void CheckBeforePlace(int id, string name, ModuleName chamber, int slot, Hand blade, Action<string> notify, Action<string> error)
  193. {
  194. Tuple<bool, Result> ret = Execute(id, () =>
  195. {
  196. notify(String.Format("Check {0}{1:D2} wafer information before place wafer", chamber.ToString(), slot));
  197. string reason = string.Empty;
  198. if (!CheckRobotMotionInterlock(chamber, slot, out reason))
  199. {
  200. EV.PostMessage(ModuleName.System.ToString(), EventEnum.TransferPrepareFailed, String.Format("Target {0}{1:D2},{2}", chamber.ToString(), slot + 1, reason));
  201. return false;
  202. }
  203. if (blade == Hand.Blade1)
  204. {
  205. bool bNoWafer = WaferManager.Instance.CheckWafer(chamber, slot, WaferStatus.Empty);
  206. if (!bNoWafer)
  207. {
  208. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferPresentWithRecord, String.Format("Target {0}{1:D2}", chamber.ToString(), slot + 1));
  209. return false;
  210. }
  211. bool bHasWafer = WaferManager.Instance.CheckWafer(ModuleName.Robot, (int)blade, WaferStatus.Normal);
  212. if (!bHasWafer)
  213. {
  214. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferNotDetectedBeforeSend);
  215. return false;
  216. }
  217. bHasWafer = CheckSeneorHasWafer(ModuleName.Robot, (int)blade); //check sensor
  218. if (!bHasWafer)
  219. {
  220. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferNotDetectedBeforeSend);
  221. return false;
  222. }
  223. if (IsEnableIdentifyThickness)
  224. {
  225. if (ModuleHelper.IsLoadPort(chamber))
  226. {
  227. if (SC.GetStringValue($"CarrierInfo.LowerThicknessType") != SC.GetStringValue($"CarrierInfo.{chamber}ThicknessType"))
  228. {
  229. EV.PostAlarmLog(ModuleName.System.ToString(), $"The wafer thickness of the lower arm is different from {chamber}.");
  230. return false;
  231. }
  232. }
  233. }
  234. }
  235. else if (blade == Hand.Blade2)
  236. {
  237. bool bHasWafer = true;
  238. for (int i = 0; i < robot.Blade2Slots; i++)
  239. {
  240. bool bNoWafer = WaferManager.Instance.CheckWafer(chamber, slot + i, WaferStatus.Empty);
  241. if (!bNoWafer)
  242. {
  243. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferPresentWithRecord, String.Format("Target {0}{1:D2}", chamber.ToString(), slot + i + 1));
  244. return false;
  245. }
  246. bHasWafer &= WaferManager.Instance.CheckWafer(ModuleName.Robot, (int)blade + i, WaferStatus.Normal);
  247. bool bSensorWafer = CheckSeneorHasWafer(ModuleName.Robot, (int)blade + i); //check sensor
  248. if (!bSensorWafer)
  249. {
  250. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferNotDetectedBeforeSend);
  251. return false;
  252. }
  253. }
  254. if (!bHasWafer)
  255. {
  256. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferNotDetectedBeforeSend);
  257. return false;
  258. }
  259. if (IsEnableIdentifyThickness)
  260. {
  261. if (ModuleHelper.IsLoadPort(chamber))
  262. {
  263. if (SC.GetStringValue($"CarrierInfo.UpperThicknessType") != SC.GetStringValue($"CarrierInfo.{chamber}ThicknessType"))
  264. {
  265. EV.PostAlarmLog(ModuleName.System.ToString(), $"The wafer thickness of the lower arm is different from {chamber}.");
  266. return false;
  267. }
  268. }
  269. }
  270. }
  271. else
  272. {
  273. bool bHasWafer = true;
  274. for (int i = 0; i < robot.Blade2Slots + 1; i++)
  275. {
  276. bool bNoWafer = WaferManager.Instance.CheckWafer(chamber, slot + i, WaferStatus.Empty);
  277. if (!bNoWafer)
  278. {
  279. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferPresentWithRecord, String.Format("Target {0}{1:D2}", chamber.ToString(), slot + i + 1));
  280. return false;
  281. }
  282. bHasWafer &= WaferManager.Instance.CheckWafer(ModuleName.Robot, (int)Hand.Blade1 + i, WaferStatus.Normal);
  283. bool bSensorWafer = CheckSeneorHasWafer(ModuleName.Robot, (int)Hand.Blade1 + i); //check sensor
  284. if (!bSensorWafer)
  285. {
  286. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferNotDetectedBeforeSend);
  287. return false;
  288. }
  289. if (ModuleHelper.IsLoadPort(chamber))
  290. {
  291. string arm = i == 0 ? "Lower" : "Upper";
  292. if (SC.GetStringValue($"CarrierInfo.{arm}ThicknessType") != SC.GetStringValue($"CarrierInfo.{chamber}ThicknessType"))
  293. {
  294. EV.PostAlarmLog(ModuleName.System.ToString(), $"The wafer thickness of the {arm} arm is different from {chamber}.");
  295. return false;
  296. }
  297. }
  298. }
  299. if (!bHasWafer)
  300. {
  301. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferNotDetectedBeforeSend);
  302. return false;
  303. }
  304. }
  305. if (ModuleHelper.IsCoolingBuffer(chamber))
  306. {
  307. IoCoolingBuffer buffer = DEVICE.GetDevice<IoCoolingBuffer>(chamber.ToString());
  308. if (!buffer.CheckPinUp())
  309. {
  310. EV.PostWarningLog(chamber.ToString(), "Can not place wafer to buffer, buffer isn't pick position.");
  311. return false;
  312. }
  313. }
  314. if (ModuleHelper.IsLoadPort(chamber))
  315. {
  316. //WaferSize size = WaferManager.Instance.GetWaferSize(ModuleName.Robot, (blade == Hand.Both) ? 0 : (int)blade);
  317. WaferInfo wafer = WaferManager.Instance.GetWafer(ModuleName.Robot, (blade == Hand.Both) ? 0 : (int)blade);
  318. LoadPortBaseDevice lp = DEVICE.GetDevice<LoadPortBaseDevice>(chamber.ToString());
  319. LoadPortBaseDevice lp1 = DEVICE.GetDevice<LoadPortBaseDevice>(((ModuleName)wafer.OriginStation).ToString());
  320. if (!EnableMoveInDiffSlotsNumLP &&lp1 != null&&lp1.ValidSlotsNumber != lp.ValidSlotsNumber)
  321. {
  322. EV.PostWarningLog(chamber.ToString(), "Can not place wafer to loadport, SlotsNumber is unmatch.");
  323. return false;
  324. }
  325. if (IsEnableMultiWaferSize)
  326. {
  327. //因为此手臂只有一个手抓
  328. WaferSize size = WaferManager.Instance.GetWaferSize(ModuleName.Robot, (blade == Hand.Both) ? 0 : (int)blade);
  329. lp = DEVICE.GetDevice<LoadPortBaseDevice>(chamber.ToString());
  330. if (size != lp.GetCurrentWaferSize())
  331. {
  332. EV.PostWarningLog(chamber.ToString(), "Can not place wafer to loadport, size is unmatch.");
  333. return false;
  334. }
  335. }
  336. }
  337. return true;
  338. });
  339. if (ret.Item1)
  340. {
  341. if (ret.Item2 == Result.FAIL)
  342. {
  343. error(String.Format("Check wafer information failed, can not place."));
  344. throw (new RoutineFaildException());
  345. }
  346. }
  347. }
  348. public void CheckAfterPlace(int id, string name, ModuleName chamber, int slot, Hand blade, Action<string> notify, Action<string> error)
  349. {
  350. Tuple<bool, Result> ret = Execute(id, () =>
  351. {
  352. notify(name);
  353. if (ModuleHelper.IsLoadLock(chamber) && Singleton<EfemEntity>.Instance.IsOnlineMode)
  354. {
  355. //online mode, DeleteWafer in LoadLock
  356. WaferManager.Instance.DeleteWafer(chamber, slot);
  357. }
  358. if (ModuleHelper.IsBuffer(chamber) && Singleton<EfemEntity>.Instance.IsOnlineMode)
  359. {
  360. //online mode, DeleteWafer in LoadLock
  361. WaferManager.Instance.DeleteWafer(chamber, slot);
  362. }
  363. if (blade == Hand.Blade1)
  364. {
  365. bool bNoWafer = CheckSensorNoWafer(ModuleName.Robot, (int)blade);
  366. if (!bNoWafer)
  367. {
  368. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferDetectedAfterSend);
  369. return false;
  370. }
  371. }
  372. else if (blade == Hand.Blade2)
  373. {
  374. for (int i = 0; i < robot.Blade2Slots; i++)
  375. {
  376. bool bNoWafer = CheckSensorNoWafer(ModuleName.Robot, (int)blade + i);
  377. if (!bNoWafer)
  378. {
  379. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferDetectedAfterSend);
  380. return false;
  381. }
  382. }
  383. }
  384. else
  385. {
  386. for (int i = 0; i < robot.Blade2Slots + 1; i++)
  387. {
  388. bool bNoWafer = CheckSensorNoWafer(ModuleName.Robot, (int)Hand.Blade1 + i);
  389. if (!bNoWafer)
  390. {
  391. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferDetectedAfterSend);
  392. return false;
  393. }
  394. }
  395. }
  396. return true;
  397. });
  398. if (ret.Item1)
  399. {
  400. if (ret.Item2 == Result.FAIL)
  401. {
  402. error(String.Format("Failed to check wafer information"));
  403. throw (new RoutineFaildException());
  404. }
  405. }
  406. }
  407. }
  408. }