WaferRobotModule.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  1. using System;
  2. using System.Diagnostics;
  3. using System.Linq;
  4. using Aitex.Core.RT.DataCenter;
  5. using Aitex.Core.RT.Device;
  6. using Aitex.Core.RT.Event;
  7. using Aitex.Core.RT.Fsm;
  8. using Aitex.Core.RT.Log;
  9. using Aitex.Core.RT.OperationCenter;
  10. using Aitex.Core.RT.Routine;
  11. using Aitex.Core.RT.SCCore;
  12. using Aitex.Core.Util;
  13. using Aitex.Core.Utilities;
  14. using Aitex.Sorter.Common;
  15. using FurnaceRT.Equipments.Systems;
  16. using MECF.Framework.Common.Alarms;
  17. using MECF.Framework.Common.Device.Bases;
  18. using MECF.Framework.Common.Equipment;
  19. using MECF.Framework.Common.Event;
  20. using MECF.Framework.Common.Schedulers;
  21. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts;
  22. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robot;
  23. namespace FurnaceRT.Equipments.WaferRobots
  24. {
  25. public partial class WaferRobotModule : WaferRobotModuleBase, IE87CallBack
  26. {
  27. public enum STATE
  28. {
  29. Init,
  30. Idle,
  31. Error,
  32. Homing,
  33. InTransfer,
  34. Picking,
  35. Placing,
  36. Mapping,
  37. Swaping,
  38. }
  39. public enum MSG
  40. {
  41. Home,
  42. Reset,
  43. Init,
  44. Error,
  45. Abort,
  46. InTransfer,
  47. TransferComplete,
  48. Pick,
  49. Place,
  50. Map,
  51. PickRetry,
  52. PlaceRetry,
  53. MapRetry,
  54. Swap,
  55. }
  56. public override bool IsReady
  57. {
  58. get { return FsmState == (int)STATE.Idle; }
  59. }
  60. public override bool IsError
  61. {
  62. get { return FsmState == (int)STATE.Error; }
  63. }
  64. public override bool IsInit
  65. {
  66. get { return FsmState == (int)STATE.Init; }
  67. }
  68. public event Action<string> OnEnterError;
  69. private bool _jobDone;
  70. private bool _isInit;
  71. private Stopwatch _timerNotifyJobDone = new Stopwatch();
  72. private WaferRobotHome _home;
  73. private WaferRobotPick _pick;
  74. private WaferRobotPlace _place;
  75. private WaferRobotMap _map;
  76. private WaferRobotSwap _swap;
  77. public WaferRobotModule(ModuleName module) : base()
  78. {
  79. Name = module.ToString();
  80. Module = module.ToString();
  81. IsOnline = true;
  82. }
  83. public override bool Initialize()
  84. {
  85. InitRoutine();
  86. InitDevice();
  87. InitFsm();
  88. InitOp();
  89. InitData();
  90. InitAlarmDefine();
  91. Singleton<EventManager>.Instance.OnAlarmEvent += Instance_OnAlarmEvent;
  92. return base.Initialize();
  93. }
  94. private void Instance_OnAlarmEvent(EventItem item)
  95. {
  96. if (item != null && item.Level == EventLevel.Alarm && (item.Source == Name || item.Source == Module))
  97. {
  98. DEVICE.GetDevice<SignalTowerBase>("System.SignalTower")?.Reset();
  99. LOG.Write($"{item.Source} {item.EventEnum} {item.Description}\n");
  100. PostMsg(MSG.Error);
  101. }
  102. }
  103. private void InitRoutine()
  104. {
  105. _home = new WaferRobotHome(this);
  106. _pick = new WaferRobotPick(this);
  107. _place = new WaferRobotPlace(this);
  108. _map = new WaferRobotMap(this);
  109. _swap = new WaferRobotSwap(this);
  110. }
  111. private void InitData()
  112. {
  113. DATA.Subscribe($"{Module}.Status", () => StringFsmStatus);
  114. DATA.Subscribe($"{Module}.SwapCycledCount", () => _swap.LoopCounter);
  115. DATA.Subscribe($"{Module}.IsOnline", () => IsOnline);
  116. }
  117. private void InitOp()
  118. {
  119. OP.Subscribe($"{Module}.Home", (string cmd, object[] args) => CheckToPostMessage((int)MSG.Home));
  120. OP.Subscribe($"{Module}.Abort", (string cmd, object[] args) => CheckToPostMessage((int)MSG.Abort));
  121. OP.Subscribe($"{Module}.Reset", (string cmd, object[] args) => CheckToPostMessage((int)MSG.Reset));
  122. OP.Subscribe($"{Module}.Pick", (string cmd, object[] args) => CheckToPostMessage((int)MSG.Pick, args));
  123. OP.Subscribe($"{Module}.Place", (string cmd, object[] args) => CheckToPostMessage((int)MSG.Place, args));
  124. OP.Subscribe($"{Module}.Swap", (string cmd, object[] args) => CheckToPostMessage((int)MSG.Swap, args));
  125. OP.Subscribe($"{Module}.Mapping", (string cmd, object[] args) => CheckToPostMessage((int)MSG.Map, args));
  126. OP.Subscribe($"{Module}.AlarmAction", (string cmd, object[] args) =>
  127. {
  128. Enum.TryParse(args[0].ToString(), out AlarmAction alarmAction);
  129. string eventName = null;
  130. if (args.Length > 1)
  131. eventName = args[1].ToString();
  132. if (eventName != null)
  133. {
  134. EV.ClearAlarmEvent(eventName);
  135. var item = _triggeredAlarmList.FirstOrDefault(x => x.EventEnum == eventName);
  136. if (item != null)
  137. {
  138. item.Reset();
  139. _triggeredAlarmList.Remove(item);
  140. }
  141. if (item != null)
  142. {
  143. switch (alarmAction)
  144. {
  145. case AlarmAction.Retry:
  146. {
  147. CheckToPostMessage((int)item.RetryMessage, item.RetryMessageParas);
  148. }
  149. break;
  150. case AlarmAction.Abort:
  151. {
  152. CheckToPostMessage((int)MSG.Abort);
  153. }
  154. break;
  155. case AlarmAction.Clear:
  156. {
  157. int alarmCount = 0;
  158. var alarms = EV.GetAlarmEvent();
  159. foreach (var alarm in alarms)
  160. {
  161. if (alarm.Level == EventLevel.Alarm && alarm.Source == Name)
  162. alarmCount++;
  163. }
  164. if (alarmCount == 0)
  165. CheckToPostMessage((int)MSG.Reset);
  166. }
  167. break;
  168. case AlarmAction.Continue:
  169. {
  170. int alarmCount = 0;
  171. var alarms = EV.GetAlarmEvent();
  172. foreach (var alarm in alarms)
  173. {
  174. if (alarm.Level == EventLevel.Alarm && alarm.Source == Name)
  175. alarmCount++;
  176. }
  177. if (alarmCount == 0)
  178. CheckToPostMessage((int)MSG.Reset);
  179. }
  180. break;
  181. }
  182. }
  183. }
  184. return true;
  185. });
  186. OP.Subscribe($"{Module}.SetOnline", (string cmd, object[] args) =>
  187. {
  188. IsOnline = true;
  189. return true;
  190. });
  191. OP.Subscribe($"{Module}.SetOffline", (string cmd, object[] args) =>
  192. {
  193. IsOnline = false;
  194. return true;
  195. });
  196. }
  197. private void InitFsm()
  198. {
  199. EnumLoop<STATE>.ForEach((item) =>
  200. {
  201. MapState((int)item, item.ToString());
  202. });
  203. EnumLoop<MSG>.ForEach((item) =>
  204. {
  205. MapMessage((int)item, item.ToString());
  206. });
  207. EnableFsm(50, STATE.Init);
  208. //Init
  209. Transition(STATE.Init, MSG.Home, FsmStartHome, STATE.Homing);
  210. Transition(STATE.Error, MSG.Home, FsmStartHome, STATE.Homing);
  211. Transition(STATE.Idle, MSG.Home, FsmStartHome, STATE.Homing);
  212. Transition(STATE.Homing, FSM_MSG.TIMER, FsmMonitorHomeTask, STATE.Idle);
  213. Transition(STATE.Homing, MSG.Error, null, STATE.Init);
  214. Transition(STATE.Homing, MSG.Abort, FsmAbortTask, STATE.Init);
  215. EnterExitTransition<STATE, FSM_MSG>(STATE.Idle, FsmEnterIdle, FSM_MSG.NONE, FsmExitIdle);
  216. Transition(STATE.Idle, MSG.Abort, null, STATE.Idle);
  217. Transition(STATE.Idle, MSG.Reset, null, STATE.Idle);
  218. Transition(STATE.Init, MSG.Reset, null, STATE.Init);
  219. Transition(STATE.Error, MSG.Abort, FsmAbortTask, STATE.Error);
  220. //Error
  221. AnyStateTransition(MSG.Error, FsmOnError, STATE.Error);
  222. Transition(STATE.Error, MSG.Reset, FsmReset, STATE.Idle);
  223. EnterExitTransition<STATE, FSM_MSG>(STATE.Error, FsmEnterError, FSM_MSG.NONE, FsmExitError);
  224. //pick
  225. Transition(STATE.Error, MSG.PickRetry, FsmStartPick, STATE.Picking);
  226. Transition(STATE.Idle, MSG.Pick, FsmStartPick, STATE.Picking);
  227. Transition(STATE.Picking, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle);
  228. Transition(STATE.Picking, MSG.Abort, FsmAbortTask, STATE.Idle);
  229. //place
  230. Transition(STATE.Error, MSG.PlaceRetry, FsmStartPlace, STATE.Placing);
  231. Transition(STATE.Idle, MSG.Place, FsmStartPlace, STATE.Placing);
  232. Transition(STATE.Placing, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle);
  233. Transition(STATE.Placing, MSG.Abort, FsmAbortTask, STATE.Idle);
  234. //map
  235. Transition(STATE.Error, MSG.MapRetry, FsmStartMap, STATE.Mapping);
  236. Transition(STATE.Idle, MSG.Map, FsmStartMap, STATE.Mapping);
  237. Transition(STATE.Mapping, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle);
  238. Transition(STATE.Mapping, MSG.Abort, FsmAbortTask, STATE.Idle);
  239. //swap
  240. Transition(STATE.Idle, MSG.Swap, FsmStartSwap, STATE.Swaping);
  241. Transition(STATE.Swaping, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle);
  242. Transition(STATE.Swaping, MSG.Abort, FsmAbortTask, STATE.Idle);
  243. }
  244. public override bool Home(out string reason)
  245. {
  246. if (!CheckToPostMessage((int)MSG.Home))
  247. {
  248. reason = $"Can not home in {StringFsmStatus} status";
  249. return false;
  250. }
  251. reason = string.Empty;
  252. return true;
  253. }
  254. public override void NoteJobStart()
  255. {
  256. _jobDone = false;
  257. }
  258. public override void NoteJobComplete()
  259. {
  260. _timerNotifyJobDone.Restart();
  261. _jobDone = true;
  262. }
  263. public override void Monitor()
  264. {
  265. base.Monitor();
  266. _alarmSignaRobotAlarmTrig.CLK = _alarmSignaRobotAlarm.Value;
  267. if(_alarmSignaRobotAlarmTrig.Q)
  268. {
  269. RobotDIAlarm.Set();
  270. WaferRobotDevice.NoteError("");
  271. }
  272. }
  273. public override void Reset()
  274. {
  275. _alarmSignaRobotAlarmTrig.RST = true;
  276. //_trigAlarmReset?.SetPulseTrigger(true, out _);
  277. if (IsError)
  278. {
  279. CheckToPostMessage((int)MSG.Reset);
  280. }
  281. }
  282. public override bool PrepareTransfer(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType, out string reason)
  283. {
  284. reason = string.Empty;
  285. return true;
  286. }
  287. public override bool TransferHandoff(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType, out string reason)
  288. {
  289. reason = string.Empty;
  290. return true;
  291. }
  292. public override bool PostTransfer(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType, out string reason)
  293. {
  294. reason = string.Empty;
  295. return true;
  296. }
  297. public override bool CheckReadyForTransfer(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType,
  298. out string reason)
  299. {
  300. reason = string.Empty;
  301. return IsReady;
  302. }
  303. public override bool CheckReadyForMap(ModuleName robot, Hand blade, out string reason)
  304. {
  305. reason = string.Empty;
  306. return IsReady;
  307. }
  308. public override void NoteTransferStart(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType)
  309. {
  310. CheckToPostMessage(MSG.InTransfer);
  311. }
  312. public override void NoteTransferStop(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType)
  313. {
  314. if (FsmState == (int)STATE.InTransfer)
  315. CheckToPostMessage(MSG.TransferComplete);
  316. }
  317. public override bool Pick(ModuleName target, Hand blade, int targetSlot, out string reason)
  318. {
  319. CheckToPostMessage((int)MSG.Pick, target.ToString(), targetSlot, blade);
  320. reason = string.Empty;
  321. return true;
  322. }
  323. public override bool Place(ModuleName target, Hand blade, int targetSlot, out string reason)
  324. {
  325. CheckToPostMessage((int)MSG.Place, target.ToString(), targetSlot, blade);
  326. reason = string.Empty;
  327. return true;
  328. }
  329. public override bool Map(ModuleName target, Hand blade, int slotNumber, string slotMap, bool isCompareWithSlotMap, bool isCreateWafer, out string reason)
  330. {
  331. CheckToPostMessage((int)MSG.Map, target.ToString(), slotNumber, blade, slotMap, isCompareWithSlotMap, isCreateWafer);
  332. reason = string.Empty;
  333. return true;
  334. }
  335. public void CarrierIDReadSuccess(string carrierID)
  336. {
  337. }
  338. public void CarrierIDReadFail()
  339. {
  340. }
  341. public void MappingComplete(string carrierID, string slotmap)
  342. {
  343. }
  344. public void LoadportError(string errorcode)
  345. {
  346. }
  347. public void LoadComplete()
  348. {
  349. }
  350. public void UnloadComplete()
  351. {
  352. }
  353. public void OnLPHomed()
  354. {
  355. }
  356. public void OnE84HandoffStart(bool isload)
  357. {
  358. }
  359. public void OnE84HandoffComplete(bool isload)
  360. {
  361. }
  362. public void CarrierArrive()
  363. {
  364. }
  365. public void CarrerRemove(string carrierID)
  366. {
  367. }
  368. private bool FsmReset(object[] param)
  369. {
  370. if (IsError)
  371. {
  372. WaferRobotDevice.RobotReset();
  373. if (Singleton<EquipmentManager>.Instance.IsAutoMode || Singleton<EquipmentManager>.Instance.IsReturnWafer)
  374. {
  375. Singleton<EquipmentManager>.Instance.ResetTask(ModuleHelper.Converter(Module));
  376. }
  377. }
  378. return true;
  379. }
  380. private bool FsmOnError(object[] param)
  381. {
  382. if (FsmState == (int)STATE.Error)
  383. {
  384. return false;
  385. }
  386. AbortRoutine();
  387. if (FsmState == (int)STATE.Init)
  388. return false;
  389. return true;
  390. }
  391. private bool FsmExitIdle(object[] param)
  392. {
  393. return true;
  394. }
  395. private bool FsmEnterIdle(object[] param)
  396. {
  397. return true;
  398. }
  399. private bool FsmExitError(object[] param)
  400. {
  401. return true;
  402. }
  403. private bool FsmEnterError(object[] param)
  404. {
  405. if (OnEnterError != null)
  406. OnEnterError(Module);
  407. return true;
  408. }
  409. private bool FsmAbortTask(object[] param)
  410. {
  411. if (!WaferRobotDevice.IsReady())
  412. WaferRobotDevice.Abort();
  413. AbortRoutine();
  414. return true;
  415. }
  416. private bool FsmToInit(object[] param)
  417. {
  418. return true;
  419. }
  420. private bool FsmToIdle(object[] param)
  421. {
  422. return true;
  423. }
  424. private bool FsmMonitorTask(object[] param)
  425. {
  426. Result ret = MonitorRoutine();
  427. if (ret == Result.FAIL)
  428. {
  429. PostMsg(MSG.Error);
  430. return false;
  431. }
  432. return ret == Result.DONE;
  433. }
  434. private bool FsmMonitorUnloadTask(object[] param)
  435. {
  436. Result ret = MonitorRoutine();
  437. if (ret == Result.FAIL)
  438. {
  439. PostMsg(MSG.Error);
  440. return false;
  441. }
  442. return ret == Result.DONE;
  443. }
  444. private bool FsmStartPick(object[] param)
  445. {
  446. _pick.Init(ModuleHelper.Converter(param[0].ToString()), (int)param[1], (Hand)param[2], param.Length > 3 ? (bool)param[3] : false);
  447. Result ret = StartRoutine(_pick);
  448. if (ret == Result.FAIL || ret == Result.DONE)
  449. return false;
  450. return ret == Result.RUN;
  451. }
  452. private bool FsmStartMap(object[] param)
  453. {
  454. _map.Init(ModuleHelper.Converter(param[0].ToString()), (int)param[1], (Hand)param[2], param[3].ToString(),
  455. (bool)param[4], (bool)param[5], param.Length > 6 ? (bool)param[6] : false);
  456. Result ret = StartRoutine(_map);
  457. if (ret == Result.FAIL || ret == Result.DONE)
  458. return false;
  459. return ret == Result.RUN;
  460. }
  461. private bool FsmStartSwap(object[] param)
  462. {
  463. _swap.Init(ModuleHelper.Converter(param[0].ToString()), ModuleHelper.Converter(param[1].ToString()), (int)param[2], (int)param[3],(Hand)param[4]);
  464. Result ret = StartRoutine(_swap);
  465. if (ret == Result.FAIL || ret == Result.DONE)
  466. return false;
  467. return ret == Result.RUN;
  468. }
  469. private bool FsmStartPlace(object[] param)
  470. {
  471. _place.Init(ModuleHelper.Converter(param[0].ToString()), (int)param[1], (Hand)param[2], param.Length > 3 ? (bool)param[3] : false);
  472. Result ret = StartRoutine(_place);
  473. if (ret == Result.FAIL || ret == Result.DONE)
  474. return false;
  475. return ret == Result.RUN;
  476. }
  477. private bool FsmStartHome(object[] param)
  478. {
  479. if (IsError)
  480. {
  481. if (Singleton<EquipmentManager>.Instance.IsAutoMode || Singleton<EquipmentManager>.Instance.IsReturnWafer)
  482. {
  483. Singleton<EquipmentManager>.Instance.ResetTask(ModuleHelper.Converter(Module));
  484. }
  485. }
  486. Result ret = StartRoutine(_home);
  487. if (ret == Result.FAIL || ret == Result.DONE)
  488. return false;
  489. _isInit = false;
  490. return ret == Result.RUN;
  491. }
  492. private bool FsmMonitorHomeTask(object[] param)
  493. {
  494. Result ret = MonitorRoutine();
  495. if (ret == Result.FAIL)
  496. {
  497. PostMsg(MSG.Error);
  498. return false;
  499. }
  500. if (ret == Result.DONE)
  501. {
  502. _alarmSignaRobotAlarmTrig.RST = true;
  503. _isInit = true;
  504. return true;
  505. }
  506. return false;
  507. }
  508. }
  509. }