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(Module, "Pick Routine");
  91. }
  92. public RState Monitor()
  93. {
  94. if (_isFlipper)
  95. Runner
  96. .Wait(PickStep.WaitForPickModuleIdle, CheckFlipperIsIdle, (int)WaitForPickTime * 1000)
  97. .Run(PickStep.NotifyFlipperPrepare, NotifyFlipperOpen, CheckFlipperOpen, 80 * 1000)
  98. .Run(PickStep.CheckBladeWaferIsExist, CheckBladeWaferIsExist, WaitRobotMotion, _timeout)
  99. .Run(PickStep.CheckBeforePick, NullFun, CheckBeforePick, _timeout)
  100. .Run(PickStep.PickWafer, PickWafer, WaitRobotMotion, 100000)
  101. .Run(PickStep.NotifyFlipperOver, NotifyFlipperClose, CheckFlipperIsIdle,_timeout)
  102. .End(PickStep.CheckAfterPick, NullFun, CheckAfterPick, _timeout);
  103. else
  104. Runner
  105. .Delay(PickStep.WaitForPickModuleIdle, (int)WaitForPickTime * 1000)
  106. .Run(PickStep.CoolBufferMoveUP, CoolBufferMoveUP, WaitCoolBufferMoveUp, _timeout)
  107. .Run(PickStep.CheckBladeWaferIsExist, CheckBladeWaferIsExist, WaitRobotMotion, _timeout)
  108. .Run(PickStep.CheckBeforePick, NullFun, CheckBeforePick, _timeout)
  109. .Run(PickStep.PickWafer, PickWafer, WaitRobotMotion, 100000)
  110. .End(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. {
  158. LogObject.Error("robot", $"cannot pick from Source:{Source} Slot:{Slot} to {Blade}");
  159. return false;
  160. }
  161. }
  162. private bool CheckBeforePick()
  163. {
  164. //"Check wafer information", this.Source, this.Slot, this.Blade,
  165. string reason ="";
  166. if (!CheckRobotMotionInterlock(Source, Slot, out reason))
  167. {
  168. LogObject.Error("System", reason);
  169. return false;
  170. }
  171. switch (Blade)
  172. {
  173. case Hand.Blade1:
  174. if (ModuleHelper.IsLoadLock(Source) && Singleton<EfemEntity>.Instance.IsOnlineMode)
  175. {
  176. //Singleton<WaferManager>.Instance.CreateWafer(Source, Slot, WaferStatus.Normal);
  177. }
  178. else if (!Singleton<WaferManager>.Instance.CheckWafer(Source, Slot, WaferStatus.Normal))
  179. {
  180. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferAbsentWithoutRecord, (object)string.Format("target {0}{1:D2}", (object)Source.ToString(), (object)(Slot + 1)));
  181. return false;
  182. }
  183. if (!Singleton<WaferManager>.Instance.CheckWafer(ModuleName.Robot, 0, WaferStatus.Empty))
  184. {
  185. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick);
  186. return false;
  187. }
  188. if (!CheckSensorNoWafer(ModuleName.Robot, 0))
  189. {
  190. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick);
  191. return false;
  192. }
  193. if (ModuleHelper.IsBuffer(Source) && !CheckSeneorHasWafer(Source, Slot))
  194. {
  195. EV.PostWarningLog(Source.ToString(), "Can not pick wafer from buffer, Buffer slot has no wafer.");
  196. return false;
  197. }
  198. break;
  199. case Hand.Blade2:
  200. bool flag1 = true;
  201. for (int index = 0; index < robot.Blade2Slots; ++index)
  202. {
  203. //if (ModuleHelper.IsLoadLock(Source) && Singleton<EfemEntity>.Instance.IsOnlineMode)
  204. // Singleton<WaferManager>.Instance.CreateWafer(Source, Slot, WaferStatus.Normal);
  205. //else
  206. // flag1 = Singleton<WaferManager>.Instance.CheckWafer(Source, Slot + index, WaferStatus.Normal);
  207. if (!Singleton<WaferManager>.Instance.CheckWafer(ModuleName.Robot, (int)(Blade + index), WaferStatus.Empty))
  208. {
  209. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick);
  210. return false;
  211. }
  212. if (!CheckSensorNoWafer(ModuleName.Robot, (int)(Blade + index)))
  213. {
  214. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick);
  215. return false;
  216. }
  217. if (ModuleHelper.IsBuffer(Source))
  218. {
  219. flag1 = CheckSeneorHasWafer(Source, Slot + index);
  220. if (!flag1)
  221. {
  222. EV.PostWarningLog(Source.ToString(), "Can not pick wafer from buffer, Buffer slot has no wafer.");
  223. return false;
  224. }
  225. }
  226. }
  227. if (!flag1)
  228. {
  229. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferAbsentWithoutRecord, string.Format("target {0}{1:D2}", (object)Source.ToString(), (object)(Slot + 1)));
  230. return false;
  231. }
  232. break;
  233. default:
  234. bool flag2 = true;
  235. for (int slot1 = 0; slot1 < robot.Blade2Slots + 1; ++slot1)
  236. {
  237. //if (ModuleHelper.IsLoadLock(Source) && Singleton<EfemEntity>.Instance.IsOnlineMode)
  238. // Singleton<WaferManager>.Instance.CreateWafer(Source, Slot, WaferStatus.Normal);
  239. //else
  240. // flag2 = Singleton<WaferManager>.Instance.CheckWafer(Source, Slot, WaferStatus.Normal);
  241. if (!Singleton<WaferManager>.Instance.CheckWafer(ModuleName.Robot, slot1, WaferStatus.Empty))
  242. {
  243. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick);
  244. return false;
  245. }
  246. if (!CheckSensorNoWafer(ModuleName.Robot, slot1))
  247. {
  248. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick);
  249. return false;
  250. }
  251. if (ModuleHelper.IsBuffer(Source) && Blade == Hand.Both)
  252. {
  253. flag2 &= this.CheckSeneorHasWafer(Source, Slot + slot1);
  254. if (!flag2)
  255. {
  256. EV.PostWarningLog(Source.ToString(), "Can not pick wafer from buffer, Buffer slot has no wafer.");
  257. return false;
  258. }
  259. }
  260. }
  261. if (!flag2)
  262. {
  263. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferAbsentWithoutRecord, string.Format("target {0}{1:D2}", (object)Source.ToString(), (object)Slot));
  264. return false;
  265. }
  266. break;
  267. }
  268. if (!ModuleHelper.IsCoolingBuffer(Source) || DEVICE.GetDevice<IoCoolingBuffer>(Source.ToString()).CheckPinUp())
  269. return true;
  270. EV.PostWarningLog(Source.ToString(), "Can not pick wafer from buffer, buffer isn't pick position.");
  271. return false;
  272. }
  273. private bool WaitRobotMotion()
  274. {
  275. if (!robot.IsBusy)
  276. {
  277. LogObject.Info("Robot", "Robot准备完毕");
  278. if (robot.IsError)
  279. {
  280. if (ModuleHelper.IsLoadPort(Source))
  281. Singleton<RouteManager1>.Instance.GetLP(Source).PostMsg(268435443);
  282. LogObject.Info("Robot", "Robot进入Error");
  283. return false;
  284. }
  285. return true;
  286. }
  287. else
  288. {
  289. //LogObject.Error("Robot", "等待Robot准备完毕");
  290. return false;
  291. }
  292. }
  293. private bool CheckBladeWaferIsExist()
  294. {
  295. //this.robot, this.Blade, this._timeout
  296. if (!robot.ReadParameter(new object[3] { "CheckWaferIsPresence", (Blade == Hand.Blade1 ? 0 : 1), _existInterval }))
  297. {
  298. //手臂上有wafer 无法pick
  299. LogObject.Error("Robot", "手臂上有片 无法pick");
  300. return false;
  301. }
  302. else
  303. {
  304. LogObject.Info("Robot", "手臂上无片 可以正常pick");
  305. return true;
  306. }
  307. }
  308. private bool WaitCoolBufferMoveUp()
  309. {
  310. if (ModuleHelper.IsCoolingBuffer(Source))
  311. {
  312. IoCoolingBuffer device = GetCoolBuffer(Source);
  313. if (!device.Error)
  314. return device.CheckMovedUp() && !device.Busy;
  315. return false;
  316. }
  317. return true;
  318. }
  319. private bool CoolBufferMoveUP()
  320. {
  321. //(4, this.GetCoolBuffer(this.Source), Singleton<WaferManager>.Instance.GetWaferSize(this.Source, this.Slot), this._timeout);
  322. if (ModuleHelper.IsCoolingBuffer(Source))
  323. {
  324. WaferSize size = Singleton<WaferManager>.Instance.GetWaferSize(Source, Slot);
  325. IoCoolingBuffer device = GetCoolBuffer(Source);
  326. try
  327. {
  328. return (device.CheckPinUp() || device.Move(size, true, out _)) ? true : false;
  329. }
  330. catch (Exception ex)
  331. {
  332. Trace.WriteLine($"{Name} Error:{ex}");
  333. LogObject.Error(Name, $"Error:{ex}");
  334. }
  335. }
  336. return true;
  337. }
  338. public void Abort()
  339. {
  340. }
  341. public IoCoolingBuffer GetCoolBuffer(ModuleName coolbufferName)
  342. {
  343. switch (coolbufferName)
  344. {
  345. //case ModuleName.Aligner1:
  346. // _ioCoolBuffer = aligner1;
  347. // break;
  348. //case ModuleName.Aligner2:
  349. // _ioCoolBuffer = aligner2;
  350. // break;
  351. case ModuleName.CoolingBuffer1:
  352. _ioCoolBuffer = buffer1;
  353. break;
  354. case ModuleName.CoolingBuffer2:
  355. _ioCoolBuffer = buffer2;
  356. break;
  357. }
  358. return _ioCoolBuffer;
  359. }
  360. protected bool CheckRobotMotionInterlock(ModuleName chamber, int slot, out string reason)
  361. {
  362. LogObject.Info("Robot",$"chamber:{chamber},slot:{slot}");
  363. reason = string.Empty;
  364. if (robot.RobotState == RobotStateEnum.Error)
  365. {
  366. reason = "robot is error.";
  367. if(ModuleHelper.IsLoadPort(Source))
  368. Singleton<RouteManager1>.Instance.GetLP(Source).PostMsg(268435443);
  369. return false;
  370. }
  371. if (!robot.IsReady())
  372. {
  373. reason = string.Format("robot isn't Ready.");
  374. return false;
  375. }
  376. if (chamber == ModuleName.Aligner || ModuleHelper.IsTurnOverStation(chamber))
  377. {
  378. //if (aligner.Moving)
  379. //{
  380. // reason = string.Format("aligner is moving.");
  381. // return false;
  382. //}
  383. if (robot.IsReady())
  384. return true;
  385. reason = string.Format("aligner isn't Ready.");
  386. return false;
  387. }
  388. if (ModuleHelper.IsLoadPort(chamber))
  389. {
  390. LoadPortBaseDevice device = DEVICE.GetDevice<LoadPortBaseDevice>(chamber.ToString());
  391. string lpreason = string.Empty;
  392. if (!device.IsEnableTransferWafer(out reason))
  393. {
  394. reason = string.Format($"{chamber} isn't Ready.The reason is {lpreason}");
  395. return false;
  396. }
  397. if (device.MapError)
  398. {
  399. reason = string.Format("{0} Map has crossed error.", (object)chamber.ToString());
  400. return false;
  401. }
  402. if (ModuleHelper.IsLoadPort(chamber) && !Singleton<RouteManager1>.Instance.GetLP(chamber).IsLoaded)
  403. {
  404. if (Singleton<RouteManager1>.Instance.GetLP(chamber).IsDoorOpen)
  405. {
  406. reason = string.Format("{0} SMIF1PODOPEN signal is Off.", (object)chamber.ToString());
  407. return false;
  408. }
  409. if (Singleton<RouteManager1>.Instance.GetLP(chamber).IsPresent)
  410. {
  411. reason = string.Format("{0} SensorSMIF1PODPRESENT signal is Off,Foup is presence.", (object)chamber.ToString());
  412. return false;
  413. }
  414. if (Singleton<RouteManager1>.Instance.GetLP(chamber).IsReady)
  415. {
  416. reason = string.Format("{0} SensorSMIF1READY signal is Off.", (object)chamber.ToString());
  417. return false;
  418. }
  419. }
  420. return true;
  421. }
  422. if (ModuleHelper.IsLoadLock(chamber))
  423. {
  424. if (WaferManager.Instance.CheckNoWafer(chamber, 0))
  425. reason = "记录中该位置没有wafer";
  426. switch (chamber)
  427. {
  428. case ModuleName.LL1:
  429. case ModuleName.LLA:
  430. case ModuleName.PMA:
  431. if (!DeviceModel.LL1DoorIsOpen.Value)
  432. reason = $"{chamber}门信号未开启 无法传送";
  433. return DeviceModel.LL1DoorIsOpen.Value && WaferManager.Instance.CheckHasWafer(chamber, 0);
  434. case ModuleName.LL2:
  435. case ModuleName.LLB:
  436. case ModuleName.PMB:
  437. if (!DeviceModel.LL2DoorIsOpen.Value)
  438. reason = $"{chamber}门信号未开启 无法传送";
  439. return DeviceModel.LL2DoorIsOpen.Value && WaferManager.Instance.CheckHasWafer(chamber, 0);
  440. default:
  441. return true;
  442. }
  443. }
  444. //return DEVICE.GetDevice<LoadLockDevice>(chamber.ToString()).IsEnableTransferWafer(out reason);
  445. if (ModuleHelper.IsCoolingBuffer(chamber))
  446. {
  447. IoCoolingBuffer device = DEVICE.GetDevice<IoCoolingBuffer>(chamber.ToString());
  448. if (device.Busy)
  449. {
  450. reason = "buffer is not idle";
  451. return false;
  452. }
  453. if (device.CheckPinUp())
  454. return true;
  455. reason = "buffer pin not up position";
  456. return false;
  457. }
  458. if (ModuleHelper.IsAligner(chamber))
  459. {
  460. //Singleton<WaferManager>.Instance.CheckHasWafer(chamber, 1);
  461. //PreAligner device = DEVICE.GetDevice<PreAligner>(chamber.ToString());
  462. //if (device.Busy)
  463. //{
  464. // reason = "Aligner is not Idle";
  465. // return false;
  466. //}
  467. return true;
  468. }
  469. if (ModuleHelper.IsBuffer(chamber))
  470. {
  471. return true;
  472. }
  473. reason = "error target";
  474. return false;
  475. }
  476. protected bool CheckSensorNoWafer(ModuleName chamber, int slot)
  477. {
  478. if (SC.GetValue<bool>("System.IsSimulatorMode") || chamber != ModuleName.Robot)
  479. return Singleton<WaferManager>.Instance.CheckNoWafer(chamber, slot);
  480. return slot == 0 ? !robot.IsWaferPresenceOnBlade1 : !robot.IsWaferPresenceOnBlade2;
  481. }
  482. protected bool CheckSeneorHasWafer(ModuleName chamber, int slot)
  483. {
  484. if (SC.GetValue<bool>("System.IsSimulatorMode") || chamber != ModuleName.Robot)
  485. return Singleton<WaferManager>.Instance.CheckHasWafer(chamber, slot);
  486. return slot == 0 ? robot.IsWaferPresenceOnBlade1 : robot.IsWaferPresenceOnBlade2;
  487. }
  488. private bool CheckFlipperIsIdle()
  489. {
  490. return Singleton<RouteManager1>.Instance.GetFlipper().IsIdle;
  491. }
  492. private bool NotifyFlipperOpen()
  493. {
  494. Singleton<RouteManager1>.Instance.GetFlipper().PostMsg(FlipperMSG.PrepareTransfer);
  495. return true;
  496. }
  497. private bool NotifyFlipperClose()
  498. {
  499. Singleton<RouteManager1>.Instance.GetFlipper().PostMsg(FlipperMSG.EndTransfer);
  500. return true;
  501. }
  502. private bool CheckFlipperOpen()
  503. {
  504. if (!Singleton<RouteManager1>.Instance.GetFlipper().IsTransfer)
  505. {
  506. Singleton<RouteManager1>.Instance.GetFlipper().PostMsg(FlipperMSG.PrepareTransfer);
  507. return false;
  508. }
  509. else
  510. return true;
  511. }
  512. public enum PickStep
  513. {
  514. WaitForPickModuleIdle,
  515. CoolBufferMoveUP,
  516. CheckBladeWaferIsExist,
  517. CheckBeforePick,
  518. PickWafer,
  519. CheckAfterPick,
  520. NotifyFlipperPrepare,
  521. NotifyFlipperOver,
  522. }
  523. }
  524. }