EfemEntity.cs 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516
  1. using System;
  2. using System.Diagnostics;
  3. using System.Collections.Generic;
  4. using Aitex.Core.Common;
  5. using Aitex.Core.RT.DataCenter;
  6. using Aitex.Core.RT.Event;
  7. using Aitex.Core.RT.Fsm;
  8. using Aitex.Core.RT.OperationCenter;
  9. using Aitex.Core.RT.SCCore;
  10. using Aitex.Core.Utilities;
  11. using Aitex.Core.Util;
  12. using Aitex.Core.RT.Log;
  13. using Aitex.Sorter.Common;
  14. using MECF.Framework.Common.Equipment;
  15. using MECF.Framework.Common.Schedulers;
  16. using MECF.Framework.Common.SubstrateTrackings;
  17. using PunkHPX8_Core;
  18. using PunkHPX8_RT;
  19. using PunkHPX8_RT.Devices;
  20. using PunkHPX8_RT.Devices.YASKAWA;
  21. using PunkHPX8_RT.Devices.EFEM;
  22. using PunkHPX8_RT.Modules.LPs;
  23. using PunkHPX8_RT.Modules.EFEM;
  24. using System.Reflection;
  25. using PunkHPX8_RT.Modules.Transporter;
  26. using MECF.Framework.Common.Alarm;
  27. using MECF.Framework.Common.CommonData;
  28. using Aitex.Core.RT.Routine;
  29. using MECF.Framework.Common.IOCore;
  30. using MECF.Framework.Common.Beckhoff.ModuleIO;
  31. namespace PunkHPX8_RT.Modules
  32. {
  33. class EfemEntity : Entity, IEntity, IModuleEntity
  34. {
  35. #region 常量
  36. private const string VACUUM_VALUE = "VacuumValue";
  37. private const string DOOR_UNLOCK = "DoorUnlock";
  38. private const string DOOR_LOCKED = "DoorLocked";
  39. #endregion
  40. //private int _bigWafer = 0;
  41. //private int _midWafer = 0;
  42. //private int _smallWafer = 0;
  43. private bool _isVacuume = false;
  44. private bool _isPause = false;
  45. private bool _isResume = false;
  46. public enum STATE
  47. {
  48. Unknown, // 0
  49. Initializing, // 1
  50. Idle, // 2
  51. Error, // 3
  52. Picking, // 4
  53. Placing, // 5
  54. Aligning, // 6
  55. Mapping, // 7
  56. Init, // 8
  57. Orgshing, // 9
  58. Lifting, // 10
  59. InitingAL, // 11
  60. InitingRB, // 12
  61. Extending, // 13
  62. Retracting, // 14
  63. //SettingLamp, // 15
  64. Swapping,
  65. Gotoing,
  66. Gripping,
  67. Ungripping,
  68. Fliping,
  69. Vacuuming,
  70. Retrying,
  71. ConfirmCompleting,
  72. ErrorPicking,
  73. ErrorPlacing,
  74. RobotCycleing,
  75. ErrorInitingAL,
  76. }
  77. public enum MSG
  78. {
  79. HomeAll, // 0
  80. Pick, // 1
  81. Place, // 2
  82. Align, // 3
  83. ActionDone, // 4
  84. MoveCmd, // 6
  85. Recover, // 8
  86. Goto, // 9
  87. Error, // 10
  88. Online, // 11
  89. CommReady, // 12
  90. Lift, // 13
  91. HomeAL, // 14
  92. HomeRB, // 15
  93. Extend, // 16
  94. Retract, // 17
  95. PMLiftPinUp, // 18
  96. PMLiftPinDown, // 19
  97. TurnOffBuzzer,
  98. Abort,
  99. GotoMap,
  100. Map,
  101. ToInit,
  102. Cool,
  103. Swap,
  104. Grip,
  105. Ungrip,
  106. Flip,
  107. LiftActionDone,
  108. Offline,
  109. SetRobotSpeed,
  110. MapDummy,
  111. Vacuum,
  112. CloseBuzzer,
  113. RobotPowerOn,
  114. Retry,
  115. ConfirmComplete,
  116. BackroundCmd=999,
  117. Load,
  118. Unload,
  119. Dock,
  120. Undock,
  121. Clamp,
  122. Unclamp,
  123. ReadCarrierId,
  124. WriteCarrierID,
  125. ReadTagData,
  126. WriteTagData,
  127. RobotCycle,
  128. }
  129. public enum EfemType
  130. {
  131. FutureEfem = 1,
  132. SunWayEFEM =2
  133. }
  134. public bool IsIdle
  135. {
  136. get { return fsm.State == (int)STATE.Idle; }
  137. }
  138. public bool IsError
  139. {
  140. get { return fsm.State == (int)STATE.Error; }
  141. }
  142. public bool IsInit
  143. {
  144. get { return fsm.State == (int)STATE.Unknown || fsm.State == (int)STATE.Init; }
  145. }
  146. public bool IsBusy
  147. {
  148. get { return !IsInit && !IsError && !IsIdle; }
  149. }
  150. public bool IsAuto { get; } = true;
  151. /// <summary>
  152. /// 是否为工程模式
  153. /// </summary>
  154. public bool IsEngineering { get; } = false;
  155. /// <summary>
  156. /// 是否为产品模式
  157. /// </summary>
  158. public bool IsProduction { get; } = true;
  159. /// <summary>
  160. /// 模块名称
  161. /// </summary>
  162. public ModuleName Module { get; private set; }
  163. public bool IsHomed
  164. {
  165. get { return _isHomed; }
  166. }
  167. public bool IsOnline { get; internal set; }
  168. public bool IsDisable { get; internal set; }
  169. public RState RobotStatus
  170. {
  171. get
  172. {
  173. if (_efem.Status != RState.Running)
  174. {
  175. if (_robotWatch.ElapsedMilliseconds < 200)
  176. return RState.Running;
  177. else
  178. return _efem.Status;
  179. }
  180. else
  181. return RState.Running;
  182. }
  183. }
  184. public double VacuumValue
  185. {
  186. get { return _vacuumValue; }
  187. }
  188. public bool Check(int msg, out string reason, params object[] args)
  189. {
  190. throw new NotImplementedException();
  191. }
  192. // Fields
  193. private readonly string Name;
  194. private readonly EfemBase _efem;
  195. private readonly LoadPortModule[] _lpms = new LoadPortModule[3];
  196. private readonly DummyDevice[] _dummies = new DummyDevice[2];
  197. private readonly EfemType _efemType;
  198. public EfemBase EfemDevice => _efem;
  199. public EfemType EFEMType => _efemType;
  200. // routine
  201. private readonly EfemPickRoutine _pickRoutine;
  202. private readonly EfemPlaceRoutine _placeRoutine;
  203. private readonly EfemHomeRoutine _homeRoutine;
  204. private readonly EFEMAlignRoutine _alignRoutine;
  205. private readonly EfemMapDummyRoutine _mapDummyRoutine;
  206. private readonly EfemVacuumRoutine _vacuumRoutine;
  207. private readonly CycleRobotCycleNewRoutine _cycleRobotCycleRoutine;
  208. private readonly EfemSafeOpenRoutine _efemSafeOpenRoutine;
  209. private readonly EfemSafeCloseRoutine _efemSafeCloseRoutine;
  210. private string LiftMessage;
  211. private Stopwatch _robotWatch = new Stopwatch();
  212. private R_TRIG _robotIdleTrigger = new R_TRIG();
  213. private bool _isHomed = false;
  214. private EfemAutoMessageProcessor _autoMessageProcessor;
  215. private STATE _errorPreState;
  216. private IRoutine _currentRoutine;
  217. private int _currentCycleTimes;
  218. /// <summary>
  219. /// 变量是否初始化字典
  220. /// </summary>
  221. private Dictionary<string, bool> _variableInitializeDic = new Dictionary<string, bool>();
  222. /// <summary>
  223. /// 真空数值
  224. /// </summary>
  225. private double _vacuumValue;
  226. private bool _doorUnlock;
  227. private bool _doorLocked;
  228. // Constructor
  229. public EfemEntity()
  230. {
  231. Module = ModuleName.EFEM;
  232. Name = ModuleName.EFEM.ToString();
  233. InitFsmMap();
  234. _efemType = (EfemType)SC.GetValue<int>($"EFEM.EfemType");
  235. _efem = new SunWayRobot();
  236. _homeRoutine = new EfemHomeRoutine(_efem);
  237. _pickRoutine = new EfemPickRoutine(_efem);
  238. _placeRoutine = new EfemPlaceRoutine(_efem);
  239. _alignRoutine = new EFEMAlignRoutine(_efem);
  240. _mapDummyRoutine = new EfemMapDummyRoutine(_efem);
  241. _vacuumRoutine = new EfemVacuumRoutine(_efem);
  242. _cycleRobotCycleRoutine = new CycleRobotCycleNewRoutine(_efem);
  243. _autoMessageProcessor =new EfemAutoMessageProcessor(_efem);
  244. _efemSafeOpenRoutine = new EfemSafeOpenRoutine(_efem);
  245. _efemSafeCloseRoutine = new EfemSafeCloseRoutine(_efem);
  246. }
  247. public LoadPortModule GetLoadportModule(int lpNumber)
  248. {
  249. if (lpNumber < 0|| _lpms.Length<=lpNumber)
  250. {
  251. return null;
  252. }
  253. return _lpms[lpNumber];
  254. }
  255. public DummyDevice GetDummyDevice(int dummyNumber)
  256. {
  257. if (dummyNumber < 0||_dummies.Length<=dummyNumber)
  258. {
  259. return null;
  260. }
  261. return _dummies[dummyNumber];
  262. }
  263. protected override bool Init()
  264. {
  265. _lpms[0] = new LoadPortModule(ModuleName.LP1, _efem);
  266. _lpms[1] = new LoadPortModule(ModuleName.LP2, _efem);
  267. _lpms[2] = new LoadPortModule(ModuleName.LP3, _efem);
  268. _dummies[0] = new DummyDevice(ModuleName.Dummy1);
  269. _dummies[1] = new DummyDevice(ModuleName.Dummy2);
  270. _lpms[0].Initialize();
  271. _lpms[1].Initialize();
  272. _lpms[2].Initialize();
  273. BeckhoffIoSubscribeUpdateVariable(VACUUM_VALUE);
  274. BeckhoffIoSubscribeUpdateVariable(DOOR_UNLOCK);
  275. BeckhoffIoSubscribeUpdateVariable(DOOR_LOCKED);
  276. OP.Subscribe($"{ModuleName.EFEM}.{EfemOperation.Home}", (cmd, args) => { PostMsg(MSG.HomeAll); return true; });
  277. OP.Subscribe($"{ModuleName.EFEM}.{EfemOperation.RobotCycle}", (cmd, args) => {
  278. CheckToPostMessage((int)MSG.RobotCycle,args); return true; });
  279. OP.Subscribe($"{ModuleName.EFEM}.{EfemOperation.ClearError}", (cmd, args) => { PostMsg(MSG.Recover); return true; });
  280. OP.Subscribe($"{ModuleName.EFEM}.{EfemOperation.TurnOffBuzzer}", (cmd, args) => { PostMsg(MSG.CloseBuzzer); return true; });
  281. OP.Subscribe($"{ModuleName.EFEM}.Online", (cmd, args) =>
  282. {
  283. PostMsg(MSG.Online, args[0]); return true;
  284. });
  285. OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Pick}", (cmd, args) => { CheckToPostMessage<STATE, MSG>(eEvent.ERR_EFEM_COMMON_FAILED,"EFEM",(int)MSG.Pick, args[0]); return true; });
  286. OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Place}", (cmd, args) => { CheckToPostMessage<STATE, MSG>(eEvent.ERR_EFEM_COMMON_FAILED, "EFEM", (int)MSG.Place, args[0]); return true; });
  287. OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Swap}", (cmd, args) => { PostMsg(MSG.Swap, args[0]); return true; });
  288. OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.DummyMap}", (cmd, args) => { CheckToPostMessage<STATE, MSG>(eEvent.ERR_EFEM_COMMON_FAILED, "EFEM", (int)MSG.MapDummy); return true; });
  289. OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Speed}", (cmd, args) => {
  290. return _efem.SetRobotSpeed(ModuleName.EfemRobot, (int)args[0]); });
  291. OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Vacuum}", (cmd, args) => {
  292. return _efem.Vacuum(ModuleName.EfemRobot, (bool)args[1], (Hand)args[2]); });
  293. OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.PowerOn}", (cmd, args) => {
  294. return _efem.RobotPowerOn(ModuleName.EfemRobot, (bool)args[0]); });
  295. OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Abort}", (cmd, args) => { PostMsg(MSG.Abort); return true; });
  296. OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Home}", (cmd, args) => { PostMsg(MSG.HomeRB); return true; });
  297. OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Grip}", (cmd, args) =>
  298. {
  299. bool isGrip = ((string)args[0]).ToLower() == "on";
  300. PostMsg(isGrip ? MSG.Grip : MSG.Ungrip, args[1]);
  301. return true;
  302. });
  303. //OP.Subscribe($"{ModuleName.EfemRobot}.{EfemOperation.Flip}", (cmd, args) => { PostMsg(MSG.Flip, args[0]); return true; });
  304. OP.Subscribe($"{ModuleName.Aligner1}.{EfemOperation.Home}", (cmd, args) => { PostMsg(MSG.HomeAL, ModuleName.Aligner1); return true; });
  305. OP.Subscribe($"{ModuleName.Aligner1}.{EfemOperation.Align}", (cmd, args) => {
  306. int alignerFlatType = SC.GetValue<int>("EFEM.Aligner1.AlignerPlatType");
  307. CheckToPostMessage<STATE,MSG>(eEvent.ERR_EFEM_COMMON_FAILED,ModuleName.EFEM.ToString(),(int)MSG.Align, ModuleName.Aligner1, args[0], args[1],alignerFlatType); return true; });
  308. //OP.Subscribe($"{ModuleName.Aligner1}.{EfemOperation.Vacuum}", (cmd, args) => { CheckToPostMessage<STATE,MSG>(eEvent.ERR_EFEM_COMMON_FAILED,ModuleName.EFEM.ToString(),(int)MSG.Vacuum, args); return true; });
  309. OP.Subscribe($"{ModuleName.Aligner1}.{EfemOperation.Vacuum}", (cmd, args) => { return VacuumAction(args); });
  310. OP.Subscribe($"{Name}.DoorUnlock", (cmd, args) => { return DoorUnlock(args); });
  311. OP.Subscribe($"{Name}.SafeOpen", (cmd, args) => { return SafeOpenAction(args); });
  312. OP.Subscribe($"{Name}.SafeClose", (cmd, args) => { return SafeCloseAction(args); });
  313. OP.Subscribe($"{Name}.Pause", (cmd, args) => { return Pause(args); });
  314. OP.Subscribe($"{Name}.Resume", (cmd, args) => { return Resume(args); });
  315. DATA.Subscribe($"{Name}.FsmState", () => ((STATE)fsm.State).ToString(),SubscriptionAttribute.FLAG.IgnoreSaveDB);
  316. DATA.Subscribe($"{Name}.FsmPrevState", () => ((STATE)fsm.PrevState).ToString(), SubscriptionAttribute.FLAG.IgnoreSaveDB);
  317. DATA.Subscribe($"{Name}.FsmLastMessage", GetFsmLastMessage, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  318. DATA.Subscribe($"{Name}.RobotMoveAction", () => (_efem.TMRobotMoveInfo), SubscriptionAttribute.FLAG.IgnoreSaveDB);
  319. DATA.Subscribe($"{Name}.State", () => ((STATE)fsm.State).ToString(), SubscriptionAttribute.FLAG.IgnoreSaveDB);
  320. DATA.Subscribe($"{Name}.IsAlarm", () => IsError, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  321. DATA.Subscribe($"{Name}.IsInit", () => IsInit, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  322. DATA.Subscribe($"{Name}.IsIdle", () => IsIdle, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  323. DATA.Subscribe($"{Name}.IsBusy", () => IsBusy, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  324. DATA.Subscribe($"{Name}.IsOnline", () => IsOnline, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  325. DATA.Subscribe($"{Name}.IsHomed", () => _isHomed, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  326. DATA.Subscribe($"{Name}.RobotSpeed",()=>IsIdle?SC.GetValue<int>("EFEM.DefaultMoveSpeedInPercent"):0);
  327. DATA.Subscribe($"{Name}.CurrentRobotCycleTime",()=>_currentCycleTimes, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  328. DATA.Subscribe($"{Name}.VacuumValue",()=>_vacuumValue, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  329. DATA.Subscribe($"{Name}.DoorUnlock", () => _doorUnlock, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  330. DATA.Subscribe($"{Name}.DoorLocked", () => _doorLocked, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  331. _robotWatch.Restart();
  332. return true;
  333. }
  334. /// <summary>
  335. /// 订阅IO变量
  336. /// </summary>
  337. /// <param name="variable"></param>
  338. private void BeckhoffIoSubscribeUpdateVariable(string variable)
  339. {
  340. _variableInitializeDic[variable] = false;
  341. IOModuleManager.Instance.SubscribeModuleVariable($"{Module}", variable, UpdateVariableValue);
  342. }
  343. /// 更新变量数值
  344. /// </summary>
  345. /// <param name="variable"></param>
  346. /// <param name="value"></param>
  347. private void UpdateVariableValue(string variable, object value)
  348. {
  349. _variableInitializeDic[variable] = true;
  350. if (variable == VACUUM_VALUE)
  351. {
  352. _vacuumValue = (double)value;
  353. }
  354. else if (variable == DOOR_UNLOCK)
  355. {
  356. _doorUnlock = (bool)value;
  357. }
  358. else if (variable == DOOR_LOCKED)
  359. {
  360. _doorLocked = (bool)value;
  361. }
  362. }
  363. private void InitFsmMap()
  364. {
  365. fsm = new StateMachine<EfemEntity>("EFEM", (int)STATE.Unknown, 50);
  366. fsm.EnableRepeatedMsg(true);
  367. AnyStateTransition(FSM_MSG.TIMER, fnMonitor, FSM_STATE.SAME);
  368. AnyStateTransition(MSG.TurnOffBuzzer, fnTurnOffBuzzer, FSM_STATE.SAME);
  369. AnyStateTransition(MSG.Error, fnError, STATE.Error);
  370. AnyStateTransition(MSG.Online, fnOnline, FSM_STATE.SAME);
  371. AnyStateTransition(MSG.Abort, fnAbortRobot, FSM_STATE.SAME);
  372. AnyStateTransition(MSG.ToInit, fnToInit, STATE.Init);
  373. AnyStateTransition(MSG.BackroundCmd, fnBackroundCommand, FSM_STATE.SAME);
  374. AnyStateTransition(MSG.CloseBuzzer, fnCloseBuzzer, FSM_STATE.SAME);
  375. Transition(STATE.Unknown,MSG.CommReady, fnCommReady, STATE.Init);
  376. //Error
  377. Transition(STATE.Error, MSG.Recover, fnRecover, STATE.Idle);
  378. // Home
  379. Transition(STATE.Unknown, MSG.HomeAll, fnHomeAll, STATE.Initializing);
  380. Transition(STATE.Init, MSG.HomeAll, fnHomeAll, STATE.Initializing);
  381. Transition(STATE.Idle, MSG.HomeAll, fnHomeAll, STATE.Initializing);
  382. Transition(STATE.Error, MSG.HomeAll, fnHomeAll, STATE.Initializing);
  383. Transition(STATE.Initializing, FSM_MSG.TIMER, fnHomingTimeout, STATE.Idle);
  384. // Home Robot
  385. Transition(STATE.Error, MSG.HomeRB, fnHomeRobot, STATE.InitingRB);
  386. Transition(STATE.Idle, MSG.HomeRB, fnHomeRobot, STATE.InitingRB);
  387. Transition(STATE.InitingRB, FSM_MSG.TIMER, fnHomingRobotTimeout, STATE.Idle);
  388. // Home Aligner
  389. Transition(STATE.Idle, MSG.HomeAL, fnHomeAligner, STATE.InitingAL);
  390. Transition(STATE.InitingAL, FSM_MSG.TIMER, fnHomingAlignTimeout, STATE.Idle);
  391. Transition(STATE.Error, MSG.HomeAL, fnHomeAligner, STATE.ErrorInitingAL);
  392. Transition(STATE.ErrorInitingAL, FSM_MSG.TIMER, fnHomingAlignTimeout, STATE.Error);
  393. // Pick wafer
  394. Transition(STATE.Idle, MSG.Pick, FnStartPick, STATE.Picking);
  395. Transition(STATE.Picking, FSM_MSG.TIMER, FnPickTimeout, STATE.Idle);
  396. Transition(STATE.Picking, MSG.Abort, FnAbortPick, STATE.Idle);
  397. //Robot Cycle
  398. Transition(STATE.Idle, MSG.RobotCycle, FnStartRobotCycle, STATE.RobotCycleing);
  399. Transition(STATE.RobotCycleing, FSM_MSG.TIMER, FnRobotCycleTimeout, STATE.Idle);
  400. Transition(STATE.RobotCycleing, MSG.Abort, FnAbortRobotCycle, STATE.Idle);
  401. Transition(STATE.Error, MSG.Pick, FnErrorStartPick, STATE.ErrorPicking);
  402. Transition(STATE.ErrorPicking, FSM_MSG.TIMER, FnErrorPickTimeout, STATE.Error);
  403. Transition(STATE.ErrorPicking, MSG.Abort, FnErrorAbortPick, STATE.Error);
  404. // Place wafer
  405. Transition(STATE.Idle, MSG.Place, FnStartPlace, STATE.Placing);
  406. Transition(STATE.Placing, FSM_MSG.TIMER, FnPlaceTimeout, STATE.Idle);
  407. Transition(STATE.Placing, MSG.Abort, FnAbortPlace, STATE.Idle);
  408. Transition(STATE.Error, MSG.Place, FnErrorStartPlace, STATE.ErrorPlacing);
  409. Transition(STATE.ErrorPlacing, FSM_MSG.TIMER, FnErrorPlaceTimeout, STATE.Error);
  410. Transition(STATE.ErrorPlacing, MSG.Abort, FnErrorAbortPlace, STATE.Error);
  411. // Goto
  412. Transition(STATE.Idle, MSG.Goto, fnGoto, STATE.Gotoing);
  413. Transition(STATE.Gotoing, MSG.ActionDone, fnActionDone, STATE.Idle);
  414. // Map
  415. Transition(STATE.Idle, MSG.Map, fnMap, STATE.Mapping);
  416. Transition(STATE.Mapping, MSG.ActionDone, fnActionDone, STATE.Idle);
  417. // Grip
  418. Transition(STATE.Idle, MSG.Grip, fnGrip, STATE.Gripping);
  419. Transition(STATE.Gripping, MSG.ActionDone, fnActionDone, STATE.Idle);
  420. // Ungrip
  421. Transition(STATE.Idle, MSG.Ungrip, fnUngrip, STATE.Ungripping);
  422. Transition(STATE.Ungripping, MSG.ActionDone, fnActionDone, STATE.Idle);
  423. Transition(STATE.Idle, MSG.Lift, fnLift, STATE.Lifting);
  424. //Transition(STATE.Lifting, MSG.LiftActionDone, fnActionDone, STATE.Idle);
  425. Transition(STATE.Lifting, FSM_MSG.TIMER, fnLiftTimeout, STATE.Idle);
  426. Transition(STATE.Idle, MSG.Align, fnAlign, STATE.Aligning);
  427. Transition(STATE.Aligning, FSM_MSG.TIMER, fnAlignTimeout, STATE.Idle);
  428. Transition(STATE.Aligning, MSG.ActionDone, fnActionDone, STATE.Idle);
  429. //MapDummy
  430. Transition(STATE.Idle, MSG.MapDummy, MapDummy, STATE.Mapping);
  431. Transition(STATE.Mapping, FSM_MSG.TIMER, MapDummyTimeout, STATE.Idle);
  432. //Resume
  433. Transition(STATE.Idle, MSG.MapDummy, MapDummy, STATE.Mapping);
  434. //Vacuum
  435. //Transition(STATE.Init, MSG.Vacuum, VacuumAction, STATE.Vacuuming);
  436. //Transition(STATE.Idle, MSG.Vacuum, VacuumAction, STATE.Vacuuming);
  437. //Transition(STATE.Error, MSG.Vacuum, VacuumAction, STATE.Vacuuming);
  438. //Transition(STATE.Vacuuming, FSM_MSG.TIMER, VacuumActionTimeout, STATE.Idle);
  439. //Retry
  440. Transition(STATE.Error, MSG.Retry, NullFunc, STATE.Retrying);
  441. Transition(STATE.Retrying, FSM_MSG.TIMER, EfemRetry, STATE.Retrying);
  442. Transition(STATE.Retrying, MSG.Align, RetryAlign, STATE.Aligning);
  443. Transition(STATE.Retrying, MSG.Pick, RetryPick, STATE.Picking);
  444. Transition(STATE.Retrying, MSG.Place, RetryPlace, STATE.Placing);
  445. //ConfirmComplete
  446. Transition(STATE.Init, MSG.ConfirmComplete, ClearModuleAlarm, STATE.Init);
  447. Transition(STATE.Idle, MSG.ConfirmComplete, ClearModuleAlarm, STATE.Idle);
  448. Transition(STATE.Error, MSG.ConfirmComplete, NullFunc, STATE.ConfirmCompleting);
  449. Transition(STATE.ConfirmCompleting, FSM_MSG.TIMER, ConfirmComplete, STATE.ConfirmCompleting);
  450. Transition(STATE.ConfirmCompleting, MSG.Align, ConfirmAlign, STATE.Idle);
  451. Transition(STATE.ConfirmCompleting, MSG.Pick, ConfirmPickup, STATE.Idle);
  452. Transition(STATE.ConfirmCompleting, MSG.Place, ConfirmPlace, STATE.Idle);
  453. EnumLoop<STATE>.ForEach((item) => { fsm.MapState((int)item, item.ToString()); });
  454. EnumLoop<MSG>.ForEach((item) => { fsm.MapMessage((int)item, item.ToString()); });
  455. Running = true;
  456. }
  457. private bool fnCommReady(object[] param)
  458. {
  459. return true;
  460. }
  461. private bool fnCloseBuzzer(object[] param)
  462. {
  463. return _efem.CloseBuzzer();
  464. }
  465. /// <summary>
  466. ///
  467. /// </summary>
  468. /// <param name="param"></param>
  469. /// <returns></returns>
  470. private bool EnterPause(object[] param)
  471. {
  472. return true;
  473. }
  474. private bool EnterResume(object[] param)
  475. {
  476. return true;
  477. }
  478. private bool fnResumeTimeout(object[] param)
  479. {
  480. _currentRoutine = _efemSafeCloseRoutine;
  481. RState ret = _efemSafeCloseRoutine.Monitor();
  482. if (ret == RState.Failed || ret == RState.Timeout)
  483. {
  484. _currentRoutine = null;
  485. PostMsg(MSG.Error);
  486. return false;
  487. }
  488. bool result = ret == RState.End;
  489. if (result)
  490. {
  491. _currentRoutine = null;
  492. }
  493. return result;
  494. }
  495. private bool fnHomeAll(object[] param)
  496. {
  497. _isHomed = false;
  498. return _homeRoutine.Start(ModuleName.EFEM) == RState.Running;
  499. }
  500. private bool fnHomingTimeout(object[] param)
  501. {
  502. _currentRoutine = _homeRoutine;
  503. RState ret = _homeRoutine.Monitor();
  504. if (ret == RState.Failed || ret == RState.Timeout)
  505. {
  506. _currentRoutine = null;
  507. PostMsg(MSG.Error);
  508. return false;
  509. }
  510. bool result= ret == RState.End;
  511. if(result)
  512. {
  513. _isHomed= true;
  514. RecoverLPStatus();
  515. _currentRoutine = null;
  516. }
  517. return result;
  518. }
  519. private void RecoverLPStatus()
  520. {
  521. _lpms[0].PostMsg(LoadPortModule.MSG.EnterIdle);
  522. _lpms[1].PostMsg(LoadPortModule.MSG.EnterIdle);
  523. _lpms[2].PostMsg(LoadPortModule.MSG.EnterIdle);
  524. }
  525. private bool Resume(object[] param)
  526. {
  527. return _efem.Resume();
  528. }
  529. private bool Pause(object[] param)
  530. {
  531. return _efem.Pause();
  532. }
  533. private bool fnHomeRobot(object[] param)
  534. {
  535. return _homeRoutine.Start(ModuleName.EfemRobot) == RState.Running;
  536. }
  537. private bool fnHomingRobotTimeout(object[] param)
  538. {
  539. _currentRoutine = _homeRoutine;
  540. RState ret = _homeRoutine.Monitor();
  541. if (ret == RState.Failed || ret == RState.Timeout)
  542. {
  543. PostMsg(MSG.Error);
  544. _currentRoutine = _homeRoutine;
  545. return false;
  546. }
  547. bool result = ret == RState.End;
  548. if (result)
  549. {
  550. _currentRoutine = null;
  551. AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), STATE.Idle.ToString());
  552. }
  553. return result;
  554. }
  555. private bool fnHomeAligner(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. return _homeRoutine.Start(unit) == RState.Running;
  566. }
  567. private bool fnHomingAlignTimeout(object[] param)
  568. {
  569. _currentRoutine = _homeRoutine;
  570. RState ret = _homeRoutine.Monitor();
  571. if (ret == RState.Failed || ret == RState.Timeout)
  572. {
  573. _currentRoutine = null;
  574. PostMsg(MSG.Error);
  575. return false;
  576. }
  577. bool result = ret == RState.End;
  578. if (result)
  579. {
  580. _currentRoutine = null;
  581. AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), STATE.Idle.ToString());
  582. }
  583. return result;
  584. }
  585. private bool fnActionDone(object[] param)
  586. {
  587. return false;
  588. }
  589. public bool CheckToPostMessage(int msg, params object[] args)
  590. {
  591. if (!fsm.FindTransition(fsm.State, msg))
  592. {
  593. LOG.Write(eEvent.WARN_EFEM_COMMON_WARN, ModuleName.EFEM, $"{Name} is in {(STATE)fsm.State} state,can not do {(MSG)msg}");
  594. return false;
  595. }
  596. Running = true;
  597. fsm.PostMsg(msg, args);
  598. return true;
  599. }
  600. private bool fnMonitor(object[] param)
  601. {
  602. if (_isVacuume)
  603. {
  604. bool result = VacuumActionTimeout();
  605. if (result)
  606. {
  607. _isVacuume = false;
  608. }
  609. }
  610. if (_isPause)
  611. {
  612. bool result = SafeOpenActionTimeout();
  613. if (result)
  614. {
  615. _isPause = false;
  616. }
  617. }
  618. if (_isResume)
  619. {
  620. bool result = SafeCloseActionTimeout();
  621. if (result)
  622. {
  623. _isResume = false;
  624. }
  625. }
  626. // robot idle check
  627. _robotIdleTrigger.CLK = _efem.Status != RState.Running;
  628. if (_robotIdleTrigger.Q)
  629. {
  630. _robotWatch.Restart();
  631. LOG.WriteLog(eEvent.EV_EFEM_ROBOT, Module.ToString(), $"robot status changed to {_efem.Status}");
  632. }
  633. _autoMessageProcessor.Monitor();
  634. return true;
  635. }
  636. private bool fnOnline(object[] param)
  637. {
  638. bool bOnlineFlag = (bool)param[0];
  639. if (_efem is EfemBase efem)
  640. {
  641. efem.SetOnline(bOnlineFlag);
  642. }
  643. IsOnline = bOnlineFlag;
  644. return true;
  645. }
  646. private string GetFsmLastMessage()
  647. {
  648. int msg = fsm.LastMsg;
  649. if (msg >= (int)MSG.HomeAll && msg <= (int)MSG.Error)
  650. return ((MSG)msg).ToString();
  651. if (msg == (int)FSM_MSG.TIMER)
  652. return "Timer";
  653. return msg.ToString();
  654. }
  655. private bool fnError(object[] param)
  656. {
  657. _errorPreState = (STATE)fsm.State;
  658. string error = (param != null && param.Length != 0) ? param[0].ToString() : "";
  659. if (Singleton<RouteManager>.Instance.IsAutoMode)
  660. {
  661. int msg = 0;
  662. if (_errorPreState == STATE.Picking)
  663. {
  664. msg = (int)MSG.Pick;
  665. }
  666. else if (_errorPreState == STATE.Aligning)
  667. {
  668. msg = (int)MSG.Align;
  669. }
  670. else if (_errorPreState == STATE.Placing)
  671. {
  672. msg = (int)MSG.Place;
  673. }
  674. else
  675. {
  676. error = $"{error}\r\n Plase Home Robot back to idle state";
  677. return true;
  678. }
  679. AlarmList alarmList = new AlarmList(Module.ToString(), ((STATE)fsm.State).ToString(), msg,
  680. error, 0, (int)AlarmType.Error);
  681. AlarmListManager.Instance.AddAlarm(alarmList);
  682. }
  683. return true;
  684. }
  685. private bool fnToInit(object[] param)
  686. {
  687. return true;
  688. }
  689. private bool fnRecover(object[] param)
  690. {
  691. bool result=_efem.ClearError();
  692. if (result)
  693. {
  694. PostMsg(MSG.ToInit);
  695. }
  696. return result;
  697. }
  698. private bool fnAbortRobot(object[] param)
  699. {
  700. //_efem.ExecuteAction();
  701. if (_currentRoutine != null)
  702. {
  703. _currentRoutine.Abort();
  704. }
  705. _efem.Halt();
  706. return true;
  707. }
  708. private bool fnBackroundCommand(object[] param)
  709. {
  710. _autoMessageProcessor.SendAutoCommandMessage(param);
  711. return true;
  712. }
  713. private bool fnRobotPowerOn(object[] param)
  714. {
  715. return _efem.RobotPowerOn(ModuleName.EfemRobot, (bool)param[0]);
  716. }
  717. private bool fnSetLED(object[] param)
  718. {
  719. LightType light = (LightType)param[0];
  720. LightStatus st = (LightStatus)param[1];
  721. return _efem.SetLamp(light, st);
  722. }
  723. private bool fnTurnOffBuzzer(object[] param)
  724. {
  725. return false;
  726. }
  727. private bool FnStartPick(object[] param)
  728. {
  729. return _pickRoutine.Start(param) == RState.Running;
  730. }
  731. private bool FnStartRobotCycle(object[] param)
  732. {
  733. return _cycleRobotCycleRoutine.Start(param) == RState.Running;
  734. }
  735. private bool FnErrorStartPick(object[] param)
  736. {
  737. if (!_isHomed)
  738. {
  739. LOG.WriteLog(eEvent.ERR_EFEM_ROBOT, Module.ToString(), "EFEM is not homed");
  740. return false;
  741. }
  742. _efem.Reset();
  743. return _pickRoutine.Start(param) == RState.Running;
  744. }
  745. /// <summary>
  746. /// Retry Pick
  747. /// </summary>
  748. /// <param name="param"></param>
  749. /// <returns></returns>
  750. private bool RetryPick(object[] param)
  751. {
  752. int stepIndex = (int)param[0];
  753. return _pickRoutine.Retry(stepIndex) == RState.Running;
  754. }
  755. private bool FnPickTimeout(object[] param)
  756. {
  757. _currentRoutine = _pickRoutine;
  758. RState ret = _pickRoutine.Monitor();
  759. if (ret == RState.Failed || ret == RState.Timeout)
  760. {
  761. PostMsg(MSG.Error,_pickRoutine.ErrorMsg);
  762. _currentRoutine = null;
  763. return false;
  764. }
  765. if (ret == RState.End)
  766. {
  767. _currentRoutine = null;
  768. AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), STATE.Picking.ToString());
  769. }
  770. return ret == RState.End;
  771. }
  772. private bool FnRobotCycleTimeout(object[] param)
  773. {
  774. RState ret = _cycleRobotCycleRoutine.Monitor();
  775. if (ret == RState.Failed || ret == RState.Timeout)
  776. {
  777. PostMsg(MSG.Error);
  778. return false;
  779. }
  780. _currentCycleTimes = _cycleRobotCycleRoutine.GetCurrentCycle();
  781. return ret == RState.End;
  782. }
  783. private bool FnErrorPickTimeout(object[] param)
  784. {
  785. RState ret = _pickRoutine.Monitor();
  786. if (ret == RState.Failed || ret == RState.Timeout)
  787. {
  788. PostMsg(MSG.Error, _pickRoutine.ErrorMsg);
  789. return false;
  790. }
  791. return ret == RState.End;
  792. }
  793. /// <summary>
  794. /// 确认Pick是否完成
  795. /// </summary>
  796. /// <param name="param"></param>
  797. /// <returns></returns>
  798. private bool ConfirmPickup(object[] param)
  799. {
  800. int stepIdex = (int)param[0];
  801. bool result = _pickRoutine.CheckCompleteCondition(stepIdex);
  802. if (!result)
  803. {
  804. PostMsg(MSG.Error,_pickRoutine.ErrorMsg);
  805. }
  806. else
  807. {
  808. if (Singleton<RouteManager>.Instance.IsAutoRunning)
  809. {
  810. AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), STATE.Picking.ToString());
  811. }
  812. }
  813. return result;
  814. }
  815. private bool FnAbortPick(object[] param)
  816. {
  817. _pickRoutine.Abort();
  818. return true;
  819. }
  820. private bool FnAbortRobotCycle(object[] param)
  821. {
  822. _cycleRobotCycleRoutine.Abort();
  823. return true;
  824. }
  825. private bool FnErrorAbortPick(object[] param)
  826. {
  827. _pickRoutine.Abort();
  828. return true;
  829. }
  830. private bool FnStartPlace(object[] param)
  831. {
  832. return _placeRoutine.Start(param) == RState.Running;
  833. }
  834. private bool FnErrorStartPlace(object[] param)
  835. {
  836. if(!_isHomed)
  837. {
  838. LOG.WriteLog(eEvent.ERR_EFEM_ROBOT, Module.ToString(), "EFEM is not homed");
  839. return false;
  840. }
  841. _efem.Reset();
  842. return _placeRoutine.Start(param) == RState.Running;
  843. }
  844. /// <summary>
  845. /// Retry Place
  846. /// </summary>
  847. /// <param name="param"></param>
  848. /// <returns></returns>
  849. private bool RetryPlace(object[] param)
  850. {
  851. int stepIndex = (int)param[0];
  852. return _placeRoutine.Retry(stepIndex) == RState.Running;
  853. }
  854. private bool FnPlaceTimeout(object[] param)
  855. {
  856. _currentRoutine = _placeRoutine;
  857. RState ret = _placeRoutine.Monitor();
  858. if (ret == RState.Failed || ret == RState.Timeout)
  859. {
  860. _currentRoutine = null;
  861. PostMsg(MSG.Error,_placeRoutine.ErrorMsg);
  862. return false;
  863. }
  864. if (ret == RState.End)
  865. {
  866. _currentRoutine = null;
  867. AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), STATE.Placing.ToString());
  868. }
  869. return ret == RState.End;
  870. }
  871. private bool FnErrorPlaceTimeout(object[] param)
  872. {
  873. RState ret = _placeRoutine.Monitor();
  874. if (ret == RState.Failed || ret == RState.Timeout)
  875. {
  876. PostMsg(MSG.Error, _placeRoutine.ErrorMsg);
  877. return false;
  878. }
  879. return ret == RState.End;
  880. }
  881. /// <summary>
  882. /// 确认Place是否完成
  883. /// </summary>
  884. /// <param name="param"></param>
  885. /// <returns></returns>
  886. private bool ConfirmPlace(object[] param)
  887. {
  888. int stepIdex = (int)param[0];
  889. bool result = _placeRoutine.CheckCompleteCondition(stepIdex);
  890. if (!result)
  891. {
  892. PostMsg(MSG.Error, _placeRoutine.ErrorMsg);
  893. }
  894. else
  895. {
  896. if (Singleton<RouteManager>.Instance.IsAutoRunning)
  897. {
  898. AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), STATE.Picking.ToString());
  899. }
  900. }
  901. return result;
  902. }
  903. private bool FnAbortPlace(object[] param)
  904. {
  905. _placeRoutine.Abort();
  906. return true;
  907. }
  908. private bool FnErrorAbortPlace(object[] param)
  909. {
  910. _placeRoutine.Abort();
  911. return true;
  912. }
  913. private bool fnGoto(object[] param)
  914. {
  915. // module
  916. ModuleName unit = ModuleName.EFEM;
  917. if (param[0] is string s1)
  918. unit = ModuleNameString.ToEnum(s1);
  919. else if (param[0] is ModuleName mod)
  920. unit = mod;
  921. else
  922. throw new ArgumentException("Argument error");
  923. _efem.Goto(unit, Hand.Blade1);
  924. return true;
  925. }
  926. private bool fnLift(object[] param)
  927. {
  928. // module
  929. ModuleName unit = ModuleName.EFEM;
  930. if (param[0] is string s1)
  931. unit = ModuleNameString.ToEnum(s1);
  932. else if (param[0] is ModuleName mod)
  933. unit = mod;
  934. else
  935. throw new ArgumentException("Argument error");
  936. bool isUp = true;
  937. if (param.Length > 1)
  938. {
  939. isUp = (bool) param[1];
  940. }
  941. if (isUp)
  942. {
  943. if (!_efem.SetPinUp(unit))
  944. return false;
  945. }
  946. else
  947. {
  948. if (!_efem.SetPinDown(unit))
  949. return false;
  950. }
  951. LiftMessage = isUp ? "Up" : "Down";
  952. return true;
  953. }
  954. private bool fnLiftTimeout(object[] param)
  955. {
  956. if (LiftMessage == "Up")
  957. {
  958. return _efem.LiftIsDown == false && _efem.LiftIsUp == true;
  959. }
  960. else if (LiftMessage == "Down")
  961. {
  962. return _efem.LiftIsDown == true && _efem.LiftIsUp == false;
  963. }
  964. return false;
  965. }
  966. private bool fnAlign(object[] param)
  967. {
  968. return _alignRoutine.Start(param) == RState.Running;
  969. }
  970. private bool fnAlignTimeout(object[] param)
  971. {
  972. _currentRoutine = _alignRoutine;
  973. RState ret = _alignRoutine.Monitor();
  974. if (ret == RState.Failed || ret == RState.Timeout)
  975. {
  976. _currentRoutine = null;
  977. PostMsg(MSG.Error,_alignRoutine.ErrorMsg);
  978. return false;
  979. }
  980. if (ret == RState.End)
  981. {
  982. _currentRoutine = null;
  983. AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), STATE.Aligning.ToString());
  984. }
  985. return ret == RState.End;
  986. }
  987. /// <summary>
  988. /// Retry Align
  989. /// </summary>
  990. /// <param name="param"></param>
  991. /// <returns></returns>
  992. private bool RetryAlign(object[] param)
  993. {
  994. int stepIndex = (int)param[0];
  995. return _alignRoutine.Retry(stepIndex) == RState.Running;
  996. }
  997. /// <summary>
  998. /// 确认Align是否完成
  999. /// </summary>
  1000. /// <param name="param"></param>
  1001. /// <returns></returns>
  1002. private bool ConfirmAlign(object[] param)
  1003. {
  1004. int stepIdex = (int)param[0];
  1005. bool result = _alignRoutine.CheckCompleteCondition(stepIdex);
  1006. if (!result)
  1007. {
  1008. PostMsg(MSG.Error, _alignRoutine.ErrorMsg);
  1009. }
  1010. else
  1011. {
  1012. if (Singleton<RouteManager>.Instance.IsAutoRunning)
  1013. {
  1014. AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), STATE.Aligning.ToString());
  1015. }
  1016. }
  1017. return result;
  1018. }
  1019. private bool MapDummyTimeout(object[] param)
  1020. {
  1021. RState ret = _mapDummyRoutine.Monitor();
  1022. if (ret == RState.Failed || ret == RState.Timeout)
  1023. {
  1024. PostMsg(MSG.Error);
  1025. return false;
  1026. }
  1027. return ret == RState.End;
  1028. }
  1029. private bool VacuumActionTimeout()
  1030. {
  1031. RState ret = _vacuumRoutine.Monitor();
  1032. if (ret == RState.Failed || ret == RState.Timeout)
  1033. {
  1034. LOG.Write(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EFEM, "Vacuum");
  1035. return false;
  1036. }
  1037. return ret == RState.End;
  1038. }
  1039. private bool SafeOpenActionTimeout()
  1040. {
  1041. RState ret = _efemSafeOpenRoutine.Monitor();
  1042. if (ret == RState.Failed || ret == RState.Timeout)
  1043. {
  1044. LOG.Write(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EFEM, "SafeOpen Failed");
  1045. return false;
  1046. }
  1047. return ret == RState.End;
  1048. }
  1049. private bool SafeCloseActionTimeout()
  1050. {
  1051. RState ret = _efemSafeCloseRoutine.Monitor();
  1052. if (ret == RState.Failed || ret == RState.Timeout)
  1053. {
  1054. LOG.Write(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EFEM, "SafeClose Failed");
  1055. return false;
  1056. }
  1057. return ret == RState.End;
  1058. }
  1059. private bool fnMap(object[] param)
  1060. {
  1061. // module
  1062. ModuleName unit = ModuleName.EFEM;
  1063. if (param[0] is string s1)
  1064. unit = ModuleNameString.ToEnum(s1);
  1065. else if (param[0] is ModuleName mod)
  1066. unit = mod;
  1067. else
  1068. throw new ArgumentException("Argument error");
  1069. if (!_efem.Map(unit))
  1070. return false;
  1071. return true;
  1072. }
  1073. private bool MapDummy(object[] param)
  1074. {
  1075. return _mapDummyRoutine.Start()==RState.Running;
  1076. }
  1077. private bool VacuumAction(object[] param)
  1078. {
  1079. ModuleName vacuumModule = (ModuleName)param[0];
  1080. bool vacuum=(bool)param[1];
  1081. bool result = _vacuumRoutine.Start(vacuumModule, vacuum) == RState.Running;
  1082. if (result)
  1083. {
  1084. _isVacuume = true;
  1085. }
  1086. return result;
  1087. }
  1088. private bool SafeOpenAction(object[] param)
  1089. {
  1090. bool result = _efemSafeOpenRoutine.Start() == RState.Running;
  1091. if (result)
  1092. {
  1093. _isPause = true;
  1094. }
  1095. return result;
  1096. }
  1097. private bool SafeCloseAction(object[] param)
  1098. {
  1099. bool result = _efemSafeCloseRoutine.Start() == RState.Running;
  1100. if (result)
  1101. {
  1102. _isResume = true;
  1103. }
  1104. return result;
  1105. }
  1106. public bool DoorUnlock(object[] param)
  1107. {
  1108. bool unlock = (bool)param[0];
  1109. string ioName = BeckhoffModuleIOManager.Instance.GetIoNameByInnerModuleName($"{Module}.{DOOR_UNLOCK}");
  1110. if (!string.IsNullOrEmpty(ioName))
  1111. {
  1112. return IOModuleManager.Instance.WriteIoValue(ioName, unlock);
  1113. }
  1114. return true;
  1115. }
  1116. private bool fnGrip(object[] param)
  1117. {
  1118. Hand arm = (Hand)Enum.Parse(typeof(Hand), (string)param[0]);
  1119. if (!_efem.Grip(arm, true))
  1120. return false;
  1121. return true;
  1122. }
  1123. public int SendEfemAutoCommand(params object[] args)
  1124. {
  1125. if (CheckToPostMessage((int)MSG.BackroundCmd, args))
  1126. return (int)MSG.BackroundCmd;
  1127. return (int)FSM_MSG.NONE;
  1128. }
  1129. private bool fnUngrip(object[] param)
  1130. {
  1131. Hand arm = (Hand)Enum.Parse(typeof(Hand), (string)param[0]);
  1132. if (!_efem.Grip(arm, false))
  1133. return false;
  1134. return true;
  1135. }
  1136. #region EfemRetry
  1137. /// <summary>
  1138. /// Retry
  1139. /// </summary>
  1140. /// <param name="param"></param>
  1141. /// <returns></returns>
  1142. private bool EfemRetry(object[] param)
  1143. {
  1144. AlarmList alarmList = AlarmListManager.Instance.GetAlarmListByModule(Module.ToString());
  1145. if (alarmList != null)
  1146. {
  1147. CheckToPostMessage<STATE, MSG>(eEvent.ERR_EFEM_ROBOT, Module.ToString(), alarmList.ModuleCmd,
  1148. alarmList.ModuleStep);
  1149. }
  1150. return false;
  1151. }
  1152. #endregion
  1153. #region ConfirmComplete
  1154. /// <summary>
  1155. /// 确认是否完成
  1156. /// </summary>
  1157. /// <param name="param"></param>
  1158. /// <returns></returns>
  1159. private bool ConfirmComplete(object[] param)
  1160. {
  1161. AlarmList alarmList = AlarmListManager.Instance.GetAlarmListByModule(Module.ToString());
  1162. if (alarmList != null)
  1163. {
  1164. if (alarmList.ModuleState == STATE.Picking.ToString())
  1165. {
  1166. CheckToPostMessage<STATE, MSG>(eEvent.ERR_EFEM_ROBOT, Module.ToString(), (int)MSG.Pick, alarmList.ModuleStep);
  1167. }
  1168. else if (alarmList.ModuleState == STATE.Placing.ToString())
  1169. {
  1170. CheckToPostMessage<STATE, MSG>(eEvent.ERR_EFEM_ROBOT, Module.ToString(), (int)MSG.Place, alarmList.ModuleStep);
  1171. }
  1172. else if (alarmList.ModuleState == STATE.Aligning.ToString())
  1173. {
  1174. CheckToPostMessage<STATE, MSG>(eEvent.ERR_EFEM_ROBOT, Module.ToString(), (int)MSG.Align, alarmList.ModuleStep);
  1175. }
  1176. else
  1177. {
  1178. PostMsg(EFEMSTATE.Error);
  1179. }
  1180. }
  1181. return false;
  1182. }
  1183. /// <summary>
  1184. /// 清除报警
  1185. /// </summary>
  1186. /// <param name="param"></param>
  1187. /// <returns></returns>
  1188. private bool ClearModuleAlarm(object[] param)
  1189. {
  1190. AlarmList alarmList = AlarmListManager.Instance.GetAlarmListByModule(Module.ToString());
  1191. if (alarmList != null)
  1192. {
  1193. AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), "");
  1194. }
  1195. return true;
  1196. }
  1197. #endregion
  1198. public int Invoke(string function, params object[] args)
  1199. {
  1200. switch (function)
  1201. {
  1202. case "HomeAll":
  1203. if (IsIdle)
  1204. {
  1205. return (int)FSM_MSG.NONE;
  1206. }
  1207. if (CheckToPostMessage((int)MSG.HomeAll))
  1208. {
  1209. return (int)MSG.HomeAll;
  1210. }
  1211. else
  1212. {
  1213. return (int)FSM_MSG.NONE;
  1214. }
  1215. case "Retry":
  1216. if (CheckToPostMessage<STATE, MSG>(eEvent.ERR_EFEM_ROBOT, Module.ToString(), (int)MSG.Retry, args))
  1217. {
  1218. return (int)MSG.Retry;
  1219. }
  1220. else
  1221. {
  1222. return (int)FSM_MSG.NONE;
  1223. }
  1224. case "ConfirmComplete":
  1225. if (CheckToPostMessage<STATE, MSG>(eEvent.ERR_EFEM_ROBOT, Module.ToString(), (int)MSG.ConfirmComplete, args))
  1226. {
  1227. return (int)MSG.ConfirmComplete;
  1228. }
  1229. else
  1230. {
  1231. return (int)FSM_MSG.NONE;
  1232. }
  1233. }
  1234. return (int)FSM_MSG.NONE;
  1235. }
  1236. public bool CheckAcked(int msg)
  1237. {
  1238. return fsm.CheckExecuted(msg);
  1239. }
  1240. internal void InvokeReset()
  1241. {
  1242. if (fsm.State == (int) STATE.Error)
  1243. {
  1244. PostMsg((int)MSG.Recover);
  1245. }
  1246. }
  1247. public int InvokeAlign(string module, int reserv, float time)
  1248. {
  1249. if (CheckToPostMessage((int)MSG.Align, module, reserv, time))
  1250. return (int)MSG.Align;
  1251. return (int)FSM_MSG.NONE;
  1252. }
  1253. public int InvokeLiftDown(string module)
  1254. {
  1255. if (CheckToPostMessage((int)MSG.Lift, module, false))
  1256. return (int)MSG.Lift;
  1257. return (int)FSM_MSG.NONE;
  1258. }
  1259. public int InvokePick(ModuleName source, int slot, Hand hand, WaferSize size)
  1260. {
  1261. if (CheckToPostMessage((int)MSG.Pick, source, slot, hand, size))
  1262. return (int)MSG.Pick;
  1263. return (int)FSM_MSG.NONE;
  1264. }
  1265. public int InvokeGoto(ModuleName source, int slot)
  1266. {
  1267. if (CheckToPostMessage((int)MSG.Goto, source, slot))
  1268. return (int)MSG.Goto;
  1269. return (int)FSM_MSG.NONE;
  1270. }
  1271. public int InvokePlace(ModuleName target, int slot, Hand hand, WaferSize size)
  1272. {
  1273. if (CheckToPostMessage((int)MSG.Place, target, slot, hand, size))
  1274. return (int)MSG.Place;
  1275. return (int)FSM_MSG.NONE;
  1276. }
  1277. public int InvokePickAndPlace(ModuleName targetModule, Hand pickHand, int pickSlot, Hand placeHand, int placeSlot, WaferSize size)
  1278. {
  1279. if (CheckToPostMessage((int)MSG.Swap, targetModule, pickSlot, pickHand, placeHand, placeSlot, size))
  1280. return (int)MSG.Swap;
  1281. return (int)FSM_MSG.NONE;
  1282. }
  1283. public int InvokeMap(string target )
  1284. {
  1285. if (CheckToPostMessage((int)MSG.Map, target ))
  1286. return (int)MSG.Map;
  1287. return (int)FSM_MSG.NONE;
  1288. }
  1289. public int InvokeFlip(Hand hand)
  1290. {
  1291. if (CheckToPostMessage((int)MSG.Flip, hand))
  1292. return (int)MSG.Flip;
  1293. return (int)FSM_MSG.NONE;
  1294. }
  1295. public bool IsPrepareTransferReady(ModuleName module, EnumTransferType type, int slot)
  1296. {
  1297. //if (type == EnumTransferType.Pick)
  1298. //{
  1299. // //需要补充:判断LP 放好了,而且已经map过。
  1300. // return _efem[module].HasCassette && _efem[module].IsMapped;
  1301. //}
  1302. //else if (type == EnumTransferType.Place)
  1303. //{
  1304. // //需要补充:判断LP 放好了,而且已经map过。
  1305. // return _efem[module].HasCassette && _efem[module].IsMapped;
  1306. //}
  1307. return false;
  1308. }
  1309. internal bool CheckReadyRunNewJob(ModuleName module)
  1310. {
  1311. //???
  1312. return true;
  1313. }
  1314. internal bool CheckReadyTransfer(ModuleName module)
  1315. {
  1316. //return _efem[module].HasCassette && _efem[module].IsMapped;
  1317. return true;
  1318. }
  1319. internal bool CheckPlaced(ModuleName module)
  1320. {
  1321. //return _efem[module].HasCassette;
  1322. return true;
  1323. }
  1324. internal void NoteJobStart(ModuleName module)
  1325. {
  1326. //_efem[module].NoteJobStart();
  1327. }
  1328. internal void NoteJobComplete(ModuleName module)
  1329. {
  1330. //_efem[module].NoteJobComplete();
  1331. }
  1332. }
  1333. }