using Aitex.Core.RT.Event; using Aitex.Core.RT.Fsm; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.Routine; using Aitex.Core.Util; using MECF.Framework.Common.Equipment; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase; using System; using athosRT.FSM; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Diagnostics; using System.Threading; using athosRT.tool; using OP = Common.OP.OP; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase; using Aitex.Core.RT.Device; using Common.DataCenter; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robot; namespace athosRT.Modules.LPs { public class LoadPortEntity : Entity, IEntity { private HomeRoutine homeRoutine = null; private LoadFoupRoutine loadRoutine = null; private UnloadFoupRoutine unloadRoutine = null; private ReadAndLoadRoutine readAndLoadRoutine = null; private ModuleName _chamber; private LoadPortBaseDevice _lp; private ModuleFsmDevice MFD = new ModuleFsmDevice(); public string Name { get; set; } public bool IsIdle => fsm.State == (int)STATE.IDLE; public bool IsRunning => fsm.State != (int)STATE.INIT && fsm.State != (int)STATE.IDLE && fsm.State != (int)STATE.ERROR; public int FsmState => fsm.State; public bool IsAlarm => false; public bool IsWarning => false; public bool IsLoaded => _lp.IsLoaded; public bool IsDoorOpen => _lp.DoorState == Aitex.Sorter.Common.FoupDoorState.Open; public bool IsPresent => _lp.IsPresent; public bool IsReady => _lp.IsReady(); public RobotBaseDevice _robot { get; set; } public LoadPortEntity(string name, RobotBaseDevice robot) { Name = name; _lp = DEVICE.GetDevice(name); _chamber = (ModuleName)Enum.Parse(typeof(ModuleName), this.Name); fsm = new StateMachine(this.Name, 0, 50); AnyStateTransition(LoadPortEntity.MSG.ERROR, new FsmFunc(this.fError), LoadPortEntity.STATE.ERROR); AnyStateTransition(LoadPortEntity.MSG.ABORT, new FsmFunc(this.fError), LoadPortEntity.STATE.IDLE); AnyStateTransition(268435443, new FsmFunc(this.fError), 8); AnyStateTransition(LoadPortEntity.MSG.RESET, new FsmFunc(this.fInit), LoadPortEntity.STATE.IDLE); Transition(LoadPortEntity.STATE.INIT, FSM_MSG.TIMER, new FsmFunc(this.fInit), LoadPortEntity.STATE.IDLE); Transition(LoadPortEntity.STATE.INIT, LoadPortEntity.MSG.ERROR, new FsmFunc(this.fError), LoadPortEntity.STATE.ERROR); Transition(LoadPortEntity.STATE.ERROR, LoadPortEntity.MSG.HOME, new FsmFunc(this.fStartHome), LoadPortEntity.STATE.HOME); Transition(LoadPortEntity.STATE.IDLE, LoadPortEntity.MSG.HOME, new FsmFunc(this.fStartHome), LoadPortEntity.STATE.HOME); Transition(LoadPortEntity.STATE.INIT, LoadPortEntity.MSG.HOME, new FsmFunc(this.fStartHome), LoadPortEntity.STATE.HOME); Transition(LoadPortEntity.STATE.HOME, FSM_MSG.TIMER, new FsmFunc(this.fHome), LoadPortEntity.STATE.IDLE); Transition(LoadPortEntity.STATE.IDLE, LoadPortEntity.MSG.Load, new FsmFunc(this.fStartLoad), LoadPortEntity.STATE.LOAD); Transition(LoadPortEntity.STATE.LOAD, FSM_MSG.TIMER, new FsmFunc(this.fLoad), LoadPortEntity.STATE.IDLE); Transition(LoadPortEntity.STATE.IDLE, LoadPortEntity.MSG.Unload, new FsmFunc(this.fStartUnload), LoadPortEntity.STATE.UNLOAD); Transition(LoadPortEntity.STATE.UNLOAD, FSM_MSG.TIMER, new FsmFunc(this.fUnload), LoadPortEntity.STATE.IDLE); Transition(LoadPortEntity.STATE.IDLE, LoadPortEntity.MSG.ReadAndLoad, new FsmFunc(this.fStartReadAndLoad), LoadPortEntity.STATE.ReadAndLoad); Transition(LoadPortEntity.STATE.ReadAndLoad, FSM_MSG.TIMER, new FsmFunc(this.fReadAndLoad), LoadPortEntity.STATE.IDLE); Running = true; _robot = robot; } public bool Check(int msg, out string reason, object[] objs) { bool flag = true; reason = ""; if (msg != 3 || this.fsm.State == 1) return flag; reason = string.Format("{0} is busy {1},can't excute {2}", (object)this.Name, (object)this.State2String(this.fsm.State), (object)this.Msg2String(msg)); return false; } private string Msg2String(int msg) { string str = ""; switch (msg) { case 6: str = "复位"; break; case 7: str = "终止"; break; } return str; } private string State2String(int state) { string str = ""; switch (state) { case 0: case 9: str = "初始化"; break; case 1: str = "就绪"; break; case 8: str = "错误"; break; } return str; } protected override bool Init() { this.loadRoutine = new LoadFoupRoutine(_chamber); this.unloadRoutine = new UnloadFoupRoutine(_chamber, _robot); this.homeRoutine = new HomeRoutine(_chamber, _robot); this.readAndLoadRoutine = new ReadAndLoadRoutine(_chamber); OP.Subscribe(string.Format("{0}.LPReset", (object)this._chamber), (Func)((cmd, args) => CheckToPostMsg(LoadPortEntity.MSG.RESET))); OP.Subscribe(string.Format("{0}.Load", (object)this._chamber), (Func)((cmd, args) => CheckToPostMsg(LoadPortEntity.MSG.Load))); OP.Subscribe(string.Format("{0}.UnLoad", (object)this._chamber), (Func)((cmd, args) => CheckToPostMsg(LoadPortEntity.MSG.Unload))); OP.Subscribe(string.Format("{0}.Home", (object)this._chamber), (Func)((cmd, args) => CheckToPostMsg(LoadPortEntity.MSG.HOME))); OP.Subscribe(string.Format("{0}.Abort", (object)this._chamber), (Func)((cmd, args) => CheckToPostMsg(LoadPortEntity.MSG.ABORT))); DATA.Subscribe($"{_chamber}.IsLoaded", () => IsLoaded); return true; } protected override void Term() { } private bool fStartHome(object[] objs) { Running = false; RState ret = MFD.StartRoutine(homeRoutine); if (ret == RState.Failed || ret == RState.End) return false; //_isInit = false; return ret == RState.Running; } private bool fHome(object[] objs) { RState ret = MFD.MonitorRoutine(); Trace.WriteLine("执行情况"+ret); if (ret == RState.Failed) { PostMsg(MSG.ERROR); return false; } if (ret == RState.End) { //_isInit = true; return true; } return false; } private bool fStartLoad(object[] objs) { Running = false; switch (this.loadRoutine.Start(objs)) { case RState.End: return false; case RState.Failed: return false; default: return true; } } private bool fLoad(object[] objs) { switch (this.loadRoutine.Monitor()) { case RState.End: this.Running = true; return true; case RState.Failed: this.PostMsg(LoadPortEntity.MSG.ERROR); return true; default: return false; } } private bool fStartUnload(object[] objs) { this.Running = false; switch (this.unloadRoutine.Start(objs)) { case RState.End: return false; case RState.Failed: return false; default: return true; } } private bool fUnload(object[] objs) { switch (this.unloadRoutine.Monitor()) { case RState.End: this.Running = true; return true; case RState.Failed: this.PostMsg(LoadPortEntity.MSG.ERROR); return true; default: return false; } } private bool fStartReadAndLoad(object[] objs) { this.Running = false; switch (this.readAndLoadRoutine.Start(objs)) { case RState.End: return false; case RState.Failed: return false; default: return true; } } private bool fReadAndLoad(object[] objs) { switch (this.readAndLoadRoutine.Monitor()) { case RState.End: this.Running = true; return true; case RState.Failed: this.PostMsg(LoadPortEntity.MSG.ERROR); return false; default: return false; } } private bool fInit(object[] objs) { Trace.WriteLine("finit开始"); return true; } private bool fError(object[] objs) { //出现错误的时候向上报 告知上层FSM处于错误状态 Trace.WriteLine("fError开始"); Singleton.Instance.CheckToPostMsg(RouteManager1.MSG.ERROR); return true; } private bool fAbort() { return true; } public bool CheckToPostMsg(LoadPortEntity.MSG msg) { Trace.WriteLine("当前状态机状态:"+this.fsm.State); if (!this.fsm.FindTransition(this.fsm.State, (int)msg)) { Trace.WriteLine("当前状态不能接受消息:"+msg.ToString()); LogObject.Error(_chamber.ToString(), $"当前状态{fsm.State}不能接受消息:{msg}"); //EV.PostMessage("System", EventEnum.DefaultWarning, (object)string.Format("{0} is in {1} state,can not do {2}", (object)this.Name, (object)(LoadPortEntity.STATE)this.fsm.State, (object)msg)); return false; } LogObject.Info(_chamber.ToString(),"当前状态能接受消息:" + msg.ToString()); this.PostMsg(msg); return true; } public enum STATE { INIT, IDLE, HOME, LOAD, UNLOAD, READ, WRITE, ReadAndLoad, ERROR, Reset, } public enum MSG { HOME, ReadRFID, WriteRFID, Load, Unload, ReadAndLoad, RESET, ABORT, ERROR, } } }