FutureEfemRobot.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Xml;
  4. using Aitex.Core.RT.DataCenter;
  5. using Aitex.Core.RT.Device;
  6. using Aitex.Core.RT.Event;
  7. using Aitex.Sorter.Common;
  8. using MECF.Framework.Common.CommonData;
  9. using MECF.Framework.Common.Equipment;
  10. using MECF.Framework.Common.SubstrateTrackings;
  11. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Efems.Rorzes;
  12. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots;
  13. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase;
  14. namespace FutureEfemLib.Efems
  15. {
  16. public class FutureEfemRobot : RobotBaseDevice, IEfemRobotCallback
  17. {
  18. private ModuleName _module;
  19. private string _efemName;
  20. private IRorzeEfemController _efem;
  21. public string Address { get; }
  22. public bool IsConnected { get; }
  23. //EfemRobotHomeRoutine _homeRoutine;
  24. public FutureEfemRobot(string module, XmlElement node, string ioModule = "") : base("EfemRobot", "EfemRobot")
  25. {
  26. var attrModule = node.GetAttribute("module");
  27. base.Module = string.IsNullOrEmpty(attrModule) ? module : attrModule;
  28. base.Name = node.GetAttribute("id");
  29. _efemName = node.GetAttribute("efem");
  30. _module = ModuleHelper.Converter(Module);
  31. }
  32. public FutureEfemRobot(string module, string name, string efemName) : base("EfemRobot", "EfemRobot")
  33. {
  34. _efemName = efemName;
  35. _module = ModuleHelper.Converter(module);
  36. }
  37. public bool Connect()
  38. {
  39. return true;
  40. }
  41. public bool Disconnect()
  42. {
  43. return true;
  44. }
  45. protected override bool Init()
  46. {
  47. if (_efem == null && !string.IsNullOrEmpty(_efemName))
  48. {
  49. _efem = DEVICE.GetDevice<RorzeEfem>(_efemName);
  50. _efem.SetRobotCallback(ModuleHelper.Converter(Module), this);
  51. }
  52. RorzeEfemHandler.ParameterModuleMap = new Dictionary<string, ModuleName>()
  53. {
  54. {"SYSTEM", ModuleName.System},
  55. {"System", ModuleName.System},
  56. {"ROB", ModuleName.EfemRobot},
  57. {"P1", ModuleName.LP1},
  58. {"P2", ModuleName.LP2},
  59. {"P3", ModuleName.LP3},
  60. {"P4", ModuleName.LP4},
  61. {"LLA", ModuleName.LLA},
  62. {"LLB", ModuleName.LLB},
  63. {"BF1", ModuleName.Buffer},
  64. {"ALIGN", ModuleName.Aligner},
  65. };
  66. DATA.Subscribe($"{Module}1.WaferSize", () => WaferManager.Instance.GetWaferSize(_module, 0).ToString());
  67. DATA.Subscribe($"{Module}2.WaferSize", () => WaferManager.Instance.GetWaferSize(_module, 1).ToString());
  68. IsOnline = true;
  69. return true;
  70. }
  71. protected override bool fClear(object[] param)
  72. {
  73. return true;
  74. }
  75. protected override bool fStartReadData(object[] param)
  76. {
  77. ModuleName tempmodule = (ModuleName)Enum.Parse(typeof(ModuleName), param[0].ToString());
  78. _efem.QueryMapResult(tempmodule.ToString(), out string reason);
  79. return true;
  80. }
  81. protected override bool fStartSetParameters(object[] param)
  82. {
  83. return true;
  84. }
  85. protected override bool fStartTransferWafer(object[] param)
  86. {
  87. return true;
  88. }
  89. protected override bool fStartUnGrip(object[] param)
  90. {
  91. return true;
  92. }
  93. protected override bool fStartGrip(object[] param)
  94. {
  95. return true;
  96. }
  97. protected override bool fStartGoTo(object[] param)
  98. {
  99. RobotArmEnum arm = (RobotArmEnum)param[0];
  100. ModuleName module = (ModuleName)Enum.Parse(typeof(ModuleName), param[1].ToString());
  101. int slot = int.Parse(param[2].ToString());
  102. if (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, arm == RobotArmEnum.Lower ? 0 : 1))
  103. {
  104. if (!_efem.MoveToReadyPut(module, slot, arm == RobotArmEnum.Lower ? Hand.Blade1 : Hand.Blade2, out string reason))
  105. {
  106. EV.PostAlarmLog(Module, $"Can not move to {module} slot {slot + 1}, " + reason);
  107. return false;
  108. }
  109. }
  110. else
  111. {
  112. if (!_efem.MoveToReadyGet(module, slot, arm == RobotArmEnum.Lower ? Hand.Blade1 : Hand.Blade2, out string reason))
  113. {
  114. EV.PostAlarmLog(Module, $"Can not move to {module} slot {slot + 1}, " + reason);
  115. return false;
  116. }
  117. }
  118. CmdRobotArm = arm;
  119. CmdTarget = module;
  120. CmdTargetSlot = slot;
  121. MoveInfo = new RobotMoveInfo()
  122. {
  123. Action = RobotAction.Moving,
  124. ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB,
  125. BladeTarget = BuildBladeTarget(),
  126. };
  127. return true;
  128. }
  129. protected override bool fGoToComplete(object[] param)
  130. {
  131. MoveInfo = new RobotMoveInfo()
  132. {
  133. Action = RobotAction.Moving,
  134. ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB,
  135. BladeTarget = BuildBladeTarget(),
  136. };
  137. return base.fGoToComplete(param);
  138. }
  139. protected override bool fStartMapWafer(object[] param)
  140. {
  141. ModuleName tempmodule = (ModuleName)Enum.Parse(typeof(ModuleName), param[0].ToString());
  142. int thicknessIndex = int.Parse(param[1].ToString());
  143. CmdRobotArm = RobotArmEnum.Lower;
  144. CmdTarget = tempmodule;
  145. CmdTargetSlot = 0;
  146. MoveInfo = new RobotMoveInfo()
  147. {
  148. Action = RobotAction.Moving,
  149. ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB,
  150. BladeTarget = BuildBladeTarget(),
  151. };
  152. FutureEfem efem = _efem as FutureEfem;
  153. efem.MapCarrier(tempmodule.ToString(), thicknessIndex, out string _, out string reason);
  154. return true;
  155. }
  156. protected override bool fMapComplete(object[] param)
  157. {
  158. MoveInfo = new RobotMoveInfo()
  159. {
  160. Action = RobotAction.Moving,
  161. ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB,
  162. BladeTarget = BuildBladeTarget(),
  163. };
  164. return base.fMapComplete(param);
  165. }
  166. protected override bool fStartSwapWafer(object[] param)
  167. {
  168. return true;
  169. }
  170. protected override bool fStartPlaceWafer(object[] param)
  171. {
  172. RobotArmEnum arm = (RobotArmEnum)param[0];
  173. ModuleName module = (ModuleName)Enum.Parse(typeof(ModuleName), param[1].ToString());
  174. int slot = int.Parse(param[2].ToString());
  175. if (!CheckEnablePlace(module, slot, arm, out string reason))
  176. {
  177. EV.PostAlarmLog(Module, $"Can not place wafer to {module} slot {slot + 1}, " + reason);
  178. return false;
  179. }
  180. if (!_efem.PutWafer(module, slot, (Hand)(int)arm, out reason))
  181. {
  182. EV.PostAlarmLog(Module, $"Can not place wafer to {module} slot {slot + 1}, " + reason);
  183. return false;
  184. }
  185. CmdRobotArm = arm;
  186. CmdTarget = module;
  187. CmdTargetSlot = slot;
  188. MoveInfo = new RobotMoveInfo()
  189. {
  190. Action = RobotAction.Placing,
  191. ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB,
  192. BladeTarget = BuildBladeTarget(),
  193. };
  194. return true;
  195. }
  196. private bool CheckEnablePlace(ModuleName module, int slot, RobotArmEnum arm, out string reason)
  197. {
  198. if (arm == RobotArmEnum.Both)
  199. {
  200. if (!WaferManager.Instance.CheckNoWafer(module, slot) && !WaferManager.Instance.CheckNoWafer(module, slot + 1))
  201. {
  202. reason = "target has wafer";
  203. return false;
  204. }
  205. if (!WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 0) && !WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 1))
  206. {
  207. reason = "robot arm has no wafer";
  208. return false;
  209. }
  210. }
  211. else
  212. {
  213. if (!WaferManager.Instance.CheckNoWafer(module, slot))
  214. {
  215. reason = "target has wafer";
  216. return false;
  217. }
  218. if (!WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, (int)arm))
  219. {
  220. reason = "robot arm has no wafer";
  221. return false;
  222. }
  223. }
  224. reason = string.Empty;
  225. return true;
  226. }
  227. protected override bool fPlaceComplete(object[] param)
  228. {
  229. if (CmdRobotArm == RobotArmEnum.Both)
  230. {
  231. WaferManager.Instance.WaferMoved(ModuleHelper.Converter(Module), (int)Hand.Blade1, CmdTarget, CmdTargetSlot);
  232. WaferManager.Instance.WaferMoved(ModuleHelper.Converter(Module), (int)Hand.Blade2, CmdTarget, CmdTargetSlot + 1);
  233. }
  234. else
  235. {
  236. WaferManager.Instance.WaferMoved(ModuleHelper.Converter(Module), (int)CmdRobotArm, CmdTarget, CmdTargetSlot);
  237. }
  238. MoveInfo = new RobotMoveInfo()
  239. {
  240. Action = RobotAction.Moving,
  241. ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB,
  242. BladeTarget = BuildBladeTarget(),
  243. };
  244. return base.fPlaceComplete(param);
  245. }
  246. private string BuildBladeTarget()
  247. {
  248. return (CmdRobotArm == RobotArmEnum.Upper ? "ArmB" : "ArmA") + "." + CmdTarget;
  249. }
  250. protected override bool fStartPickWafer(object[] param)
  251. {
  252. RobotArmEnum arm = (RobotArmEnum)param[0];
  253. ModuleName module = (ModuleName)Enum.Parse(typeof(ModuleName), param[1].ToString());
  254. int slot = int.Parse(param[2].ToString());
  255. if (!CheckEnablePick(module, slot, arm, out string reason))
  256. {
  257. EV.PostAlarmLog(Module, $"Can not pick wafer from {module} slot {slot + 1}, " + reason);
  258. return false;
  259. }
  260. if (!_efem.GetWafer(module, slot, (Hand)(int)arm, out reason))
  261. {
  262. EV.PostAlarmLog(Module, $"Can not pick wafer from {module} slot {slot + 1}, " + reason);
  263. return false;
  264. }
  265. CmdRobotArm = arm;
  266. CmdTarget = module;
  267. CmdTargetSlot = slot;
  268. MoveInfo = new RobotMoveInfo()
  269. {
  270. Action = RobotAction.Picking,
  271. ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB,
  272. BladeTarget = BuildBladeTarget(),
  273. };
  274. return true;
  275. }
  276. private bool CheckEnablePick(ModuleName module, int slot, RobotArmEnum arm, out string reason)
  277. {
  278. if (arm == RobotArmEnum.Both)
  279. {
  280. if (!WaferManager.Instance.CheckHasWafer(module, slot) && !WaferManager.Instance.CheckHasWafer(module, slot + 1))
  281. {
  282. reason = "source has no wafer";
  283. return false;
  284. }
  285. if (!WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 0) && !WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 1))
  286. {
  287. reason = "robot arm has wafer";
  288. return false;
  289. }
  290. }
  291. else
  292. {
  293. if (!WaferManager.Instance.CheckHasWafer(module, slot))
  294. {
  295. reason = "source has no wafer";
  296. return false;
  297. }
  298. if (!WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, (int)arm))
  299. {
  300. reason = "robot arm has wafer";
  301. return false;
  302. }
  303. }
  304. reason = string.Empty;
  305. return true;
  306. }
  307. protected override bool fPickComplete(object[] param)
  308. {
  309. if (CmdRobotArm == RobotArmEnum.Both)
  310. {
  311. WaferManager.Instance.WaferMoved(CmdTarget, CmdTargetSlot, ModuleHelper.Converter(Module), (int)Hand.Blade1);
  312. WaferManager.Instance.WaferMoved(CmdTarget, CmdTargetSlot + 1, ModuleHelper.Converter(Module), (int)Hand.Blade2);
  313. }
  314. else
  315. {
  316. WaferManager.Instance.WaferMoved(CmdTarget, CmdTargetSlot, ModuleHelper.Converter(Module), (int)CmdRobotArm);
  317. }
  318. MoveInfo = new RobotMoveInfo()
  319. {
  320. Action = RobotAction.Moving,
  321. ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB,
  322. BladeTarget = BuildBladeTarget(),
  323. };
  324. return base.fPickComplete(param);
  325. }
  326. protected override bool fResetToReady(object[] param)
  327. {
  328. return true;
  329. }
  330. protected override bool fReset(object[] param)
  331. {
  332. return true;
  333. }
  334. #region Init/Home
  335. public bool Home(out string reason)
  336. {
  337. if (!CheckToPostMessage((int)RobotMsg.StartInit))
  338. {
  339. reason = $"Can not home at {(RobotStateEnum)fsm.State} state";
  340. return false;
  341. }
  342. reason = string.Empty;
  343. return true;
  344. }
  345. protected override bool fStartInit(object[] param)
  346. {
  347. CmdRobotArm = RobotArmEnum.Lower;
  348. CmdTarget = ModuleName.System;
  349. CmdTargetSlot = 0;
  350. MoveInfo = new RobotMoveInfo()
  351. {
  352. Action = RobotAction.Retracting,
  353. ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB,
  354. BladeTarget = BuildBladeTarget(),
  355. };
  356. return true;
  357. }
  358. protected override bool fInitComplete(object[] param)
  359. {
  360. return base.fInitComplete(param);
  361. }
  362. protected override bool fMonitorInit(object[] param)
  363. {
  364. IsBusy = false;
  365. return true;
  366. }
  367. protected override bool fMonitorReadData(object[] param)
  368. {
  369. return base.fMonitorReadData(param);
  370. }
  371. #endregion
  372. public override bool HomeAllAxes(out string reason)
  373. {
  374. if (!_efem.HomeAllAxes(out reason))
  375. return false;
  376. IsBusy = true;
  377. return true;
  378. }
  379. protected override bool fError(object[] param)
  380. {
  381. string errorInfo = param[0].ToString();
  382. if (param.Length > 0)
  383. EV.PostAlarmLog(Module, errorInfo);
  384. if (fsm.State == (int)RobotStateEnum.Initializing)
  385. {
  386. }
  387. else if (fsm.State == (int)RobotStateEnum.Picking)
  388. {
  389. bool waferGot = errorInfo.Contains("|WAFER");
  390. if (waferGot)
  391. {
  392. if (CmdRobotArm == RobotArmEnum.Both)
  393. {
  394. WaferManager.Instance.WaferMoved(CmdTarget, CmdTargetSlot, ModuleHelper.Converter(Module), (int)Hand.Blade1);
  395. WaferManager.Instance.WaferMoved(CmdTarget, CmdTargetSlot + 1, ModuleHelper.Converter(Module), (int)Hand.Blade2);
  396. }
  397. else
  398. {
  399. WaferManager.Instance.WaferMoved(CmdTarget, CmdTargetSlot, ModuleHelper.Converter(Module), (int)CmdRobotArm);
  400. }
  401. }
  402. }
  403. else if (fsm.State == (int)RobotStateEnum.Placing)
  404. {
  405. bool waferPut = errorInfo.Contains("|NONWAF");
  406. if (waferPut)
  407. {
  408. if (CmdRobotArm == RobotArmEnum.Both)
  409. {
  410. WaferManager.Instance.WaferMoved(ModuleHelper.Converter(Module), (int)Hand.Blade1, CmdTarget, CmdTargetSlot);
  411. WaferManager.Instance.WaferMoved(ModuleHelper.Converter(Module), (int)Hand.Blade2, CmdTarget, CmdTargetSlot + 1);
  412. }
  413. else
  414. {
  415. WaferManager.Instance.WaferMoved(ModuleHelper.Converter(Module), (int)CmdRobotArm, CmdTarget, CmdTargetSlot);
  416. }
  417. }
  418. }
  419. MoveInfo = new RobotMoveInfo()
  420. {
  421. Action = RobotAction.Moving,
  422. ArmTarget = CmdRobotArm == RobotArmEnum.Lower ? RobotArm.ArmA : RobotArm.ArmB,
  423. BladeTarget = BuildBladeTarget(),
  424. };
  425. return true;
  426. }
  427. protected override bool fStartExtendForPick(object[] param)
  428. {
  429. return true;
  430. }
  431. protected override bool fStartExtendForPlace(object[] param)
  432. {
  433. return true;
  434. }
  435. protected override bool fStartRetractFromPick(object[] param)
  436. {
  437. return true;
  438. }
  439. protected override bool fStartRetractFromPlace(object[] param)
  440. {
  441. return true;
  442. }
  443. public override RobotArmWaferStateEnum GetWaferState(RobotArmEnum arm)
  444. {
  445. return RobotArmWaferStateEnum.Unknown;
  446. }
  447. public bool Pick(ModuleName target, Hand blade, int targetSlot, out string reason)
  448. {
  449. reason = string.Empty;
  450. return base.Pick((RobotArmEnum)(int)blade, target.ToString(), targetSlot);
  451. }
  452. public bool Place(ModuleName target, Hand blade, int targetSlot, out string reason)
  453. {
  454. reason = string.Empty;
  455. return base.Place((RobotArmEnum)(int)blade, target.ToString(), targetSlot);
  456. }
  457. public bool PickAndPlace(ModuleName pickTarget, Hand pickHand, int pickSlot, ModuleName placeTarget, Hand placeHand,
  458. int placeSlot, out string reason)
  459. {
  460. reason = string.Empty;
  461. return false;
  462. }
  463. public bool Goto(ModuleName target, Hand blade, int targetSlot, out string reason)
  464. {
  465. reason = string.Empty;
  466. return base.GoTo((RobotArmEnum)(int)blade, target.ToString(), targetSlot, RobotPostionEnum.PickReady);
  467. }
  468. public bool Map(ModuleName target, int thicknessIndex, out string reason)
  469. {
  470. reason = string.Empty;
  471. return base.WaferMapping(target, thicknessIndex);
  472. }
  473. public void NoteFailed(string error)
  474. {
  475. IsBusy = false;
  476. PostMsg(RobotMsg.ERROR, error);
  477. }
  478. public void NoteComplete()
  479. {
  480. if (fsm.State == (int)RobotStateEnum.Initializing)
  481. {
  482. IsBusy = false;
  483. return;
  484. }
  485. if (fsm.State == (int)RobotStateEnum.Mapping)
  486. {
  487. IsBusy = false;
  488. PostMsg(RobotMsg.ReadData, CmdTarget);
  489. }
  490. else
  491. {
  492. IsBusy = false;
  493. PostMsg(RobotMsg.ActionDone);
  494. }
  495. }
  496. public void NoteCancel(string error)
  497. {
  498. if (fsm.State == (int)RobotStateEnum.Initializing)
  499. {
  500. PostMsg(RobotMsg.ERROR, error);
  501. IsBusy = false;
  502. return;
  503. }
  504. IsBusy = false;
  505. PostMsg(RobotMsg.ERROR, error);
  506. }
  507. }
  508. }