PickRoutine.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. using Aitex.Core.Common;
  2. using Aitex.Core.RT.Device;
  3. using Aitex.Core.RT.Device.Unit;
  4. using Aitex.Core.RT.Event;
  5. using Aitex.Core.RT.SCCore;
  6. using Aitex.Core.Util;
  7. using Aitex.Sorter.Common;
  8. using athosRT.Devices;
  9. using athosRT.Devices.PA;
  10. using athosRT.FSM;
  11. using athosRT.tool;
  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.Robot;
  17. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots;
  18. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase;
  19. using System;
  20. using System.Collections.Generic;
  21. using System.Diagnostics;
  22. using System.Linq;
  23. using System.Numerics;
  24. using System.Text;
  25. using System.Threading.Tasks;
  26. using static athosRT.Modules.FLP.FlipperEntity;
  27. using EV = athosRT.tool.EV;
  28. namespace athosRT.Modules.EFEMs.Routine
  29. {
  30. public class PickRoutine : ModuleRoutineBase, FSM.IRoutine
  31. {
  32. protected bool MultiWaferSize = Singleton<DeviceDefineManager>.Instance.GetValue<bool>(nameof(MultiWaferSize)).GetValueOrDefault();
  33. private SCConfigItem _scPickTimeout = null;
  34. private int _timeout = 0;
  35. private int _axisTimeout = 0;
  36. private int _axisSpeed = 0;
  37. public double WaitForPickTime = 0.0;
  38. private LoadPort _lpDevice;
  39. private bool _skipWait;
  40. protected readonly bool HaveMotionAxis = Singleton<DeviceDefineManager>.Instance.GetValue<bool>("MotionAxisInstalled").GetValueOrDefault();
  41. public ModuleName Source { get; set; }
  42. public int Slot { get; set; }
  43. public Hand Blade { get; set; }
  44. protected int OffsetX;
  45. protected int OffsetY;
  46. protected int OffsetZ;
  47. public RobotBaseDevice robot;
  48. protected Aligner aligner = null;
  49. protected IoCoolingBuffer buffer1 = null;
  50. protected IoCoolingBuffer buffer2 = null;
  51. protected PreAligner aligner1 = null;
  52. protected PreAligner aligner2 = null;
  53. protected LoadLockDevice ll1;
  54. protected LoadLockDevice ll2;
  55. protected IoCoolingBuffer _ioCoolBuffer;
  56. private int _existInterval = SC.GetValue<int>("Robot.Robot.ExistInterval");
  57. private bool _isFlipper = false;
  58. public PickRoutine(ModuleName module) : base(module)
  59. {
  60. robot = DEVICE.GetDevice<RobotBaseDevice>("Robot");
  61. _scPickTimeout = SC.GetConfigItem("Robot.TimeLimitForPickWafer");
  62. aligner = DEVICE.GetDevice<Aligner>("Aligner");
  63. buffer1 = DEVICE.GetDevice<IoCoolingBuffer>("CoolingBuffer1");
  64. buffer2 = DEVICE.GetDevice<IoCoolingBuffer>("CoolingBuffer2");
  65. aligner1 = DEVICE.GetDevice<PreAligner>("Aligner1");
  66. aligner2 = DEVICE.GetDevice<PreAligner>("Aligner2");
  67. if (!HaveMotionAxis)
  68. return;
  69. _axisTimeout = SC.GetValue<int>("MotionAxis.MoveTimeout");
  70. _axisSpeed = SC.GetValue<int>("MotionAxis.AutoSpeed");
  71. }
  72. public RState Start(params object[] objs)
  73. {
  74. Reset();
  75. _isFlipper = false;
  76. _timeout = robot.RobotCommandTimeout * 1000;
  77. ModuleName moduleName = ModuleName.System;
  78. string module = moduleName.ToString();
  79. object[] objArray = new object[1];
  80. moduleName = Source;
  81. objArray[0] = (object)string.Format("{0}{1:D2} by {2}", (object)moduleName.ToString(), (object)(this.Slot + 1), (object)this.Blade.ToString());
  82. //EV.PostMessage<EventEnum>(module, EventEnum.PickingWaferFromChamberBegins, objArray);
  83. if (ModuleHelper.IsTurnOverStation(Source))
  84. _isFlipper = true;
  85. if (Singleton<WaferManager>.Instance.CheckNoWafer(Source, Slot))
  86. {
  87. LogObject.Error("robot", $"cannot pick from Source:{Source} Slot:{Slot} to {Blade} as no wafer");
  88. return RState.Failed;
  89. }
  90. return Runner.Start(ModuleName.System, "PickRoutine");
  91. }
  92. public RState Monitor()
  93. {
  94. if (_isFlipper)
  95. Runner
  96. .Wait((int)PickStep.WaitForPickModuleIdle, CheckFlipperIsIdle, (int)WaitForPickTime * 1000)
  97. .Run((int)PickStep.NotifyFlipperPrepare, NotifyFlipperOpen, CheckFlipperOpen, 80 * 1000)
  98. .Run((int)PickStep.CheckBladeWaferIsExist, CheckBladeWaferIsExist, WaitRobotMotion, _timeout)
  99. .Run((int)PickStep.CheckBeforePick, NullFun, CheckBeforePick, _timeout)
  100. .Run((int)PickStep.PickWafer, PickWafer, WaitRobotMotion, 100000)
  101. .Run((int)PickStep.NotifyFlipperOver, NotifyFlipperClose, CheckFlipperIsIdle,_timeout)
  102. .End((int)PickStep.CheckAfterPick, NullFun, CheckAfterPick, _timeout);
  103. else
  104. Runner
  105. .Delay((int)PickStep.WaitForPickModuleIdle, (int)WaitForPickTime * 1000)
  106. .Run((int)PickStep.CoolBufferMoveUP, CoolBufferMoveUP, WaitCoolBufferMoveUp, _timeout)
  107. .Run((int)PickStep.CheckBladeWaferIsExist, CheckBladeWaferIsExist, WaitRobotMotion, _timeout)
  108. .Run((int)PickStep.CheckBeforePick, NullFun, CheckBeforePick, _timeout)
  109. .Run((int)PickStep.PickWafer, PickWafer, WaitRobotMotion, 100000)
  110. .End((int)PickStep.CheckAfterPick, NullFun,CheckAfterPick, _timeout);
  111. return Runner.Status;
  112. }
  113. private bool CheckAfterPick()
  114. {
  115. switch (Blade)
  116. {
  117. case Hand.Blade1:
  118. if (!CheckSeneorHasWafer(ModuleName.Robot, (int)Blade))
  119. {
  120. LogObject.Error("Robot", "Wafer Is Not Detected on blade1 After Pick");
  121. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferNotDetectedAfterPick);
  122. return false;
  123. }
  124. break;
  125. case Hand.Blade2:
  126. for (int index = 0; index < robot.Blade2Slots; ++index)
  127. {
  128. if (!CheckSeneorHasWafer(ModuleName.Robot, 1 + index))
  129. {
  130. LogObject.Error("Robot", "Wafer Is Not Detected on blade2 After Pick");
  131. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferNotDetectedAfterPick);
  132. return false;
  133. }
  134. }
  135. break;
  136. default:
  137. for (int slot1 = 0; slot1 < robot.Blade2Slots + 1; ++slot1)
  138. {
  139. if (!CheckSeneorHasWafer(ModuleName.Robot, slot1))
  140. {
  141. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferNotDetectedAfterPick);
  142. return false;
  143. }
  144. }
  145. break;
  146. }
  147. return true;
  148. }
  149. private bool PickWafer()
  150. {
  151. bool flag = OffsetX == 0 && OffsetY == 0 && OffsetZ == 0 ? robot.Pick((RobotArmEnum)Blade, Source.ToString(), Slot) : robot.PickEx((RobotArmEnum)Blade, Source.ToString(), Slot, (float)OffsetX, (float)OffsetY, (float)OffsetZ);
  152. if (flag)
  153. {
  154. LogObject.Info("robot",$"pick from Source:{Source} Slot:{Slot} to {Blade}");
  155. return true;
  156. }
  157. else
  158. {
  159. LogObject.Error("robot", $"cannot pick from Source:{Source} Slot:{Slot} to {Blade}");
  160. return false;
  161. }
  162. }
  163. private bool CheckBeforePick()
  164. {
  165. //"Check wafer information", this.Source, this.Slot, this.Blade,
  166. string reason ="";
  167. if (!CheckRobotMotionInterlock(Source, Slot, out reason))
  168. {
  169. LogObject.Error("System", reason);
  170. return false;
  171. }
  172. switch (Blade)
  173. {
  174. case Hand.Blade1:
  175. if (ModuleHelper.IsLoadLock(Source) && Singleton<EfemEntity>.Instance.IsOnlineMode)
  176. {
  177. //Singleton<WaferManager>.Instance.CreateWafer(Source, Slot, WaferStatus.Normal);
  178. }
  179. else if (!Singleton<WaferManager>.Instance.CheckWafer(Source, Slot, WaferStatus.Normal))
  180. {
  181. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferAbsentWithoutRecord, (object)string.Format("target {0}{1:D2}", (object)Source.ToString(), (object)(Slot + 1)));
  182. return false;
  183. }
  184. if (!Singleton<WaferManager>.Instance.CheckWafer(ModuleName.Robot, 0, WaferStatus.Empty))
  185. {
  186. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick);
  187. return false;
  188. }
  189. if (!CheckSensorNoWafer(ModuleName.Robot, 0))
  190. {
  191. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick);
  192. return false;
  193. }
  194. if (ModuleHelper.IsBuffer(Source) && !CheckSeneorHasWafer(Source, Slot))
  195. {
  196. EV.PostWarningLog(Source.ToString(), "Can not pick wafer from buffer, Buffer slot has no wafer.");
  197. return false;
  198. }
  199. break;
  200. case Hand.Blade2:
  201. bool flag1 = true;
  202. for (int index = 0; index < robot.Blade2Slots; ++index)
  203. {
  204. //if (ModuleHelper.IsLoadLock(Source) && Singleton<EfemEntity>.Instance.IsOnlineMode)
  205. // Singleton<WaferManager>.Instance.CreateWafer(Source, Slot, WaferStatus.Normal);
  206. //else
  207. // flag1 = Singleton<WaferManager>.Instance.CheckWafer(Source, Slot + index, WaferStatus.Normal);
  208. if (!Singleton<WaferManager>.Instance.CheckWafer(ModuleName.Robot, (int)(Blade + index), WaferStatus.Empty))
  209. {
  210. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick);
  211. return false;
  212. }
  213. if (!CheckSensorNoWafer(ModuleName.Robot, (int)(Blade + index)))
  214. {
  215. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick);
  216. return false;
  217. }
  218. if (ModuleHelper.IsBuffer(Source))
  219. {
  220. flag1 = CheckSeneorHasWafer(Source, Slot + index);
  221. if (!flag1)
  222. {
  223. EV.PostWarningLog(Source.ToString(), "Can not pick wafer from buffer, Buffer slot has no wafer.");
  224. return false;
  225. }
  226. }
  227. }
  228. if (!flag1)
  229. {
  230. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferAbsentWithoutRecord, string.Format("target {0}{1:D2}", (object)Source.ToString(), (object)(Slot + 1)));
  231. return false;
  232. }
  233. break;
  234. default:
  235. bool flag2 = true;
  236. for (int slot1 = 0; slot1 < robot.Blade2Slots + 1; ++slot1)
  237. {
  238. //if (ModuleHelper.IsLoadLock(Source) && Singleton<EfemEntity>.Instance.IsOnlineMode)
  239. // Singleton<WaferManager>.Instance.CreateWafer(Source, Slot, WaferStatus.Normal);
  240. //else
  241. // flag2 = Singleton<WaferManager>.Instance.CheckWafer(Source, Slot, WaferStatus.Normal);
  242. if (!Singleton<WaferManager>.Instance.CheckWafer(ModuleName.Robot, slot1, WaferStatus.Empty))
  243. {
  244. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick);
  245. return false;
  246. }
  247. if (!CheckSensorNoWafer(ModuleName.Robot, slot1))
  248. {
  249. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick);
  250. return false;
  251. }
  252. if (ModuleHelper.IsBuffer(Source) && Blade == Hand.Both)
  253. {
  254. flag2 &= this.CheckSeneorHasWafer(Source, Slot + slot1);
  255. if (!flag2)
  256. {
  257. EV.PostWarningLog(Source.ToString(), "Can not pick wafer from buffer, Buffer slot has no wafer.");
  258. return false;
  259. }
  260. }
  261. }
  262. if (!flag2)
  263. {
  264. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferAbsentWithoutRecord, string.Format("target {0}{1:D2}", (object)Source.ToString(), (object)Slot));
  265. return false;
  266. }
  267. break;
  268. }
  269. if (!ModuleHelper.IsCoolingBuffer(Source) || DEVICE.GetDevice<IoCoolingBuffer>(Source.ToString()).CheckPinUp())
  270. return true;
  271. EV.PostWarningLog(Source.ToString(), "Can not pick wafer from buffer, buffer isn't pick position.");
  272. return false;
  273. }
  274. private bool WaitRobotMotion()
  275. {
  276. if (!robot.IsBusy)
  277. {
  278. LogObject.Info("Robot", "Robot准备完毕");
  279. if (robot.IsError)
  280. {
  281. if (ModuleHelper.IsLoadPort(Source))
  282. Singleton<RouteManager1>.Instance.GetLP(Source).PostMsg(268435443);
  283. LogObject.Info("Robot", "Robot进入Error");
  284. return false;
  285. }
  286. return true;
  287. }
  288. else
  289. {
  290. //LogObject.Error("Robot", "等待Robot准备完毕");
  291. return false;
  292. }
  293. }
  294. private bool CheckBladeWaferIsExist()
  295. {
  296. //this.robot, this.Blade, this._timeout
  297. if (!robot.ReadParameter(new object[3] { "CheckWaferIsPresence", (Blade == Hand.Blade1 ? 0 : 1), _existInterval }))
  298. {
  299. //手臂上有wafer 无法pick
  300. LogObject.Error("Robot", "手臂上有片 无法pick");
  301. return false;
  302. }
  303. else
  304. {
  305. LogObject.Info("Robot", "手臂上无片 可以正常pick");
  306. return true;
  307. }
  308. }
  309. private bool WaitCoolBufferMoveUp()
  310. {
  311. if (ModuleHelper.IsCoolingBuffer(Source))
  312. {
  313. IoCoolingBuffer device = GetCoolBuffer(Source);
  314. if (!device.Error)
  315. return device.CheckMovedUp() && !device.Busy;
  316. return false;
  317. }
  318. return true;
  319. }
  320. private bool CoolBufferMoveUP()
  321. {
  322. //(4, this.GetCoolBuffer(this.Source), Singleton<WaferManager>.Instance.GetWaferSize(this.Source, this.Slot), this._timeout);
  323. if (ModuleHelper.IsCoolingBuffer(Source))
  324. {
  325. WaferSize size = Singleton<WaferManager>.Instance.GetWaferSize(Source, Slot);
  326. IoCoolingBuffer device = GetCoolBuffer(Source);
  327. try
  328. {
  329. return (device.CheckPinUp() || device.Move(size, true, out _)) ? true : false;
  330. }
  331. catch (Exception ex)
  332. {
  333. Trace.WriteLine($"{Name} Error:{ex}");
  334. LogObject.Error(Name, $"Error:{ex}");
  335. }
  336. }
  337. return true;
  338. }
  339. public void Abort()
  340. {
  341. }
  342. public IoCoolingBuffer GetCoolBuffer(ModuleName coolbufferName)
  343. {
  344. switch (coolbufferName)
  345. {
  346. //case ModuleName.Aligner1:
  347. // _ioCoolBuffer = aligner1;
  348. // break;
  349. //case ModuleName.Aligner2:
  350. // _ioCoolBuffer = aligner2;
  351. // break;
  352. case ModuleName.CoolingBuffer1:
  353. _ioCoolBuffer = buffer1;
  354. break;
  355. case ModuleName.CoolingBuffer2:
  356. _ioCoolBuffer = buffer2;
  357. break;
  358. }
  359. return _ioCoolBuffer;
  360. }
  361. protected bool CheckRobotMotionInterlock(ModuleName chamber, int slot, out string reason)
  362. {
  363. LogObject.Info("Robot",$"chamber:{chamber},slot:{slot}");
  364. reason = string.Empty;
  365. if (robot.RobotState == RobotStateEnum.Error)
  366. {
  367. reason = "robot is error.";
  368. if(ModuleHelper.IsLoadPort(Source))
  369. Singleton<RouteManager1>.Instance.GetLP(Source).PostMsg(268435443);
  370. return false;
  371. }
  372. if (!robot.IsReady())
  373. {
  374. reason = string.Format("robot isn't Ready.");
  375. return false;
  376. }
  377. if (chamber == ModuleName.Aligner || ModuleHelper.IsTurnOverStation(chamber))
  378. {
  379. //if (aligner.Moving)
  380. //{
  381. // reason = string.Format("aligner is moving.");
  382. // return false;
  383. //}
  384. if (robot.IsReady())
  385. return true;
  386. reason = string.Format("aligner isn't Ready.");
  387. return false;
  388. }
  389. if (ModuleHelper.IsLoadPort(chamber))
  390. {
  391. LoadPortBaseDevice device = DEVICE.GetDevice<LoadPortBaseDevice>(chamber.ToString());
  392. string lpreason = string.Empty;
  393. if (!device.IsEnableTransferWafer(out reason))
  394. {
  395. reason = string.Format($"{chamber} isn't Ready.The reason is {lpreason}");
  396. return false;
  397. }
  398. if (device.MapError)
  399. {
  400. reason = string.Format("{0} Map has crossed error.", (object)chamber.ToString());
  401. return false;
  402. }
  403. if (ModuleHelper.IsLoadPort(chamber) && !Singleton<RouteManager1>.Instance.GetLP(chamber).IsLoaded)
  404. {
  405. if (Singleton<RouteManager1>.Instance.GetLP(chamber).IsDoorOpen)
  406. {
  407. reason = string.Format("{0} SMIF1PODOPEN signal is Off.", (object)chamber.ToString());
  408. return false;
  409. }
  410. if (Singleton<RouteManager1>.Instance.GetLP(chamber).IsPresent)
  411. {
  412. reason = string.Format("{0} SensorSMIF1PODPRESENT signal is Off,Foup is presence.", (object)chamber.ToString());
  413. return false;
  414. }
  415. if (Singleton<RouteManager1>.Instance.GetLP(chamber).IsReady)
  416. {
  417. reason = string.Format("{0} SensorSMIF1READY signal is Off.", (object)chamber.ToString());
  418. return false;
  419. }
  420. }
  421. return true;
  422. }
  423. if (ModuleHelper.IsLoadLock(chamber))
  424. {
  425. if (WaferManager.Instance.CheckNoWafer(chamber, 0))
  426. reason = "记录中该位置没有wafer";
  427. switch (chamber)
  428. {
  429. case ModuleName.LL1:
  430. case ModuleName.LLA:
  431. case ModuleName.PMA:
  432. if (!DeviceModel.LL1DoorIsOpen.Value)
  433. reason = $"{chamber}门信号未开启 无法传送";
  434. return DeviceModel.LL1DoorIsOpen.Value && WaferManager.Instance.CheckHasWafer(chamber, 0);
  435. case ModuleName.LL2:
  436. case ModuleName.LLB:
  437. case ModuleName.PMB:
  438. if (!DeviceModel.LL2DoorIsOpen.Value)
  439. reason = $"{chamber}门信号未开启 无法传送";
  440. return DeviceModel.LL2DoorIsOpen.Value && WaferManager.Instance.CheckHasWafer(chamber, 0);
  441. default:
  442. return true;
  443. }
  444. }
  445. //return DEVICE.GetDevice<LoadLockDevice>(chamber.ToString()).IsEnableTransferWafer(out reason);
  446. if (ModuleHelper.IsCoolingBuffer(chamber))
  447. {
  448. IoCoolingBuffer device = DEVICE.GetDevice<IoCoolingBuffer>(chamber.ToString());
  449. if (device.Busy)
  450. {
  451. reason = "buffer is not idle";
  452. return false;
  453. }
  454. if (device.CheckPinUp())
  455. return true;
  456. reason = "buffer pin not up position";
  457. return false;
  458. }
  459. if (ModuleHelper.IsAligner(chamber))
  460. {
  461. //Singleton<WaferManager>.Instance.CheckHasWafer(chamber, 1);
  462. //PreAligner device = DEVICE.GetDevice<PreAligner>(chamber.ToString());
  463. //if (device.Busy)
  464. //{
  465. // reason = "Aligner is not Idle";
  466. // return false;
  467. //}
  468. return true;
  469. }
  470. if (ModuleHelper.IsBuffer(chamber))
  471. {
  472. return true;
  473. }
  474. reason = "error target";
  475. return false;
  476. }
  477. protected bool CheckSensorNoWafer(ModuleName chamber, int slot)
  478. {
  479. if (SC.GetValue<bool>("System.IsSimulatorMode") || chamber != ModuleName.Robot)
  480. return Singleton<WaferManager>.Instance.CheckNoWafer(chamber, slot);
  481. return slot == 0 ? !robot.IsWaferPresenceOnBlade1 : !robot.IsWaferPresenceOnBlade2;
  482. }
  483. protected bool CheckSeneorHasWafer(ModuleName chamber, int slot)
  484. {
  485. if (SC.GetValue<bool>("System.IsSimulatorMode") || chamber != ModuleName.Robot)
  486. return Singleton<WaferManager>.Instance.CheckHasWafer(chamber, slot);
  487. return slot == 0 ? robot.IsWaferPresenceOnBlade1 : robot.IsWaferPresenceOnBlade2;
  488. }
  489. private bool CheckFlipperIsIdle()
  490. {
  491. return Singleton<RouteManager1>.Instance.GetFlipper().IsIdle;
  492. }
  493. private bool NotifyFlipperOpen()
  494. {
  495. Singleton<RouteManager1>.Instance.GetFlipper().PostMsg(FlipperMSG.PrepareTransfer);
  496. return true;
  497. }
  498. private bool NotifyFlipperClose()
  499. {
  500. Singleton<RouteManager1>.Instance.GetFlipper().PostMsg(FlipperMSG.EndTransfer);
  501. return true;
  502. }
  503. private bool CheckFlipperOpen()
  504. {
  505. if (!Singleton<RouteManager1>.Instance.GetFlipper().IsTransfer)
  506. {
  507. Singleton<RouteManager1>.Instance.GetFlipper().PostMsg(FlipperMSG.PrepareTransfer);
  508. return false;
  509. }
  510. else
  511. return true;
  512. }
  513. public enum PickStep
  514. {
  515. WaitForPickModuleIdle,
  516. CoolBufferMoveUP,
  517. CheckBladeWaferIsExist,
  518. CheckBeforePick,
  519. PickWafer,
  520. CheckAfterPick,
  521. NotifyFlipperPrepare,
  522. NotifyFlipperOver,
  523. }
  524. }
  525. }