PickRoutine.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. using System;
  2. using Aitex.Core.Common;
  3. using Aitex.Core.RT.Device;
  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.RT.EquipmentLibrary.HardwareUnits.Robot;
  9. using MECF.Framework.Common.Equipment;
  10. using MECF.Framework.Common.SubstrateTrackings;
  11. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts;
  12. using Aitex.Sorter.RT.SorterCommonFrame.Modules;
  13. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase;
  14. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Aligners.AlignersBase;
  15. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots;
  16. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase;
  17. using System.Threading;
  18. using Aitex.Core.RT.Log;
  19. using Aitex.Core.Util;
  20. using Aitex.Sorter.RT.SorterCommonFrame.SorterJobControl;
  21. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Flipper.FlipperBase;
  22. namespace Aitex.Sorter.RT.SorterCommonFrame.Routines
  23. {
  24. public class PickRoutine : CommonRoutineSorter, IRoutine
  25. {
  26. enum Pick
  27. {
  28. ReleaseAligner,
  29. WaitLastMotion,
  30. WaitAlignerReady,
  31. AlignerPostAction,
  32. TurnReady,
  33. WaitTurnReady,
  34. TurnTo0,
  35. WaitTurnTo0,
  36. CheckBeforePick,
  37. GoPickPosition,
  38. WaitGotoPos,
  39. PickWafer,
  40. WaitPick,
  41. UnGrip,
  42. WaitUngrip,
  43. RobotRetract,
  44. WaitRobotRetract,
  45. CheckAfterPick,
  46. TurnBack,
  47. WaitTurnBack,
  48. Finish,
  49. }
  50. public PickRoutine(string module, string name)
  51. {
  52. Module = module;
  53. Name =name;
  54. }
  55. public bool Initalize()
  56. {
  57. Reset();
  58. IsRoutineActive = false;
  59. return true;
  60. }
  61. public ModuleName Source { get; set; }
  62. public int Slot { get; set; }
  63. public Hand Blade { get; set; }
  64. public ModuleName RobotModulename { get; set; } = ModuleName.Robot;
  65. private bool _isNeedWaitTurnOverIdle;
  66. private bool _isNeedReleasePA;
  67. public Result Start(params object[] objs)
  68. {
  69. Reset();
  70. Robot = DEVICE.GetDevice<RobotBaseDevice>(RobotModulename.ToString());
  71. Aligner = DEVICE.GetDevice<AlignerBaseDevice>(ModuleName.Aligner.ToString());
  72. if (Blade == Hand.Blade1 && !Robot.Blade1Enable)
  73. {
  74. EV.PostAlarmLog(ModuleName.System.ToString(), $"Can not {Name}, {Blade} is not enable");
  75. return Result.FAIL;
  76. }
  77. if (Blade == Hand.Blade2 && !Robot.Blade2Enable)
  78. {
  79. EV.PostAlarmLog(ModuleName.System.ToString(), $"Can not {Name}, {Blade} is not enable");
  80. return Result.FAIL;
  81. }
  82. if (Blade == Hand.Blade1 || Blade == Hand.Blade2)
  83. {
  84. if (WaferManager.Instance.CheckHasWafer(RobotModulename, (int)Blade))
  85. {
  86. EV.PostAlarmLog(ModuleName.System.ToString(), $"Can not {Name}, there's wafer on {Blade}.");
  87. return Result.FAIL;
  88. }
  89. }
  90. if (Blade == Hand.Both)
  91. {
  92. if (WaferManager.Instance.CheckHasWafer(RobotModulename, 0))
  93. {
  94. EV.PostAlarmLog(ModuleName.System.ToString(), $"Can not {Name}, there's wafer on lower arm.");
  95. return Result.FAIL;
  96. }
  97. if (WaferManager.Instance.CheckHasWafer(RobotModulename, 1))
  98. {
  99. EV.PostAlarmLog(ModuleName.System.ToString(), $"Can not {Name}, there's wafer on upper arm.");
  100. return Result.FAIL;
  101. }
  102. }
  103. FixedTurnOverPosition = SC.ContainsItem("Process.FixedTurnOverPosition") ? SC.GetValue<bool>("Process.FixedTurnOverPosition") : true;
  104. if (Source == ModuleName.TurnOverStation && !_ioTurnOver.IsPlacement)
  105. {
  106. EV.PostAlarmLog(ModuleName.System.ToString(), $"Can not {Name}, destination no wafer.");
  107. return Result.FAIL;
  108. }
  109. if (!ModuleHelper.IsTurnOverStation(Source) && Source != ModuleName.Aligner)
  110. {
  111. if (!RobotOffsetConfig.Instance.GetPickOffset(Source, ref _offsetX, ref _offsetY, ref _offsetZ,
  112. out string reason))
  113. {
  114. EV.PostWarningLog(ModuleName.System.ToString(), $"Can not {Name}, {reason}");
  115. return Result.FAIL;
  116. }
  117. }
  118. else
  119. {
  120. _offsetX = 0;
  121. _offsetY = 0;
  122. _offsetY = 0;
  123. }
  124. if(ModuleHelper.IsAligner(Source))
  125. {
  126. if (!DEVICE.GetDevice<AlignerBaseDevice>(Source.ToString()).IsReady())
  127. {
  128. EV.PostAlarmLog(ModuleName.System.ToString(), "Aligner is not ready");
  129. return Result.FAIL;
  130. }
  131. _isNeedReleasePA = Aligner.IsNeedRelease;
  132. }
  133. if (ModuleHelper.IsLoadPort(Source))
  134. {
  135. var lp = DEVICE.GetDevice<LoadPortBaseDevice>(Source.ToString());
  136. if(lp.IsForbidAccessSlotAboveWafer() && Slot>0 && WaferManager.Instance.CheckHasWafer(Source,Slot-1))
  137. {
  138. EV.PostAlarmLog(ModuleName.System.ToString(), "Access dennied to the slot above wafer.");
  139. return Result.FAIL;
  140. }
  141. string reason;
  142. if(!lp.IsEnableTransferWafer(out reason))
  143. {
  144. EV.PostAlarmLog(ModuleName.System.ToString(), $"{Source} is not ready to transfer wafer:{reason}.");
  145. return Result.FAIL;
  146. }
  147. var wafer = WaferManager.Instance.GetWafer(Source, Slot);
  148. if(ModuleHelper.IsLoadPort((ModuleName)wafer.DestinationStation))
  149. {
  150. if(!Singleton<SorterJobManager>.Instance.CheckCarrierAccessPermit(Source, (ModuleName)wafer.DestinationStation))
  151. {
  152. EV.PostAlarmLog("System", $"Can't start pick routine: carrier access dennied.");
  153. return Result.FAIL;
  154. }
  155. }
  156. }
  157. if (ModuleHelper.IsTurnOverStation(Source) && !_ioTurnOver.IsReady)
  158. {
  159. _isNeedWaitTurnOverIdle = true;
  160. }
  161. else
  162. _isNeedWaitTurnOverIdle = false;
  163. if (ModuleHelper.IsTurnOverStation(Source))
  164. {
  165. _isTurnOverOn0deg = _ioTurnOver.CurrentFlipperPosition == FlipperPosEnum.FrontSide;
  166. }
  167. EV.PostInfoLog("System",$"Start picking wafer from station:{Source} slot:{Slot+1} with blade {Blade}");
  168. IsRoutineActive = true;
  169. return Monitor();
  170. }
  171. private bool _isTurnOverOn0deg;
  172. public Result Monitor()
  173. {
  174. if (!IsRoutineActive) return Result.DONE;
  175. var ret = MonitorRoutine();
  176. if (ret == Result.FAIL)
  177. {
  178. IsRoutineActive = false;
  179. }
  180. if (ret == Result.DONE)
  181. {
  182. IsRoutineActive = false;
  183. }
  184. return ret;
  185. }
  186. private Result MonitorRoutine()
  187. {
  188. try
  189. {
  190. if (!ModuleHelper.IsTurnOverStation(Source))
  191. {
  192. if (ModuleHelper.IsAligner(Source) && _isNeedReleasePA)
  193. {
  194. RtReleaseAligner((int)Pick.ReleaseAligner, Notify, Stop);
  195. if (ExecuteResult.Item1)
  196. {
  197. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  198. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  199. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  200. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  201. }
  202. RtWaitAlignerMotion((int)Pick.WaitAlignerReady, Aligner, "Wait Aligner Ready",Aligner.TimeLimitAlignWafer, Notify, Stop);
  203. if (ExecuteResult.Item1)
  204. {
  205. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  206. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  207. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  208. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  209. }
  210. }
  211. RtPickWafer((int)Pick.PickWafer, "Start pick wafer", Source, Slot, Blade, Robot.RobotCommandTimeout, _offsetX, _offsetY, _offsetZ, Notify, Stop);
  212. if (ExecuteResult.Item1)
  213. {
  214. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  215. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  216. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  217. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  218. }
  219. if (ModuleHelper.IsAligner(Source))
  220. {
  221. AlignerPostActionAfterPick((int)Pick.AlignerPostAction, Notify, Stop);
  222. if (ExecuteResult.Item1)
  223. {
  224. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  225. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  226. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  227. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  228. }
  229. }
  230. }
  231. else
  232. {
  233. if (_isNeedWaitTurnOverIdle)
  234. {
  235. RtWaitTurnOverMotion((int)Pick.WaitTurnReady, _ioTurnOver, _ioTurnOver.TimelimitAction, Notify, Stop);
  236. if (ExecuteResult.Item1)
  237. {
  238. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  239. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  240. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  241. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  242. }
  243. }
  244. if (FixedTurnOverPosition)
  245. {
  246. if (_isTurnOverOn0deg)
  247. {
  248. RtTurnOverTurn((int)Pick.TurnTo0, Notify, Stop);
  249. if (ExecuteResult.Item1)
  250. {
  251. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  252. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  253. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  254. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  255. }
  256. RtWaitTurnOverTurnTo180((int)Pick.WaitTurnTo0, _ioTurnOver, _ioTurnOver.TimelimitAction, Notify, Stop);
  257. if (ExecuteResult.Item1)
  258. {
  259. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  260. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  261. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  262. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  263. }
  264. }
  265. RtRobotArmGoReadyForPickFromTurnOver((int)Pick.GoPickPosition, Source, Slot, Blade, Robot.RobotCommandTimeout, Notify, Stop, GetWaferOffsetForTurnOverOn180());
  266. if (ExecuteResult.Item1)
  267. {
  268. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  269. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  270. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  271. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  272. }
  273. RtTurnOverUnGripWafer((int)Pick.UnGrip, Notify, Stop);
  274. if (ExecuteResult.Item1)
  275. {
  276. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  277. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  278. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  279. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  280. }
  281. RtWaitTurnOverUnGrip((int)Pick.WaitUngrip, _ioTurnOver, _ioTurnOver.TimelimitAction, Notify, Stop);
  282. if (ExecuteResult.Item1)
  283. {
  284. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  285. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  286. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  287. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  288. }
  289. RtPickWaferFromTurnOver((int)Pick.RobotRetract, Source, Slot, Blade, Robot.RobotCommandTimeout, Notify, Stop, GetWaferOffsetForTurnOverOn180());
  290. if (ExecuteResult.Item1)
  291. {
  292. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  293. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  294. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  295. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  296. }
  297. RtTurnOverTurnBack((int)Pick.TurnBack, Notify, Stop);
  298. if (ExecuteResult.Item1)
  299. {
  300. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  301. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  302. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  303. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  304. }
  305. }
  306. else
  307. {
  308. if (_isTurnOverOn0deg)
  309. {
  310. RtRobotArmGoReadyForPickFromTurnOver((int)Pick.GoPickPosition, Source, Slot, Blade, Robot.RobotCommandTimeout, Notify, Stop);
  311. if (ExecuteResult.Item1)
  312. {
  313. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  314. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  315. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  316. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  317. }
  318. RtTurnOverUnGripWafer((int)Pick.UnGrip, Notify, Stop);
  319. if (ExecuteResult.Item1)
  320. {
  321. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  322. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  323. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  324. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  325. }
  326. RtWaitTurnOverUnGrip((int)Pick.WaitUngrip, _ioTurnOver, _ioTurnOver.TimelimitAction, Notify, Stop);
  327. if (ExecuteResult.Item1)
  328. {
  329. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  330. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  331. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  332. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  333. }
  334. RtPickWaferFromTurnOver((int)Pick.RobotRetract, Source, Slot, Blade, Robot.RobotCommandTimeout, Notify, Stop);
  335. if (ExecuteResult.Item1)
  336. {
  337. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  338. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  339. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  340. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  341. }
  342. }
  343. else
  344. {
  345. RtRobotArmGoReadyForPickFromTurnOver((int)Pick.GoPickPosition, Source, Slot, Blade, Robot.RobotCommandTimeout, Notify, Stop, GetWaferOffsetForTurnOverOn180());
  346. if (ExecuteResult.Item1)
  347. {
  348. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  349. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  350. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  351. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  352. }
  353. RtTurnOverUnGripWafer((int)Pick.UnGrip, Notify, Stop);
  354. if (ExecuteResult.Item1)
  355. {
  356. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  357. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  358. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  359. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  360. }
  361. RtWaitTurnOverUnGrip((int)Pick.WaitUngrip, _ioTurnOver, _ioTurnOver.TimelimitAction, Notify, Stop);
  362. if (ExecuteResult.Item1)
  363. {
  364. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  365. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  366. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  367. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  368. }
  369. RtPickWaferFromTurnOver((int)Pick.RobotRetract, Source, Slot, Blade, Robot.RobotCommandTimeout, Notify, Stop, GetWaferOffsetForTurnOverOn180());
  370. if (ExecuteResult.Item1)
  371. {
  372. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  373. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  374. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  375. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  376. }
  377. }
  378. }
  379. }
  380. RtUpdateWaferSingleStepProcessState((int)Pick.Finish, "Update wafer single step process state", RobotModulename, 0, Blade,
  381. EnumWaferProcessStatus.Idle, Notify, Stop);
  382. if (ExecuteResult.Item1)
  383. {
  384. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  385. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  386. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  387. if (ExecuteResult.Item2 == Result.DONE) return Result.DONE;
  388. }
  389. EV.PostInfoLog("System", $"Complete picking wafer from station:{Source} slot:{Slot + 1} with blade {Blade}.");
  390. IsRoutineActive = false;
  391. return Result.DONE;
  392. }
  393. catch (Exception ex)
  394. {
  395. EV.PostAlarmLog("System", $"Failed to pick wafer from station:{Source} slot:{Slot + 1} with blade {Blade}.");
  396. LOG.Write(ex);
  397. IsRoutineActive = false;
  398. return Result.FAIL;
  399. }
  400. }
  401. }
  402. }