EfemEntity.cs 38 KB

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