EfemTransferRoutine.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  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 EfemTransferRoutine : CommonRoutineSorter, IRoutine
  25. {
  26. enum Transfer
  27. {
  28. ReleaseAligner,
  29. QueryState,
  30. WaitLastMotion,
  31. WaitAlignerReady,
  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. PlaceSetAlignerWaferSize,
  49. PlaceRaiseAligner,
  50. PlaceWafer,
  51. Finish,
  52. }
  53. private int _timeout = 0;
  54. public EfemTransferRoutine(string module, string name)
  55. {
  56. Module = module;
  57. Name =name;
  58. }
  59. public bool Initalize()
  60. {
  61. Reset();
  62. IsRoutineActive = false;
  63. return true;
  64. }
  65. public ModuleName Source { get; set; }
  66. public int Slot { get; set; }
  67. public ModuleName Destination { get; set; }
  68. public int DestSlot { get; set; }
  69. public Hand PickBlade { get; set; }
  70. public Hand PlaceBlade { get; set; }
  71. private WaferSize _currentWaferSize;
  72. public ModuleName RobotModulename { get; set; } = ModuleName.Robot;
  73. private bool _isNeedWaitTurnOverIdle;
  74. private bool _isNeedReleasePA;
  75. private bool _isNeedToCheckAlginerWaferSize;
  76. private bool _isNeedAlignerPrepare;
  77. public Result Start(params object[] objs)
  78. {
  79. Reset();
  80. Robot = DEVICE.GetDevice<RobotBaseDevice>(RobotModulename.ToString());
  81. Aligner = DEVICE.GetDevice<AlignerBaseDevice>(ModuleName.Aligner.ToString());
  82. _timeout = Robot.RobotCommandTimeout;
  83. if (PickBlade == Hand.Blade1 || PickBlade == Hand.Blade2)
  84. {
  85. if (WaferManager.Instance.CheckHasWafer(RobotModulename, (int)PickBlade))
  86. {
  87. EV.PostAlarmLog(ModuleName.System.ToString(), $"Can not {Name}, there's wafer on {PickBlade}.");
  88. return Result.FAIL;
  89. }
  90. }
  91. if (PickBlade == Hand.Both)
  92. {
  93. if (WaferManager.Instance.CheckHasWafer(RobotModulename, 0))
  94. {
  95. EV.PostAlarmLog(ModuleName.System.ToString(), $"Can not {Name}, there's wafer on lower arm.");
  96. return Result.FAIL;
  97. }
  98. if (WaferManager.Instance.CheckHasWafer(RobotModulename, 1))
  99. {
  100. EV.PostAlarmLog(ModuleName.System.ToString(), $"Can not {Name}, there's wafer on upper arm.");
  101. return Result.FAIL;
  102. }
  103. }
  104. if(PickBlade != PlaceBlade)
  105. {
  106. if (PlaceBlade == Hand.Blade1 || PlaceBlade == Hand.Blade2)
  107. {
  108. if (!WaferManager.Instance.CheckHasWafer(RobotModulename, (int)PlaceBlade))
  109. {
  110. EV.PostAlarmLog(ModuleName.System.ToString(), $"Can not {Name}, there's no wafer on {PlaceBlade}.");
  111. return Result.FAIL;
  112. }
  113. }
  114. }
  115. FixedTurnOverPosition = SC.ContainsItem("Process.FixedTurnOverPosition") ? SC.GetValue<bool>("Process.FixedTurnOverPosition") : true;
  116. if (Source == ModuleName.TurnOverStation && !_ioTurnOver.IsPlacement)
  117. {
  118. EV.PostAlarmLog(ModuleName.System.ToString(), $"Can not {Name}, destination no wafer.");
  119. return Result.FAIL;
  120. }
  121. if (!ModuleHelper.IsTurnOverStation(Source) && Source != ModuleName.Aligner)
  122. {
  123. if (!RobotOffsetConfig.Instance.GetPickOffset(Source, ref _offsetX, ref _offsetY, ref _offsetZ,
  124. out string reason))
  125. {
  126. EV.PostWarningLog(ModuleName.System.ToString(), $"Can not {Name}, {reason}");
  127. return Result.FAIL;
  128. }
  129. }
  130. else
  131. {
  132. _offsetX = 0;
  133. _offsetY = 0;
  134. _offsetY = 0;
  135. }
  136. if(ModuleHelper.IsAligner(Source))
  137. {
  138. if (!DEVICE.GetDevice<AlignerBaseDevice>(Source.ToString()).IsReady())
  139. {
  140. EV.PostAlarmLog(ModuleName.System.ToString(), "Aligner is not ready");
  141. return Result.FAIL;
  142. }
  143. _isNeedReleasePA = Aligner.IsNeedRelease;
  144. }
  145. if (ModuleHelper.IsLoadPort(Source))
  146. {
  147. var lp = DEVICE.GetDevice<LoadPortBaseDevice>(Source.ToString());
  148. if(lp.IsForbidAccessSlotAboveWafer() && Slot>0 && WaferManager.Instance.CheckHasWafer(Source,Slot-1))
  149. {
  150. EV.PostAlarmLog(ModuleName.System.ToString(), "Access dennied to the slot above wafer.");
  151. return Result.FAIL;
  152. }
  153. string reason;
  154. if(!lp.IsEnableTransferWafer(out reason))
  155. {
  156. EV.PostAlarmLog(ModuleName.System.ToString(), $"{Source} is not ready to transfer wafer:{reason}.");
  157. return Result.FAIL;
  158. }
  159. var wafer = WaferManager.Instance.GetWafer(Source, Slot);
  160. if(ModuleHelper.IsLoadPort((ModuleName)wafer.DestinationStation))
  161. {
  162. if(!Singleton<SorterJobManager>.Instance.CheckCarrierAccessPermit(Source, (ModuleName)wafer.DestinationStation))
  163. {
  164. EV.PostAlarmLog("System", $"Can't start pick routine: carrier access dennied.");
  165. return Result.FAIL;
  166. }
  167. }
  168. }
  169. if (ModuleHelper.IsTurnOverStation(Source) && !_ioTurnOver.IsReady)
  170. {
  171. _isNeedWaitTurnOverIdle = true;
  172. }
  173. else
  174. _isNeedWaitTurnOverIdle = false;
  175. if (ModuleHelper.IsTurnOverStation(Source))
  176. {
  177. _isTurnOverOn0deg = _ioTurnOver.CurrentFlipperPosition == FlipperPosEnum.FrontSide;
  178. }
  179. if (ModuleHelper.IsAligner(Destination))
  180. {
  181. if (!DEVICE.GetDevice<AlignerBaseDevice>(Destination.ToString()).IsReady())
  182. {
  183. EV.PostAlarmLog(Destination.ToString(), $"{Destination} is not ready.");
  184. return Result.FAIL;
  185. }
  186. if (DEVICE.GetDevice<AlignerBaseDevice>(Destination.ToString()).IsWaferPresent(0))
  187. {
  188. EV.PostAlarmLog(Destination.ToString(), $"{Destination} wafer present.");
  189. return Result.FAIL;
  190. }
  191. _isNeedAlignerPrepare = Aligner.IsNeedPrepareBeforePlaceWafer();
  192. _currentWaferSize = WaferManager.Instance.GetWaferSize(Source, Slot);
  193. _isNeedToCheckAlginerWaferSize = Aligner.IsNeedChangeWaferSize(_currentWaferSize);
  194. }
  195. EV.PostInfoLog("System",$"Start transfer wafer from station:{Source} slot:{Slot+1} to {Destination} slot:{DestSlot+1} with pickk blade:{PickBlade} and place blade:{PlaceBlade}");
  196. IsRoutineActive = true;
  197. return Monitor();
  198. }
  199. private bool _isTurnOverOn0deg;
  200. public Result Monitor()
  201. {
  202. if (!IsRoutineActive) return Result.DONE;
  203. var ret = MonitorRoutine();
  204. if (ret == Result.FAIL)
  205. {
  206. Initalize();
  207. IsRoutineActive = false;
  208. }
  209. if (ret == Result.DONE)
  210. {
  211. IsRoutineActive = false;
  212. }
  213. return ret;
  214. }
  215. private Result MonitorRoutine()
  216. {
  217. try
  218. {
  219. if (!ModuleHelper.IsTurnOverStation(Source))
  220. {
  221. if (ModuleHelper.IsAligner(Source) && _isNeedReleasePA)
  222. {
  223. RtReleaseAligner((int)Transfer.ReleaseAligner, Notify, Stop);
  224. if (ExecuteResult.Item1)
  225. {
  226. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  227. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  228. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  229. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  230. }
  231. RtWaitAlignerMotion((int)Transfer.WaitAlignerReady, Aligner, "Wait Aligner Ready", _timeout, Notify, Stop);
  232. if (ExecuteResult.Item1)
  233. {
  234. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  235. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  236. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  237. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  238. }
  239. }
  240. RtPickWafer((int)Transfer.PickWafer, "Start pick wafer", Source, Slot, PickBlade, _timeout, _offsetX, _offsetY, _offsetZ, Notify, Stop);
  241. if (ExecuteResult.Item1)
  242. {
  243. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  244. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  245. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  246. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  247. }
  248. }
  249. else
  250. {
  251. if (_isNeedWaitTurnOverIdle)
  252. {
  253. RtWaitTurnOverMotion((int)Transfer.WaitTurnReady, _ioTurnOver, _ioTurnOver.TimelimitAction, Notify, Stop);
  254. if (ExecuteResult.Item1)
  255. {
  256. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  257. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  258. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  259. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  260. }
  261. }
  262. if (FixedTurnOverPosition)
  263. {
  264. if (_isTurnOverOn0deg)
  265. {
  266. RtTurnOverTurn((int)Transfer.TurnTo0, Notify, Stop);
  267. if (ExecuteResult.Item1)
  268. {
  269. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  270. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  271. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  272. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  273. }
  274. RtWaitTurnOverTurnTo180((int)Transfer.WaitTurnTo0, _ioTurnOver, _ioTurnOver.TimelimitAction, Notify, Stop);
  275. if (ExecuteResult.Item1)
  276. {
  277. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  278. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  279. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  280. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  281. }
  282. }
  283. RtRobotArmGoReadyForPickFromTurnOver((int)Transfer.GoPickPosition, Source, Slot, PickBlade, _timeout, Notify, Stop, GetWaferOffsetForTurnOverOn180());
  284. if (ExecuteResult.Item1)
  285. {
  286. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  287. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  288. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  289. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  290. }
  291. RtTurnOverUnGripWafer((int)Transfer.UnGrip, Notify, Stop);
  292. if (ExecuteResult.Item1)
  293. {
  294. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  295. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  296. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  297. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  298. }
  299. RtWaitTurnOverUnGrip((int)Transfer.WaitUngrip, _ioTurnOver, _ioTurnOver.TimelimitAction, Notify, Stop);
  300. if (ExecuteResult.Item1)
  301. {
  302. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  303. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  304. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  305. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  306. }
  307. RtPickWaferFromTurnOver((int)Transfer.RobotRetract, Source, Slot, PickBlade, _timeout, Notify, Stop, GetWaferOffsetForTurnOverOn180());
  308. if (ExecuteResult.Item1)
  309. {
  310. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  311. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  312. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  313. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  314. }
  315. RtTurnOverTurnBack((int)Transfer.TurnBack, Notify, Stop);
  316. if (ExecuteResult.Item1)
  317. {
  318. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  319. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  320. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  321. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  322. }
  323. }
  324. else
  325. {
  326. if (_isTurnOverOn0deg)
  327. {
  328. RtRobotArmGoReadyForPickFromTurnOver((int)Transfer.GoPickPosition, Source, Slot, PickBlade, _timeout, Notify, Stop);
  329. if (ExecuteResult.Item1)
  330. {
  331. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  332. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  333. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  334. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  335. }
  336. RtTurnOverUnGripWafer((int)Transfer.UnGrip, Notify, Stop);
  337. if (ExecuteResult.Item1)
  338. {
  339. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  340. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  341. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  342. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  343. }
  344. RtWaitTurnOverUnGrip((int)Transfer.WaitUngrip, _ioTurnOver, _ioTurnOver.TimelimitAction, Notify, Stop);
  345. if (ExecuteResult.Item1)
  346. {
  347. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  348. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  349. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  350. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  351. }
  352. RtPickWaferFromTurnOver((int)Transfer.RobotRetract, Source, Slot, PickBlade, _timeout, Notify, Stop);
  353. if (ExecuteResult.Item1)
  354. {
  355. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  356. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  357. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  358. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  359. }
  360. }
  361. else
  362. {
  363. RtRobotArmGoReadyForPickFromTurnOver((int)Transfer.GoPickPosition, Source, Slot, PickBlade, _timeout, Notify, Stop, GetWaferOffsetForTurnOverOn180());
  364. if (ExecuteResult.Item1)
  365. {
  366. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  367. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  368. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  369. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  370. }
  371. RtTurnOverUnGripWafer((int)Transfer.UnGrip, Notify, Stop);
  372. if (ExecuteResult.Item1)
  373. {
  374. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  375. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  376. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  377. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  378. }
  379. RtWaitTurnOverUnGrip((int)Transfer.WaitUngrip, _ioTurnOver, _ioTurnOver.TimelimitAction, Notify, Stop);
  380. if (ExecuteResult.Item1)
  381. {
  382. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  383. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  384. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  385. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  386. }
  387. RtPickWaferFromTurnOver((int)Transfer.RobotRetract, Source, Slot, PickBlade, _timeout, Notify, Stop, GetWaferOffsetForTurnOverOn180());
  388. if (ExecuteResult.Item1)
  389. {
  390. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  391. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  392. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  393. if (ExecuteResult.Item2 == Result.DONE) return Result.RUN;
  394. }
  395. }
  396. }
  397. }
  398. if (ModuleHelper.IsAligner(Destination) && _isNeedToCheckAlginerWaferSize)
  399. {
  400. RtAlignerSetWaferSize((int)Transfer.PlaceSetAlignerWaferSize, _currentWaferSize, _timeout, Notify, Stop);
  401. if (ExecuteResult.Item1)
  402. {
  403. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  404. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  405. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  406. if (ExecuteResult.Item2 == Result.DONE) return Result.DONE;
  407. }
  408. }
  409. if (ModuleHelper.IsAligner(Destination) && _isNeedAlignerPrepare)
  410. {
  411. RtAlignerPrepareAccept((int)Transfer.PlaceRaiseAligner, _timeout, Notify, Stop);
  412. if (ExecuteResult.Item1)
  413. {
  414. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  415. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  416. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  417. if (ExecuteResult.Item2 == Result.DONE) return Result.DONE;
  418. }
  419. }
  420. RtPlaceWafer((int)Transfer.PlaceWafer, "Place wafer", Destination, DestSlot, PlaceBlade, _timeout, _offsetX, _offsetY, _offsetZ, Notify, Stop);
  421. if (ExecuteResult.Item1)
  422. {
  423. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  424. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  425. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  426. if (ExecuteResult.Item2 == Result.DONE) return Result.DONE;
  427. }
  428. RtUpdateWaferSingleStepProcessState((int)Transfer.Finish, "Update wafer single step process state", Destination, DestSlot, PlaceBlade,
  429. EnumWaferProcessStatus.Idle, Notify, Stop);
  430. if (ExecuteResult.Item1)
  431. {
  432. if (ExecuteResult.Item2 == Result.RUN) return Result.RUN;
  433. if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL;
  434. if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL;
  435. if (ExecuteResult.Item2 == Result.DONE) return Result.DONE;
  436. }
  437. EV.PostInfoLog("System", $"Complete transfer wafer from station:{Source} slot:{Slot + 1} to {Destination} slot:{DestSlot}" +
  438. $"with blade {PlaceBlade}.");
  439. IsRoutineActive = false;
  440. return Result.DONE;
  441. }
  442. catch (Exception ex)
  443. {
  444. EV.PostAlarmLog("System", $"Failed to transfer wafer from station:{Source} slot:{Slot + 1} with blade {PickBlade}.");
  445. LOG.Write(ex);
  446. IsRoutineActive = false;
  447. return Result.FAIL;
  448. }
  449. }
  450. }
  451. }