AlignerModule.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. using System;
  2. using Aitex.Core.RT.DataCenter;
  3. using Aitex.Core.RT.Device;
  4. using Aitex.Core.RT.Event;
  5. using Aitex.Core.RT.Fsm;
  6. using Aitex.Core.RT.OperationCenter;
  7. using Aitex.Core.RT.Routine;
  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 MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Efems.Rorzes;
  14. using MECF.Framework.RT.ModuleLibrary.AlignerModules;
  15. namespace FutureEfemLib.Aligners
  16. {
  17. public class AlignerModule : AlignerModuleBase
  18. {
  19. private FutureAligner _alignerDevice;
  20. public enum STATE
  21. {
  22. NotInstall,
  23. Init,
  24. Idle,
  25. Homing,
  26. MapWaferPresence,
  27. Error,
  28. NotConnect,
  29. InTransfer,
  30. Aligning,
  31. }
  32. public enum MSG
  33. {
  34. Home,
  35. Connected,
  36. Disconnected,
  37. MapWaferPresence,
  38. Align,
  39. Reset,
  40. Abort,
  41. Error,
  42. ToInit,
  43. InTransfer,
  44. TransferComplete
  45. }
  46. public event Action<string> OnEnterError;
  47. public override bool IsReady
  48. {
  49. get { return FsmState == (int)STATE.Idle && CheckAllMessageProcessed(); }
  50. }
  51. public override bool IsError
  52. {
  53. get { return FsmState == (int)STATE.Error; }
  54. }
  55. private bool _isInit;
  56. public override bool IsInit
  57. {
  58. get { return _isInit; }
  59. }
  60. private AlignerHomeRoutine _home;
  61. private AlignerAlignRoutine _align;
  62. public AlignerModule(ModuleName module) : base(1)
  63. {
  64. Name = module.ToString();
  65. Module = module.ToString();
  66. IsOnline = true;
  67. }
  68. public override bool Initialize()
  69. {
  70. InitRoutine();
  71. InitDevice();
  72. InitFsm();
  73. InitOp();
  74. InitData();
  75. return base.Initialize();
  76. }
  77. private void InitRoutine()
  78. {
  79. _home = new AlignerHomeRoutine(this);
  80. _align = new AlignerAlignRoutine(this);
  81. }
  82. public void InitDevice()
  83. {
  84. _alignerDevice = DEVICE.GetDevice<FutureAligner>($"{ModuleName.Aligner}.{ModuleName.Aligner}");
  85. }
  86. private void InitData()
  87. {
  88. DATA.Subscribe($"{Module}.Status", () => StringFsmStatus);
  89. DATA.Subscribe($"{Module}.IsOnline", () => IsOnline);
  90. DATA.Subscribe($"{Module}.WaferSize", () => WaferManager.Instance.GetWaferSize(ModuleHelper.Converter(Module), 0).ToString());
  91. }
  92. private void InitOp()
  93. {
  94. OP.Subscribe($"{Module}.Home", (string cmd, object[] args) => CheckToPostMessage((int)MSG.Home));
  95. OP.Subscribe($"{Module}.Reset", (string cmd, object[] args) => CheckToPostMessage((int)MSG.Reset));
  96. OP.Subscribe($"{Module}.Align", (string cmd, object[] args) => CheckToPostMessage((int)MSG.Align,args));
  97. }
  98. private void InitFsm()
  99. {
  100. EnumLoop<STATE>.ForEach((item) =>
  101. {
  102. MapState((int)item, item.ToString());
  103. });
  104. EnumLoop<MSG>.ForEach((item) =>
  105. {
  106. MapMessage((int)item, item.ToString());
  107. });
  108. EnableFsm(50, IsInstalled ? STATE.Init : STATE.NotInstall);
  109. //Error
  110. AnyStateTransition(MSG.Error, FsmOnError, STATE.Error);
  111. Transition(STATE.Error, MSG.Reset, FsmReset, STATE.Idle);
  112. EnterExitTransition<STATE, FSM_MSG>(STATE.Error, FsmEnterError, FSM_MSG.NONE, FsmExitError);
  113. //Init
  114. Transition(STATE.Init, MSG.Home, FsmStartHome, STATE.Homing);
  115. Transition(STATE.Error, MSG.Home, FsmStartHome, STATE.Homing);
  116. Transition(STATE.Idle, MSG.Home, FsmStartHome, STATE.Homing);
  117. Transition(STATE.Homing, FSM_MSG.TIMER, FsmMonitorHomeTask, STATE.Idle);
  118. Transition(STATE.Homing, MSG.Error, null, STATE.Init);
  119. Transition(STATE.Homing, MSG.Abort, FsmAbortTask, STATE.Init);
  120. AnyStateTransition(MSG.ToInit, FsmToInit, STATE.Init);
  121. //idle
  122. EnterExitTransition<STATE, FSM_MSG>(STATE.Idle, FsmEnterIdle, FSM_MSG.NONE, FsmExitIdle);
  123. //align
  124. Transition(STATE.Idle, MSG.Align, FsmStartAlign, STATE.Aligning);
  125. Transition(STATE.Aligning, FSM_MSG.TIMER, FsmMonitorAlignTask, STATE.Idle);
  126. Transition(STATE.Aligning, MSG.Error, null, STATE.Init);
  127. Transition(STATE.Aligning, MSG.Abort, FsmAbortTask, STATE.Init);
  128. }
  129. #region Service Functions
  130. public override bool Align(double angle)
  131. {
  132. return CheckToPostMessage((int)MSG.Align,angle);
  133. }
  134. public override bool Home(out string reason)
  135. {
  136. if (!CheckToPostMessage((int)MSG.Home))
  137. {
  138. reason = $"Can not home in {StringFsmStatus} status";
  139. return false;
  140. }
  141. reason = string.Empty;
  142. return true;
  143. }
  144. public override void Reset()
  145. {
  146. if (IsError)
  147. {
  148. if (_alignerDevice.IsError)
  149. {
  150. _alignerDevice.Reset();
  151. }
  152. CheckToPostMessage((int)MSG.Reset);
  153. }
  154. }
  155. public override bool PrepareTransfer(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType, out string reason)
  156. {
  157. reason = string.Empty;
  158. return true;
  159. }
  160. public override bool TransferHandoff(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType, out string reason)
  161. {
  162. reason = string.Empty;
  163. return true;
  164. }
  165. public override bool PostTransfer(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType, out string reason)
  166. {
  167. reason = string.Empty;
  168. return true;
  169. }
  170. public override bool CheckReadyForTransfer(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType,
  171. out string reason)
  172. {
  173. reason = string.Empty;
  174. if (transferType == EnumTransferType.Pick)
  175. {
  176. return IsReady&&WaferManager.Instance.CheckHasWafer(Module, targetSlot);
  177. }
  178. if (transferType == EnumTransferType.Place)
  179. {
  180. return IsReady&&WaferManager.Instance.CheckNoWafer(Module, targetSlot);
  181. }
  182. return false;
  183. }
  184. public override void NoteTransferStart(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType)
  185. {
  186. //CheckToPostMessage(MSG.InTransfer);
  187. }
  188. public override void NoteTransferStop(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType)
  189. {
  190. //if (FsmState == (int)STATE.InTransfer)
  191. // CheckToPostMessage(MSG.TransferComplete);
  192. }
  193. private bool FsmReset(object[] param)
  194. {
  195. if (!_isInit)
  196. {
  197. PostMsg(MSG.ToInit);
  198. return false;
  199. }
  200. if (_alignerDevice.IsError)
  201. {
  202. EV.PostWarningLog(Module, $"{Module} in error, home to recover");
  203. PostMsg(MSG.ToInit);
  204. return false;
  205. }
  206. return true;
  207. }
  208. private bool FsmOnError(object[] param)
  209. {
  210. if (FsmState == (int)STATE.Error)
  211. {
  212. return false;
  213. }
  214. AbortRoutine();
  215. if (FsmState == (int)STATE.Init)
  216. return false;
  217. return true;
  218. }
  219. private bool FsmExitIdle(object[] param)
  220. {
  221. return true;
  222. }
  223. private bool FsmEnterIdle(object[] param)
  224. {
  225. return true;
  226. }
  227. private bool FsmExitError(object[] param)
  228. {
  229. return true;
  230. }
  231. private bool FsmEnterError(object[] param)
  232. {
  233. if (OnEnterError != null)
  234. OnEnterError(Module);
  235. return true;
  236. }
  237. private bool FsmAbortTask(object[] param)
  238. {
  239. AbortRoutine();
  240. return true;
  241. }
  242. private bool FsmStartHome(object[] param)
  243. {
  244. Result ret = StartRoutine(_home);
  245. if (ret == Result.FAIL || ret == Result.DONE)
  246. return false;
  247. _isInit = false;
  248. return ret == Result.RUN;
  249. }
  250. private bool FsmMonitorHomeTask(object[] param)
  251. {
  252. Result ret = MonitorRoutine();
  253. if (ret == Result.FAIL)
  254. {
  255. PostMsg(MSG.Error);
  256. return false;
  257. }
  258. if (ret == Result.DONE)
  259. {
  260. _isInit = true;
  261. return true;
  262. }
  263. return false;
  264. }
  265. private bool FsmStartAlign(object[] param)
  266. {
  267. _align.Init(Convert.ToDouble(param[0]));
  268. Result ret = StartRoutine(_align);
  269. if (ret == Result.FAIL || ret == Result.DONE)
  270. return false;
  271. _isInit = false;
  272. return ret == Result.RUN;
  273. }
  274. private bool FsmMonitorAlignTask(object[] param)
  275. {
  276. Result ret = MonitorRoutine();
  277. if (ret == Result.FAIL)
  278. {
  279. PostMsg(MSG.Error);
  280. return false;
  281. }
  282. if (ret == Result.DONE)
  283. {
  284. _isInit = true;
  285. return true;
  286. }
  287. return false;
  288. }
  289. private bool FsmToInit(object[] param)
  290. {
  291. return true;
  292. }
  293. private bool FsmToIdle(object[] param)
  294. {
  295. return true;
  296. }
  297. public override bool Lift(bool up)
  298. {
  299. return true;
  300. }
  301. #endregion
  302. }
  303. }