EfemEntity.cs 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204
  1. using System;
  2. using Aitex.Core.Common;
  3. using Aitex.Core.RT.DataCenter;
  4. using Aitex.Core.RT.Event;
  5. using Aitex.Core.RT.Fsm;
  6. using Aitex.Core.RT.OperationCenter;
  7. using Aitex.Core.RT.SCCore;
  8. using Aitex.Core.Utilities;
  9. using Aitex.Sorter.Common;
  10. using MECF.Framework.Common.Equipment;
  11. using MECF.Framework.Common.Schedulers;
  12. using MECF.Framework.Common.SubstrateTrackings;
  13. using VirgoCommon;
  14. using VirgoRT.Device;
  15. using VirgoRT.Device.YASKAWA;
  16. using VirgoRT.Devices.EFEM;
  17. using VirgoRT.Modules.LPs;
  18. using BAI.Systems.Common.Substrates;
  19. namespace VirgoRT.Modules
  20. {
  21. class EfemEntity : Entity, IEntity, IModuleEntity
  22. {
  23. private int _bigWafer = 0;
  24. private int _midWafer = 0;
  25. private int _smallWafer = 0;
  26. private bool _hasPlacementError = false;
  27. private bool _EnableResetEFEMError = false;
  28. public enum STATE
  29. {
  30. Unknown, // 0
  31. Initializing, // 1
  32. Idle, // 2
  33. Error, // 3
  34. Picking, // 4
  35. Placing, // 5
  36. Aligning, // 6
  37. Mapping, // 7
  38. Init, // 8
  39. Orgshing, // 9
  40. Lifting, // 10
  41. InitingAL, // 11
  42. InitingRB, // 12
  43. Extending, // 13
  44. Retracting, // 14
  45. //SettingLamp, // 15
  46. Swapping,
  47. Gotoing,
  48. Gripping,
  49. Ungripping,
  50. Fliping,
  51. EmsStoping,
  52. SetSpeed,
  53. Loading,
  54. }
  55. public enum MSG
  56. {
  57. HomeAll, // 0
  58. Pick, // 1
  59. Place, // 2
  60. Align, // 3
  61. ActionDone, // 4
  62. RecHwMsg, // 5
  63. MoveCmd, // 6
  64. //LED, // 7
  65. Recover, // 8
  66. Goto, // 9
  67. Error, // 10
  68. Online, // 11
  69. CommReady, // 12
  70. Lift, // 13
  71. HomeAL, // 14
  72. HomeRB, // 15
  73. Extend, // 16
  74. Retract, // 17
  75. PMLiftPinUp, // 18
  76. PMLiftPinDown, // 19
  77. TurnOffBuzzer,
  78. //SwitchOnBuzzerAndRed,
  79. Abort,
  80. Map,
  81. ToInit,
  82. Cool,
  83. PickAndPlace,
  84. Grip,
  85. Ungrip,
  86. Flip,
  87. LiftActionDone,
  88. EmsStop,
  89. SetRobotSpeed,
  90. Load,
  91. }
  92. public enum EfemType
  93. {
  94. FutureEfem = 1,
  95. JetEfem = 2,
  96. BrooksEFEM = 3,
  97. BeamSUNWAY = 4,
  98. }
  99. public bool Check(int msg, out string reason, params object[] args)
  100. {
  101. throw new NotImplementedException();
  102. }
  103. // Fields
  104. //
  105. private readonly string Name;
  106. private readonly Efem _efem;
  107. private readonly LoadPortModule[] _lpms = new LoadPortModule[2];
  108. private readonly EfemType _efemType;
  109. public Efem EfemDevice => _efem;
  110. public EfemType EFEMType => _efemType;
  111. // Constructor
  112. //
  113. public EfemEntity()
  114. {
  115. _smallWafer = SC.GetValue<int>($"System.SmallWafer");
  116. _midWafer = SC.GetValue<int>($"System.MidWafer");
  117. _bigWafer = SC.GetValue<int>($"System.BigWafer");
  118. _efemType = (EfemType)SC.GetValue<int>($"EFEM.EfemType");
  119. _EnableResetEFEMError = SC.GetValue<bool>($"EFEM.EnableResetError");
  120. _efem = new Efem();
  121. Name = ModuleName.EFEM.ToString();
  122. InitFsmMap();
  123. }
  124. public void NotifyLP(ModuleName mod, LoadportEntity.MSG msg)
  125. {
  126. _lpms[mod - ModuleName.LP1].PostMsg(msg);
  127. }
  128. public void NotifyLPError(ModuleName mod )
  129. {
  130. _lpms[mod - ModuleName.LP1].PostMsg(LoadportEntity.MSG.ActionDone);
  131. //_lpms[mod - ModuleName.LP1]..OnError();
  132. }
  133. protected override bool Init()
  134. {
  135. _lpms[0] = new LoadPortModule(ModuleName.LP1, _efem);
  136. _lpms[1] = new LoadPortModule(ModuleName.LP2, _efem);
  137. _lpms[0].Initialize();
  138. _lpms[1].Initialize();
  139. OP.Subscribe($"{ModuleName.EFEM}.{EfemOperation.Home}", (cmd, args) => { PostMsg(MSG.HomeAll); return true; });
  140. OP.Subscribe($"{ModuleName.EFEM}.{EfemOperation.ClearError}", (cmd, args) => { PostMsg(MSG.Recover); return true; });
  141. OP.Subscribe($"{ModuleName.EFEM}.{EfemOperation.TurnOffBuzzer}", (cmd, args) => { PostMsg(MSG.TurnOffBuzzer); return true; });
  142. //OP.Subscribe($"{ModuleName.EFEM}.{EfemOperation.SwitchOnBuzzerAndRed}", (cmd, args) => { PostMsg(MSG.SwitchOnBuzzerAndRed); return true; });
  143. OP.Subscribe($"{ModuleName.EFEM}.Online", (cmd, args) => { PostMsg(MSG.Online); return true; });
  144. OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Pick}", (cmd, args) => { PostMsg(MSG.Pick, args[0], args[1], args[3], args[2]); return true; });
  145. OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Place}", (cmd, args) => { PostMsg(MSG.Place, args[0], args[1], args[3], args[2]); return true; });
  146. OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Extend}", (cmd, args) => { PostMsg(MSG.Extend, args[0], args[1], args[2]); return true; });
  147. OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Retract}", (cmd, args) => { PostMsg(MSG.Retract, args[0], args[1]); return true; });
  148. OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Abort}", (cmd, args) => { PostMsg(MSG.Abort); return true; });
  149. OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Home}", (cmd, args) => { PostMsg(MSG.HomeRB, args); return true; });
  150. OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Grip}", (cmd, args) =>
  151. {
  152. bool isGrip = ((string)args[0]).ToLower() == "on";
  153. PostMsg(isGrip ? MSG.Grip : MSG.Ungrip, args[1]);
  154. return true;
  155. });
  156. OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Flip}", (cmd, args) => { PostMsg(MSG.Flip, args[0]); return true; });
  157. OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.EmsStop}", (cmd, args) => { PostMsg(MSG.EmsStop); return true; });
  158. OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.SetRobotSpeed}", (cmd, args) => { PostMsg(MSG.SetRobotSpeed, args[0]); return true; });
  159. OP.Subscribe($"{ModuleName.Aligner1}.{EfemOperation.Home}", (cmd, args) => { PostMsg(MSG.HomeAL, ModuleName.Aligner1); return true; });
  160. OP.Subscribe($"{ModuleName.Aligner2}.{EfemOperation.Home}", (cmd, args) => { PostMsg(MSG.HomeAL, ModuleName.Aligner2); return true; });
  161. OP.Subscribe($"{ModuleName.Cooling1}.{EfemOperation.Home}", (cmd, args) => { PostMsg(MSG.HomeAL, ModuleName.Cooling1); return true; });
  162. OP.Subscribe($"{ModuleName.Cooling2}.{EfemOperation.Home}", (cmd, args) => { PostMsg(MSG.HomeAL, ModuleName.Cooling2); return true; });
  163. OP.Subscribe($"{ModuleName.Aligner1}.{EfemOperation.Align}", (cmd, args) => { PostMsg(MSG.Align, ModuleName.Aligner1, args[0]); return true; });
  164. OP.Subscribe($"{ModuleName.Aligner2}.{EfemOperation.Align}", (cmd, args) => { PostMsg(MSG.Align, ModuleName.Aligner2, args[0]); return true; });
  165. OP.Subscribe($"{ModuleName.Cooling1}.{EfemOperation.Align}", (cmd, args) => { PostMsg(MSG.Align, ModuleName.Cooling1, args[0]); return true; });
  166. OP.Subscribe($"{ModuleName.Cooling2}.{EfemOperation.Align}", (cmd, args) => { PostMsg(MSG.Align, ModuleName.Cooling2, args[0]); return true; });
  167. OP.Subscribe($"{ModuleName.Aligner1}.{EfemOperation.Lift}", (cmd, args) => { PostMsg(MSG.Lift, ModuleName.Aligner1); return true; });
  168. OP.Subscribe($"{ModuleName.Aligner2}.{EfemOperation.Lift}", (cmd, args) => { PostMsg(MSG.Lift, ModuleName.Aligner2); return true; });
  169. OP.Subscribe($"{ModuleName.Cooling1}.{EfemOperation.Lift}", (cmd, args) => { PostMsg(MSG.Lift, ModuleName.Cooling1); return true; });
  170. OP.Subscribe($"{ModuleName.Cooling2}.{EfemOperation.Lift}", (cmd, args) => { PostMsg(MSG.Lift, ModuleName.Cooling2); return true; });
  171. DATA.Subscribe($"{Name}.FsmState", () => ((STATE)fsm.State).ToString());
  172. DATA.Subscribe($"{Name}.FsmPrevState", () => ((STATE)fsm.PrevState).ToString());
  173. DATA.Subscribe($"{Name}.FsmLastMessage", GetFsmLastMessage);
  174. DATA.Subscribe($"{Name}.SmallWafer", () => _smallWafer);
  175. DATA.Subscribe($"{Name}.BigWafer", () => _bigWafer);
  176. DATA.Subscribe($"{Name}.MidWafer", () => _midWafer);
  177. DATA.Subscribe($"{Name}.HasPlacementError", () => _hasPlacementError);
  178. return true;
  179. }
  180. private void InitFsmMap()
  181. {
  182. fsm = new StateMachine<EfemEntity>("EFEM", (int)STATE.Unknown, 50);
  183. fsm.EnableRepeatedMsg(true);
  184. AnyStateTransition(FSM_MSG.TIMER, fnMonitor, FSM_STATE.SAME);
  185. AnyStateTransition(MSG.RecHwMsg, fnRecMsg, FSM_STATE.SAME);
  186. //AnyStateTransition(MSG.LED, fnSetLED, STATE.SettingLamp);
  187. AnyStateTransition(MSG.TurnOffBuzzer, fnTurnOffBuzzer, FSM_STATE.SAME);
  188. //AnyStateTransition(MSG.SwitchOnBuzzerAndRed, fnSwitchOnBuzzerAndRed, FSM_STATE.SAME);
  189. AnyStateTransition(MSG.Recover, fnRecover, FSM_STATE.SAME);
  190. AnyStateTransition(MSG.Error, fnError, STATE.Error);
  191. AnyStateTransition(MSG.Online, fnOnline, FSM_STATE.SAME);
  192. AnyStateTransition(MSG.Abort, fnAbortRobot, STATE.Idle);
  193. AnyStateTransition(MSG.ToInit, fnToInit, STATE.Init);
  194. EnterExitTransition<STATE, FSM_MSG>(STATE.Initializing, fnEnterExecute, FSM_MSG.NONE, fnExitExecute);
  195. EnterExitTransition<STATE, FSM_MSG>(STATE.InitingRB, fnEnterExecute, FSM_MSG.NONE, null);
  196. EnterExitTransition<STATE, FSM_MSG>(STATE.InitingAL, fnEnterExecute, FSM_MSG.NONE, null);
  197. EnterExitTransition<STATE, FSM_MSG>(STATE.Picking, fnEnterExecute, FSM_MSG.NONE, fnExitExecute);
  198. EnterExitTransition<STATE, FSM_MSG>(STATE.Gotoing, fnEnterExecute, FSM_MSG.NONE, fnExitExecute);
  199. EnterExitTransition<STATE, FSM_MSG>(STATE.Placing, fnEnterExecute, FSM_MSG.NONE, fnExitExecute);
  200. EnterExitTransition<STATE, FSM_MSG>(STATE.Swapping, fnEnterExecute, FSM_MSG.NONE, fnExitExecute);
  201. EnterExitTransition<STATE, FSM_MSG>(STATE.Extending, fnEnterExecute, FSM_MSG.NONE, fnExitExecute);
  202. EnterExitTransition<STATE, FSM_MSG>(STATE.Retracting, fnEnterExecute, FSM_MSG.NONE, fnExitExecute);
  203. EnterExitTransition<STATE, FSM_MSG>(STATE.Lifting, fnEnterExecute, FSM_MSG.NONE, null);
  204. EnterExitTransition<STATE, FSM_MSG>(STATE.Aligning, fnEnterExecute, FSM_MSG.NONE, null);
  205. EnterExitTransition<STATE, FSM_MSG>(STATE.Mapping, fnEnterExecute, FSM_MSG.NONE, fnExitExecute);
  206. EnterExitTransition<STATE, FSM_MSG>(STATE.Gripping, fnEnterExecute, FSM_MSG.NONE, null);
  207. EnterExitTransition<STATE, FSM_MSG>(STATE.Ungripping, fnEnterExecute, FSM_MSG.NONE, null);
  208. EnterExitTransition<STATE, FSM_MSG>(STATE.Fliping, fnEnterExecute, FSM_MSG.NONE, fnExitExecute);
  209. EnterExitTransition<STATE, FSM_MSG>(STATE.EmsStoping, fnEnterExecute, FSM_MSG.NONE, fnExitExecute);
  210. EnterExitTransition<STATE, FSM_MSG>(STATE.SetSpeed, fnEnterExecute, FSM_MSG.NONE, fnExitExecute);
  211. EnterExitTransition<STATE, FSM_MSG>(STATE.Loading, fnEnterExecute, FSM_MSG.NONE, fnExitExecute);
  212. Transition(STATE.Unknown, MSG.CommReady, null, STATE.Init);
  213. // Home
  214. Transition(STATE.Init, MSG.HomeAll, fnHomeAll, STATE.Initializing);
  215. Transition(STATE.Idle, MSG.HomeAll, fnHomeAll, STATE.Initializing); // 暂时加,出错的时候做 HOME
  216. Transition(STATE.Error, MSG.HomeAll, fnHomeAll, STATE.Initializing);
  217. Transition(STATE.Initializing, MSG.ActionDone, fnActionDone, STATE.Orgshing);
  218. Transition(STATE.Orgshing, MSG.ActionDone, fnActionDone, STATE.Idle);
  219. Transition(STATE.Idle, MSG.HomeRB, fnHomeRobot, STATE.InitingRB);
  220. Transition(STATE.InitingRB, MSG.ActionDone, null, STATE.Idle);
  221. //Transition(STATE.SettingLamp, MSG.ActionDone, fnSetLampDone, STATE.Idle);
  222. // Pick
  223. Transition(STATE.Idle, MSG.Pick, fnPick, STATE.Picking);
  224. Transition(STATE.Picking, MSG.ActionDone, fnActionDone, STATE.Idle);
  225. Transition(STATE.Picking, MSG.PMLiftPinUp, fnPmPinUp, STATE.Idle);
  226. Transition(STATE.Picking, MSG.PMLiftPinDown, fnPmPinDown, STATE.Idle);
  227. // Place
  228. Transition(STATE.Idle, MSG.Place, fnPlace, STATE.Placing);
  229. Transition(STATE.Placing, MSG.ActionDone, fnActionDone, STATE.Idle);
  230. Transition(STATE.Placing, MSG.PMLiftPinUp, fnPmPinUp, STATE.Idle);
  231. Transition(STATE.Placing, MSG.PMLiftPinDown, fnPmPinDown, STATE.Idle);
  232. // PickAndPlace
  233. Transition(STATE.Idle, MSG.PickAndPlace, fnSwap, STATE.Swapping);
  234. Transition(STATE.Swapping, MSG.ActionDone, fnActionDone, STATE.Idle);
  235. Transition(STATE.Swapping, MSG.PMLiftPinUp, fnPmPinUp, STATE.Idle);
  236. Transition(STATE.Swapping, MSG.PMLiftPinDown, fnPmPinDown, STATE.Idle);
  237. // Goto
  238. Transition(STATE.Idle, MSG.Goto, fnGoto, STATE.Gotoing);
  239. Transition(STATE.Gotoing, MSG.ActionDone, fnActionDone, STATE.Idle);
  240. // Extend
  241. Transition(STATE.Idle, MSG.Extend, fnExtend, STATE.Extending);
  242. Transition(STATE.Extending, MSG.ActionDone, fnActionDone, STATE.Idle);
  243. // Retract
  244. Transition(STATE.Idle, MSG.Retract, fnRetract, STATE.Retracting);
  245. Transition(STATE.Retracting, MSG.ActionDone, fnActionDone, STATE.Idle);
  246. // Map
  247. Transition(STATE.Idle, MSG.Map, fnMap, STATE.Mapping);
  248. Transition(STATE.Mapping, MSG.ActionDone, fnActionDone, STATE.Idle);
  249. // Grip
  250. Transition(STATE.Idle, MSG.Grip, fnGrip, STATE.Gripping);
  251. Transition(STATE.Gripping, MSG.ActionDone, fnActionDone, STATE.Idle);
  252. // Ungrip
  253. Transition(STATE.Idle, MSG.Ungrip, fnUngrip, STATE.Ungripping);
  254. Transition(STATE.Ungripping, MSG.ActionDone, fnActionDone, STATE.Idle);
  255. // Aligner
  256. Transition(STATE.Idle, MSG.HomeAL, fnHomeAligner, STATE.InitingAL);
  257. Transition(STATE.InitingAL, MSG.ActionDone, fnActionDone, STATE.Idle);
  258. Transition(STATE.Idle, MSG.Lift, fnLift, STATE.Lifting);
  259. Transition(STATE.Lifting, MSG.LiftActionDone, fnActionDone, STATE.Idle);
  260. Transition(STATE.Idle, MSG.Align, fnAlign, STATE.Aligning);
  261. Transition(STATE.Aligning, MSG.ActionDone, fnActionDone, STATE.Idle);
  262. // Flip
  263. Transition(STATE.Idle, MSG.Flip, fnFlip, STATE.Fliping);
  264. Transition(STATE.Fliping, MSG.ActionDone, fnActionDone, STATE.Idle);
  265. // EmsStop
  266. Transition(STATE.Idle, MSG.EmsStop, fnEmsStop, STATE.EmsStoping);
  267. Transition(STATE.EmsStoping, MSG.ActionDone, fnActionDone, STATE.Idle);
  268. // Set Robot Speed
  269. Transition(STATE.Idle, MSG.SetRobotSpeed, fnSetRobotSpeed, STATE.SetSpeed);
  270. Transition(STATE.SetSpeed, MSG.ActionDone, fnActionDone, STATE.Idle);
  271. // Load Foup
  272. Transition(STATE.Idle, MSG.Load, fnLoadFoup, STATE.Loading);
  273. Transition(STATE.Loading, MSG.ActionDone, fnActionDone, STATE.Idle);
  274. EnumLoop<STATE>.ForEach((item) => { fsm.MapState((int)item, item.ToString()); });
  275. EnumLoop<MSG>.ForEach((item) => { fsm.MapMessage((int)item, item.ToString()); });
  276. }
  277. private bool fnHomeAll(object[] param)
  278. {
  279. _efem.ClearActions();
  280. _efem.HomeAll();
  281. return true;
  282. }
  283. private bool fnHomeRobot(object[] param)
  284. {
  285. _efem.ClearActions();
  286. _efem.Home(ModuleName.EfemRobot, (string)param[0]);
  287. return true;
  288. }
  289. private bool fnHomeAligner(object[] param)
  290. {
  291. // module
  292. ModuleName unit = ModuleName.EFEM;
  293. if (param[0] is string s1)
  294. unit = ModuleNameString.ToEnum(s1);
  295. else if (param[0] is ModuleName mod)
  296. unit = mod;
  297. else
  298. throw new ArgumentException("Argument error");
  299. _efem.Home(unit, "");
  300. return true;
  301. }
  302. private bool fnEnterExecute(object[] param)
  303. {
  304. if(!_efem.HasUncompleteActions)
  305. _efem.ExecuteAction();
  306. return false;
  307. }
  308. private bool fnExitExecute(object[] param)
  309. {
  310. if (!_efem.HasUncompleteActions)
  311. _efem.ExecuteAction();
  312. return false;
  313. }
  314. private bool fnActionDone(object[] param)
  315. {
  316. try
  317. {
  318. EfemOperation actionType = (EfemOperation)param[0];
  319. if (((fsm.State == (int)STATE.Orgshing) && (actionType == EfemOperation.Orgsh || actionType == EfemOperation.Home)) ||
  320. (fsm.State == (int)STATE.Initializing && actionType == EfemOperation.ClearError) ||
  321. (fsm.State == (int)STATE.Extending) ||
  322. (fsm.State == (int)STATE.Picking) ||
  323. (fsm.State == (int)STATE.Placing) ||
  324. (fsm.State == (int)STATE.Swapping) ||
  325. (fsm.State == (int)STATE.Aligning) ||
  326. (fsm.State == (int)STATE.Fliping))
  327. {
  328. if (_efem.HasActions || _efem.HasUncompleteActions)
  329. {
  330. if(!_efem.HasUncompleteActions)
  331. {
  332. _efem.ExecuteAction();
  333. }
  334. return false;
  335. }
  336. }
  337. return true;
  338. }
  339. catch (Exception ex)
  340. {
  341. EV.PostAlarmLog(ModuleName.EFEM.ToString(), ex.Message);
  342. return true;
  343. }
  344. }
  345. public bool CheckToPostMessage(int msg, params object[] args)
  346. {
  347. if (!fsm.FindTransition(fsm.State, msg))
  348. {
  349. EV.PostWarningLog(Name, $"{Name} is in {(STATE)fsm.State} state,can not do {(MSG)msg}");
  350. return false;
  351. }
  352. Running = true;
  353. fsm.PostMsg(msg, args);
  354. return true;
  355. }
  356. private bool fnRecMsg(object[] param)
  357. {
  358. if (param == null) return false;
  359. string strHwMsg = param[0] as string;
  360. if (_efem is EfemBase device)
  361. {
  362. device.ReceiveMessage(strHwMsg);
  363. return true;
  364. }
  365. return false;
  366. }
  367. private bool fnMonitor(object[] param)
  368. {
  369. STATE curSt = (STATE)fsm.State;
  370. if (curSt == STATE.Initializing || curSt == STATE.Mapping || curSt == STATE.Picking || curSt == STATE.Placing
  371. || curSt == STATE.Orgshing || curSt == STATE.Lifting || curSt == STATE.Extending || curSt == STATE.Retracting
  372. || curSt == STATE.InitingAL || curSt == STATE.InitingRB)
  373. {
  374. int time = SC.GetValue<int>("EFEM.MotionTimeout");
  375. if (fsm.ElapsedTime > time * 1000)
  376. {
  377. EV.PostAlarmLog("EFEM", $"Can not complete motion {curSt} in {time} seconds. ");
  378. PostMsg(MSG.Error);
  379. }
  380. }
  381. else if (curSt == STATE.Aligning)
  382. {
  383. int _timeout = SC.GetValue<int>("EFEM.AlignerTimeout");
  384. if (fsm.ElapsedTime > _timeout * 1000)
  385. {
  386. EV.PostAlarmLog(ModuleName.Aligner.ToString(), "Align timeout");
  387. PostMsg(MSG.Error);
  388. }
  389. }
  390. else if (curSt == STATE.Idle)
  391. {
  392. if (_efem.HasActions && !_efem.HasUncompleteActions)
  393. {
  394. _efem.ExecuteAction();
  395. }
  396. }
  397. if (_efemType == EfemType.BrooksEFEM && (SC.GetValue<bool>("EFEM.LoadPort.EnableDockUndock") == false))
  398. {
  399. _efem.QueryLPState();
  400. }
  401. // update Loadport wafer placement parity error status
  402. _hasPlacementError = _efem[ModuleName.LP1].HasPlacementError || _efem[ModuleName.LP2].HasPlacementError;
  403. return true;
  404. }
  405. private bool fnOnline(object[] param)
  406. {
  407. bool bOnlineFlag = (bool)param[0];
  408. if (_efem is EfemBase efem)
  409. {
  410. efem.SetOnline(bOnlineFlag);
  411. }
  412. return true;
  413. }
  414. private string GetFsmLastMessage()
  415. {
  416. int msg = fsm.LastMsg;
  417. if (msg >= (int)MSG.HomeAll && msg <= (int)MSG.Error)
  418. return ((MSG)msg).ToString();
  419. if (msg == (int)FSM_MSG.TIMER)
  420. return "Timer";
  421. return msg.ToString();
  422. }
  423. private bool fnError(object[] param)
  424. {
  425. return true;
  426. }
  427. private bool fnToInit(object[] param)
  428. {
  429. return true;
  430. }
  431. private bool fnRecover(object[] param)
  432. {
  433. _efem.ClearActions();
  434. _efem.ClearError();
  435. //_efem.ExecuteAction();
  436. return true;
  437. }
  438. private bool fnAbortRobot(object[] param)
  439. {
  440. _efem.ClearActions();
  441. _efem.AbortRobot();
  442. //_efem.ExecuteAction();
  443. return true;
  444. }
  445. private bool fnSetLED(object[] param)
  446. {
  447. LightType light = (LightType)param[0];
  448. LightStatus st = (LightStatus)param[1];
  449. _efem.SetLamp(light, st);
  450. return true;
  451. }
  452. private bool fnTurnOffBuzzer(object[] param)
  453. {
  454. _efem.TurnOffBuzzer();
  455. return false;
  456. }
  457. //private bool fnSwitchOnBuzzerAndRed(object[] param)
  458. //{
  459. // _efem.SwitchOnBuzzerAndRed();
  460. // return false;
  461. //}
  462. //
  463. private bool fnSetLampDone(object[] param)
  464. {
  465. if (_efem.HasActions && !_efem.HasUncompleteActions)
  466. {
  467. _efem.ExecuteAction();
  468. return false;
  469. }
  470. else
  471. {
  472. return true;
  473. }
  474. }
  475. private bool fnPick(object[] param)
  476. {
  477. // module
  478. ModuleName unit = ModuleName.EFEM;
  479. if (param[0] is string s1)
  480. unit = ModuleNameString.ToEnum(s1);
  481. else if (param[0] is ModuleName mod)
  482. unit = mod;
  483. else
  484. throw new ArgumentException("Argument error");
  485. // slot
  486. byte slot = (byte)(int)param[1];
  487. // hand
  488. Hand arm = (Hand)Enum.Parse(typeof(Hand), param[2].ToString());
  489. // wafer size
  490. WaferSize ws1 = WaferSize.WS0;
  491. if (param[3] is string s2)
  492. {
  493. if (Enum.TryParse(s2, out WaferSize p5))
  494. ws1 = p5;
  495. }
  496. else if (param[3] is WaferSize p6)
  497. {
  498. ws1 = p6;
  499. }
  500. MoveParam mp = new MoveParam(unit, slot, ModuleName.EfemRobot, (byte)arm, arm, ws1);
  501. if (!_efem.Pick(mp))
  502. return false;
  503. return true;
  504. }
  505. private bool fnPlace(object[] param)
  506. {
  507. // module
  508. ModuleName unit = ModuleName.EFEM;
  509. if (param[0] is string s1)
  510. unit = ModuleNameString.ToEnum(s1);
  511. else if (param[0] is ModuleName mod)
  512. unit = mod;
  513. else
  514. throw new ArgumentException("Argument error");
  515. // slot
  516. byte slot = (byte)(int)param[1];
  517. // hand
  518. Hand arm = (Hand)Enum.Parse(typeof(Hand), param[2].ToString());
  519. // wafer size
  520. WaferSize ws1 = WaferSize.WS0;
  521. if (param[3] is string s2)
  522. {
  523. if (Enum.TryParse(s2, out WaferSize p5))
  524. ws1 = p5;
  525. }
  526. else if (param[3] is WaferSize p6)
  527. {
  528. ws1 = p6;
  529. }
  530. MoveParam mp = new MoveParam(ModuleName.EfemRobot, (byte)arm, unit, slot, arm, ws1);
  531. if (!_efem.Place(mp))
  532. return false;
  533. return true;
  534. }
  535. private bool fnGoto(object[] param)
  536. {
  537. // module
  538. ModuleName unit = ModuleName.EFEM;
  539. if (param[0] is string s1)
  540. unit = ModuleNameString.ToEnum(s1);
  541. else if (param[0] is ModuleName mod)
  542. unit = mod;
  543. else
  544. throw new ArgumentException("Argument error");
  545. // slot
  546. byte slot = (byte)(int)param[1];
  547. Hand arm = Hand.Blade1;
  548. WaferSize ws = WaferSize.WS6;
  549. if (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 0))
  550. {
  551. arm = Hand.Blade1;
  552. ws = WaferManager.Instance.GetWafer(ModuleName.EfemRobot, 0).Size;
  553. }
  554. else if (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 1))
  555. {
  556. arm = Hand.Blade2;
  557. ws = WaferManager.Instance.GetWafer(ModuleName.EfemRobot, 1).Size;
  558. }
  559. MoveParam mp = new MoveParam(unit, slot, unit, slot, arm, ws);
  560. _efem.Goto(mp);
  561. return true;
  562. }
  563. private bool fnSwap(object[] param)
  564. {
  565. // module
  566. ModuleName unit = ModuleName.EFEM;
  567. if (param[0] is string s1)
  568. unit = ModuleNameString.ToEnum(s1);
  569. else if (param[0] is ModuleName mod)
  570. unit = mod;
  571. else
  572. throw new ArgumentException("Argument error");
  573. // pickSlot
  574. byte pickSlot = (byte)(int)param[1];
  575. // pick hand
  576. Hand pickArm = (Hand)Enum.Parse(typeof(Hand), param[2].ToString());
  577. // wafer size
  578. WaferSize ws1 = WaferSize.WS0;
  579. if (param[5] is string s2)
  580. {
  581. if (Enum.TryParse(s2, out WaferSize p5))
  582. ws1 = p5;
  583. }
  584. else if (param[5] is WaferSize p6)
  585. {
  586. ws1 = p6;
  587. }
  588. MoveParam pickParam = new MoveParam(unit, pickSlot, ModuleName.EfemRobot, (byte)pickArm, pickArm, ws1);
  589. // place slot
  590. byte placeSlot = (byte)(int)param[4];
  591. // hand
  592. Hand placeArm = (Hand)Enum.Parse(typeof(Hand), param[3].ToString());
  593. MoveParam placeParam = new MoveParam(ModuleName.EfemRobot, (byte)placeArm, unit, placeSlot, placeArm, ws1);
  594. _efem.PickAndPlace(pickParam, placeParam);
  595. return true;
  596. }
  597. private bool fnExtend(object[] param)
  598. {
  599. // module
  600. ModuleName unit = ModuleName.EFEM;
  601. if (param[0] is string s1)
  602. unit = ModuleNameString.ToEnum(s1);
  603. else if (param[0] is ModuleName mod)
  604. unit = mod;
  605. else
  606. throw new ArgumentException("Argument error");
  607. Hand arm = (Hand)Enum.Parse(typeof(Hand), (string)param[2]);
  608. ExtendParam mp = new ExtendParam
  609. {
  610. Module = unit,
  611. Arm = arm,
  612. Pos = (ExtendPos)Enum.Parse(typeof(ExtendPos), param[1] as string)
  613. };
  614. if (!_efem.Extend(mp))
  615. return false;
  616. return true;
  617. }
  618. private bool fnRetract(object[] param)
  619. {
  620. // module
  621. ModuleName unit = ModuleName.EFEM;
  622. if (param[0] is string s1)
  623. unit = ModuleNameString.ToEnum(s1);
  624. else if (param[0] is ModuleName mod)
  625. unit = mod;
  626. else
  627. throw new ArgumentException("Argument error");
  628. Hand arm = (Hand)Enum.Parse(typeof(Hand), (string)param[2]);
  629. ExtendParam mp = new ExtendParam
  630. {
  631. Module = unit,
  632. Arm = arm,
  633. Pos = (ExtendPos)Enum.Parse(typeof(ExtendPos), param[1] as string)
  634. };
  635. if (!_efem.Retract(mp))
  636. return false;
  637. return true;
  638. }
  639. private bool fnPmPinUp(object[] param)
  640. {
  641. _efem.UpdateStatus((ushort)param[0], ActionStatus.Completed);
  642. if (_efem.HasActions && !_efem.HasUncompleteActions)
  643. {
  644. _efem.ExecuteAction();
  645. return false;
  646. }
  647. else
  648. {
  649. return true;
  650. }
  651. }
  652. private bool fnPmPinDown(object[] param)
  653. {
  654. _efem.UpdateStatus((ushort)param[0], ActionStatus.Completed);
  655. if (_efem.HasActions && !_efem.HasUncompleteActions)
  656. {
  657. _efem.ExecuteAction();
  658. return false;
  659. }
  660. else
  661. {
  662. return true;
  663. }
  664. }
  665. private bool fnLift(object[] param)
  666. {
  667. // module
  668. ModuleName unit = ModuleName.EFEM;
  669. if (param[0] is string s1)
  670. unit = ModuleNameString.ToEnum(s1);
  671. else if (param[0] is ModuleName mod)
  672. unit = mod;
  673. else
  674. throw new ArgumentException("Argument error");
  675. bool isUp = true;
  676. if (param.Length > 1)
  677. {
  678. isUp = (bool) param[1];
  679. }
  680. if (isUp)
  681. {
  682. if (!_efem.SetPinUp(unit))
  683. return false;
  684. }
  685. else
  686. {
  687. if (!_efem.SetPinDown(unit))
  688. return false;
  689. }
  690. return true;
  691. }
  692. private bool fnAlign(object[] param)
  693. {
  694. // module
  695. ModuleName unit = ModuleName.EFEM;
  696. if (param[0] is string s1)
  697. unit = ModuleNameString.ToEnum(s1);
  698. else if (param[0] is ModuleName mod)
  699. unit = mod;
  700. else
  701. throw new ArgumentException("Argument error");
  702. // wafer size
  703. WaferSize ws1 = WaferSize.WS0;
  704. if (param[1] is string s2)
  705. {
  706. if (Enum.TryParse(s2, out WaferSize p5))
  707. ws1 = p5;
  708. }
  709. else if (param[1] is WaferSize p6)
  710. {
  711. ws1 = p6;
  712. }
  713. if (!_efem.Align(unit, 1000, ws1))
  714. return false;
  715. return true;
  716. }
  717. private bool fnMap(object[] param)
  718. {
  719. // module
  720. ModuleName unit = ModuleName.EFEM;
  721. if (param[0] is string s1)
  722. unit = ModuleNameString.ToEnum(s1);
  723. else if (param[0] is ModuleName mod)
  724. unit = mod;
  725. else
  726. throw new ArgumentException("Argument error");
  727. if (!_efem.Map(unit))
  728. return false;
  729. return true;
  730. }
  731. private bool fnGrip(object[] param)
  732. {
  733. Hand arm = (Hand)Enum.Parse(typeof(Hand), (string)param[0]);
  734. if (!_efem.Grip(arm, true))
  735. return false;
  736. return true;
  737. }
  738. private bool fnUngrip(object[] param)
  739. {
  740. Hand arm = (Hand)Enum.Parse(typeof(Hand), (string)param[0]);
  741. if (!_efem.Grip(arm, false))
  742. return false;
  743. return true;
  744. }
  745. private bool fnFlip(object[] param)
  746. {
  747. string orient = (string)param[0];
  748. if (!_efem.Flip(orient))
  749. return false;
  750. return true;
  751. }
  752. private bool fnEmsStop(object[] param)
  753. {
  754. if (!_efem.EmsStop())
  755. return false;
  756. return true;
  757. }
  758. private bool fnSetRobotSpeed(object[] param)
  759. {
  760. string speed = (string)param[0];
  761. if (!_efem.SetSpeed(speed))
  762. return false;
  763. return true;
  764. }
  765. private bool fnLoadFoup(object[] param)
  766. {
  767. ModuleName lp = ModuleHelper.Converter((string)param[0]);
  768. if (!_efem.Load(lp))
  769. return false;
  770. return true;
  771. }
  772. public bool IsIdle
  773. {
  774. get { return fsm.State == (int)STATE.Idle; }
  775. }
  776. public bool IsError
  777. {
  778. get { return fsm.State == (int)STATE.Error; }
  779. }
  780. public bool IsInit
  781. {
  782. get { return fsm.State == (int)STATE.Unknown || fsm.State==(int)STATE.Init; }
  783. }
  784. public bool IsBusy
  785. {
  786. get { return !IsInit && !IsError && !IsIdle; }
  787. }
  788. public bool IsOnline { get; internal set; }
  789. public int Invoke(string function, params object[] args)
  790. {
  791. switch (function)
  792. {
  793. case "Home":
  794. CheckToPostMessage((int)MSG.HomeAll);
  795. return (int)MSG.HomeAll;
  796. }
  797. return (int)FSM_MSG.NONE;
  798. }
  799. public bool CheckAcked(int msg)
  800. {
  801. return fsm.CheckExecuted(msg);
  802. }
  803. internal void InvokeReset()
  804. {
  805. if (_EnableResetEFEMError && fsm.State == (int) STATE.Error)
  806. {
  807. PostMsg((int)MSG.Recover);
  808. }
  809. }
  810. public int InvokeAlign(string module, float time)
  811. {
  812. if (CheckToPostMessage((int)MSG.Align, module, time))
  813. return (int)MSG.Align;
  814. return (int)FSM_MSG.NONE;
  815. }
  816. public int InvokeLiftDown(string module)
  817. {
  818. if (CheckToPostMessage((int)MSG.Lift, module, false))
  819. return (int)MSG.Lift;
  820. return (int)FSM_MSG.NONE;
  821. }
  822. public int InvokePick(ModuleName source, int slot, Hand hand, WaferSize size)
  823. {
  824. if (CheckToPostMessage((int)MSG.Pick, source, slot, hand, size))
  825. return (int)MSG.Pick;
  826. return (int)FSM_MSG.NONE;
  827. }
  828. public int InvokeGoto(ModuleName source, int slot)
  829. {
  830. if (CheckToPostMessage((int)MSG.Goto, source, slot))
  831. return (int)MSG.Goto;
  832. return (int)FSM_MSG.NONE;
  833. }
  834. public int InvokePlace(ModuleName target, int slot, Hand hand, WaferSize size)
  835. {
  836. if (CheckToPostMessage((int)MSG.Place, target, slot, hand, size))
  837. return (int)MSG.Place;
  838. return (int)FSM_MSG.NONE;
  839. }
  840. public int InvokePickAndPlace(ModuleName targetModule, Hand pickHand, int pickSlot, Hand placeHand, int placeSlot, WaferSize size)
  841. {
  842. if (CheckToPostMessage((int)MSG.PickAndPlace, targetModule, pickSlot, pickHand, placeHand, placeSlot, size))
  843. return (int)MSG.PickAndPlace;
  844. return (int)FSM_MSG.NONE;
  845. }
  846. public int InvokeMap(string target )
  847. {
  848. if (CheckToPostMessage((int)MSG.Map, target ))
  849. return (int)MSG.Map;
  850. return (int)FSM_MSG.NONE;
  851. }
  852. public int InvokeFlip(string orient)
  853. {
  854. if (CheckToPostMessage((int)MSG.Flip, orient))
  855. return (int)MSG.Flip;
  856. return (int)FSM_MSG.NONE;
  857. }
  858. public bool IsPrepareTransferReady(ModuleName module, EnumTransferType type, int slot)
  859. {
  860. if (type == EnumTransferType.Pick)
  861. {
  862. //需要补充:判断LP 放好了,而且已经map过。
  863. return _efem[module].HasCassette && _efem[module].IsMapped;
  864. }
  865. else if (type == EnumTransferType.Place)
  866. {
  867. //需要补充:判断LP 放好了,而且已经map过。
  868. return _efem[module].HasCassette && _efem[module].IsMapped;
  869. }
  870. return false;
  871. }
  872. internal bool CheckReadyRunNewJob(ModuleName module)
  873. {
  874. //???
  875. return true;
  876. }
  877. internal bool CheckReadyTransfer(ModuleName module)
  878. {
  879. return _efem[module].HasCassette && _efem[module].IsMapped;
  880. }
  881. internal bool CheckPlaced(ModuleName module)
  882. {
  883. return _efem[module].HasCassette;
  884. }
  885. internal void NoteJobStart(ModuleName module)
  886. {
  887. _efem[module].NoteJobStart();
  888. }
  889. internal void NoteJobComplete(ModuleName module)
  890. {
  891. _efem[module].NoteJobComplete();
  892. }
  893. internal string GetCarrierID(ModuleName module)
  894. {
  895. return _efem[module].CarrierId;
  896. }
  897. }
  898. /// <summary>
  899. /// LP entity
  900. /// </summary>
  901. class LoadportEntity : Entity, IEntity
  902. {
  903. private enum STATE
  904. {
  905. Unknown,
  906. Idle, // 1
  907. Initializing, // 2
  908. Initialized, // 3
  909. Mapping, // 4
  910. Mapped, // 5
  911. }
  912. public enum MSG
  913. {
  914. Home, // 0
  915. Map, // 1
  916. ActionDone, // 2
  917. RecHwMsg, // 3
  918. Recover, // 4
  919. Abort, // 5
  920. Online, // 6
  921. Error // 7
  922. }
  923. private readonly Efem _efem;
  924. private ModuleName Module { get; }
  925. public LoadportEntity(ModuleName mod, Efem efem)
  926. {
  927. this.Module = mod;
  928. _efem = efem;
  929. InitFsmMap();
  930. OP.Subscribe($"{Module}.Home", (cmd, args) => { PostMsg(MSG.Home); return true; });
  931. OP.Subscribe($"{Module}.Abort", (cmd, args) => { PostMsg(MSG.Abort); return true; });
  932. //OP.Subscribe($"{Module}.Map", (cmd, args) => { PostMsg(MSG.Map); return true; });
  933. OP.Subscribe($"{Module}.Online", (cmd, args) => { PostMsg(MSG.Online); return true; });
  934. DATA.Subscribe($"{Module}.Status", () => ((STATE)fsm.State).ToString());
  935. DATA.Subscribe($"{Module}.FsmState", () => ((STATE)fsm.State).ToString());
  936. DATA.Subscribe($"{Module}.FsmPrevState", () => ((STATE)fsm.PrevState).ToString());
  937. DATA.Subscribe($"{Module}.FsmLastMessage", GetFsmLastMessage);
  938. }
  939. private string GetFsmLastMessage()
  940. {
  941. int msg = fsm.LastMsg;
  942. if (msg >= (int)MSG.Home && msg <= (int)MSG.Error)
  943. return ((MSG)msg).ToString();
  944. if (msg == (int)FSM_MSG.TIMER)
  945. return "Timer";
  946. return msg.ToString();
  947. }
  948. private void InitFsmMap()
  949. {
  950. fsm = new StateMachine<LoadportEntity>($"LPM_{Module}", (int)STATE.Idle, 500);
  951. AnyStateTransition(FSM_MSG.TIMER, fnMonitor, FSM_STATE.SAME);
  952. //AnyStateTransition(MSG.RecHwMsg, fnRecMsg, FSM_STATE.SAME);
  953. AnyStateTransition(MSG.Online, fnOnline, FSM_STATE.SAME);
  954. AnyStateTransition(MSG.Recover, fnRecover, STATE.Idle);
  955. AnyStateTransition(MSG.Abort, fnRecover, STATE.Idle);
  956. EnterExitTransition<STATE, FSM_MSG>(STATE.Initializing, fnEnterExecute, FSM_MSG.NONE, fnExitExecute);
  957. // Home
  958. AnyStateTransition(MSG.Home, fnHome, STATE.Initializing);
  959. Transition(STATE.Initializing, MSG.ActionDone, fnActionDone, STATE.Idle);
  960. }
  961. private bool fnOnline(object[] param)
  962. {
  963. bool online = (bool)param[0];
  964. _efem.SetOnline(Module, online);
  965. return true;
  966. }
  967. private bool fnRecover(object[] param)
  968. {
  969. return true;
  970. }
  971. private bool fnMonitor(object[] param)
  972. {
  973. STATE curSt = (STATE)fsm.State;
  974. if (curSt == STATE.Initializing || curSt == STATE.Mapping)
  975. {
  976. if (fsm.ElapsedTime > 20 * 1000)
  977. {
  978. PostMsg(MSG.Recover);
  979. }
  980. }
  981. return true;
  982. }
  983. private bool fnEnterExecute(object[] param)
  984. {
  985. _efem.ExecuteAction();
  986. return true;
  987. }
  988. private bool fnExitExecute(object[] param)
  989. {
  990. return true;
  991. }
  992. private bool fnActionDone(object[] param)
  993. {
  994. return true;
  995. }
  996. private bool fnHome(object[] param)
  997. {
  998. _efem.Home(Module, ModuleName.EFEM.ToString());
  999. return true;
  1000. }
  1001. public bool Check(int msg, out string reason, params object[] args)
  1002. {
  1003. throw new NotImplementedException();
  1004. }
  1005. }
  1006. }