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.RT.Routine; using Aitex.Core.Utilities; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.WaferHolder; using CyberX8_Core; using CyberX8_RT.Devices.AXIS; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Aitex.Core.Util; using MECF.Framework.Common.Layout; using Aitex.Core.RT.SCCore; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.Common.CommonData; using MECF.Framework.Common.Alarm; using MECF.Framework.Common.Utilities; namespace CyberX8_RT.Modules.Transporter { public class TransporterEntity : Entity, IEntity, IModuleEntity { #region 内部变量 /// /// 是否完成Home /// private bool _isHomed; /// /// Gantry电机 /// private JetAxisBase _gantryAxis; /// /// Elevator电机 /// private JetAxisBase _elevatorAxis; /// /// 当前Routine /// private IRoutine _currentRoutine; /// /// 目标Cell(Transfer或pickupMoveto或moveto目标Cell) /// private string _targetCell; /// /// 源Cell(Transfer或pickupMoveto) /// private string _sourceCell; #endregion #region routine private TransporterHomeRoutine _homeAllRoutine; private TransporterSwitchOnRoutine _switchOnRoutine; private TransporterSwitchOffRoutine _switchOffRoutine; private TransporterPositionRoutine _positionRoutine; private TransporterGantryPositionRoutine _gantryPositionRoutine; private TransporterPickUpFromRoutine _pickUpFromRoutine; private TransporterMoveToRoutine _moveToRoutine; private TransporterPickDownToRoutine _placeRoutine; private TransporterParkRoutine _parkRoutine; private TransporterElevatorUpRoutine _elevatorUpRoutine; private TransporterElevatorLowRoutine _elevatorLowRoutine; private TransporterTransferRoutine _transferRoutine; private TransporterPickUpMoveToRoutine _pickUpMoveToRoutine; private TransporterPickUpValidateRoutine _pickUpValidateRoutine; #endregion #region 属性 public ModuleName Module { get; private set; } //初始状态 public bool IsInit { get { return fsm.State == (int)TransporterState.Init; } } /// ///Initialized状态(Safety) /// public bool IsInitialized { get { return fsm.State==(int)TransporterState.Initialized; } } /// /// Busy状态 /// public bool IsBusy { get { return !IsInit && !IsError && !IsIdle; } } /// /// Idle状态 /// public bool IsIdle { get { return fsm.State == (int)TransporterState.Idle; } } public bool IsAuto { get; } = true; /// /// 是否为工程模式 /// public bool IsEngineering { get; } = false; /// /// 是否为产品模式 /// public bool IsProduction { get; } = true; /// /// 错误状态 /// public bool IsError { get { return fsm.State == (int)TransporterState.Error; } } /// /// Home状态 /// public bool IsHomed { get { return _isHomed; } } /// /// 是否禁用 /// public bool IsDisable { get; internal set; } /// /// Grantry是否SwitchOn /// public bool IsGantrySwitchOn { get { return _gantryAxis.IsSwitchOn; } } /// /// Elevator是否SwitchOn /// public bool IsElevatorSwitchOn { get { return _elevatorAxis.IsSwitchOn; } } /// /// 当前状态机状态 /// public int State { get { return fsm.State; } } /// /// 目标Cell(Transfer或pickupMoveto或moveto目标Cell) /// public string TargetCell { get { return _targetCell; } } /// /// 源Cell(Transfer或pickupMoveto) /// public string SourceCell { get { return _sourceCell; } } /// /// WaferHolder信息 /// public WaferHolderInfo WaferHolderInfo { get { return WaferHolderManager.Instance.GetWaferHolder(Module.ToString()); } } #endregion /// /// 构造函数 /// /// public TransporterEntity(ModuleName module) { this.Module = module; _elevatorAxis = DEVICE.GetDevice($"{module}.Elevator"); _gantryAxis = DEVICE.GetDevice($"{Module}.Gantry"); WaferManager.Instance.SubscribeLocation(Module, 2); InitialFsm(); } /// /// 初始化 /// /// protected override bool Init() { InitialOperation(); InitialDATA(); InitialRoutine(); return true; } /// /// 初始化状态机 /// private void InitialFsm() { fsm = new StateMachine(Module.ToString(), (int)TransporterState.Init, 100); fsm.EnableRepeatedMsg(true); AnyStateTransition(TransporterMSG.Error, EnterError, TransporterState.Error); AnyStateTransition(TransporterMSG.Abort, Abort, TransporterState.Init); AnyStateTransition(TransporterMSG.ReturnIdle, NullFunc, TransporterState.Idle); AnyStateTransition(TransporterMSG.HomeAll, HomeAll, TransporterState.Homing); Transition(TransporterState.Error, TransporterMSG.ResumeError,ResumeError, TransporterState.Init); //SwitchOn Transition(TransporterState.Init, TransporterMSG.SwitchOn, SwitchOnAll, TransporterState.SwitchOning); Transition(TransporterState.Idle, TransporterMSG.SwitchOn, SwitchOnAll, TransporterState.SwitchOning); Transition(TransporterState.Error, TransporterMSG.SwitchOn, SwitchOnAll, TransporterState.SwitchOning); Transition(TransporterState.SwitchOning, FSM_MSG.TIMER, SwitchOnTimeout, TransporterState.Init); //SwitchOff Transition(TransporterState.Init, TransporterMSG.SwitchOff, SwitchOffAll, TransporterState.SwitchOffing); Transition(TransporterState.Idle, TransporterMSG.SwitchOff, SwitchOffAll, TransporterState.SwitchOffing); Transition(TransporterState.Error, TransporterMSG.SwitchOff, SwitchOffAll, TransporterState.SwitchOffing); Transition(TransporterState.SwitchOffing, FSM_MSG.TIMER, SwitchOffTimeout, TransporterState.Init); // Home Transition(TransporterState.Homing, FSM_MSG.TIMER, HomingTimeout, TransporterState.Idle); //Gantry Save Move Transition(TransporterState.Idle, TransporterMSG.GantrySafeMove, GantrySafeMove, TransporterState.GantrySafeMoving); Transition(TransporterState.GantrySafeMoving, FSM_MSG.TIMER, GantrySafeMoveMonitor, TransporterState.Idle); //GantryGoToSavedPosition Transition(TransporterState.Error, TransporterMSG.GantryGoToSavedPosition, ManualGantryGotoPosition, TransporterState.ErrorGantryPositioning); Transition(TransporterState.ErrorGantryPositioning, FSM_MSG.TIMER, ManualGantryGotoPositionTimeout, TransporterState.Error); Transition(TransporterState.Idle,TransporterMSG.GantryGoToSavedPosition, ManualGantryGotoPosition, TransporterState.GantryPositioning); Transition(TransporterState.GantryPositioning, FSM_MSG.TIMER, ManualGantryGotoPositionTimeout, TransporterState.Idle); //Pickup Transition(TransporterState.Idle, TransporterMSG.PickUpFrom, PickUp, TransporterState.PickUping); Transition(TransporterState.PickUping, FSM_MSG.TIMER, PickUpFromTimeout, TransporterState.Idle); //MoveTo Transition(TransporterState.Idle, TransporterMSG.MoveTo, MoveTo, TransporterState.MovingTo); Transition(TransporterState.MovingTo, FSM_MSG.TIMER, MoveToTimeout, TransporterState.Idle); //Place Transition(TransporterState.Idle, TransporterMSG.Place, Place, TransporterState.Placing); Transition(TransporterState.Placing, FSM_MSG.TIMER, PlaceTimeout, TransporterState.Idle); //Park Transition(TransporterState.Idle, TransporterMSG.Park, Park, TransporterState.Parking); Transition(TransporterState.Parking, FSM_MSG.TIMER, ParkTimeout, TransporterState.Idle); //Elevator Up Transition(TransporterState.Idle, TransporterMSG.ElevatorUp, ElevatorUp, TransporterState.ElevatorUping); Transition(TransporterState.ElevatorUping, FSM_MSG.TIMER, ElevatorUpTimeout, TransporterState.Idle); //Elevator Low Transition(TransporterState.Idle, TransporterMSG.ElevatorLow, ElevatorLow, TransporterState.ElevatorLowing); Transition(TransporterState.ElevatorLowing, FSM_MSG.TIMER, ElevatorLowTimeout, TransporterState.Idle); //Transfer Transition(TransporterState.Idle, TransporterMSG.Transfer, Transfer, TransporterState.Transfering); Transition(TransporterState.Transfering, FSM_MSG.TIMER, TransferTimeout, TransporterState.Idle); //PickUpMoveTo Transition(TransporterState.Idle, TransporterMSG.PickUpMoveTo, PickUpMoveTo, TransporterState.PickUpMoveToing); Transition(TransporterState.PickUpMoveToing, FSM_MSG.TIMER, PickUpMoveToTimeout, TransporterState.PickUpMoveToComplete); Transition(TransporterState.PickUpMoveToComplete,TransporterMSG.Place, Place, TransporterState.Placing); Transition(TransporterState.Placing, FSM_MSG.TIMER, PlaceTimeout, TransporterState.Idle); //PickUpValidate Transition(TransporterState.Idle, TransporterMSG.PickUpValidate, PickUpValidate, TransporterState.PickUpValidating); Transition(TransporterState.PickUpValidating, FSM_MSG.TIMER, PickUpValidateTimeout, TransporterState.PickUpValidateComplete); Transition(TransporterState.PickUpValidateComplete, TransporterMSG.MoveTo, MoveTo, TransporterState.ValidateMoveTo); Transition(TransporterState.ValidateMoveTo, FSM_MSG.TIMER, MoveToTimeout, TransporterState.ValidateMoveToComplete); Transition(TransporterState.ValidateMoveToComplete, TransporterMSG.Place, Place, TransporterState.Placing); //Retry Transition(TransporterState.Error, TransporterMSG.Retry, NullFunc, TransporterState.Retrying); Transition(TransporterState.Retrying, FSM_MSG.TIMER, TransporterRetry, TransporterState.Retrying); Transition(TransporterState.Retrying, TransporterMSG.Transfer, RetryTransfer, TransporterState.Transfering); Transition(TransporterState.Retrying, TransporterMSG.PickUpMoveTo, RetryPickUpMoveTo, TransporterState.PickUpMoveToing); Transition(TransporterState.Retrying, TransporterMSG.PickUpValidate, RetryPickUpValidate, TransporterState.PickUpValidating); Transition(TransporterState.Retrying, TransporterMSG.Place, RetryPlace, TransporterState.Placing); //ConfirmComplete Transition(TransporterState.Init, TransporterMSG.ConfirmComplete, ClearModuleAlarm, TransporterState.Init); Transition(TransporterState.Idle, TransporterMSG.ConfirmComplete, ClearModuleAlarm, TransporterState.Idle); Transition(TransporterState.Error, TransporterMSG.ConfirmComplete, NullFunc, TransporterState.ConfirmCompleting); Transition(TransporterState.ConfirmCompleting, FSM_MSG.TIMER, ConfirmComplete, TransporterState.ConfirmCompleting); Transition(TransporterState.ConfirmCompleting, TransporterMSG.Transfer, ConfirmTransfer, TransporterState.Idle); Transition(TransporterState.ConfirmCompleting, TransporterMSG.PickUpValidate, ConfirmPickupValidate, TransporterState.PickUpValidateComplete); Transition(TransporterState.ConfirmCompleting, TransporterMSG.PickUpMoveTo, ConfirmPickupMoveto, TransporterState.PickUpMoveToComplete); Transition(TransporterState.ConfirmCompleting, TransporterMSG.Place, ConfirmPlace, TransporterState.Idle); EnumLoop.ForEach((item) => { fsm.MapState((int)item, item.ToString()); }); EnumLoop.ForEach((item) => { fsm.MapMessage((int)item, item.ToString()); }); } /// /// 初始化操作 /// private void InitialOperation() { OP.Subscribe($"{Module}.Abort", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_TRANSPORTER, Module.ToString(), (int)TransporterMSG.Abort); }); OP.Subscribe($"{Module}.ClearError", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_TRANSPORTER, Module.ToString(), (int)TransporterMSG.ResumeError); }); OP.Subscribe($"{Module}.HomeAll", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_TRANSPORTER,Module.ToString(),(int)TransporterMSG.HomeAll); }); OP.Subscribe($"{Module}.Gantry.GantryGotoSavedPosition", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_TRANSPORTER, Module.ToString(), (int)TransporterMSG.GantryGoToSavedPosition, "Gantry", args); }); //OP.Subscribe($"{Module}.Elevator.GotoSavedPosition", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_TRANSPORTER, Module.ToString(), (int)TransporterMSG.GoToSavedPosition, "Elevator", args); }); OP.Subscribe($"{Module}.PickUpFrom", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_TRANSPORTER, Module.ToString(), (int)TransporterMSG.PickUpFrom,args); }); OP.Subscribe($"{Module}.MoveTo", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_TRANSPORTER, Module.ToString(), (int)TransporterMSG.MoveTo, args); }); OP.Subscribe($"{Module}.PutDownTo", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_TRANSPORTER, Module.ToString(), (int)TransporterMSG.Place, args); }); OP.Subscribe($"{Module}.Park", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_TRANSPORTER, Module.ToString(), (int)TransporterMSG.Park, args); }); OP.Subscribe($"{Module}.ElevatorUp", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_TRANSPORTER, Module.ToString(), (int)TransporterMSG.ElevatorUp, args); }); OP.Subscribe($"{Module}.ElevatorLow", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_TRANSPORTER, Module.ToString(), (int)TransporterMSG.ElevatorLow, args); }); OP.Subscribe($"{Module}.SwitchOn", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_TRANSPORTER, Module.ToString(), (int)TransporterMSG.SwitchOn, args); }); OP.Subscribe($"{Module}.SwitchOff", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_TRANSPORTER, Module.ToString(), (int)TransporterMSG.SwitchOff, args); }); OP.Subscribe($"{Module}.Transfer", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_TRANSPORTER, Module.ToString(), (int)TransporterMSG.Transfer, args); }); } /// /// 初始化数据 /// private void InitialDATA() { InitializeSvid(); DATA.Subscribe($"{Module}.FsmState", () => ((TransporterState)fsm.State).ToString(), SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.IsHomed", () => _isHomed, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.IsIdle", () => IsIdle, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.IsError", () => IsError, SubscriptionAttribute.FLAG.IgnoreSaveDB); } /// /// 初始化SVID /// private void InitializeSvid() { DATA.Subscribe($"{Module}.State", () => ((TransporterState)fsm.State).ToString(), SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.LotID", () => (WaferHolderInfo != null ? WaferHolderInfo.LotId : ""), SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.WSID", () => (WaferHolderInfo != null ? WaferHolderInfo.Id : ""), SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.LSAID", () => (WaferHolderInfo != null ? WaferHolderInfo.CrsAId : ""), SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.LSBID", () => (WaferHolderInfo != null ? WaferHolderInfo.CrsBId : ""), SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.SequenceRecipe", () => (WaferHolderInfo != null ? WaferHolderInfo.SequenceId : ""), SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.WaferAID", () => (WaferHolderInfo != null ? WaferHolderInfo.WaferAId : ""), SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.WaferBID", () => (WaferHolderInfo != null ? WaferHolderInfo.WaferBId : ""), SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.Task", () => WaferHolderInfo != null ? WaferHolderInfo.CurrentControlJobId : "", SubscriptionAttribute.FLAG.IgnoreSaveDB); } /// /// 初始化Routine /// private void InitialRoutine() { _homeAllRoutine = new TransporterHomeRoutine(Module.ToString()); _switchOnRoutine = new TransporterSwitchOnRoutine(Module.ToString()); _switchOffRoutine=new TransporterSwitchOffRoutine(Module.ToString()); _positionRoutine = new TransporterPositionRoutine(Module.ToString()); _gantryPositionRoutine = new TransporterGantryPositionRoutine(Module.ToString()); _pickUpFromRoutine = new TransporterPickUpFromRoutine(Module.ToString()); _moveToRoutine=new TransporterMoveToRoutine(Module.ToString()); _placeRoutine=new TransporterPickDownToRoutine(Module.ToString()); _parkRoutine=new TransporterParkRoutine(Module.ToString()); _elevatorUpRoutine=new TransporterElevatorUpRoutine(Module.ToString()); _elevatorLowRoutine = new TransporterElevatorLowRoutine(Module.ToString()); _transferRoutine =new TransporterTransferRoutine(Module.ToString()); _pickUpMoveToRoutine = new TransporterPickUpMoveToRoutine(Module.ToString()); _pickUpValidateRoutine=new TransporterPickUpValidateRoutine(Module.ToString()); } /// /// 进入Error状态 /// /// /// private bool EnterError(object[] param) { return true; } /// /// 恢复错误 /// /// /// private bool ResumeError(object[] param) { if(_isHomed) { PostMsg(TransporterMSG.ReturnIdle); return false; } return true; } #region Abort private bool Abort(object parameter) { bool preHomed = IsHomed; _gantryAxis.StopPositionOperation(); _elevatorAxis.StopPositionOperation(); if (_currentRoutine != null) { _currentRoutine.Abort(); _currentRoutine = null; } if (preHomed) { PostMsg(TransporterMSG.ReturnIdle); return false; } return true; } #endregion #region Switch On /// /// SwitchAll /// /// /// private bool SwitchOnAll(object[] param) { return _switchOnRoutine.Start() == RState.Running; } private bool SwitchOnTimeout(object[] param) { RState ret = _switchOnRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(TransporterMSG.Error); return false; } bool result = ret == RState.End; if (result) { _isHomed = false; } return result; } #endregion #region Switch Off /// /// SwitchAll /// /// /// private bool SwitchOffAll(object[] param) { return _switchOffRoutine.Start() == RState.Running; } private bool SwitchOffTimeout(object[] param) { RState ret = _switchOffRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(TransporterMSG.Error); return false; } bool result = ret == RState.End; if (result) { _isHomed = false; } return result; } #endregion #region Home /// /// HomeAll /// /// /// private bool HomeAll(object[] param) { _isHomed = false; bool result= _homeAllRoutine.Start() == RState.Running; if (result) { _currentRoutine = _homeAllRoutine; } return result; } /// /// Home超时 /// /// /// private bool HomingTimeout(object[] param) { RState ret = _homeAllRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { _currentRoutine = null; PostMsg(TransporterMSG.Error); _isHomed = false; return false; } bool result = ret == RState.End; if (result) { _currentRoutine = null; _isHomed = true; } return result; } #endregion #region GantrySafeMove /// /// Gantry安全移动 /// /// /// private bool GantrySafeMove(object[] param) { double targetPosition=(double)param[0]; return _gantryAxis.ProfilePositionOperation(targetPosition); } /// /// Gantry安全移动监控 /// /// /// private bool GantrySafeMoveMonitor(object[] param) { if (_gantryAxis.Status == RState.End) { return true; } if (_gantryAxis.Status == RState.Failed || _gantryAxis.Status == RState.Timeout) { PostMsg(TransporterMSG.Error); return false; } return false; } #endregion #region Manual Gantry GoToPosition /// /// Manual Gantry Go to Position /// /// /// private bool ManualGantryGotoPosition(object[] param) { string axis = param[0].ToString(); object[] objs = (object[])param[1]; string position = objs[1].ToString(); var result = CheckGotoPositionPreCondition(axis, position); if (result.result) { bool posresult = _gantryPositionRoutine.Start(position) == RState.Running; if (posresult) { _currentRoutine = _positionRoutine; } return posresult; } else { return false; } } /// /// Manual gantry Go to Position Time Out /// /// /// private bool ManualGantryGotoPositionTimeout(object[] param) { RState ret = _gantryPositionRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(TransporterMSG.Error); _currentRoutine = null; return false; } bool result = ret == RState.End; if (result) { _currentRoutine = null; } return result; } /// /// 检验GotoPosition前置条件 /// /// /// /// private (bool result, JetAxisBase axis) CheckGotoPositionPreCondition(string axis, string position) { switch (axis) { case "Gantry": return (_gantryAxis.CheckGotoPosition(position), _gantryAxis); case "Elevator": return (_elevatorAxis.CheckGotoPosition(position), _elevatorAxis); default: return (false, null); } } #endregion #region Pick Up /// /// Pick Up /// /// /// private bool PickUp(object[] param) { bool result= _pickUpFromRoutine.Start(param[0]) == RState.Running; if(result) { _currentRoutine = _pickUpFromRoutine; } return result; } /// /// PickUpFrom超时 /// /// /// private bool PickUpFromTimeout(object[] param) { RState ret = _pickUpFromRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { _currentRoutine = null; PostMsg(TransporterMSG.Error); return false; } bool result= ret == RState.End; if(result) { _currentRoutine = null; } return result; } #endregion #region Move To /// /// Move To /// /// /// private bool MoveTo(object[] param) { if (!CheckOtherEntityStatus(param[0].ToString())) { LOG.WriteLog(eEvent.WARN_TRANSPORTER, Module.ToString(), $"Module Axis meets conflict of other Axis"); return false; } bool result= _moveToRoutine.Start(param[0]) == RState.Running; if(result) { _targetCell = param[0].ToString(); _sourceCell = ""; _currentRoutine = _moveToRoutine; } return result; } /// /// MoveTo超时 /// /// /// private bool MoveToTimeout(object[] param) { RState ret = _moveToRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { _targetCell = ""; _currentRoutine = null; PostMsg(TransporterMSG.Error); return false; } bool result = ret == RState.End; if(result) { _targetCell = ""; _currentRoutine = null; if (!string.IsNullOrEmpty(_sourceCell)) { _sourceCell = ""; } } return result; } #endregion #region Place /// /// Place /// /// /// private bool Place(object[] param) { _targetCell = ""; bool result = _placeRoutine.Start(param[0]) == RState.Running; if(result) { _currentRoutine = _placeRoutine; _targetCell = param[0].ToString(); } return result; } /// /// Retry Place /// /// /// private bool RetryPlace(object[] param) { int stepIndex = (int)param[0]; bool result = _placeRoutine.Retry(stepIndex) == RState.Running; if (result) { _currentRoutine = _placeRoutine; } return result; } /// /// Place超时 /// /// /// private bool PlaceTimeout(object[] param) { RState ret = _placeRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { _currentRoutine = null; if (Singleton.Instance.IsAutoRunning) { AlarmList alarmList = new AlarmList(Module.ToString(), ((TransporterState)fsm.State).ToString(), (int)TransporterMSG.Place, _placeRoutine.ErrorMsg, _placeRoutine.ErrorStep, (int)AlarmType.Error); AlarmListManager.Instance.AddAlarm(alarmList); } PostMsg(TransporterMSG.Error); return false; } bool result = ret == RState.End; if (result) { _currentRoutine = null; _targetCell = ""; if (!string.IsNullOrEmpty(_sourceCell)) { _sourceCell = ""; } } return result; } /// /// 确认Place是否完成 /// /// /// private bool ConfirmPlace(object[] param) { int stepIdex = (int)param[0]; bool result = _placeRoutine.CheckCompleteCondition(stepIdex); if (!result) { if (Singleton.Instance.IsAutoRunning) { AlarmList alarmList = new AlarmList(Module.ToString(), ((TransporterState)fsm.State).ToString(), (int)TransporterMSG.Place, _placeRoutine.ErrorMsg, _placeRoutine.ErrorStep, (int)AlarmType.Error); AlarmListManager.Instance.AddAlarm(alarmList); } PostMsg(TransporterMSG.Error); } else { if (Singleton.Instance.IsAutoRunning) { AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), TransporterState.Placing.ToString()); } } return result; } #endregion #region Park /// /// Park /// /// /// private bool Park(object[] param) { bool result = _parkRoutine.Start() == RState.Running; if (result) { _currentRoutine = _parkRoutine; } return result; } /// /// Park超时 /// /// /// private bool ParkTimeout(object[] param) { RState ret = _parkRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { _currentRoutine = null; PostMsg(TransporterMSG.Error); return false; } bool result = ret == RState.End; if (result) { _currentRoutine = null; } return result; } #endregion #region Elevator Up /// /// Elevator Up /// /// /// private bool ElevatorUp(object[] param) { bool result = _elevatorUpRoutine.Start() == RState.Running; if (result) { _currentRoutine = _elevatorUpRoutine; } return result; } /// /// Elevator Up超时 /// /// /// private bool ElevatorUpTimeout(object[] param) { RState ret = _elevatorUpRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { _currentRoutine = null; PostMsg(TransporterMSG.Error); return false; } bool result = ret == RState.End; if (result) { _currentRoutine = null; } return result; } #endregion #region Elevator Low /// /// Elevator Low /// /// /// private bool ElevatorLow(object[] param) { bool result= _elevatorLowRoutine.Start() == RState.Running; if (result) { _currentRoutine = _elevatorLowRoutine; } return result; } /// /// Elevator Low超时 /// /// /// private bool ElevatorLowTimeout(object[] param) { RState ret = _elevatorLowRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { _currentRoutine = null; PostMsg(TransporterMSG.Error); return false; } bool result = ret == RState.End; if (result) { _currentRoutine = null; } return result; } #endregion #region Transfer /// /// Transfer /// /// /// private bool Transfer(object[] param) { if (!CheckOtherEntityStatus(param[0].ToString())) { LOG.WriteLog(eEvent.WARN_TRANSPORTER, Module.ToString(), $"Module Axis meets conflict of other Axis from {param[0]}"); return false; } if (!CheckOtherEntityStatus(param[1].ToString())) { LOG.WriteLog(eEvent.WARN_TRANSPORTER, Module.ToString(), $"Module Axis meets conflict of other Axis to {param[1]}"); return false; } bool result = _transferRoutine.Start(param) == RState.Running; if (result) { _sourceCell=param[0].ToString(); _targetCell = param[1].ToString(); _currentRoutine = _transferRoutine; } return result; } /// /// Retry Transfer /// /// /// private bool RetryTransfer(object[] param) { if (!CheckOtherEntityStatus(_sourceCell)) { LOG.WriteLog(eEvent.WARN_TRANSPORTER, Module.ToString(), $"Module Axis meets conflict of other Axis from {_sourceCell}"); return false; } if (!CheckOtherEntityStatus(_targetCell)) { LOG.WriteLog(eEvent.WARN_TRANSPORTER, Module.ToString(), $"Module Axis meets conflict of other Axis to {_targetCell}"); return false; } int stepIndex = (int)param[0]; bool result = _transferRoutine.Retry(stepIndex) == RState.Running; if (result) { _currentRoutine = _transferRoutine; } return result; } /// /// Transfer超时 /// /// /// private bool TransferTimeout(object[] param) { RState ret = _transferRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { _targetCell = ""; _sourceCell = ""; _currentRoutine = null; if (Singleton.Instance.IsAutoRunning) { AlarmList alarmList = new AlarmList(Module.ToString(), ((TransporterState)fsm.State).ToString(), (int)TransporterMSG.Transfer, _transferRoutine.ErrorMsg, _transferRoutine.ErrorStep, (int)AlarmType.Error); AlarmListManager.Instance.AddAlarm(alarmList); } PostMsg(TransporterMSG.Error); return false; } bool result = ret == RState.End; if (result) { _targetCell = ""; _sourceCell = ""; _currentRoutine = null; AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), TransporterState.Transfering.ToString()); } return result; } /// /// 确认Transfer是否完成 /// /// /// private bool ConfirmTransfer(object[] param) { int stepIdex = (int)param[0]; bool result = _transferRoutine.CheckCompleteCondition(stepIdex); if (!result) { if (Singleton.Instance.IsAutoRunning) { AlarmList alarmList = new AlarmList(Module.ToString(), ((TransporterState)fsm.State).ToString(), (int)TransporterMSG.Transfer, _transferRoutine.ErrorMsg, _transferRoutine.ErrorStep, (int)AlarmType.Error); AlarmListManager.Instance.AddAlarm(alarmList); } PostMsg(TransporterMSG.Error); } else { if (Singleton.Instance.IsAutoRunning) { AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), TransporterState.Transfering.ToString()); } } return result; } /// /// 检验另一个Axis状态 /// /// public bool CheckOtherEntityStatus(string targetCell) { bool positive = false; TransporterEntity otherEntity=null; string otherModule = ""; if (Module == ModuleName.Transporter2) { otherModule = ModuleName.Transporter1.ToString(); otherEntity = Singleton.Instance.GetModule(ModuleName.Transporter1.ToString()); positive = true; } else { otherModule = ModuleName.Transporter2.ToString(); otherEntity = Singleton.Instance.GetModule(ModuleName.Transporter2.ToString()); } if(otherEntity==null) { return true; } if (otherEntity.IsIdle) { return true; } if (otherEntity.IsError) { return false; } if(otherEntity.State==(int)TransporterState.Transfering||otherEntity.State==(int)TransporterState.PickUpMoveToing ||otherEntity.State==(int)TransporterState.MovingTo||otherEntity.State==(int)TransporterState.PickUpValidating ||otherEntity.State==(int)TransporterState.PickUpValidateComplete||otherEntity.State==(int)TransporterState.ValidateMoveTo) { bool conflict= CheckModuleWithOtherModuleConflict(otherEntity,otherModule,positive,targetCell); if(conflict) { return false; } else { return true; } } else { return true; } } /// /// 分析目标cell的位置 /// /// /// /// private (bool result,double targetPosition) AnalyseTargetCellPosition(string otherModule,string targetCell) { ProcessLayoutCellItem _cellItem = ProcessLayoutManager.Instance.GetProcessLayoutCellItemByModuleName(targetCell); string stationName = targetCell; if (_cellItem != null) { if (targetCell.ToLower() != "loader" && targetCell.ToLower() != "park") { stationName = $"Cell{_cellItem.CellId}"; } } else { LOG.WriteLog(eEvent.ERR_TRANSPORTER, Module.ToString(), $"{targetCell} not in layout"); return (false,0); } JetAxisBase otherGantryAxis = DEVICE.GetDevice($"{otherModule}.Gantry"); var result = otherGantryAxis.GetPositionByStation(stationName); if(result.success) { return (true,result.position); } return (false,0); } /// /// 检验当前模块与另一个模块是否存在冲突 /// /// private bool CheckModuleWithOtherModuleConflict(TransporterEntity otherEntity,string otherModule,bool positive,string targetCell) { int transporterMinimumDistance = SC.GetValue("Transporter.TransporterMinimumDistance"); double motorPosition = _gantryAxis.MotionData.MotorPosition; if(targetCell==ModuleName.Loader1.ToString()) { targetCell = "Loader"; } var result = AnalyseTargetCellPosition(Module.ToString(), targetCell); if(!result.result) { return false; } double targetPosition=result.targetPosition; JetAxisBase otherGantryAxis = DEVICE.GetDevice($"{otherModule}.Gantry"); if(otherGantryAxis==null) { return false; } double otherPosition = otherGantryAxis.MotionData.MotorPosition; if (!string.IsNullOrEmpty(otherEntity.TargetCell)) { return CheckOtherModuleCellConflict(otherModule, otherEntity.TargetCell,otherPosition, positive, targetPosition); } if(!string.IsNullOrEmpty(otherEntity.SourceCell)) { bool conflict= CheckOtherModuleCellConflict(otherModule, otherEntity.SourceCell,otherPosition, positive, targetPosition); if (conflict) { //另一个Entity已经到达了目标位置 if (!string.IsNullOrEmpty(otherEntity.TargetCell)&&CheckOtherEntityAlreadyInTargetCell(otherEntity, otherEntity.TargetCell)) { return false; } } return conflict; } else { return false; } } /// /// 检验其他TransporterEntity已经到达目标cell /// /// /// /// private bool CheckOtherEntityAlreadyInTargetCell(TransporterEntity otherEntity,string targetCell) { //另一个Transporter已经取走了WaferHolder,同时gantry已经到达了目标cell if (otherEntity.WaferHolderInfo != null) { JetAxisBase jetAxisBase = DEVICE.GetDevice($"{otherEntity.Module}.Gantry"); if (jetAxisBase != null && jetAxisBase.CheckPositionIsInStation(jetAxisBase.MotionData.MotorPosition, targetCell)) { return true; } } return false; } /// /// 检验另一个模块Cell是否存在冲突 /// /// /// /// /// /// /// private bool CheckOtherModuleCellConflict(string otherModule, string cell,double otherPosition, bool positive,double targetPosition) { int transporterMinimumDistance = SC.GetValue("Transporter.TransporterMinimumDistance"); var result = AnalyseTargetCellPosition(otherModule, cell); if (!result.result) { return false; } else { if (positive) { // if (result.targetPosition - transporterMinimumDistance <= motorPosition) // { // return true; // } if (result.targetPosition - transporterMinimumDistance <= targetPosition) { return true; } if(otherPosition - transporterMinimumDistance <= targetPosition) { return true; } return false; } else { //if (result.targetPosition + transporterMinimumDistance >= motorPosition) //{ // return true; //} if (result.targetPosition + transporterMinimumDistance >= targetPosition) { return true; } if(otherPosition + transporterMinimumDistance >= targetPosition) { return true; } return false; } } } #endregion #region PickUpMoveTo /// /// PickUpMoveTo /// /// /// private bool PickUpMoveTo(object[] param) { if (!CheckOtherEntityStatus(param[0].ToString())) { LOG.WriteLog(eEvent.WARN_TRANSPORTER, Module.ToString(), $"Module Axis meets conflict of other Axis from {param[0]}"); return false; } if (!CheckOtherEntityStatus(param[1].ToString())) { LOG.WriteLog(eEvent.WARN_TRANSPORTER, Module.ToString(), $"Module Axis meets conflict of other Axis to {param[1]}"); return false; } bool result = _pickUpMoveToRoutine.Start(param) == RState.Running; if (result) { _sourceCell = param[0].ToString(); _targetCell = param[1].ToString(); _currentRoutine = _pickUpMoveToRoutine; } return result; } /// /// Retry PickUpMoveTo /// /// /// private bool RetryPickUpMoveTo(object[] param) { if (!CheckOtherEntityStatus(_sourceCell)) { LOG.WriteLog(eEvent.WARN_TRANSPORTER, Module.ToString(), $"Module Axis meets conflict of other Axis from {_sourceCell}"); return false; } if (!CheckOtherEntityStatus(_targetCell)) { LOG.WriteLog(eEvent.WARN_TRANSPORTER, Module.ToString(), $"Module Axis meets conflict of other Axis to {_targetCell}"); return false; } int stepIndex = (int)param[0]; bool result = _pickUpMoveToRoutine.Retry(stepIndex) == RState.Running; if (result) { _currentRoutine = _pickUpMoveToRoutine; } return result; } /// /// PickUpMoveTo超时 /// /// /// private bool PickUpMoveToTimeout(object[] param) { RState ret = _pickUpMoveToRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { _targetCell = ""; _sourceCell = ""; _currentRoutine = null; if (Singleton.Instance.IsAutoRunning) { AlarmList alarmList = new AlarmList(Module.ToString(), ((TransporterState)fsm.State).ToString(), (int)TransporterMSG.PickUpMoveTo, _pickUpMoveToRoutine.ErrorMsg, _pickUpMoveToRoutine.ErrorStep, (int)AlarmType.Error); AlarmListManager.Instance.AddAlarm(alarmList); } PostMsg(TransporterMSG.Error); return false; } bool result = ret == RState.End; if (result) { _targetCell = ""; _sourceCell = ""; _currentRoutine = null; AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), TransporterState.PickUpMoveToing.ToString()); } return result; } /// /// 确认PickupMoveto是否完成 /// /// /// private bool ConfirmPickupMoveto(object[] param) { int stepIdex = (int)param[0]; bool result = _pickUpMoveToRoutine.CheckCompleteCondition(stepIdex); if (!result) { if (Singleton.Instance.IsAutoRunning) { AlarmList alarmList = new AlarmList(Module.ToString(), ((TransporterState)fsm.State).ToString(), (int)TransporterMSG.PickUpMoveTo, _pickUpMoveToRoutine.ErrorMsg, _pickUpMoveToRoutine.ErrorStep, (int)AlarmType.Error); AlarmListManager.Instance.AddAlarm(alarmList); } PostMsg(TransporterMSG.Error); } else { if (Singleton.Instance.IsAutoRunning) { AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), TransporterState.PickUpMoveToing.ToString()); } } return result; } #endregion #region PickUpValidate /// /// PickUpValidate /// /// /// private bool PickUpValidate(object[] param) { if (!CheckOtherEntityStatus(param[0].ToString())) { LOG.WriteLog(eEvent.WARN_TRANSPORTER, Module.ToString(), $"Module Axis meets conflict of other Axis from {param[0]}"); return false; } bool result = _pickUpValidateRoutine.Start(param) == RState.Running; if (result) { _sourceCell = param[0].ToString(); _currentRoutine = _pickUpValidateRoutine; } return result; } /// /// Retry PickUpValidate /// /// /// private bool RetryPickUpValidate(object[] param) { if (!CheckOtherEntityStatus(_sourceCell)) { LOG.WriteLog(eEvent.WARN_TRANSPORTER, Module.ToString(), $"Module Axis meets conflict of other Axis from {_sourceCell}"); return false; } int stepIndex = (int)param[0]; bool result = _pickUpValidateRoutine.Retry(stepIndex) == RState.Running; if (result) { _currentRoutine = _pickUpValidateRoutine; } return result; } /// /// PickUpValidate超时 /// /// /// private bool PickUpValidateTimeout(object[] param) { RState ret = _pickUpValidateRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { _sourceCell = ""; _currentRoutine = null; if (Singleton.Instance.IsAutoRunning) { AlarmList alarmList = new AlarmList(Module.ToString(), ((TransporterState)fsm.State).ToString(), (int)TransporterMSG.PickUpValidate, _pickUpValidateRoutine.ErrorMsg, _pickUpValidateRoutine.ErrorStep, (int)AlarmType.Error); AlarmListManager.Instance.AddAlarm(alarmList); } PostMsg(TransporterMSG.Error); return false; } bool result = ret == RState.End; if (result) { _currentRoutine = null; AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), TransporterState.PickUpValidating.ToString()); //Routine完成,但transporter却没有WaferHolder,则表示此次取WH失败,transporter返回Idle,便于调度重新选择下一个WaferHolder if (WaferHolderInfo == null) { PostMsg(TransporterMSG.ReturnIdle); return false; } } return result; } /// /// 确认PickupValidate是否完成 /// /// /// private bool ConfirmPickupValidate(object[] param) { int stepIdex = (int)param[0]; bool result = _pickUpValidateRoutine.CheckCompleteCondition(stepIdex); if (!result) { if (Singleton.Instance.IsAutoRunning) { AlarmList alarmList = new AlarmList(Module.ToString(), ((TransporterState)fsm.State).ToString(), (int)TransporterMSG.PickUpValidate, _pickUpValidateRoutine.ErrorMsg, _pickUpValidateRoutine.ErrorStep, (int)AlarmType.Error); AlarmListManager.Instance.AddAlarm(alarmList); } PostMsg(TransporterMSG.Error); } else { if (Singleton.Instance.IsAutoRunning) { AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), TransporterState.PickUpValidating.ToString()); } } return result; } #endregion #region TransporterRetry /// /// Retry /// /// /// private bool TransporterRetry(object[] param) { AlarmList alarmList = AlarmListManager.Instance.GetAlarmListByModule(Module.ToString()); if (alarmList != null) { CheckToPostMessage(eEvent.ERR_TRANSPORTER, Module.ToString(), alarmList.ModuleCmd, alarmList.ModuleStep); } return false; } #endregion #region ConfirmComplete /// /// 确认是否完成 /// /// /// private bool ConfirmComplete(object[] param) { AlarmList alarmList = AlarmListManager.Instance.GetAlarmListByModule(Module.ToString()); if (alarmList != null) { if (alarmList.ModuleState == TransporterState.Transfering.ToString()) { CheckToPostMessage(eEvent.ERR_TRANSPORTER, Module.ToString(), (int)TransporterMSG.Transfer, alarmList.ModuleStep); } else if (alarmList.ModuleState == TransporterState.PickUpMoveToing.ToString()) { CheckToPostMessage(eEvent.ERR_TRANSPORTER, Module.ToString(), (int)TransporterMSG.PickUpMoveTo, alarmList.ModuleStep); } else if (alarmList.ModuleState == TransporterState.Placing.ToString()) { CheckToPostMessage(eEvent.ERR_TRANSPORTER, Module.ToString(), (int)TransporterMSG.Place, alarmList.ModuleStep); } else { PostMsg(TransporterMSG.Error); } } return false; } /// /// 清除报警 /// /// /// private bool ClearModuleAlarm(object[] param) { AlarmList alarmList = AlarmListManager.Instance.GetAlarmListByModule(Module.ToString()); if (alarmList != null) { AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), ""); } return true; } #endregion public bool Check(int msg, out string reason, params object[] args) { reason = ""; return false; } public bool CheckAcked(int msg) { return false; } public int Invoke(string function, params object[] args) { switch (function) { case "HomeAll": if(IsIdle) { return (int)FSM_MSG.NONE; } if (CheckToPostMessage(eEvent.ERR_TRANSPORTER, Module.ToString(), (int)TransporterMSG.HomeAll)) { return (int)FSM_MSG.NONE; } else { return (int)FSM_MSG.ALARM; } case "Abort": CheckToPostMessage(eEvent.ERR_TRANSPORTER, Module.ToString(), (int)TransporterMSG.Abort); return (int)FSM_MSG.NONE; case "Retry": if (CheckToPostMessage(eEvent.ERR_TRANSPORTER, Module.ToString(), (int)TransporterMSG.Retry, args)) { return (int)TransporterMSG.Retry; } else { return (int)FSM_MSG.NONE; } case "ConfirmComplete": if (CheckToPostMessage(eEvent.ERR_TRANSPORTER, Module.ToString(), (int)TransporterMSG.ConfirmComplete, args)) { return (int)TransporterMSG.ConfirmComplete; } else { return (int)FSM_MSG.NONE; } } return (int)FSM_MSG.NONE; } } public enum TransporterMSG { HomeAll, // 0 SwitchOn, SwitchOff, Error, ResumeError, ReturnIdle, Abort, GantryGoToSavedPosition, GoToSavedPosition, PickUpFrom, MoveTo, Place, Park, ElevatorUp, ElevatorLow, Transfer, PickUpMoveTo, PickUpValidate, GantrySafeMove, Retry, ConfirmComplete } }