SETMEntity.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  1. using Aitex.Core.RT.DataCenter;
  2. using Aitex.Core.RT.Device;
  3. using Aitex.Core.RT.Fsm;
  4. using Aitex.Core.RT.Log;
  5. using Aitex.Core.RT.OperationCenter;
  6. using Aitex.Sorter.Common;
  7. using MECF.Framework.Common.Equipment;
  8. using MECF.Framework.Common.SubstrateTrackings;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.Diagnostics;
  12. using System.Linq;
  13. using System.Reflection;
  14. using System.Text;
  15. using System.Threading.Tasks;
  16. using Venus_Core;
  17. using Venus_RT.Devices;
  18. using Venus_RT.Devices.PreAligner;
  19. using Venus_RT.Devices.VCE;
  20. using Venus_RT.Modules.PMs;
  21. namespace Venus_RT.Modules.TM.VenusEntity
  22. {
  23. public class SETMEntity : Entity, IModuleEntity
  24. {
  25. public enum STATE
  26. {
  27. Unknown,
  28. Init,
  29. Initializing,
  30. InitializingRB,
  31. Idle,
  32. Error,
  33. Pumping,
  34. Venting,
  35. Purging,
  36. Leakchecking,
  37. Picking,
  38. Placing,
  39. Swaping,
  40. PMPicking,
  41. PMPlacing,
  42. PMSwaping,
  43. Aligning,
  44. Mapping,
  45. Extending,
  46. Retracting,
  47. Swapping,
  48. Gotoing,
  49. ControllingPressure,
  50. }
  51. public enum MSG
  52. {
  53. Home,
  54. RobotHome,
  55. Online,
  56. Offline,
  57. Pump,
  58. Vent,
  59. Purge,
  60. CyclePurge,
  61. LeakCheck,
  62. Pick,
  63. Place,
  64. Swap,
  65. DoublePick,
  66. DoublePlace,
  67. DoubleSwap,
  68. PMPick,
  69. PMPlace,
  70. PMSwap,
  71. Extend,
  72. Retract,
  73. TMCycle,
  74. ControlPressure,
  75. Error,
  76. Abort,
  77. AbortControlPressure,
  78. Align,
  79. CreateJob,
  80. StartJob,
  81. }
  82. #region 公开变量
  83. public bool IsIdle
  84. {
  85. get { return fsm.State == (int)STATE.Idle; }
  86. }
  87. public bool IsError
  88. {
  89. get { return fsm.State == (int)STATE.Error; }
  90. }
  91. public bool IsInit
  92. {
  93. get { return fsm.State == (int)STATE.Unknown || fsm.State == (int)STATE.Init; }
  94. }
  95. public bool IsBusy
  96. {
  97. get { return !IsInit && !IsError && !IsIdle; }
  98. }
  99. public bool VCEIsATM => _tm.IsTMATM;
  100. public bool TMIsATM => _tm.IsVCEATM;
  101. public bool TMIsVAC => _tm.IsTMVAC;
  102. public bool VCEIsVAC => _tm.IsVCEVAC;
  103. public bool IsPMASlitDoorClosed => _tm.PMASlitDoorClosed;
  104. public bool IsPMBSlitDoorClosed => _tm.PMBSlitDoorClosed;
  105. public bool IsPMCSlitDoorClosed => _tm.PMCSlitDoorClosed;
  106. public RState RobotStatus
  107. {
  108. get
  109. {
  110. if (_robot.Status != RState.Running)
  111. {
  112. if (_robotWatch.ElapsedMilliseconds < 100)
  113. return RState.Running;
  114. else
  115. return _robot.Status;
  116. }
  117. else
  118. return RState.Running;
  119. }
  120. }
  121. public bool IsOnline { get; internal set; }
  122. //public bool IsTMVac => _tm.IsTMVac;
  123. //public bool IsTMATM => _tm.IsTMATM;
  124. #endregion
  125. #region 私有变量
  126. private readonly HongHuTM _tm;
  127. private readonly ITransferRobot _robot;
  128. private readonly IPreAlign _vpa;
  129. private readonly SEMFHomeRoutine _homeRoutine;
  130. private readonly SEMFPickRoutine _pickRoutine;
  131. private readonly SEMFPlaceRoutine _placeRoutine;
  132. private readonly SEMFVentRoutine _ventRoutine;
  133. private readonly SEMFPumpRoutine _pumpRoutine;
  134. private readonly SEMFPMPickRoutine _pickpmRoutine;
  135. private readonly SEMFPMPlaceRoutine _placepmRoutine;
  136. private readonly SEMFSwapRoutine _swaproutine;
  137. private readonly SEMFPMSwapRoutine _pmswaproutine;
  138. //private readonly
  139. private readonly Stopwatch _robotWatch = new Stopwatch();
  140. #endregion
  141. public SETMEntity()
  142. {
  143. _tm = DEVICE.GetDevice<HongHuTM>("SETM");
  144. if(ModuleHelper.IsInstalled(ModuleName.TMRobot))
  145. _robot = new HongHuVR();
  146. _vpa = new HongHuVPA(ModuleName.VPA);
  147. _robotWatch = new Stopwatch();
  148. _homeRoutine = new SEMFHomeRoutine(_tm,_robot, _vpa);
  149. _pickRoutine = new SEMFPickRoutine(_tm,_robot, _vpa);
  150. _placeRoutine = new SEMFPlaceRoutine(_tm, _robot, _vpa);
  151. _pumpRoutine = new SEMFPumpRoutine(_tm, ModuleName.SETM);
  152. _ventRoutine = new SEMFVentRoutine(_tm, ModuleName.SETM);
  153. _pickpmRoutine = new SEMFPMPickRoutine(_tm, _robot);
  154. _placepmRoutine = new SEMFPMPlaceRoutine(_tm, _robot);
  155. _swaproutine = new SEMFSwapRoutine(_tm, _robot);
  156. _pmswaproutine = new SEMFPMSwapRoutine(_tm, _robot);
  157. InitFsmMap();
  158. }
  159. protected override bool Init()
  160. {
  161. DATA.Subscribe($"SETM.FsmState", () => ((STATE)fsm.State).ToString());
  162. OP.Subscribe("SETM.Home", (cmd, args) => { PostMsg(MSG.Home); return true; });
  163. OP.Subscribe("SETM.Pick", (cmd, args) => { PostMsg(MSG.Pick, args); return true; });
  164. OP.Subscribe("SETM.Place", (cmd, args) => { PostMsg(MSG.Place, args); return true; });
  165. OP.Subscribe("SETM.PMPick", (cmd, args) => { PostMsg(MSG.PMPick, args); return true; });
  166. OP.Subscribe("SETM.PMPlace", (cmd, args) => { PostMsg(MSG.PMPlace, args); return true; });
  167. OP.Subscribe("SETM.PumpDown", (cmd, args) => { PostMsg(MSG.Pump); return true; });
  168. OP.Subscribe("SETM.Vent", (cmd, args) => { PostMsg(MSG.Vent); return true; });
  169. return true;
  170. }
  171. private void InitFsmMap()
  172. {
  173. fsm = new StateMachine<SETMEntity>("SETM", (int)STATE.Init, 50);
  174. AnyStateTransition(MSG.Error, fnError, STATE.Error);
  175. AnyStateTransition(MSG.Online, fnOnline, FSM_STATE.SAME);
  176. AnyStateTransition(MSG.Offline, fnOffline, FSM_STATE.SAME);
  177. AnyStateTransition(MSG.Home, fnHome, STATE.Initializing);
  178. //Home
  179. Transition(STATE.Initializing, FSM_MSG.TIMER, fnHomeTimeout, STATE.Idle);
  180. Transition(STATE.Initializing, MSG.Abort, fnAbortHome, STATE.Idle);
  181. //Pick
  182. Transition(STATE.Idle, MSG.Pick, fnStartPick, STATE.Picking);
  183. Transition(STATE.Picking, FSM_MSG.TIMER, fnPickTimeout, STATE.Idle);
  184. Transition(STATE.Picking, MSG.Abort, fnAbortPick, STATE.Idle);
  185. //Place
  186. Transition(STATE.Idle, MSG.Place, fnStartPlace, STATE.Placing);
  187. Transition(STATE.Placing, FSM_MSG.TIMER, fnPlaceTimeout, STATE.Idle);
  188. Transition(STATE.Placing, MSG.Abort, fnAbortPlace, STATE.Idle);
  189. //Pump
  190. Transition(STATE.Idle, MSG.Pump, fnStartPump, STATE.Pumping);
  191. Transition(STATE.Pumping, FSM_MSG.TIMER, fnPumpTimeout, STATE.Idle);
  192. Transition(STATE.Pumping, MSG.Abort, fnAbortPump, STATE.Idle);
  193. //Vent
  194. Transition(STATE.Idle, MSG.Vent, fnStartVent, STATE.Venting);
  195. Transition(STATE.Venting, FSM_MSG.TIMER, fnVentTimeout, STATE.Idle);
  196. Transition(STATE.Venting, MSG.Abort, fnAbortVent, STATE.Idle);
  197. //PMPick
  198. Transition(STATE.Idle, MSG.PMPick, fnStartPMPick, STATE.PMPicking);
  199. Transition(STATE.PMPicking, FSM_MSG.TIMER, fnPMPickTimeout, STATE.Idle);
  200. Transition(STATE.PMPicking, MSG.Abort, fnAbortPMPick, STATE.Idle);
  201. //PMPlace
  202. Transition(STATE.Idle, MSG.PMPlace, fnStartPMPlace, STATE.PMPlacing);
  203. Transition(STATE.PMPlacing, FSM_MSG.TIMER, fnPMPlaceTimeout, STATE.Idle);
  204. Transition(STATE.PMPlacing, MSG.Abort, fnAbortPMPlace, STATE.Idle);
  205. //PA align
  206. Transition(STATE.Idle, MSG.Align, fnStartAlign, STATE.Aligning);
  207. Transition(STATE.Aligning, FSM_MSG.TIMER, fnAlignTimeout, STATE.Idle);
  208. Transition(STATE.Aligning, MSG.Abort, fnAbortAlign, STATE.Idle);
  209. //Swap
  210. Transition(STATE.Idle, MSG.Swap, fnStartSwap, STATE.Swapping);
  211. Transition(STATE.Swapping, FSM_MSG.TIMER, fnSwapTimeout, STATE.Idle);
  212. Transition(STATE.Swapping, MSG.Abort, fnAbortSwap, STATE.Idle);
  213. //PM Swap
  214. Transition(STATE.Idle, MSG.PMSwap, fnStartPMSwap, STATE.PMSwaping);
  215. Transition(STATE.PMSwaping, FSM_MSG.TIMER, fnPMSwapTimeout, STATE.Idle);
  216. Transition(STATE.PMSwaping, MSG.Abort, fnAbortPMSwap, STATE.Idle);
  217. Running = true;
  218. }
  219. private bool fnAbortPMSwap(object[] param)
  220. {
  221. _pmswaproutine.Abort();
  222. return true;
  223. }
  224. private bool fnPMSwapTimeout(object[] param)
  225. {
  226. RState ret = _pmswaproutine.Monitor();
  227. if (ret == RState.Failed || ret == RState.Timeout)
  228. {
  229. PostMsg(MSG.Error);
  230. return false;
  231. }
  232. return ret == RState.End;
  233. }
  234. private bool fnStartPMSwap(object[] param)
  235. {
  236. return _pmswaproutine.Start(param) == RState.Running;
  237. }
  238. private bool fnAbortSwap(object[] param)
  239. {
  240. _swaproutine.Abort();
  241. return true;
  242. }
  243. private bool fnSwapTimeout(object[] param)
  244. {
  245. RState ret = _swaproutine.Monitor();
  246. if (ret == RState.Failed || ret == RState.Timeout)
  247. {
  248. PostMsg(MSG.Error);
  249. return false;
  250. }
  251. return ret == RState.End;
  252. }
  253. private bool fnStartSwap(object[] param)
  254. {
  255. return _swaproutine.Start(param) == RState.Running;
  256. }
  257. private bool fnStartAlign(object[] param)
  258. {
  259. if (float.TryParse(param[0].ToString(), out float angle))
  260. {
  261. return _vpa.AlignWithAngle(angle);
  262. }
  263. else
  264. {
  265. LOG.Write(eEvent.ERR_TM,ModuleName.VPA,$"wrong angle, value is {param[0]}.");
  266. return false;
  267. }
  268. }
  269. private bool fnAlignTimeout(object[] param)
  270. {
  271. if (_vpa.Status == RState.End)
  272. {
  273. return true;
  274. }
  275. else if (_vpa.Status != RState.Running)
  276. {
  277. LOG.Write(eEvent.ERR_TM, ModuleName.VPA, $"PreAligner align failed: {_vpa.Status}");
  278. return true;
  279. }
  280. return false;
  281. }
  282. private bool fnAbortAlign(object[] param)
  283. {
  284. return true;
  285. }
  286. private bool fnAbortPMPlace(object[] param)
  287. {
  288. _placepmRoutine.Abort();
  289. return true;
  290. }
  291. private bool fnPMPlaceTimeout(object[] param)
  292. {
  293. RState ret = _placepmRoutine.Monitor();
  294. if (ret == RState.Failed || ret == RState.Timeout)
  295. {
  296. PostMsg(MSG.Error);
  297. return false;
  298. }
  299. return ret == RState.End;
  300. }
  301. private bool fnStartPMPlace(object[] param)
  302. {
  303. return _placepmRoutine.Start(param) == RState.Running;
  304. }
  305. private bool fnAbortPMPick(object[] param)
  306. {
  307. _pickpmRoutine.Abort();
  308. return true;
  309. }
  310. private bool fnPMPickTimeout(object[] param)
  311. {
  312. RState ret = _pickpmRoutine.Monitor();
  313. if (ret == RState.Failed || ret == RState.Timeout)
  314. {
  315. PostMsg(MSG.Error);
  316. return false;
  317. }
  318. return ret == RState.End;
  319. }
  320. private bool fnStartPMPick(object[] param)
  321. {
  322. return _pickpmRoutine.Start(param) == RState.Running;
  323. }
  324. private bool fnAbortVent(object[] param)
  325. {
  326. _ventRoutine.Abort();
  327. return true;
  328. }
  329. private bool fnVentTimeout(object[] param)
  330. {
  331. RState ret = _ventRoutine.Monitor();
  332. if (ret == RState.Failed || ret == RState.Timeout)
  333. {
  334. PostMsg(MSG.Error);
  335. return false;
  336. }
  337. return ret == RState.End;
  338. }
  339. private bool fnStartVent(object[] param)
  340. {
  341. return _ventRoutine.Start(param) == RState.Running;
  342. }
  343. private bool fnAbortPump(object[] param)
  344. {
  345. _pumpRoutine.Abort();
  346. return true;
  347. }
  348. private bool fnPumpTimeout(object[] param)
  349. {
  350. RState ret = _pumpRoutine.Monitor();
  351. if (ret == RState.Failed || ret == RState.Timeout)
  352. {
  353. PostMsg(MSG.Error);
  354. return false;
  355. }
  356. return ret == RState.End;
  357. }
  358. private bool fnStartPump(object[] param)
  359. {
  360. return _pumpRoutine.Start(param) == RState.Running;
  361. }
  362. private bool fnAbortPlace(object[] param)
  363. {
  364. return true;
  365. }
  366. private bool fnPlaceTimeout(object[] param)
  367. {
  368. RState ret = _placeRoutine.Monitor();
  369. if (ret == RState.Failed || ret == RState.Timeout)
  370. {
  371. PostMsg(MSG.Error);
  372. return false;
  373. }
  374. return ret == RState.End;
  375. }
  376. private bool fnStartPlace(object[] param)
  377. {
  378. return _placeRoutine.Start(param) == RState.Running;
  379. }
  380. private bool fnAbortPick(object[] param)
  381. {
  382. _pickRoutine.Abort();
  383. return true;
  384. }
  385. private bool fnStartPick(object[] param)
  386. {
  387. return _pickRoutine.Start(param) == RState.Running;
  388. }
  389. private bool fnPickTimeout(object[] param)
  390. {
  391. RState ret = _pickRoutine.Monitor();
  392. if (ret == RState.Failed || ret == RState.Timeout)
  393. {
  394. PostMsg(MSG.Error);
  395. return false;
  396. }
  397. return ret == RState.End;
  398. }
  399. private bool fnAbortHome(object[] param)
  400. {
  401. _homeRoutine.Abort();
  402. return true;
  403. }
  404. private bool fnHome(object[] param)
  405. {
  406. if (fsm.State == (int)STATE.Init && param.Length > 0)//带参home
  407. {
  408. return false;
  409. }
  410. else
  411. return _homeRoutine.Start(param) == RState.Running;
  412. }
  413. private bool fnHomeTimeout(object[] param)
  414. {
  415. RState ret = _homeRoutine.Monitor();
  416. if (ret == RState.Failed || ret == RState.Timeout)
  417. {
  418. PostMsg(MSG.Error);
  419. return false;
  420. }
  421. return ret == RState.End;
  422. }
  423. private bool fnOffline(object[] param)
  424. {
  425. throw new NotImplementedException();
  426. }
  427. private bool fnOnline(object[] param)
  428. {
  429. throw new NotImplementedException();
  430. }
  431. private bool fnError(object[] param)
  432. {
  433. return true;
  434. }
  435. public bool Check(int msg, out string reason, params object[] args)
  436. {
  437. reason = "";
  438. return true;
  439. }
  440. public bool CheckAcked(int msg)
  441. {
  442. return fsm.CheckExecuted(msg);
  443. }
  444. public bool CheckToPostMessage(int msg, params object[] args)
  445. {
  446. if (!fsm.FindTransition(fsm.State, msg))
  447. {
  448. LOG.Write(eEvent.WARN_FSM_WARN, ModuleName.TM, $"TM is in {(STATE)fsm.State} state,can not do {(MSG)msg}");
  449. return false;
  450. }
  451. Running = true;
  452. fsm.PostMsg(msg, args);
  453. return true;
  454. }
  455. public int Invoke(string function, params object[] args)
  456. {
  457. switch (function)
  458. {
  459. case "Home":
  460. CheckToPostMessage((int)MSG.Home);
  461. return (int)MSG.Home;
  462. }
  463. return (int)FSM_MSG.NONE;
  464. }
  465. }
  466. }