using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Fsm; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.Utilities; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Schedulers; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.ModuleLibrary.VceModules; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Windows; using Venus_Core; using Venus_RT.Devices; using Venus_RT.Devices.VCE; using Venus_RT.Modules.PMs; using Venus_RT.Modules.TM; using Venus_RT.Modules.TM.VenusEntity; namespace Venus_RT.Modules.VCE { #region 状态和消息 public enum VceSTATE { Init,//初始化 Idle,//空闲 Error,//错误 Homing,//home操作 对应HM DoorOpenning,//开门操作 对应DC DoorClosing,//关门操作 对应DO Loading,//取cassette操作 包括开门关门 对应LOAD, UnLoading, Mapping,//扫片 ReadingMap, //对应MP 包括三种格式 hex binary 智能(只有智能模式可以判断复杂情况) Goting,//指定槽到达窗口 对应 GC GotingLP, Resetting,//重置 LoadingWithoutSMIF,//没有SMIF的load LoadPreparing,//准备 SafeLoading, SafeUnloading, Pumping, Venting, Unknown } public enum VceMSG { Home, Error, DoorOpen, DoorClose, Map, ReadMap, Load, UnLoad, LoadPrepare, LoadWithoutSMIF, Reset, Goto, GotoLP, SafeLoad, SafeUnload, Pump, Vent, Abort, None } #endregion public class VceEntity : Entity, IEntity, IModuleEntity { private ModuleName _modulename; private readonly VceModuleBase _vce; private bool _vceoutdoorclosed; public bool IsIdle => fsm.State == (int)VceSTATE.Idle; public bool IsInit => fsm.State == (int)VceSTATE.Init || fsm.State == (int)VceSTATE.Unknown; public bool IsBusy => !IsInit && !IsError && !IsIdle; public bool IsError => fsm.State == (int)VceSTATE.Error; public bool VCEOutDoorClosed => _vceoutdoorclosed; private int currentSlot; private int targetSlot; private LoadRoutine _loadRoutine; private LoadPrepareRoutine _prepareRoutine; private UnloadRoutine _unloadRoutine; private readonly SEMFPumpRoutine _pumpRoutine; private readonly SEMFVentRoutine _ventRoutine; public VceEntity(ModuleName moduleName) { currentSlot = 0; _modulename = moduleName; _vce = new HongHuVce(25, _modulename); _vceoutdoorclosed = true;//初始状态outdoor是关闭 _loadRoutine = new LoadRoutine(_modulename,_vce); _prepareRoutine = new LoadPrepareRoutine(_modulename,_vce); _unloadRoutine = new UnloadRoutine(_modulename, _vce); _pumpRoutine = new SEMFPumpRoutine(DEVICE.GetDevice("SETM"), _modulename); _ventRoutine = new SEMFVentRoutine(DEVICE.GetDevice("SETM"), _modulename); InitFsmMap(); } protected override bool Init() { DATA.Subscribe($"{_modulename}.VCEOutDoorClosed", () => !VCEOutDoorClosed); DATA.Subscribe($"{_modulename}.CurrentSlot", () => currentSlot); DATA.Subscribe($"{_modulename}.FsmState", () => ((VceSTATE)fsm.State).ToString()); //DATA.Subscribe($"{_modulename}.IsRunning", () => IsIdle); //DATA.Subscribe($"{_modulename}.IsRunning", () => IsIdle); OP.Subscribe($"{_modulename}.HOME", (cmd,args) => { PostMsg(VceMSG.Home);return true; }); OP.Subscribe($"{_modulename}.DoorOpen", (cmd,args) => { PostMsg(VceMSG.DoorOpen);return true; }); OP.Subscribe($"{_modulename}.DoorClose", (cmd,args) => { PostMsg(VceMSG.DoorClose);return true; }); OP.Subscribe($"{_modulename}.Map", (cmd,args) => { PostMsg(VceMSG.Map);return true; }); OP.Subscribe($"{_modulename}.ReadMap", (cmd,args) => { PostMsg(VceMSG.ReadMap);return true; }); OP.Subscribe($"{_modulename}.Load", (cmd,args) => { PostMsg(VceMSG.Load);return true; }); OP.Subscribe($"{_modulename}.UnLoad", (cmd,args) => { PostMsg(VceMSG.UnLoad);return true; }); OP.Subscribe($"{_modulename}.Reset", (cmd,args) => { PostMsg(VceMSG.Reset);return true; }); OP.Subscribe($"{_modulename}.Goto", (cmd,args) => { PostMsg(VceMSG.Goto, args[0]);return true; }); OP.Subscribe($"{_modulename}.GotoLP", (cmd, args) => { PostMsg(VceMSG.GotoLP); return true; }); OP.Subscribe($"{_modulename}.Abort", (cmd, args) => { PostMsg(VceMSG.Abort); return true; }); OP.Subscribe($"{_modulename}.PumpDown", (cmd, args) => { PostMsg(VceMSG.Pump); return true; }); OP.Subscribe($"{_modulename}.Vent", (cmd, args) => { PostMsg(VceMSG.Vent); return true; }); OP.Subscribe($"{_modulename}.LoadPrepare", (cmd, args) => { PostMsg(VceMSG.LoadPrepare); return true; }); OP.Subscribe($"{_modulename}.SafeLoad", (cmd, args) => { PostMsg(VceMSG.SafeLoad); return true; }); OP.Subscribe($"{_modulename}.SafeUnload", (cmd, args) => { PostMsg(VceMSG.SafeUnload); return true; }); return true; } /// /// 定义状态机的迁移表 /// private void InitFsmMap() { fsm = new StateMachine(_modulename.ToString(), (int)VceSTATE.Init, 50); fsm.EnableRepeatedMsg(true); AnyStateTransition(VceMSG.Error, fnError, VceSTATE.Error); AnyStateTransition(VceMSG.Abort, fnAbort, VceSTATE.Idle); AnyStateTransition(VceMSG.Home, fnStartHome, VceSTATE.Homing); //HOME init->homing idle->homing Transition(VceSTATE.Init, VceMSG.Home, fnStartHome, VceSTATE.Homing); Transition(VceSTATE.Idle, VceMSG.Home, fnStartHome, VceSTATE.Homing); Transition(VceSTATE.Error, VceMSG.Home, fnStartHome, VceSTATE.Homing); Transition(VceSTATE.Homing, FSM_MSG.TIMER, fnHomeTimeout, VceSTATE.Idle); //Open Door 开门 Transition(VceSTATE.Idle, VceMSG.DoorOpen, fnStartOpenDoor, VceSTATE.DoorOpenning); Transition(VceSTATE.DoorOpenning, FSM_MSG.TIMER, fnOpenDoorTimeout, VceSTATE.Idle); //Close Door 关门 Transition(VceSTATE.Idle, VceMSG.DoorClose, fnStartCloseDoor, VceSTATE.DoorClosing); Transition(VceSTATE.DoorClosing, FSM_MSG.TIMER, fnCloseDoorTimeout, VceSTATE.Idle); //Map 扫片 Transition(VceSTATE.Idle, VceMSG.Map, fnStartMapping, VceSTATE.Mapping); Transition(VceSTATE.Mapping, FSM_MSG.TIMER, fnMappingTimeout, VceSTATE.Idle); //Load 取cassette Transition(VceSTATE.Idle, VceMSG.Load, fnStartLoading, VceSTATE.Loading); Transition(VceSTATE.Loading, FSM_MSG.TIMER, fnLoadingTimeout, VceSTATE.Idle); //UnLoad 放cassette Transition(VceSTATE.Idle, VceMSG.UnLoad, fnStartUnLoading, VceSTATE.UnLoading); Transition(VceSTATE.UnLoading, FSM_MSG.TIMER, fnUnLoadingTimeout, VceSTATE.Idle); //Goto 指定槽对准窗口 Transition(VceSTATE.Idle, VceMSG.Goto, fnStartGoto, VceSTATE.Goting); Transition(VceSTATE.Goting, FSM_MSG.TIMER, fnGotingTimeout, VceSTATE.Idle); //ReadMap Transition(VceSTATE.Idle, VceMSG.ReadMap, fnStartReadingMap, VceSTATE.ReadingMap); Transition(VceSTATE.ReadingMap, FSM_MSG.TIMER, fnReadingMapTimeout, VceSTATE.Idle); //Load Prepare Transition(VceSTATE.Idle, VceMSG.LoadPrepare,fnStartLoadPrepare,VceSTATE.LoadPreparing) ; Transition(VceSTATE.LoadPreparing, FSM_MSG.TIMER, fnLoadingPrepareTimeout,VceSTATE.Idle) ; //Safe Load Transition(VceSTATE.Idle,VceMSG.SafeLoad,fnStartSafeLoad,VceSTATE.SafeLoading) ; Transition(VceSTATE.SafeLoading, FSM_MSG.TIMER,fnSafeLoadTimeout,VceSTATE.Idle); //Safe UnLoad Transition(VceSTATE.Idle, VceMSG.SafeUnload, fnStartSafeUnLoad, VceSTATE.SafeUnloading); Transition(VceSTATE.SafeUnloading, FSM_MSG.TIMER, fnSafeUnLoadTimeout, VceSTATE.Idle); //Goto LP Transition(VceSTATE.Idle, VceMSG.GotoLP, fnStartGotoLP, VceSTATE.GotingLP); Transition(VceSTATE.GotingLP, FSM_MSG.TIMER, fnGotoLPTimeout, VceSTATE.Idle); //Pump down //Pump Transition(VceSTATE.Idle, VceMSG.Pump, fnStartPump, VceSTATE.Pumping); Transition(VceSTATE.Pumping, FSM_MSG.TIMER, fnPumpTimeout, VceSTATE.Idle); Transition(VceSTATE.Pumping, VceMSG.Abort, fnAbortPump, VceSTATE.Idle); //Vent Transition(VceSTATE.Idle, VceMSG.Vent, fnStartVent, VceSTATE.Venting); Transition(VceSTATE.Venting, FSM_MSG.TIMER, fnVentTimeout, VceSTATE.Idle); Transition(VceSTATE.Venting, VceMSG.Abort, fnAbortVent, VceSTATE.Idle); EnumLoop.ForEach((item) => { fsm.MapState((int)item, item.ToString()); }); EnumLoop.ForEach((item) => { fsm.MapMessage((int)item, item.ToString()); }); Running = true; } private bool fnAbortVent(object[] param) { _ventRoutine.Abort(); return true; } private bool fnVentTimeout(object[] param) { RState ret = _ventRoutine.Monitor(); if (ret == RState.Timeout || ret == RState.Failed) { PostMsg(VceMSG.Error); return false; } return ret == RState.End; } private bool fnStartVent(object[] param) { return _ventRoutine.Start(param) == RState.Running; } private bool fnAbortPump(object[] param) { _pumpRoutine.Abort(); return true; } private bool fnPumpTimeout(object[] param) { RState ret = _pumpRoutine.Monitor(); if (ret == RState.Timeout || ret == RState.Failed) { PostMsg(VceMSG.Error); return false; } return ret == RState.End; } private bool fnStartPump(object[] param) { return _pumpRoutine.Start(param) == RState.Running; } private bool fnGotoLPTimeout(object[] param) { if (_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } if (_vce.Status == RState.End) { currentSlot = targetSlot; } return _vce.Status == RState.End; } private bool fnStartGotoLP(object[] param) { if (_vce.GotoLP()) { targetSlot = -1; return true; } else return false; } private bool fnSafeUnLoadTimeout(object[] param) { RState ret = _unloadRoutine.Monitor(); if (ret == RState.Timeout || ret == RState.Failed) { PostMsg(VceMSG.Error); return false; } return ret == RState.End; } private bool fnStartSafeUnLoad(object[] param) { return _unloadRoutine.Start(param) == RState.Running; } private bool fnSafeLoadTimeout(object[] param) { RState ret = _loadRoutine.Monitor(); if (ret == RState.Timeout || ret == RState.Failed) { PostMsg(VceMSG.Error); return false; } return ret == RState.End; } private bool fnStartSafeLoad(object[] param) { return _loadRoutine.Start(param) == RState.Running; } private bool fnLoadingPrepareTimeout(object[] param) { RState ret = _prepareRoutine.Monitor(); if (ret == RState.Timeout || ret == RState.Failed) { PostMsg(VceMSG.Error); return false; } return ret == RState.End; } private bool fnStartLoadPrepare(object[] param) { return _prepareRoutine.Start(param) == RState.Running; } private bool fnReadingMapTimeout(object[] param) { if (_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } return _vce.Status == RState.End; } private bool fnStartReadingMap(object[] param) { return _vce.ReadMap(); } //急停 private bool fnAbort(object[] param) { return true; } //升降到槽位 private bool fnStartGoto(object[] param) { if (_vce.Goto(Convert.ToInt32(param[0]))) { targetSlot = Convert.ToInt32(param[0]); return true; } else return false; } private bool fnGotingTimeout(object[] param) { if (_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } if(_vce.Status == RState.End) currentSlot = targetSlot; return _vce.Status == RState.End; } private bool fnError(object[] param) { return true; } private bool fnStartHome(object[] param) { return _vce.HomeALL(); } private bool fnHomeTimeout(object[] param) { if (_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } return _vce.Status == RState.End; } private bool fnStartOpenDoor(object[] param) { return _vce.OpenDoor(); } private bool fnOpenDoorTimeout(object[] param) { if (_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } if (_vce.Status == RState.End) { _vceoutdoorclosed = false; } return _vce.Status == RState.End; } private bool fnStartCloseDoor(object[] param) { return _vce.CloseDoor(); } private bool fnCloseDoorTimeout(object[] param) { if (_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } //关门成功 if (_vce.Status == RState.End) { _vceoutdoorclosed = true; } return _vce.Status == RState.End; } private bool fnStartMapping(object[] param) { return _vce.Map(); } private bool fnMappingTimeout(object[] param) { if(_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } return _vce.Status == RState.End; } private bool fnStartLoading(object[] param) { return _vce.Load(); } private bool fnLoadingTimeout(object[] param) { if (_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } return _vce.Status == RState.End; } private bool fnStartUnLoading(object[] param) { return _vce.UnLoad(); } private bool fnUnLoadingTimeout(object[] param) { if (_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } return _vce.Status == RState.End; } public bool Check(int msg, out string reason, params object[] args) { reason = ""; return true; } public int Invoke(string function, params object[] args) { switch (function) { case "Home": CheckToPostMessage((int)VceMSG.Home); return (int)VceMSG.Home; } return (int)VceMSG.None; } public bool CheckToPostMessage(int msg, params object[] args) { if (!fsm.FindTransition(fsm.State, msg)) { LOG.Write(eEvent.WARN_FSM_WARN, _modulename, $"{_modulename} is in {(VceSTATE)fsm.State} state,can not do {(VceMSG)msg}"); return false; } Running = true; fsm.PostMsg(msg, args); return true; } public bool CheckAcked(int msg) { return fsm.CheckExecuted(msg); } public bool IsPrepareTransferReady(ModuleName module, EnumTransferType transferType, int slot) { return false; } } }