using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Event; using Aitex.Core.RT.Fsm; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.Routine; using Aitex.Core.Util; using EFEM.RT.Devices.Flipper; using EFEM.RT.Routines.FLP; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; namespace EFEM.RT.Devices { public class FlipperEntity : Entity, IEntity { public enum FlipperMSG { Home = 1, TurnOver = 2, Clamp = 3, UnClamp = 4, Error = 5, Reset = 6, Abort = 7, PrepareTransfer = 8, EndTransfer = 9, manualTurn = 10, manualTurnStop = 11, manualClamp = 12, manualClampStop = 13, } private JetFlipper _flipper => DeviceModel.Flipper; private FlipperHomeRoutine flipperhomeroutine = null; public bool IsTransfer => fsm.State == (int)FlipperState.TransferState; public bool IsIdle => fsm.State == (int)FlipperState.Idle; public ModuleName _modulename; public FlipperState State => ((FlipperState)fsm.State); public bool ClampOpen => _flipper == null ? false : _flipper.IsClampOpen; public bool ClampClose => _flipper == null ? false : _flipper.IsClampClose; public bool IsFlipperOrigin => _flipper == null ? false : _flipper.IsFlipperOrigin;//是否在0° public bool IsFlipperHorizontal => _flipper == null ? false : _flipper.IsFlipperHorizontal;//是否在180° public bool IsFlipperOverOrigin => _flipper == null ? false : _flipper.IsFlipperOverOrigin;//是否反转 public FlipperEntity(ModuleName name) { _modulename = name; flipperhomeroutine = new FlipperHomeRoutine(_modulename, _flipper); fsm = new StateMachine(_modulename.ToString(), (int)FlipperState.Init, 50);//状态机频率 BuildTransitionTable(); Singleton.Instance.SubscribeLocation(_modulename, 1); OP.Subscribe($"{_modulename}.{FlipperMSG.TurnOver}", (cmd, args) => { PostMsg(FlipperMSG.TurnOver); return true; }); OP.Subscribe($"{_modulename}.{FlipperMSG.Clamp}", (cmd, args) => { PostMsg(FlipperMSG.Clamp); return true; }); OP.Subscribe($"{_modulename}.{FlipperMSG.UnClamp}", (cmd, args) => { PostMsg(FlipperMSG.UnClamp); return true; }); OP.Subscribe($"{_modulename}.{FlipperMSG.Home}", (cmd, args) => { CheckToPostMsg(FlipperMSG.Home); return true; }); OP.Subscribe($"{_modulename}.{FlipperMSG.Abort}", (cmd, args) => { PostMsg(FlipperMSG.Abort); return true; }); OP.Subscribe($"{_modulename}.{FlipperMSG.Reset}", (cmd, args) => { PostMsg(FlipperMSG.Reset); return true; }); OP.Subscribe($"{_modulename}.{FlipperMSG.manualTurn}", (cmd, args) => { PostMsg(FlipperMSG.manualTurn, args); return true; }); OP.Subscribe($"{_modulename}.{FlipperMSG.manualTurnStop}", (cmd, args) => { PostMsg(FlipperMSG.manualTurnStop, args); return true; }); DATA.Subscribe($"{_modulename}.Status", () => ((FlipperState)fsm.State).ToString()); DATA.Subscribe($"{_modulename}.IsFlipperOrigin", () => IsFlipperOrigin); DATA.Subscribe($"{_modulename}.IsFlipperHorizontal", () => IsFlipperHorizontal); DATA.Subscribe($"{_modulename}.IsFlipperOverOrigin", () => IsFlipperOverOrigin); DATA.Subscribe($"{_modulename}.ClampOpen", () => ClampOpen); DATA.Subscribe($"{_modulename}.ClampClose", () => ClampClose); } //状态迁移表 private void BuildTransitionTable() { AnyStateTransition(FlipperMSG.Home, fStartHome, FlipperState.Homing); //Home sequence Transition(FlipperState.Init, FlipperMSG.Home, fStartHome, FlipperState.Homing); Transition(FlipperState.Idle, FlipperMSG.Home, fStartHome, FlipperState.Homing); Transition(FlipperState.Homing, FSM_MSG.TIMER, fHomeTimout, FlipperState.Idle); Transition(FlipperState.Homing, FlipperMSG.Abort, fReset, FlipperState.Idle); //TurnOver sequence Transition(FlipperState.Idle, FlipperMSG.TurnOver, fStartTurnOver, FlipperState.Turning); Transition(FlipperState.Turning, FSM_MSG.TIMER, fTurnOverTimout, FlipperState.Idle); Transition(FlipperState.Turning, FlipperMSG.Abort, fReset, FlipperState.Idle); //TurnOver Jog sequence Transition(FlipperState.Idle, FlipperMSG.manualTurn, fStartTurnJog, FlipperState.TurnOverJog); Transition(FlipperState.TurnOverJog, FSM_MSG.TIMER, fTurnOverJogTimout, FlipperState.TurnOverJog); Transition(FlipperState.TurnOverJog, FlipperMSG.manualTurnStop, fStartTurnJogStop, FlipperState.Idle); //Transition(FlipperState.Turning, FlipperMSG.Abort, fReset, FlipperState.Idle); //Grip sequence Transition(FlipperState.Idle, FlipperMSG.Clamp, fStartGrip, FlipperState.Gripping); Transition(FlipperState.Gripping, FSM_MSG.TIMER, fGripTimout, FlipperState.Idle); Transition(FlipperState.Gripping, FlipperMSG.Abort, fReset, FlipperState.Idle); //UnGrip sequence Transition(FlipperState.Idle, FlipperMSG.UnClamp, fStartUnGrip, FlipperState.UnGripping); Transition(FlipperState.UnGripping, FSM_MSG.TIMER, fUnGripTimout, FlipperState.Idle); Transition(FlipperState.UnGripping, FlipperMSG.Abort, fReset, FlipperState.Idle); //Transfer Transition(FlipperState.Idle, FlipperMSG.PrepareTransfer, fStartUnGrip, FlipperState.StartTransfer); Transition(FlipperState.StartTransfer, FSM_MSG.TIMER, fUnGripTimout, FlipperState.TransferState); Transition(FlipperState.TransferState, FlipperMSG.EndTransfer, fStartGrip, FlipperState.EndTransfer); Transition(FlipperState.EndTransfer, FSM_MSG.TIMER, fGripTimout, FlipperState.Idle); //Reset Transition(FlipperState.Error, FlipperMSG.Reset, fReset, FlipperState.Idle); Transition(FlipperState.Idle, FlipperMSG.Reset, fReset, FlipperState.Idle); Running = true; } private bool fStartGrip(object[] param) { LOG.Info($"{_modulename.ToString()} start Grip!"); if (!_flipper.IsBusy) { return _flipper.Clamp(true); } else { // LogObject.Error(_modulename.ToString(), "is busy!"); return false; } } private bool fStartUnGrip(object[] param) { LOG.Info($"{_modulename.ToString()} start UnGrip!"); if (!_flipper.IsBusy) { return _flipper.Clamp(false); } else { //LogObject.Error(_modulename.ToString(), "is busy!"); return false; } } private bool fGripTimout(object[] param) { //LogObject.Info(_modulename.ToString(), "Gripping!"); _flipper.Monitor(); switch (_flipper.State) { case FlipperState.Gripping: return false; case FlipperState.Idle: return true; default: PostMsg(FlipperMSG.Error); return true; } } private bool fUnGripTimout(object[] param) { //LogObject.Info(_modulename.ToString(), "UnGripping!"); _flipper.Monitor(); switch (_flipper.State) { case FlipperState.UnGripping: return false; case FlipperState.Idle: return true; default: PostMsg(FlipperMSG.Error); return true; } } private bool fStartTurnJog(object[] param) { LOG.Info($"{_modulename.ToString()} fStartTurnJog----" + param[0].ToString()); string NorP = param[0].ToString(); if (!_flipper.IsBusy) { return _flipper.TrunOverJog(NorP); } else { LOG.Info($"{_modulename.ToString()} is busy!"); return false; } } private bool fStartTurnJogStop(object[] param) { string NorP = param[0].ToString(); return _flipper.TrunOverJogStop(NorP); } private bool fStartTurnOver(object[] param) { LOG.Info($"{_modulename.ToString()} Start TurnOver!"); if (!_flipper.IsBusy) { return _flipper.TurnOver(); } else { //LogObject.Error(_modulename.ToString(), "is busy!"); return false; } } private bool fTurnOverTimout(object[] param) { //LogObject.Info(_modulename.ToString(), "Turnning Over!"); _flipper.Monitor(); switch (_flipper.State) { case FlipperState.Turning: case FlipperState.Homing: return false; case FlipperState.Idle: LOG.Info($"{_modulename.ToString()} 已完成旋转"); if (Singleton.Instance.CheckHasWafer(_modulename, 0)) Singleton.Instance.GetWafer(_modulename, 0).IsChecked = true; return true; default: PostMsg(FlipperMSG.Error); return true; } } private bool fTurnOverJogTimout(object[] param) { _flipper.Monitor(); return true; } private bool fStartHome(object[] param) { return flipperhomeroutine.Start(param) == Result.RUN; } private bool fHomeTimout(object[] param) { Result state = flipperhomeroutine.Monitor(); if (state == Result.DONE) { return true; } if (state == Result.FAIL || state == Result.TIMEOUT) { PostMsg(FlipperMSG.Error); return true; } return false; } private bool fReset(object[] param) { _flipper.Reset(); return _flipper.State == FlipperState.Idle; } public bool Check(int msg, out string reason, params object[] args) { if (!fsm.FindTransition(fsm.State, msg)) { reason = string.Format("{0} is in {1} state,can not do {2}", (object)_modulename, (object)(FlipperState)fsm.State, (object)(FlipperMSG)msg); return false; } reason = ""; PostMsg(msg); return true; } public bool CheckToPostMsg(FlipperMSG msg) { if (!fsm.FindTransition(fsm.State, (int)msg)) { EV.PostMessage("System", EventEnum.DefaultWarning, string.Format("{0} is in {1} state,can not do {2}", _modulename.ToString(), (FlipperState)fsm.State, (FlipperMSG)msg)); return false; } PostMsg(msg); return true; } } }