PickExtendRoutine.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  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.FSM;
  10. using athosRT.Modules.EFEMs.Tasks;
  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.Text;
  23. using System.Threading.Tasks;
  24. using static athosRT.Modules.EFEMs.Routine.PickRoutine;
  25. using static MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase.RobotBaseDevice;
  26. using EV = athosRT.tool.EV;
  27. namespace athosRT.Modules.EFEMs.Routine
  28. {
  29. public class PickExtendRoutine : ModuleRoutineBase, FSM.IRoutine
  30. {
  31. protected bool MultiWaferSize = Singleton<DeviceDefineManager>.Instance.GetValue<bool>(nameof(MultiWaferSize)).GetValueOrDefault();
  32. private SCConfigItem _scPickTimeout = (SCConfigItem)null;
  33. private int _timeout = 0;
  34. private int _axisTimeout = 0;
  35. private int _axisSpeed = 0;
  36. public double WaitForPickTime = 0.0;
  37. private LoadPort _lpDevice;
  38. protected bool NeedRobotGripAndUngrip = SC.GetValue<bool>("System.EnableRobotGripAndUngrip");
  39. protected readonly bool HaveMotionAxis = Singleton<DeviceDefineManager>.Instance.GetValue<bool>("MotionAxisInstalled").GetValueOrDefault();
  40. private int _existInterval = SC.GetValue<int>("Robot.Robot.ExistInterval");
  41. public ModuleName Source { get; set; }
  42. public int Slot { get; set; }
  43. public Hand Blade { get; set; }
  44. public MpntTaskEnum TaskEnum { get; set; }
  45. public RobotBaseDevice robot;
  46. protected Aligner aligner = null;
  47. public PickExtendRoutine(ModuleName module) : base(module)
  48. {
  49. robot = DEVICE.GetDevice<RobotBaseDevice>("Robot");
  50. aligner = DEVICE.GetDevice<Aligner>("Aligner");
  51. _scPickTimeout = SC.GetConfigItem("Robot.TimeLimitForPickWafer");
  52. if (HaveMotionAxis)
  53. {
  54. _axisTimeout = SC.GetValue<int>("MotionAxis.MoveTimeout");
  55. _axisSpeed = SC.GetValue<int>("MotionAxis.AutoSpeed");
  56. }
  57. }
  58. public RState Start(params object[] objs)
  59. {
  60. Reset();
  61. _scPickTimeout = SC.GetConfigItem("Robot.TimeLimitForPickWafer");
  62. if (HaveMotionAxis)
  63. {
  64. _axisTimeout = SC.GetValue<int>("MotionAxis.MoveTimeout");
  65. _axisSpeed = SC.GetValue<int>("MotionAxis.AutoSpeed");
  66. }
  67. _timeout = _scPickTimeout.IntValue * 1000;
  68. if (!ModuleHelper.IsLoadLock(Source) || TaskEnum == MpntTaskEnum.ParamNg)
  69. {
  70. return RState.Failed;
  71. }
  72. else
  73. {
  74. return Runner.Start(ModuleName.Robot, "Robot");
  75. }
  76. }
  77. /// <summary>
  78. /// 注意 此处会按照不同的task类型进行任务的下发
  79. /// G1 GB G4
  80. /// </summary>
  81. /// <returns></returns>
  82. public RState Monitor()
  83. {
  84. switch (TaskEnum)
  85. {
  86. case MpntTaskEnum.G1:
  87. Runner
  88. .Run(PickExtendStep.CheckBeforePick,NullFun, CheckBeforePick, _timeout)
  89. .End(PickExtendStep.RobotGoto, RobotGoto, WaitRobotMotion, _timeout)
  90. ;
  91. break;
  92. case MpntTaskEnum.GB:
  93. Runner
  94. .Run(PickExtendStep.CheckBladeWaferIsExist, CheckBladeWaferIsExist, WaitRobotReady, _timeout)
  95. .Run(PickExtendStep.CheckBeforePick,NullFun ,CheckBeforePick, _timeout)
  96. .End(PickExtendStep.RobotGoto, RobotGoto, WaitRobotReady, _timeout)
  97. ;
  98. break;
  99. case MpntTaskEnum.G4:
  100. Runner
  101. .Run(PickExtendStep.GripRobotBlade, GripRobotBlade, CheckRobotNoBusy, _timeout)
  102. .Run(PickExtendStep.RobotGoto, RobotGotoPickRetracted, WaitRobotMotion,_timeout)
  103. .Run(PickExtendStep.CheckBladeWaferIsExist, CheckBladeWaferIsExist, WaitRobotReady, _timeout)
  104. .End(PickExtendStep.CheckAfterPick, NullFun,CheckAfterPick, _timeout)
  105. ;
  106. break;
  107. default:
  108. return RState.Failed;
  109. }
  110. return Runner.Status;
  111. }
  112. private bool CheckRobotNoBusy()
  113. {
  114. if (!robot.IsBusy)
  115. {
  116. LogObject.Info("robot", "is not busy");
  117. return true;
  118. }
  119. else
  120. {
  121. //LogObject.Warning("robot", "is busy");
  122. return false;
  123. }
  124. }
  125. private bool WaitRobotReady()
  126. {
  127. if (robot.IsReady())
  128. {
  129. LogObject.Info("robot", "is ready");
  130. return true;
  131. }
  132. else
  133. {
  134. //LogObject.Error("robot", "not ready");
  135. return false;
  136. }
  137. }
  138. /// <summary>
  139. /// 将Robot的伸展到指定槽的位置
  140. /// </summary>
  141. /// <returns></returns>
  142. private bool RobotGoto()
  143. {
  144. if (robot.GoTo(new object[4] {
  145. (RobotArmEnum)Blade,
  146. Source.ToString(),
  147. Slot,
  148. RobotPostionEnum.PickExtend}))
  149. {
  150. LogObject.Info("Robot", "PickExtend has Goto");
  151. return true;
  152. }
  153. else
  154. {
  155. LogObject.Error("Robot", "PickExtend Cannot Goto");
  156. return false;
  157. }
  158. }
  159. private bool RobotGotoPickRetracted()
  160. {
  161. if (robot.GoTo(new object[4] {
  162. (RobotArmEnum)Blade,
  163. Source.ToString(),
  164. Slot,
  165. RobotPostionEnum.PickRetracted}))
  166. {
  167. LogObject.Info("Robot", "PickExtend has Goto");
  168. return true;
  169. }
  170. else
  171. {
  172. LogObject.Error("Robot", "PickExtend Cannot Goto");
  173. return false;
  174. }
  175. }
  176. private bool CheckBladeWaferIsExist()
  177. {
  178. //this.robot, this.Blade, this._timeout
  179. if (!robot.ReadParameter(new object[3] { "CheckWaferIsPresence", (Blade == Hand.Blade1 ? 0 : 1), _existInterval }))
  180. {
  181. //手臂上有wafer 无法pick
  182. return false;
  183. }
  184. return true;
  185. }
  186. private bool CheckAfterPick()
  187. {
  188. switch (Blade)
  189. {
  190. case Hand.Blade1:
  191. if (!CheckSeneorHasWafer(ModuleName.Robot, (int)Blade))
  192. {
  193. LogObject.Error("Robot",$"{Blade} not Has Wafer");
  194. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferNotDetectedAfterPick);
  195. return false;
  196. }
  197. break;
  198. case Hand.Blade2:
  199. for (int index = 0; index < robot.Blade2Slots; ++index)
  200. {
  201. if (!CheckSeneorHasWafer(ModuleName.Robot, 1 + index))
  202. {
  203. LogObject.Error("Robot", $"{Blade} {index} not Has Wafer");
  204. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferNotDetectedAfterPick);
  205. return false;
  206. }
  207. }
  208. break;
  209. default:
  210. for (int slot1 = 0; slot1 < robot.Blade2Slots + 1; ++slot1)
  211. {
  212. if (!CheckSeneorHasWafer(ModuleName.Robot, slot1))
  213. {
  214. LogObject.Error("Robot", $"{Blade} {slot1} not Has Wafer");
  215. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferNotDetectedAfterPick);
  216. return false;
  217. }
  218. }
  219. break;
  220. }
  221. return true;
  222. }
  223. private bool WaitRobotMotion()
  224. {
  225. if (robot.IsReady())
  226. {
  227. LogObject.Info("robot","is ready");
  228. return true;
  229. }
  230. else
  231. {
  232. //LogObject.Error("robot","not ready");
  233. return false;
  234. }
  235. }
  236. private bool GripRobotBlade()
  237. {
  238. //this.Blade, this.robot, this._timeout
  239. if (NeedRobotGripAndUngrip)
  240. {
  241. if (robot.CheckToPostMessage(RobotMsg.Grip, (RobotArmEnum)Blade, Source))
  242. {
  243. return true;
  244. }
  245. return false;
  246. }
  247. return true;
  248. }
  249. private bool CheckBeforePick()
  250. {
  251. //"Check wafer information", this.Source, this.Slot, this.Blade
  252. if (!CheckRobotMotionInterlock(Source, Slot, out _))
  253. {
  254. //EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.TransferPrepareFailed, (object)string.Format("target {0}{1:D2},{2}", (object)chamber.ToString(), (object)(slot + 1), (object)reason));
  255. return false;
  256. }
  257. switch (Blade)
  258. {
  259. case Hand.Blade1:
  260. //为了让efemUI上显示wafer
  261. if (ModuleHelper.IsLoadLock(Source) && Singleton<EfemEntity>.Instance.IsOnlineMode)
  262. Singleton<WaferManager>.Instance.CreateWafer(Source, Slot, WaferStatus.Normal);
  263. else if (!Singleton<WaferManager>.Instance.CheckWafer(Source, Slot, WaferStatus.Normal))
  264. {
  265. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferAbsentWithoutRecord, (object)string.Format("target {0}{1:D2}", (object)Source.ToString(), (object)(Slot + 1)));
  266. return false;
  267. }
  268. if (!Singleton<WaferManager>.Instance.CheckWafer(ModuleName.Robot, 0, WaferStatus.Empty))
  269. {
  270. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick);
  271. return false;
  272. }
  273. if (!CheckSensorNoWafer(ModuleName.Robot, 0))
  274. {
  275. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick);
  276. return false;
  277. }
  278. if (ModuleHelper.IsBuffer(Source) && !CheckSeneorHasWafer(Source, Slot))
  279. {
  280. EV.PostWarningLog(Source.ToString(), "Can not pick wafer from buffer, Buffer slot has no wafer.");
  281. return false;
  282. }
  283. break;
  284. case Hand.Blade2:
  285. bool flag1 = true;
  286. for (int index = 0; index < robot.Blade2Slots; ++index)
  287. {
  288. if (ModuleHelper.IsLoadLock(Source) && Singleton<EfemEntity>.Instance.IsOnlineMode)
  289. Singleton<WaferManager>.Instance.CreateWafer(Source, Slot, WaferStatus.Normal);
  290. else
  291. flag1 = Singleton<WaferManager>.Instance.CheckWafer(Source, Slot + index, WaferStatus.Normal);
  292. if (!Singleton<WaferManager>.Instance.CheckWafer(ModuleName.Robot, (int)(Blade + index), WaferStatus.Empty))
  293. {
  294. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick);
  295. return false;
  296. }
  297. if (!CheckSensorNoWafer(ModuleName.Robot, (int)(Blade + index)))
  298. {
  299. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick);
  300. return false;
  301. }
  302. if (ModuleHelper.IsBuffer(Source))
  303. {
  304. flag1 = CheckSeneorHasWafer(Source, Slot + index);
  305. if (!flag1)
  306. {
  307. EV.PostWarningLog(Source.ToString(), "Can not pick wafer from buffer, Buffer slot has no wafer.");
  308. return false;
  309. }
  310. }
  311. }
  312. if (!flag1)
  313. {
  314. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferAbsentWithoutRecord, string.Format("target {0}{1:D2}", (object)Source.ToString(), (object)(Slot + 1)));
  315. return false;
  316. }
  317. break;
  318. default:
  319. bool flag2 = true;
  320. for (int slot1 = 0; slot1 < robot.Blade2Slots + 1; ++slot1)
  321. {
  322. if (ModuleHelper.IsLoadLock(Source) && Singleton<EfemEntity>.Instance.IsOnlineMode)
  323. Singleton<WaferManager>.Instance.CreateWafer(Source, Slot, WaferStatus.Normal);
  324. else
  325. flag2 = Singleton<WaferManager>.Instance.CheckWafer(Source, Slot, WaferStatus.Normal);
  326. if (!Singleton<WaferManager>.Instance.CheckWafer(ModuleName.Robot, slot1, WaferStatus.Empty))
  327. {
  328. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick);
  329. return false;
  330. }
  331. if (!CheckSensorNoWafer(ModuleName.Robot, slot1))
  332. {
  333. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick);
  334. return false;
  335. }
  336. if (ModuleHelper.IsBuffer(Source) && Blade == Hand.Both)
  337. {
  338. flag2 &= this.CheckSeneorHasWafer(Source, Slot + slot1);
  339. if (!flag2)
  340. {
  341. EV.PostWarningLog(Source.ToString(), "Can not pick wafer from buffer, Buffer slot has no wafer.");
  342. return false;
  343. }
  344. }
  345. }
  346. if (!flag2)
  347. {
  348. EV.PostMessage<EventEnum>(ModuleName.System.ToString(), EventEnum.WaferAbsentWithoutRecord, string.Format("target {0}{1:D2}", (object)Source.ToString(), (object)Slot));
  349. return false;
  350. }
  351. break;
  352. }
  353. if (!ModuleHelper.IsCoolingBuffer(Source) || DEVICE.GetDevice<IoCoolingBuffer>(Source.ToString()).CheckPinUp())
  354. return true;
  355. EV.PostWarningLog(Source.ToString(), "Can not pick wafer from buffer, buffer isn't pick position.");
  356. return false;
  357. }
  358. public void Abort()
  359. {
  360. }
  361. protected bool CheckRobotMotionInterlock(ModuleName chamber, int slot, out string reason)
  362. {
  363. reason = string.Empty;
  364. if (robot.RobotState == RobotStateEnum.Error)
  365. {
  366. reason = "robot is error.";
  367. return false;
  368. }
  369. if (!robot.IsReady())
  370. {
  371. reason = string.Format("robot isn't Ready.");
  372. return false;
  373. }
  374. if (chamber == ModuleName.Aligner)
  375. {
  376. if (aligner.Moving)
  377. {
  378. reason = string.Format("aligner is moving.");
  379. return false;
  380. }
  381. if (robot.IsReady())
  382. return true;
  383. reason = string.Format("aligner isn't Ready.");
  384. return false;
  385. }
  386. if (ModuleHelper.IsLoadPort(chamber))
  387. {
  388. LoadPortBaseDevice device = DEVICE.GetDevice<LoadPortBaseDevice>(chamber.ToString());
  389. if (!device.IsEnableTransferWafer(out reason))
  390. {
  391. reason = string.Format($"{chamber} isn't Ready.The reason is {reason}");
  392. return false;
  393. }
  394. if (device.MapError)
  395. {
  396. reason = string.Format("{0} Map has crossed error.", (object)chamber.ToString());
  397. return false;
  398. }
  399. if (chamber.Equals(ModuleName.LP1))
  400. {
  401. if (!DeviceModel.SensorSMIF1PODOPEN.Value)
  402. {
  403. reason = string.Format("{0} SMIF1PODOPEN signal is Off.", (object)chamber.ToString());
  404. return false;
  405. }
  406. if (!DeviceModel.SensorSMIF1PODPRESENT.Value)
  407. {
  408. reason = string.Format("{0} SensorSMIF1PODPRESENT signal is Off,Foup is presence.", (object)chamber.ToString());
  409. return false;
  410. }
  411. if (!DeviceModel.SensorSMIF1READY.Value)
  412. {
  413. reason = string.Format("{0} SensorSMIF1READY signal is Off.", (object)chamber.ToString());
  414. return false;
  415. }
  416. }
  417. else if (chamber.Equals(ModuleName.LP2))
  418. {
  419. if (!DeviceModel.SensorSMIF2PODOPEN.Value)
  420. {
  421. reason = string.Format("{0} SMIF2PODOPEN signal is Off.", (object)chamber.ToString());
  422. return false;
  423. }
  424. if (!DeviceModel.SensorSMIF2PODPRESENT.Value)
  425. {
  426. reason = string.Format("{0} SensorSMIF2PODPRESENT signal is Off,Foup is not presence .", (object)chamber.ToString());
  427. return false;
  428. }
  429. if (!DeviceModel.SensorSMIF2READY.Value)
  430. {
  431. reason = string.Format("{0} SensorSMIF2READY signal is Off.", (object)chamber.ToString());
  432. return false;
  433. }
  434. }
  435. return true;
  436. }
  437. if (ModuleHelper.IsLoadLock(chamber))
  438. return DEVICE.GetDevice<LoadLockDevice>(chamber.ToString()).IsEnableTransferWafer(out reason);
  439. if (ModuleHelper.IsCoolingBuffer(chamber))
  440. {
  441. IoCoolingBuffer device = DEVICE.GetDevice<IoCoolingBuffer>(chamber.ToString());
  442. if (device.Busy)
  443. {
  444. reason = "buffer is not Idle";
  445. return false;
  446. }
  447. if (device.CheckPinUp())
  448. return true;
  449. reason = "buffer pin not up position";
  450. return false;
  451. }
  452. if (ModuleHelper.IsAligner(chamber))
  453. {
  454. Aligner device = DEVICE.GetDevice<Aligner>(chamber.ToString());
  455. if (device.Busy)
  456. {
  457. reason = "Aligner is not Idle";
  458. return false;
  459. }
  460. return true;
  461. }
  462. reason = "error target";
  463. return false;
  464. }
  465. protected bool CheckSensorNoWafer(ModuleName chamber, int slot)
  466. {
  467. if (SC.GetValue<bool>("System.IsSimulatorMode") || chamber != ModuleName.Robot)
  468. return Singleton<WaferManager>.Instance.CheckNoWafer(chamber, slot);
  469. return slot == 0 ? !this.robot.IsWaferPresenceOnBlade1 : !this.robot.IsWaferPresenceOnBlade2;
  470. }
  471. protected bool CheckSeneorHasWafer(ModuleName chamber, int slot)
  472. {
  473. if (SC.GetValue<bool>("System.IsSimulatorMode") || chamber != ModuleName.Robot)
  474. return Singleton<WaferManager>.Instance.CheckHasWafer(chamber, slot);
  475. return slot == 0 ? this.robot.IsWaferPresenceOnBlade1 : this.robot.IsWaferPresenceOnBlade2;
  476. }
  477. public enum PickExtendStep {
  478. CheckBladeWaferIsExist,
  479. CheckBeforePick,
  480. RobotGoto,
  481. WaitRobotMotion,
  482. GripRobotBlade,
  483. CheckAfterPick,
  484. WaitRobotReady,
  485. CheckRobotNoBusy
  486. }
  487. }
  488. }