PlaceRoutine.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  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.Linq;
  22. using System.Numerics;
  23. using System.Text;
  24. using System.Threading.Tasks;
  25. using static athosRT.Modules.FLP.FlipperEntity;
  26. using EV = athosRT.tool.EV;
  27. namespace athosRT.Modules.EFEMs.Routine
  28. {
  29. public class PlaceRoutine : ModuleRoutineBase, FSM.IRoutine
  30. {
  31. private string _routinename = "PlaceRoutine";
  32. private string _errorhead = "cannot place for the reason:";
  33. protected bool MultiWaferSize = Singleton<DeviceDefineManager>.Instance.GetValue<bool>(nameof(MultiWaferSize)).GetValueOrDefault();
  34. private SCConfigItem _scPlaceTimeout = (SCConfigItem)null;
  35. private int _timeout = 0;
  36. private int _axisTimeout = 0;
  37. private int _axisSpeed = 0;
  38. private int _alignerdelay = 0;
  39. private int _coolingdelay = 0;
  40. private int delaytime = 0;
  41. public LoadPort _lpDevice;
  42. private bool _skipWait;
  43. protected readonly bool HaveMotionAxis = Singleton<DeviceDefineManager>.Instance.GetValue<bool>("MotionAxisInstalled").GetValueOrDefault();
  44. RobotBaseDevice robot = null;
  45. protected Aligner aligner = null;
  46. protected IoCoolingBuffer buffer1 = null;
  47. protected IoCoolingBuffer buffer2 = null;
  48. protected PreAligner aligner1 = null;
  49. protected PreAligner aligner2 = null;
  50. protected LoadLockDevice ll1 = null;
  51. protected LoadLockDevice ll2 = null;
  52. protected IoCoolingBuffer _ioCoolBuffer;
  53. private int _existInterval = SC.GetValue<int>("Robot.Robot.ExistInterval");
  54. protected static readonly bool LoadLockDoorControlByStation = Singleton<DeviceDefineManager>.Instance.GetValue<bool>("LLDoorControlByStation").GetValueOrDefault();
  55. public ModuleName Station { get; set; }
  56. protected int OffsetX;
  57. protected int OffsetY;
  58. protected int OffsetZ;
  59. public int Slot { get; set; }
  60. private bool _isFlipper = false;
  61. public Hand Blade { get; set; }
  62. //放置
  63. public PlaceRoutine(ModuleName module) : base(module)
  64. {
  65. robot = DEVICE.GetDevice<RobotBaseDevice>("Robot");
  66. _alignerdelay = SC.GetValue<int>("System.AlignerPinDownDelay");
  67. _coolingdelay = SC.GetValue<int>("System.CoolingPinDownDelay");
  68. _scPlaceTimeout = SC.GetConfigItem("Robot.TimeLimitForPlaceWafer");
  69. aligner = DEVICE.GetDevice<Aligner>("Aligner");
  70. buffer1 = DEVICE.GetDevice<IoCoolingBuffer>("CoolingBuffer1");
  71. buffer2 = DEVICE.GetDevice<IoCoolingBuffer>("CoolingBuffer2");
  72. aligner1 = DEVICE.GetDevice<PreAligner>("Aligner1");
  73. aligner2 = DEVICE.GetDevice<PreAligner>("Aligner2");
  74. if (!HaveMotionAxis)
  75. return;
  76. _axisTimeout = SC.GetValue<int>("MotionAxis.MoveTimeout");
  77. _axisSpeed = SC.GetValue<int>("MotionAxis.AutoSpeed");
  78. }
  79. public RState Start(params object[] objs)
  80. {
  81. Reset();
  82. _isFlipper = false;
  83. _alignerdelay = SC.GetValue<int>("System.AlignerPinDownDelay");
  84. _coolingdelay = SC.GetValue<int>("System.CoolingPinDownDelay");
  85. _timeout = robot.RobotCommandTimeout * 1000;
  86. if (!Singleton<EfemEntity>.Instance.IsOnlineMode && (ModuleHelper.IsCoolingBuffer(this.Station) || ModuleHelper.IsAligner(this.Station)))
  87. {
  88. delaytime = !ModuleHelper.IsCoolingBuffer(Station) ? _alignerdelay * 1000 : _coolingdelay * 1000;
  89. }
  90. else
  91. {
  92. delaytime = 0;
  93. }
  94. if (WaferManager.Instance.CheckHasWafer(Station, Slot))
  95. {
  96. LogObject.Error(Station.ToString(), "站点有wafer 无法Place");
  97. return RState.Failed;
  98. }
  99. if (ModuleHelper.IsTurnOverStation(Station))
  100. _isFlipper = true;
  101. //LogObject.Info("Place", "Place to Wa");
  102. return Runner.Start(Module, "Place Routine");
  103. }
  104. public enum PlaceStep
  105. {
  106. WaitForPlaceModuleIdle,
  107. CoolBufferMoveUP,
  108. CheckBladeWaferIsExist,
  109. CheckBeforePlace,
  110. PlaceWafer,
  111. LoadLockCloseAtmDoor,
  112. WaitForCoolBuffer,
  113. CoolBufferMoveDown,
  114. WaitCoolBufferMoveDown,
  115. CheckAfterPlace,
  116. NotifyFlipperPrepare,
  117. NotifyFlipperOver,
  118. }
  119. public RState Monitor()
  120. {
  121. if (_isFlipper)
  122. Runner
  123. .Wait(PlaceStep.WaitForPlaceModuleIdle, CheckFlipperIsIdle, _timeout)
  124. .Run(PlaceStep.NotifyFlipperPrepare, NotifyFlipperOpen, CheckFlipperOpen, _timeout)
  125. .Run(PlaceStep.CheckBeforePlace, NullFun, CheckBeforePlace, _timeout)
  126. .Run(PlaceStep.PlaceWafer, PlaceWafer, WaitRobotMotion)
  127. .Run(PlaceStep.NotifyFlipperOver, NotifyFlipperClose, CheckFlipperIsIdle, _timeout)
  128. .End(PlaceStep.CheckAfterPlace, NullFun, CheckAfterPlace, _timeout);
  129. else
  130. Runner
  131. .Run(PlaceStep.CoolBufferMoveUP,CoolBufferMoveUP, WaitCoolBufferMoveUp, _timeout)
  132. .Run(PlaceStep.CheckBladeWaferIsExist,CheckBladeWaferIsExist, WaitRobotMotion, _timeout)
  133. .Run(PlaceStep.CheckBeforePlace,NullFun,CheckBeforePlace, _timeout)
  134. .Run(PlaceStep.PlaceWafer,PlaceWafer, WaitRobotMotion)
  135. .Run(PlaceStep.LoadLockCloseAtmDoor,LoadLockCloseAtmDoor,LoadLockCloseAtmDoorOut,_timeout)
  136. .Delay(PlaceStep.WaitForCoolBuffer, delaytime)
  137. .Run(PlaceStep.CoolBufferMoveDown,CoolBufferMoveDown, WaitCoolBufferMoveDown, _timeout)
  138. .End(PlaceStep.CheckAfterPlace, NullFun,CheckAfterPlace, _timeout);
  139. //.Wait(PlaceStep.WaitCoolBufferMoveUp,WaitCoolBufferMoveUp,_timeout)
  140. //.Wait(PlaceStep.WaitRobotMotion,WaitRobotMotion,_timeout)
  141. //.Wait(PlaceStep.WaitRobotMotion, WaitRobotMotion, _timeout)
  142. //.Wait(PlaceStep.WaitRobotMotion,WaitRobotMotion,_timeout)
  143. //.Wait(PlaceStep.WaitCoolBufferMoveDown,WaitCoolBufferMoveDown,_timeout)
  144. return Runner.Status;
  145. }
  146. private bool CheckFlipperIsIdle()
  147. {
  148. return Singleton<RouteManager1>.Instance.GetFlipper().IsIdle;
  149. }
  150. private bool NotifyFlipperOpen()
  151. {
  152. Singleton<RouteManager1>.Instance.GetFlipper().PostMsg(FlipperMSG.PrepareTransfer);
  153. return true;
  154. }
  155. private bool NotifyFlipperClose()
  156. {
  157. Singleton<RouteManager1>.Instance.GetFlipper().PostMsg(FlipperMSG.EndTransfer);
  158. return true;
  159. }
  160. private bool CheckFlipperOpen()
  161. {
  162. return Singleton<RouteManager1>.Instance.GetFlipper().IsTransfer;
  163. }
  164. private bool CheckAfterPlace()
  165. {
  166. //"Check wafer information after wafer placed", this.Station, this.Slot, this.Blade
  167. //if (ModuleHelper.IsLoadLock(Station) && Singleton<EfemEntity>.Instance.IsOnlineMode)
  168. // Singleton<WaferManager>.Instance.DeleteWafer(Station, Slot);
  169. switch (Blade)
  170. {
  171. case Hand.Blade1:
  172. if (!CheckSensorNoWafer(ModuleName.Robot, (int)Blade))
  173. {
  174. LogObject.Error("Robot", "Wafer Is Still Detected on blade1 After Place!");
  175. if (ModuleHelper.IsLoadPort(Station))
  176. Singleton<RouteManager1>.Instance.GetLP(Station).PostMsg(268435443);
  177. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferDetectedAfterSend);
  178. return false;
  179. }
  180. break;
  181. case Hand.Blade2:
  182. for (int index = 0; index < robot.Blade2Slots; ++index)
  183. {
  184. if (!CheckSensorNoWafer(ModuleName.Robot, (int)(Blade + index)))
  185. {
  186. LogObject.Error("Robot", "Wafer Is Still Detected on blade2 After Place!");
  187. if (ModuleHelper.IsLoadPort(Station))
  188. Singleton<RouteManager1>.Instance.GetLP(Station).PostMsg(268435443);
  189. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferDetectedAfterSend);
  190. return false;
  191. }
  192. }
  193. break;
  194. default:
  195. for (int slot1 = 0; slot1 < this.robot.Blade2Slots + 1; ++slot1)
  196. {
  197. if (!CheckSensorNoWafer(ModuleName.Robot, slot1))
  198. {
  199. if (ModuleHelper.IsLoadPort(Station))
  200. Singleton<RouteManager1>.Instance.GetLP(Station).PostMsg(268435443);
  201. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferDetectedAfterSend);
  202. return false;
  203. }
  204. }
  205. break;
  206. }
  207. return true;
  208. }
  209. private bool WaitCoolBufferMoveDown()
  210. {
  211. if (!Singleton<EfemEntity>.Instance.IsOnlineMode && (ModuleHelper.IsCoolingBuffer(this.Station)))
  212. {
  213. IoCoolingBuffer device = GetCoolBuffer(Station);
  214. if (!device.Error)
  215. return device.CheckMovedDown() && !device.Busy;
  216. return false;
  217. }
  218. return true;
  219. }
  220. private bool CoolBufferMoveDown()
  221. {
  222. if (!Singleton<EfemEntity>.Instance.IsOnlineMode && (ModuleHelper.IsCoolingBuffer(this.Station)))
  223. {
  224. IoCoolingBuffer device = GetCoolBuffer(Station);
  225. string reason = "";
  226. if (device.CheckPinDown() || device.Move(Singleton<WaferManager>.Instance.GetWaferSize(Station, Slot), false, out reason))
  227. return true;
  228. else
  229. LogObject.Error(_routinename, _errorhead+reason);
  230. return false;
  231. }
  232. if (ModuleHelper.IsAligner(this.Station))
  233. {
  234. return true;
  235. }
  236. return true;
  237. }
  238. private bool CheckSensorNoWafer(ModuleName chamber, int slot) {
  239. if (SC.GetValue<bool>("System.IsSimulatorMode") || chamber != ModuleName.Robot)
  240. return Singleton<WaferManager>.Instance.CheckNoWafer(chamber, slot);
  241. return slot == 0 ? !robot.IsWaferPresenceOnBlade1 : !robot.IsWaferPresenceOnBlade2;
  242. }
  243. private bool LoadLockCloseAtmDoor()
  244. {
  245. if (LoadLockDoorControlByStation && ModuleHelper.IsLoadLock(this.Station) && !Singleton<EfemEntity>.Instance.IsOnlineMode)
  246. {
  247. string _reason = string.Empty;
  248. if (LoadLockDevice.LoadLockAtmDoorState == LoadLockDoorState.Closed || LoadLockDevice.CloseAtmDoor(out _reason))
  249. {
  250. LogObject.Info("LL","ATM Door Closed");
  251. return true;
  252. }
  253. else
  254. {
  255. LogObject.Error("LL", $"ATM Door cannot Closed {_reason}");
  256. return false;
  257. }
  258. }
  259. LogObject.Info("LL", "LL not has to control ATM");
  260. return true;
  261. }
  262. private bool LoadLockCloseAtmDoorOut()
  263. {
  264. if (LoadLockDoorControlByStation && ModuleHelper.IsLoadLock(this.Station) && !Singleton<EfemEntity>.Instance.IsOnlineMode)
  265. {
  266. string _reason = string.Empty;
  267. if (LoadLockDevice.LoadLockAtmDoorState == LoadLockDoorState.Closed)
  268. {
  269. LogObject.Info("LL", "ATM Door Closed");
  270. return true;
  271. }
  272. else
  273. {
  274. LogObject.Error("LL", "ATM Door not Closed");
  275. return false;
  276. }
  277. }
  278. LogObject.Info("LL", "LL not has to control ATM");
  279. return true;
  280. }
  281. private bool PlaceWafer()
  282. {
  283. //if (!ModuleHelper.IsLoadLock(Station))
  284. {
  285. bool flag = OffsetX == 0 && OffsetY == 0 && OffsetZ == 0 ? robot.Place((RobotArmEnum)Blade, Station.ToString(), Slot) : this.robot.PlaceEx((RobotArmEnum)Blade, Station.ToString(), Slot, (float)OffsetX, (float)OffsetY, (float)OffsetZ);
  286. if (flag)
  287. {
  288. LogObject.Info("Place", $"执行成功:{Station}-{Slot}");
  289. return true;
  290. }
  291. else
  292. {
  293. LogObject.Error("Place", "执行失败");
  294. return false;
  295. }
  296. }
  297. //LogObject.Info("Place", "因是LL无法执行");
  298. return true;
  299. }
  300. private bool CheckBeforePlace()
  301. {
  302. //this.Station, this.Slot, this.Blade
  303. string reason = "";
  304. if (!CheckRobotMotionInterlock(Station,Slot,out reason))
  305. {
  306. LogObject.Error("Place",$"cannot place for the reason:{reason}");
  307. return false;
  308. }
  309. switch (Blade) {
  310. case Hand.Blade1:
  311. //检查 目标上有没有wafer 有就false
  312. if (!Singleton<WaferManager>.Instance.CheckWafer(Station,Slot,WaferStatus.Empty))
  313. {
  314. return false;
  315. }
  316. //检查robot上有没有wafer 没有就返回false
  317. if (!Singleton<WaferManager>.Instance.CheckWafer(ModuleName.Robot, (int)Blade, WaferStatus.Normal))
  318. {
  319. //EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferNotDetectedBeforeSend);
  320. return false;
  321. }
  322. if (!CheckSeneorHasWafer(ModuleName.Robot, (int)Blade))
  323. {
  324. //EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferNotDetectedBeforeSend);
  325. return false;
  326. }
  327. //==debug
  328. //if (ModuleHelper.IsLoadPort(Station) && SC.GetStringValue("CarrierInfo.LowerThicknessType") != SC.GetStringValue(string.Format("CarrierInfo.{0}ThicknessType", (object)Station)))
  329. //{
  330. // //EV.PostAlarmLog(ModuleName.System.ToString(), string.Format("The wafer thickness of the lower arm is different from {0}.", (object)Station));
  331. // return false;
  332. //}
  333. break;
  334. case Hand.Blade2:
  335. default:
  336. bool flag1 = true;
  337. for (int index = 0; index < robot.Blade2Slots; ++index)
  338. {
  339. if (!Singleton<WaferManager>.Instance.CheckWafer(Station, Slot + index, WaferStatus.Empty))
  340. {
  341. //EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferPresentWithRecord, (object)string.Format("Target {0}{1:D2}", (object)Station.ToString(), (object)(Slot + index + 1)));
  342. return false;
  343. }
  344. flag1 &= Singleton<WaferManager>.Instance.CheckWafer(ModuleName.Robot, (int)(Blade + index), WaferStatus.Normal);
  345. if (!this.CheckSeneorHasWafer(ModuleName.Robot, (int)(Blade + index)))
  346. {
  347. //EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferNotDetectedBeforeSend);
  348. return false;
  349. }
  350. }
  351. if (!flag1)
  352. {
  353. //EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferNotDetectedBeforeSend);
  354. return false;
  355. }
  356. //==debug==
  357. //if (ModuleHelper.IsLoadPort(Station) && SC.GetStringValue("CarrierInfo.UpperThicknessType") != SC.GetStringValue(string.Format($"CarrierInfo.{Station}ThicknessType")))
  358. //{
  359. // //EV.PostAlarmLog(ModuleName.System.ToString(), string.Format("The wafer thickness of the lower arm is different from {0}.", (object)Station));
  360. // return false;
  361. //}
  362. break;
  363. }
  364. if (!ModuleHelper.IsCoolingBuffer(Station) || DEVICE.GetDevice<IoCoolingBuffer>(Station.ToString()).CheckPinUp())
  365. {
  366. return true;
  367. }
  368. EV.PostWarningLog(Station.ToString(), "Can not place wafer to buffer, buffer isn't pick position.");
  369. return false;
  370. }
  371. private bool CheckSeneorHasWafer(ModuleName robot, int slot)
  372. {
  373. if (SC.GetValue<bool>("System.IsSimulatorMode") || robot != ModuleName.Robot)
  374. return Singleton<WaferManager>.Instance.CheckHasWafer(robot, slot);
  375. return slot == 0 ? this.robot.IsWaferPresenceOnBlade1 : this.robot.IsWaferPresenceOnBlade2;
  376. }
  377. private bool CheckBladeWaferIsExist()
  378. {
  379. if (!robot.ReadParameter(new object[3] { "CheckWaferIsPresence", (Blade == Hand.Blade1 ? 0 : 1), _existInterval }))
  380. {
  381. //手臂上有wafer 无法pick
  382. LogObject.Error("Robot", "手臂上无片 无法place");
  383. return false;
  384. }
  385. else
  386. {
  387. LogObject.Info("Robot", "手臂上有片 可以正常place");
  388. return true;
  389. }
  390. }
  391. private bool WaitRobotMotion()
  392. {
  393. if (robot.IsReady())
  394. {
  395. LogObject.Info("Robot", "robot is ready.");
  396. return true;
  397. }
  398. else
  399. {
  400. if (robot.IsError)
  401. {
  402. LogObject.Info("Robot", "Robot进入Error");
  403. }
  404. return false;
  405. }
  406. }
  407. private bool WaitCoolBufferMoveUp()
  408. {
  409. //if (ModuleHelper.IsCoolingBuffer(Station) )
  410. //{
  411. // IoCoolingBuffer device = GetCoolBuffer(Station);
  412. // if (!device.Error)
  413. // return device.CheckMovedUp() && !device.Busy;
  414. // return false;
  415. //}
  416. if (ModuleHelper.IsAligner(Station))
  417. {
  418. return true;
  419. }
  420. return true;
  421. }
  422. private bool CoolBufferMoveUP()
  423. {
  424. //if (ModuleHelper.IsCoolingBuffer(Station))
  425. //{
  426. // WaferSize size = Singleton<WaferManager>.Instance.GetWaferSize(ModuleName.Robot,0);
  427. // IoCoolingBuffer device = GetCoolBuffer(Station);
  428. // string _reason = "";
  429. // if (device.CheckPinUp() || device.Move(size, true, out _reason))
  430. // {
  431. // return true;
  432. // }
  433. // else
  434. // {
  435. // LogObject.Error(_routinename, _errorhead + _reason);
  436. // return false;
  437. // }
  438. //}
  439. if (ModuleHelper.IsAligner(Station))
  440. {
  441. return true;
  442. }
  443. return true;
  444. }
  445. public void Abort()
  446. {
  447. }
  448. public IoCoolingBuffer GetCoolBuffer(ModuleName coolbufferName)
  449. {
  450. switch (coolbufferName)
  451. {
  452. //case ModuleName.Aligner1:
  453. // _ioCoolBuffer = aligner1;
  454. // break;
  455. //case ModuleName.Aligner2:
  456. // this._ioCoolBuffer = aligner2;
  457. // break;
  458. case ModuleName.CoolingBuffer1:
  459. this._ioCoolBuffer = this.buffer1;
  460. break;
  461. case ModuleName.CoolingBuffer2:
  462. this._ioCoolBuffer = this.buffer2;
  463. break;
  464. }
  465. return _ioCoolBuffer;
  466. }
  467. protected bool CheckRobotMotionInterlock(ModuleName chamber, int slot, out string reason)
  468. {
  469. reason = string.Empty;
  470. if (robot.RobotState == RobotStateEnum.Error)
  471. {
  472. reason = "robot is error.";
  473. if (ModuleHelper.IsLoadPort(Station))
  474. Singleton<RouteManager1>.Instance.GetLP(Station).PostMsg(268435443);
  475. return false;
  476. }
  477. if (!robot.IsReady())
  478. {
  479. reason = string.Format("robot isn't Ready.");
  480. return false;
  481. }
  482. if (chamber == ModuleName.Aligner)
  483. {
  484. //if (aligner.Moving)
  485. //{
  486. // reason = string.Format("aligner is moving.");
  487. // return false;
  488. //}
  489. if (robot.IsReady())
  490. return true;
  491. reason = string.Format("aligner isn't Ready.");
  492. return false;
  493. }
  494. if (ModuleHelper.IsTurnOverStation(chamber))
  495. {
  496. if (robot.IsReady())
  497. return true;
  498. }
  499. if (ModuleHelper.IsLoadPort(chamber))
  500. {
  501. LoadPortBaseDevice device = DEVICE.GetDevice<LoadPortBaseDevice>(chamber.ToString());
  502. if (!device.IsEnableTransferWafer(out reason))
  503. {
  504. reason = string.Format($"{chamber} isn't Ready.The reason is {reason}");
  505. return false;
  506. }
  507. if (device.MapError)
  508. {
  509. reason = string.Format("{0} Map has crossed error.", (object)chamber.ToString());
  510. return false;
  511. }
  512. if (ModuleHelper.IsLoadPort(chamber) && !Singleton<RouteManager1>.Instance.GetLP(chamber).IsLoaded)
  513. {
  514. if (Singleton<RouteManager1>.Instance.GetLP(chamber).IsDoorOpen)
  515. {
  516. reason = string.Format("{0} SMIF1PODOPEN signal is Off.", (object)chamber.ToString());
  517. return false;
  518. }
  519. if (Singleton<RouteManager1>.Instance.GetLP(chamber).IsPresent)
  520. {
  521. reason = string.Format("{0} SensorSMIF1PODPRESENT signal is Off,Foup is presence.", (object)chamber.ToString());
  522. return false;
  523. }
  524. if (Singleton<RouteManager1>.Instance.GetLP(chamber).IsReady)
  525. {
  526. reason = string.Format("{0} SensorSMIF1READY signal is Off.", (object)chamber.ToString());
  527. return false;
  528. }
  529. }
  530. return true;
  531. }
  532. if (ModuleHelper.IsLoadLock(chamber) || ModuleHelper.IsPm(chamber))
  533. {
  534. if (WaferManager.Instance.CheckHasWafer(chamber, 0))
  535. reason = "记录中该位置有wafer";
  536. switch (chamber)
  537. {
  538. case ModuleName.LL1:
  539. case ModuleName.LLA:
  540. case ModuleName.PMA:
  541. if (!DeviceModel.LL1DoorIsOpen.Value)
  542. reason = $"{chamber}门信号未开启 无法传送";
  543. return DeviceModel.LL1DoorIsOpen.Value && WaferManager.Instance.CheckNoWafer(chamber, 0);
  544. case ModuleName.LL2:
  545. case ModuleName.LLB:
  546. case ModuleName.PMB:
  547. if (!DeviceModel.LL2DoorIsOpen.Value)
  548. reason = $"{chamber}门信号未开启 无法传送";
  549. return DeviceModel.LL2DoorIsOpen.Value && WaferManager.Instance.CheckNoWafer(chamber, 0);
  550. default:
  551. return true;
  552. }
  553. }
  554. if (ModuleHelper.IsCoolingBuffer(chamber) )
  555. {
  556. IoCoolingBuffer device = DEVICE.GetDevice<IoCoolingBuffer>(chamber.ToString());
  557. if (device.Busy)
  558. {
  559. reason = "buffer is not idle";
  560. return false;
  561. }
  562. if (device.CheckPinUp())
  563. return true;
  564. reason = "buffer pin not up position";
  565. return false;
  566. }
  567. if (ModuleHelper.IsAligner(Station))
  568. {
  569. //PreAligner device = DEVICE.GetDevice<PreAligner>(Station.ToString());
  570. //if (device.Busy)
  571. //{
  572. // reason = "Aligner is not idle";
  573. // return false;
  574. //}
  575. return true;
  576. }
  577. if (ModuleHelper.IsBuffer(Station))
  578. {
  579. return true;
  580. }
  581. reason = "error target";
  582. return false;
  583. }
  584. }
  585. }