EfemEntity.cs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823
  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.Utilities;
  8. using Aitex.Sorter.Common;
  9. using MECF.Framework.Common.Equipment;
  10. using MECF.Framework.Common.Schedulers;
  11. using Virgo_DCommon;
  12. using Virgo_DRT.Device;
  13. using Virgo_DRT.Device.YASKAWA;
  14. namespace Virgo_DRT.Modules
  15. {
  16. class EfemEntity : Entity, IEntity, IModuleEntity
  17. {
  18. public enum STATE
  19. {
  20. Unknown, // 0
  21. Initializing, // 1
  22. Idle, // 2
  23. Error, // 3
  24. Picking, // 4
  25. Placing, // 5
  26. Aligning, // 6
  27. Mapping, // 7
  28. Init, // 8
  29. Orgshing, // 9
  30. Lifting, // 10
  31. InitingAL, // 11
  32. InitingRB, // 12
  33. Extending, // 13
  34. Retracting, // 14
  35. SettingLamp //15
  36. }
  37. public enum MSG
  38. {
  39. HomeAll, // 0
  40. Pick, // 1
  41. Place, // 2
  42. Align, // 3
  43. ActionDone, // 4
  44. RecHwMsg, // 5
  45. MoveCmd, // 6
  46. LED, // 7
  47. Recover, // 8
  48. Goto, // 9
  49. Error, // 10
  50. Online, // 11
  51. CommReady, // 12
  52. Lift, // 13
  53. HomeAL, // 14
  54. HomeRB, // 15
  55. Extend, // 16
  56. Retract, // 17
  57. PMLiftPinUp, // 18
  58. PMLiftPinDown, // 19
  59. AllLightsOFF,
  60. Abort,
  61. Map,
  62. }
  63. public bool Check(int msg, out string reason, params object[] args)
  64. {
  65. throw new NotImplementedException();
  66. }
  67. // Fields
  68. //
  69. private readonly string Name;
  70. private readonly Efem _efem;
  71. private readonly LoadportEntity[] _lpms = new LoadportEntity[2];
  72. // Constructor
  73. //
  74. public EfemEntity()
  75. {
  76. _efem = new Efem();
  77. _lpms[0] = new LoadportEntity(ModuleName.LP1, _efem);
  78. _lpms[1] = new LoadportEntity(ModuleName.LP2, _efem);
  79. Name = ModuleName.EFEM.ToString();
  80. InitFsmMap();
  81. _lpms[0].Initialize();
  82. _lpms[1].Initialize();
  83. }
  84. public void NotifyLP(ModuleName mod, LoadportEntity.MSG msg)
  85. {
  86. _lpms[mod - ModuleName.LP1].PostMsg(msg);
  87. }
  88. protected override bool Init()
  89. {
  90. OP.Subscribe($"{ModuleName.EFEM}.{EfemOperation.Home}", (cmd, args) => { PostMsg(MSG.HomeAll); return true; });
  91. OP.Subscribe($"{ModuleName.EFEM}.{EfemOperation.ClearError}", (cmd, args) => { PostMsg(MSG.Recover); return true; });
  92. OP.Subscribe($"{ModuleName.EFEM}.{EfemOperation.TurnOffAllLights}", (cmd, args) => { PostMsg(MSG.AllLightsOFF); return true; });
  93. OP.Subscribe($"{ModuleName.EFEM}.Online", (cmd, args) => { PostMsg(MSG.Online); return true; });
  94. OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Pick}", (cmd, args) => { PostMsg(MSG.Pick, args[0], args[1], Hand.Blade1, args[2]); return true; });
  95. OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Place}", (cmd, args) => { PostMsg(MSG.Place, args[0], args[1], Hand.Blade1, args[2]); return true; });
  96. OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Extend}", (cmd, args) => { PostMsg(MSG.Extend, args[0], args[1]); return true; });
  97. OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Retract}", (cmd, args) => { PostMsg(MSG.Retract, args[0], args[1]); return true; });
  98. OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Abort}", (cmd, args) => { PostMsg(MSG.Abort); return true; });
  99. OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Home}", (cmd, args) => { PostMsg(MSG.HomeRB); return true; });
  100. OP.Subscribe($"{ModuleName.Aligner1}.{EfemOperation.Home}", (cmd, args) => { PostMsg(MSG.HomeAL, ModuleName.Aligner1); return true; });
  101. OP.Subscribe($"{ModuleName.Aligner2}.{EfemOperation.Home}", (cmd, args) => { PostMsg(MSG.HomeAL, ModuleName.Aligner2); return true; });
  102. OP.Subscribe($"{ModuleName.Aligner1}.{EfemOperation.Align}", (cmd, args) => { PostMsg(MSG.Align, ModuleName.Aligner1, args[0]); return true; });
  103. OP.Subscribe($"{ModuleName.Aligner2}.{EfemOperation.Align}", (cmd, args) => { PostMsg(MSG.Align, ModuleName.Aligner2, args[0]); return true; });
  104. OP.Subscribe($"{ModuleName.Aligner1}.{EfemOperation.Lift}", (cmd, args) => { PostMsg(MSG.Lift, ModuleName.Aligner1); return true; });
  105. OP.Subscribe($"{ModuleName.Aligner2}.{EfemOperation.Lift}", (cmd, args) => { PostMsg(MSG.Lift, ModuleName.Aligner2); return true; });
  106. DATA.Subscribe($"{Name}.FsmState", () => ((STATE)fsm.State).ToString());
  107. DATA.Subscribe($"{Name}.FsmPrevState", () => ((STATE)fsm.PrevState).ToString());
  108. DATA.Subscribe($"{Name}.FsmLastMessage", GetFsmLastMessage);
  109. return true;
  110. }
  111. private void InitFsmMap()
  112. {
  113. fsm = new StateMachine<EfemEntity>("EFEM", (int)STATE.Unknown, 50);
  114. AnyStateTransition(FSM_MSG.TIMER, fnMonitor, FSM_STATE.SAME);
  115. AnyStateTransition(MSG.RecHwMsg, fnRecMsg, FSM_STATE.SAME);
  116. AnyStateTransition(MSG.LED, fnSetLED, STATE.SettingLamp);
  117. AnyStateTransition(MSG.AllLightsOFF, fnTurnOffLED, STATE.SettingLamp);
  118. AnyStateTransition(MSG.Recover, fnRecover, STATE.Idle);
  119. AnyStateTransition(MSG.Error, fnError, STATE.Error);
  120. AnyStateTransition(MSG.Online, fnOnline, FSM_STATE.SAME);
  121. AnyStateTransition(MSG.Abort, fnAbortRobot, FSM_STATE.SAME);
  122. EnterExitTransition<STATE, FSM_MSG>(STATE.Initializing, fnEnterExecute, FSM_MSG.NONE, fnExitExecute);
  123. EnterExitTransition<STATE, FSM_MSG>(STATE.InitingRB, fnEnterExecute, FSM_MSG.NONE, null);
  124. EnterExitTransition<STATE, FSM_MSG>(STATE.InitingAL, fnEnterExecute, FSM_MSG.NONE, null);
  125. EnterExitTransition<STATE, FSM_MSG>(STATE.Picking, fnEnterExecute, FSM_MSG.NONE, fnExitExecute);
  126. EnterExitTransition<STATE, FSM_MSG>(STATE.Placing, fnEnterExecute, FSM_MSG.NONE, fnExitExecute);
  127. EnterExitTransition<STATE, FSM_MSG>(STATE.Extending, fnEnterExecute, FSM_MSG.NONE, fnExitExecute);
  128. EnterExitTransition<STATE, FSM_MSG>(STATE.Retracting, fnEnterExecute, FSM_MSG.NONE, fnExitExecute);
  129. EnterExitTransition<STATE, FSM_MSG>(STATE.Lifting, fnEnterExecute, FSM_MSG.NONE, null);
  130. EnterExitTransition<STATE, FSM_MSG>(STATE.Aligning, fnEnterExecute, FSM_MSG.NONE, null);
  131. EnterExitTransition<STATE, FSM_MSG>(STATE.SettingLamp, fnEnterExecute, FSM_MSG.NONE, null);
  132. EnterExitTransition<STATE, FSM_MSG>(STATE.Mapping, fnEnterExecute, FSM_MSG.NONE, fnExitExecute);
  133. Transition(STATE.Unknown, MSG.CommReady, null, STATE.Init);
  134. // Home
  135. Transition(STATE.Init, MSG.HomeAll, fnHomeAll, STATE.Initializing);
  136. Transition(STATE.Idle, MSG.HomeAll, fnHomeAll, STATE.Initializing); // 暂时加,出错的时候做 HOME
  137. Transition(STATE.Initializing, MSG.ActionDone, null, STATE.Orgshing);
  138. Transition(STATE.Orgshing, MSG.ActionDone, fnActionDone, STATE.Idle);
  139. Transition(STATE.Idle, MSG.HomeRB, fnHomeRobot, STATE.InitingRB);
  140. Transition(STATE.InitingRB, MSG.ActionDone, null, STATE.Idle);
  141. Transition(STATE.SettingLamp, MSG.ActionDone, fnSetLampDone, STATE.Idle);
  142. // Pick
  143. Transition(STATE.Idle, MSG.Pick, fnPick, STATE.Picking);
  144. Transition(STATE.Picking, MSG.ActionDone, fnActionDone, STATE.Idle);
  145. Transition(STATE.Picking, MSG.PMLiftPinUp, fnPmPinUp, STATE.Idle);
  146. Transition(STATE.Picking, MSG.PMLiftPinDown, fnPmPinDown, STATE.Idle);
  147. // Place
  148. Transition(STATE.Idle, MSG.Place, fnPlace, STATE.Placing);
  149. Transition(STATE.Placing, MSG.ActionDone, fnActionDone, STATE.Idle);
  150. Transition(STATE.Placing, MSG.PMLiftPinUp, fnPmPinUp, STATE.Idle);
  151. Transition(STATE.Placing, MSG.PMLiftPinDown, fnPmPinDown, STATE.Idle);
  152. // Extend
  153. Transition(STATE.Idle, MSG.Extend, fnExtend, STATE.Extending);
  154. Transition(STATE.Extending, MSG.ActionDone, fnActionDone, STATE.Idle);
  155. // Retract
  156. Transition(STATE.Idle, MSG.Retract, fnRetract, STATE.Retracting);
  157. Transition(STATE.Retracting, MSG.ActionDone, fnActionDone, STATE.Idle);
  158. // Map
  159. Transition(STATE.Idle, MSG.Map, fnMap, STATE.Mapping);
  160. Transition(STATE.Mapping, MSG.ActionDone, fnActionDone, STATE.Idle);
  161. // Aligner
  162. Transition(STATE.Idle, MSG.HomeAL, fnHomeAligner, STATE.InitingAL);
  163. Transition(STATE.InitingAL, MSG.ActionDone, fnActionDone, STATE.Idle);
  164. Transition(STATE.Idle, MSG.Lift, fnLift, STATE.Lifting);
  165. Transition(STATE.Lifting, MSG.ActionDone, fnActionDone, STATE.Idle);
  166. Transition(STATE.Idle, MSG.Align, fnAlign, STATE.Aligning);
  167. Transition(STATE.Aligning, MSG.ActionDone, fnActionDone, STATE.Idle);
  168. EnumLoop<STATE>.ForEach((item) => { fsm.MapState((int)item, item.ToString()); });
  169. EnumLoop<MSG>.ForEach((item) => { fsm.MapMessage((int)item, item.ToString()); });
  170. }
  171. private bool fnHomeAll(object[] param)
  172. {
  173. _efem.ClearActions();
  174. _efem.HomeAll();
  175. return true;
  176. }
  177. private bool fnHomeRobot(object[] param)
  178. {
  179. _efem.Home(ModuleName.EfemRobot);
  180. return true;
  181. }
  182. private bool fnHomeAligner(object[] param)
  183. {
  184. // module
  185. ModuleName unit = ModuleName.EFEM;
  186. if (param[0] is string s1)
  187. unit = ModuleNameString.ToEnum(s1);
  188. else if (param[0] is ModuleName mod)
  189. unit = mod;
  190. else
  191. throw new ArgumentException("Argument error");
  192. _efem.Home(unit);
  193. return true;
  194. }
  195. private bool fnEnterExecute(object[] param)
  196. {
  197. _efem.ExecuteAction();
  198. return false;
  199. }
  200. private bool fnExitExecute(object[] param)
  201. {
  202. _efem.ExecuteAction();
  203. return false;
  204. }
  205. private bool fnActionDone(object[] param)
  206. {
  207. try
  208. {
  209. EfemOperation actionType = (EfemOperation)param[0];
  210. if (actionType == EfemOperation.Extend)
  211. {
  212. if (fsm.State == (int)STATE.Placing)
  213. {
  214. _efem.ExecuteAction();
  215. return false;
  216. }
  217. else if (fsm.State == (int)STATE.Picking)
  218. {
  219. if (_efem.HasActions)
  220. {
  221. _efem.ExecuteAction();
  222. return false;
  223. }
  224. else
  225. {
  226. return true;
  227. }
  228. }
  229. }
  230. return true;
  231. }
  232. catch (Exception ex)
  233. {
  234. EV.PostAlarmLog(ModuleName.EFEM.ToString(), ex.Message);
  235. return true;
  236. }
  237. }
  238. public bool CheckToPostMessage(int msg, params object[] args)
  239. {
  240. if (!fsm.FindTransition(fsm.State, msg))
  241. {
  242. EV.PostWarningLog(Name, $"{Name} is in {(STATE)fsm.State} state,can not do {(MSG)msg}");
  243. return false;
  244. }
  245. Running = true;
  246. fsm.PostMsg(msg, args);
  247. return true;
  248. }
  249. private bool fnRecMsg(object[] param)
  250. {
  251. if (param == null) return false;
  252. string strHwMsg = param[0] as string;
  253. if (_efem is EfemBase device)
  254. {
  255. device.ReceiveMessage(strHwMsg);
  256. return true;
  257. }
  258. return false;
  259. }
  260. private bool fnMonitor(object[] param)
  261. {
  262. STATE curSt = (STATE)fsm.State;
  263. if (curSt == STATE.Initializing || curSt == STATE.Mapping)
  264. {
  265. if (fsm.ElapsedTime > 60 * 1000)
  266. {
  267. PostMsg(MSG.Recover);
  268. }
  269. }
  270. if (curSt == STATE.Aligning)
  271. {
  272. if (fsm.ElapsedTime > 10 * 1000)
  273. {
  274. EV.PostAlarmLog(ModuleName.Aligner.ToString(), "Align timeout");
  275. PostMsg(MSG.ActionDone, "alignment timeout");
  276. }
  277. }
  278. return true;
  279. }
  280. private bool fnOnline(object[] param)
  281. {
  282. bool bOnlineFlag = (bool)param[0];
  283. if (_efem is EfemBase efem)
  284. {
  285. efem.SetOnline(bOnlineFlag);
  286. }
  287. return true;
  288. }
  289. private string GetFsmLastMessage()
  290. {
  291. int msg = fsm.LastMsg;
  292. if (msg >= (int)MSG.HomeAll && msg <= (int)MSG.Error)
  293. return ((MSG)msg).ToString();
  294. if (msg == (int)FSM_MSG.TIMER)
  295. return "Timer";
  296. return msg.ToString();
  297. }
  298. private bool fnError(object[] param)
  299. {
  300. return true;
  301. }
  302. private bool fnRecover(object[] param)
  303. {
  304. _efem.ClearActions();
  305. _efem.ClearError();
  306. _efem.ExecuteAction();
  307. return true;
  308. }
  309. private bool fnAbortRobot(object[] param)
  310. {
  311. _efem.AbortRobot();
  312. _efem.ExecuteAction();
  313. return true;
  314. }
  315. private bool fnSetLED(object[] param)
  316. {
  317. LightType light = (LightType)param[0];
  318. LightStatus st = (LightStatus)param[1];
  319. _efem.SetLamp(light, st);
  320. return true;
  321. }
  322. private bool fnTurnOffLED(object[] param)
  323. {
  324. _efem.TurnOffAllLamps();
  325. return true;
  326. }
  327. private bool fnSetLampDone(object[] param)
  328. {
  329. if (_efem.HasActions)
  330. {
  331. _efem.ExecuteAction();
  332. return false;
  333. }
  334. else
  335. {
  336. return true;
  337. }
  338. }
  339. private bool fnPick(object[] param)
  340. {
  341. // module
  342. ModuleName unit = ModuleName.EFEM;
  343. if (param[0] is string s1)
  344. unit = ModuleNameString.ToEnum(s1);
  345. else if (param[0] is ModuleName mod)
  346. unit = mod;
  347. else
  348. throw new ArgumentException("Argument error");
  349. // slot
  350. byte slot = (byte)(int)param[1];
  351. // hand
  352. Hand arm = (Hand)param[2];
  353. // wafer size
  354. WaferSize ws1 = WaferSize.WS0;
  355. if (param[3] is string s2)
  356. {
  357. if (Enum.TryParse(s2, out WaferSize p5))
  358. ws1 = p5;
  359. }
  360. else if (param[3] is WaferSize p6)
  361. {
  362. ws1 = p6;
  363. }
  364. MoveParam mp = new MoveParam(unit, slot, ModuleName.EfemRobot, (byte)arm, arm, ws1);
  365. _efem.Pick(mp);
  366. return true;
  367. }
  368. private bool fnPlace(object[] param)
  369. {
  370. // module
  371. ModuleName unit = ModuleName.EFEM;
  372. if (param[0] is string s1)
  373. unit = ModuleNameString.ToEnum(s1);
  374. else if (param[0] is ModuleName mod)
  375. unit = mod;
  376. else
  377. throw new ArgumentException("Argument error");
  378. // slot
  379. byte slot = (byte)(int)param[1];
  380. // hand
  381. Hand arm = (Hand)param[2];
  382. // wafer size
  383. WaferSize ws1 = WaferSize.WS0;
  384. if (param[3] is string s2)
  385. {
  386. if (Enum.TryParse(s2, out WaferSize p5))
  387. ws1 = p5;
  388. }
  389. else if (param[3] is WaferSize p6)
  390. {
  391. ws1 = p6;
  392. }
  393. MoveParam mp = new MoveParam(ModuleName.EfemRobot, (byte)arm, unit, slot, arm, ws1);
  394. _efem.Place(mp);
  395. return true;
  396. }
  397. private bool fnExtend(object[] param)
  398. {
  399. // module
  400. ModuleName unit = ModuleName.EFEM;
  401. if (param[0] is string s1)
  402. unit = ModuleNameString.ToEnum(s1);
  403. else if (param[0] is ModuleName mod)
  404. unit = mod;
  405. else
  406. throw new ArgumentException("Argument error");
  407. ExtendParam mp = new ExtendParam
  408. {
  409. Module = unit,
  410. Pos = (ExtendPos)Enum.Parse(typeof(ExtendPos), param[1] as string)
  411. };
  412. _efem.Extend(mp);
  413. return true;
  414. }
  415. private bool fnRetract(object[] param)
  416. {
  417. // module
  418. ModuleName unit = ModuleName.EFEM;
  419. if (param[0] is string s1)
  420. unit = ModuleNameString.ToEnum(s1);
  421. else if (param[0] is ModuleName mod)
  422. unit = mod;
  423. else
  424. throw new ArgumentException("Argument error");
  425. ExtendParam mp = new ExtendParam
  426. {
  427. Module = unit,
  428. Pos = (ExtendPos)Enum.Parse(typeof(ExtendPos), param[1] as string)
  429. };
  430. _efem.Retract(mp);
  431. return true;
  432. }
  433. private bool fnPmPinUp(object[] param)
  434. {
  435. _efem.UpdateStatus((ushort)param[0], ActionStatus.Completed);
  436. if (_efem.HasActions)
  437. {
  438. _efem.ExecuteAction();
  439. return false;
  440. }
  441. else
  442. {
  443. return true;
  444. }
  445. }
  446. private bool fnPmPinDown(object[] param)
  447. {
  448. _efem.UpdateStatus((ushort)param[0], ActionStatus.Completed);
  449. if (_efem.HasActions)
  450. {
  451. _efem.ExecuteAction();
  452. return false;
  453. }
  454. else
  455. {
  456. return true;
  457. }
  458. }
  459. private bool fnLift(object[] param)
  460. {
  461. // module
  462. ModuleName unit = ModuleName.EFEM;
  463. if (param[0] is string s1)
  464. unit = ModuleNameString.ToEnum(s1);
  465. else if (param[0] is ModuleName mod)
  466. unit = mod;
  467. else
  468. throw new ArgumentException("Argument error");
  469. _efem.SetPinUp(unit);
  470. return true;
  471. }
  472. private bool fnAlign(object[] param)
  473. {
  474. // module
  475. ModuleName unit = ModuleName.EFEM;
  476. if (param[0] is string s1)
  477. unit = ModuleNameString.ToEnum(s1);
  478. else if (param[0] is ModuleName mod)
  479. unit = mod;
  480. else
  481. throw new ArgumentException("Argument error");
  482. // wafer size
  483. WaferSize ws1 = WaferSize.WS0;
  484. if (param[1] is string s2)
  485. {
  486. if (Enum.TryParse(s2, out WaferSize p5))
  487. ws1 = p5;
  488. }
  489. else if (param[1] is WaferSize p6)
  490. {
  491. ws1 = p6;
  492. }
  493. _efem.Align(unit, 1000, ws1);
  494. return true;
  495. }
  496. private bool fnMap(object[] param)
  497. {
  498. // module
  499. ModuleName unit = ModuleName.EFEM;
  500. if (param[0] is string s1)
  501. unit = ModuleNameString.ToEnum(s1);
  502. else if (param[0] is ModuleName mod)
  503. unit = mod;
  504. else
  505. throw new ArgumentException("Argument error");
  506. _efem.Map(unit);
  507. return true;
  508. }
  509. public bool IsIdle
  510. {
  511. get { return fsm.State == (int)STATE.Idle; }
  512. }
  513. public bool IsError
  514. {
  515. get { return fsm.State == (int)STATE.Error; }
  516. }
  517. public bool IsInit
  518. {
  519. get { return fsm.State == (int)STATE.Unknown || fsm.State==(int)STATE.Init; }
  520. }
  521. public bool IsBusy
  522. {
  523. get { return !IsInit && !IsError && !IsIdle; }
  524. }
  525. public bool IsOnline { get; internal set; }
  526. public int Invoke(string function, params object[] args)
  527. {
  528. switch (function)
  529. {
  530. case "Home":
  531. CheckToPostMessage((int)MSG.HomeAll);
  532. return (int)MSG.HomeAll;
  533. }
  534. return (int)FSM_MSG.NONE;
  535. }
  536. public bool CheckAcked(int msg)
  537. {
  538. return fsm.CheckExecuted(msg);
  539. }
  540. internal void InvokeReset()
  541. {
  542. PostMsg((int)MSG.Recover);
  543. }
  544. public int InvokeAlign(string module, float time)
  545. {
  546. if (CheckToPostMessage((int)MSG.Align, module, time))
  547. return (int)MSG.Align;
  548. return (int)FSM_MSG.NONE;
  549. }
  550. public int InvokePick(ModuleName source, int slot, Hand hand, WaferSize size)
  551. {
  552. if (CheckToPostMessage((int)MSG.Pick, source, slot, hand, size))
  553. return (int)MSG.Pick;
  554. return (int)FSM_MSG.NONE;
  555. }
  556. public int InvokePlace(ModuleName target, int slot, Hand hand, WaferSize size)
  557. {
  558. if (CheckToPostMessage((int)MSG.Place, target, slot, hand, size))
  559. return (int)MSG.Place;
  560. return (int)FSM_MSG.NONE;
  561. }
  562. public int InvokeMap(string target )
  563. {
  564. if (CheckToPostMessage((int)MSG.Map, target ))
  565. return (int)MSG.Map;
  566. return (int)FSM_MSG.NONE;
  567. }
  568. public bool IsPrepareTransferReady(ModuleName module, EnumTransferType type, int slot)
  569. {
  570. if (type == EnumTransferType.Pick)
  571. {
  572. //需要补充:判断LP 放好了,而且已经map过。
  573. return _efem[module].HasCassette && _efem[module].IsMapped;
  574. }
  575. else if (type == EnumTransferType.Place)
  576. {
  577. //需要补充:判断LP 放好了,而且已经map过。
  578. return _efem[module].HasCassette && _efem[module].IsMapped;
  579. }
  580. return false;
  581. }
  582. internal bool CheckReadyRunNewJob(ModuleName module)
  583. {
  584. //???
  585. return true;
  586. }
  587. internal bool CheckReadyTransfer(ModuleName module)
  588. {
  589. return _efem[module].HasCassette && _efem[module].IsMapped;
  590. }
  591. }
  592. /// <summary>
  593. /// LP entity
  594. /// </summary>
  595. class LoadportEntity : Entity, IEntity
  596. {
  597. private enum STATE
  598. {
  599. Unknown,
  600. Idle, // 1
  601. Initializing, // 2
  602. Initialized, // 3
  603. Mapping, // 4
  604. Mapped, // 5
  605. }
  606. public enum MSG
  607. {
  608. Home, // 0
  609. Map, // 1
  610. ActionDone, // 2
  611. RecHwMsg, // 3
  612. Recover, // 4
  613. Abort, // 5
  614. Online, // 6
  615. Error // 7
  616. }
  617. private readonly Efem _efem;
  618. private ModuleName Module { get; }
  619. public LoadportEntity(ModuleName mod, Efem efem)
  620. {
  621. this.Module = mod;
  622. _efem = efem;
  623. InitFsmMap();
  624. OP.Subscribe($"{Module}.Home", (cmd, args) => { PostMsg(MSG.Home); return true; });
  625. OP.Subscribe($"{Module}.Abort", (cmd, args) => { PostMsg(MSG.Abort); return true; });
  626. //OP.Subscribe($"{Module}.Map", (cmd, args) => { PostMsg(MSG.Map); return true; });
  627. OP.Subscribe($"{Module}.Online", (cmd, args) => { PostMsg(MSG.Online); return true; });
  628. DATA.Subscribe($"{Module}.Status", () => ((STATE)fsm.State).ToString());
  629. DATA.Subscribe($"{Module}.FsmState", () => ((STATE)fsm.State).ToString());
  630. DATA.Subscribe($"{Module}.FsmPrevState", () => ((STATE)fsm.PrevState).ToString());
  631. DATA.Subscribe($"{Module}.FsmLastMessage", GetFsmLastMessage);
  632. }
  633. private string GetFsmLastMessage()
  634. {
  635. int msg = fsm.LastMsg;
  636. if (msg >= (int)MSG.Home && msg <= (int)MSG.Error)
  637. return ((MSG)msg).ToString();
  638. if (msg == (int)FSM_MSG.TIMER)
  639. return "Timer";
  640. return msg.ToString();
  641. }
  642. private void InitFsmMap()
  643. {
  644. fsm = new StateMachine<LoadportEntity>($"LPM_{Module}", (int)STATE.Idle, 500);
  645. AnyStateTransition(FSM_MSG.TIMER, fnMonitor, FSM_STATE.SAME);
  646. //AnyStateTransition(MSG.RecHwMsg, fnRecMsg, FSM_STATE.SAME);
  647. AnyStateTransition(MSG.Online, fnOnline, FSM_STATE.SAME);
  648. AnyStateTransition(MSG.Recover, fnRecover, STATE.Idle);
  649. AnyStateTransition(MSG.Abort, fnRecover, STATE.Idle);
  650. EnterExitTransition<STATE, FSM_MSG>(STATE.Initializing, fnEnterExecute, FSM_MSG.NONE, fnExitExecute);
  651. // Home
  652. AnyStateTransition(MSG.Home, fnHome, STATE.Initializing);
  653. Transition(STATE.Initializing, MSG.ActionDone, fnActionDone, STATE.Idle);
  654. }
  655. private bool fnOnline(object[] param)
  656. {
  657. bool online = (bool)param[0];
  658. _efem.SetOnline(Module, online);
  659. return true;
  660. }
  661. private bool fnRecover(object[] param)
  662. {
  663. return true;
  664. }
  665. private bool fnMonitor(object[] param)
  666. {
  667. STATE curSt = (STATE)fsm.State;
  668. if (curSt == STATE.Initializing || curSt == STATE.Mapping)
  669. {
  670. if (fsm.ElapsedTime > 20 * 1000)
  671. {
  672. PostMsg(MSG.Recover);
  673. }
  674. }
  675. return true;
  676. }
  677. private bool fnEnterExecute(object[] param)
  678. {
  679. _efem.ExecuteAction();
  680. return true;
  681. }
  682. private bool fnExitExecute(object[] param)
  683. {
  684. return true;
  685. }
  686. private bool fnActionDone(object[] param)
  687. {
  688. return true;
  689. }
  690. private bool fnHome(object[] param)
  691. {
  692. _efem.Home(Module);
  693. return true;
  694. }
  695. public bool Check(int msg, out string reason, params object[] args)
  696. {
  697. throw new NotImplementedException();
  698. }
  699. }
  700. }