using Aitex.Core.Common; 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.RecipeCenter; using Aitex.Core.Util; using Aitex.Core.Utilities; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.RecipeCenter; using MECF.Framework.Common.SubstrateTrackings; using CyberX8_Core; using CyberX8_RT.Devices.AXIS; using CyberX8_RT.Devices.SRD; using CyberX8_RT.Modules.Transporter; using System; using MECF.Framework.Common.Persistent.SRD; using MECF.Framework.Common.ToolLayout; using CyberX8_RT.Modules.Dryer; using MECF.Framework.Common.Alarm; using MECF.Framework.Common.CommonData; using CyberX8_RT.Modules.Loader; namespace CyberX8_RT.Modules.SRD { public class SRDEntity : Entity, IEntity, IModuleEntity { #region 常量 private const string AUTO = "Auto"; private const string MANUAL = "Manual"; private const string DISABLED = "Disabled"; private const string ENGINEERING = "Engineering"; private const string PRODUCTION = "Production"; #endregion #region 内部变量 /// /// 是否Homed /// private bool _isHomed; /// /// rotation电机 /// private JetAxisBase _rotationAxis; /// /// arm电机 /// private JetAxisBase _armAxis; /// /// IsPresenceTesting /// private bool _isPresenceTesting = false; /// /// IsAWCCycling /// private bool _isAWCCycling = false; /// /// 当前Recipe /// private SrdRecipe _currentRecipe = null; /// /// 持久化对象 /// private SRDPersistentValue _persistentValue; /// /// run recipe start time /// private DateTime _runRecipeStartTime; /// /// run recipe complete time /// private DateTime _runRecipeCompleteTime; #endregion #region Routine /// /// SRD Home /// private SRDHomeRoutine _homeRoutine; /// /// SRD初始化Home Routine /// private SRDInitializeHomeRoutine _initializeHomeRoutine; /// /// SRD SwicthOn /// private SRDSwitchOnRoutine _switchOnRoutine; /// /// SRD SwicthOff /// private SRDSwitchOffRoutine _switchOffRoutine; /// /// SRD Initialize /// private SRDInitializeRoutine _initializeRoutine; /// /// SRD Common Device /// private SrdCommonDevice _srdCommon; /// /// SRD GoToPosition /// private SRDPositionRoutine _positionRoutine; /// /// SRD StartRotation /// private SRDRotationRoutine _rotationRoutine; /// /// SRD PresenceTest /// private SRDPresenceTestRoutine _presenceTestRoutine; /// /// SRD ProcessRecipe /// private SRDProcessRecipeRoutine _processRecipeRoutine; /// /// SRD AWC Cycle /// private SRDAWCCycleRoutine _awcCycleRoutine; /// /// SRD Process Error /// private SRDProcessErrorRoutine _processErrorRoutine; /// /// RecipeCycle /// private int _cycle = 0; /// /// recipe时长 /// private int _recipeTime; #endregion #region 属性 /// /// 模块名称 /// public ModuleName Module { get; private set; } /// /// 初始化状态 /// public bool IsInit { get { return fsm.State == (int)SRDState.Init; } } /// /// 空闲状态 /// public bool IsIdle { get { return fsm.State == (int)SRDState.Idle; } } /// /// 当前状态机状态 /// public int State { get { return fsm.State; } } /// /// 是否发生错误 /// public bool IsError { get { return fsm.State == (int)SRDState.Error; } } /// /// 是否正在作业 /// public bool IsBusy { get { return !IsInit && !IsError && !IsIdle; } } /// /// 是否已Home /// public bool IsHomed { get { return _isHomed; } } /// /// 是否正在用水 /// public bool IsUsingWater { get { return _processRecipeRoutine.IsUsingWater; } } /// /// SRD门是否关闭 /// public bool IsSrdDoorClosed { get { return !_srdCommon.CommonData.DoorOpened && _srdCommon.CommonData.DoorClosed; } } /// /// SRD真空是否开启 /// public bool IsSrdChuckVacuum { get { return _srdCommon.CommonData.ChuckVacuum; } } /// /// 是否禁用 /// public bool IsDisable { get { return _persistentValue == null || _persistentValue.OperatingMode == DISABLED; } } /// /// 自动模式 /// public bool IsAuto { get { return _persistentValue != null && _persistentValue.OperatingMode == AUTO; } } /// /// 自动模式 /// public bool IsManual { get { return _persistentValue != null && _persistentValue.OperatingMode == MANUAL; } } /// /// Arm是否SwitchOn /// public bool IsArmSwitchOn { get { return _armAxis.IsSwitchOn; } } /// /// Rotation是否SwitchOn /// public bool IsRotationSwitchOn { get { return _rotationAxis.IsSwitchOn; } } /// /// 已完成的RunRecipeCycle次数 /// public int AchievedCycle { get { return _processRecipeRoutine.AchievedCycle; } } /// /// PresenceTest状态 /// public bool IsPresenceTesting { get { return _isPresenceTesting; } } /// /// AWCCycle状态 /// public bool IsAWCCycling { get { return _isAWCCycling; } } /// /// 当前状态机 /// public string CurrentStateMachine { get { return GetCurrentStateMachine(); } } /// /// 是否为工程模式 /// public bool IsEngineering { get { return _persistentValue != null && _persistentValue.RecipeOperatingMode == ENGINEERING; } } /// /// 是否为产品模式 /// public bool IsProduction { get { return _persistentValue != null && _persistentValue.RecipeOperatingMode == PRODUCTION; } } #endregion /// /// 构造函数 /// /// public SRDEntity(ModuleName module) { this.Module = module; _armAxis = DEVICE.GetDevice($"{module}.Arm"); _rotationAxis = DEVICE.GetDevice($"{module}.Rotation"); WaferManager.Instance.SubscribeLocation(Module, 1); InitialFsm(); } /// /// 总初始化 /// /// protected override bool Init() { _srdCommon = DEVICE.GetDevice($"{Module}.Common"); InitializeParameter(); InitialDATA(); InitialRoutine(); InitialOperation(); return true; } /// /// 初始化参数 /// private void InitializeParameter() { _persistentValue = SRDPersistentManager.Instance.GetModulePersistentValue(Module.ToString()); if (_persistentValue == null) { LOG.WriteLog(eEvent.ERR_SRD, Module.ToString(), "Persistent Value Object is not exist"); } } /// /// 初始化数据 /// private void InitialDATA() { DATA.Subscribe($"{Module}.FsmState", () => ((SRDState)fsm.State).ToString(), SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.IsHomed", () => _isHomed, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.IsError", () => IsError, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.SrdDoorClosed", () => IsSrdDoorClosed, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.AchievedCycle", () => AchievedCycle, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.IsPresenceTesting", () => IsPresenceTesting, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.CurrentStateMachine", () => CurrentStateMachine, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.IsAWCCycling", () => IsAWCCycling, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.CurrentRecipe", () => _currentRecipe != null ? _currentRecipe.Ppid : "", SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.TotalTime", () => _recipeTime, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.TimeRemain", () => CalculateTimeRemain(), SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.OperatingMode", () => _persistentValue != null ? _persistentValue.OperatingMode : "None", SubscriptionAttribute.FLAG.IgnoreSaveDB); } /// /// 初始化状态机 /// private void InitialFsm() { fsm = new StateMachine(Module.ToString(), (int)SRDState.Init, 20); fsm.EnableRepeatedMsg(true); AnyStateTransition(SRDMSG.Error, EnterError, SRDState.Error); Transition(SRDState.Error, SRDMSG.ResumeError, (param) => { return true; }, SRDState.Init); //Initialized AnyStateTransition(SRDMSG.Initialize, InitializeAll, SRDState.Initializing); Transition(SRDState.Initializing, FSM_MSG.TIMER, InitializeAllTimeout, SRDState.Initialized); //SwitchOn Transition(SRDState.Init, SRDMSG.SwitchOn, SwitchOnAll, SRDState.SwitchOning); Transition(SRDState.Idle, SRDMSG.SwitchOn, SwitchOnAll, SRDState.SwitchOning); Transition(SRDState.Error, SRDMSG.SwitchOn, SwitchOnAll, SRDState.SwitchOning); Transition(SRDState.Initialized, SRDMSG.SwitchOn, SwitchOnAll, SRDState.SwitchOning); Transition(SRDState.SwitchOning, FSM_MSG.TIMER, SwitchOnTimeout, SRDState.Init); //SwitchOff Transition(SRDState.Init, SRDMSG.SwitchOff, SwitchOffAll, SRDState.SwitchOffing); Transition(SRDState.Idle, SRDMSG.SwitchOff, SwitchOffAll, SRDState.SwitchOffing); Transition(SRDState.Error, SRDMSG.SwitchOff, SwitchOffAll, SRDState.SwitchOffing); Transition(SRDState.Initialized, SRDMSG.SwitchOff, SwitchOffAll, SRDState.SwitchOffing); Transition(SRDState.SwitchOffing, FSM_MSG.TIMER, SwitchOffTimeout, SRDState.Init); // Home Transition(SRDState.Init, SRDMSG.HomeAll, HomeAll, SRDState.Homing); Transition(SRDState.Initialized, SRDMSG.HomeAll, HomeAll, SRDState.Homing); Transition(SRDState.Error, SRDMSG.HomeAll, HomeAll, SRDState.Homing); Transition(SRDState.Idle, SRDMSG.HomeAll, HomeAll, SRDState.Homing); Transition(SRDState.Abort, SRDMSG.HomeAll, HomeAll, SRDState.Homing); Transition(SRDState.Homing, FSM_MSG.TIMER, HomingTimeout, SRDState.Idle); //Initialize Home Transition(SRDState.Init, SRDMSG.InitializeHome, InitializeHome, SRDState.InitializeHoming); Transition(SRDState.Error, SRDMSG.InitializeHome, InitializeHome, SRDState.InitializeHoming); Transition(SRDState.InitializeHoming, FSM_MSG.TIMER, InitializeHomeTimeout, SRDState.Idle); Transition(SRDState.Abort, SRDMSG.InitializeHome, InitializeHome, SRDState.InitializeHoming); Transition(SRDState.Idle, SRDMSG.InitializeHome, InitializeHome, SRDState.InitializeHoming); //Process Recipe Transition(SRDState.Idle, SRDMSG.ProcessRecipe, ProcessRecipe, SRDState.ProcessReciping); Transition(SRDState.ProcessReciping, FSM_MSG.TIMER, ProcessRecipeTimeout, SRDState.Idle); Transition(SRDState.ProcessReciping, SRDMSG.ProcessError, ProcessError, SRDState.ProcessError); Transition(SRDState.ProcessError, FSM_MSG.TIMER, ProcessErrorMonitor, SRDState.Error); //GoToSavedPosition Transition(SRDState.Idle, SRDMSG.GoToSavedPosition, GotoPosition, SRDState.Positioning); Transition(SRDState.Positioning, FSM_MSG.TIMER, GotoPositionTimeout, SRDState.Idle); //StartRotation Transition(SRDState.Idle, SRDMSG.StartRotation, StartRotation, SRDState.Rotating); Transition(SRDState.Rotating, FSM_MSG.TIMER, RotationTimeout, SRDState.Idle); //StopRotation Transition(SRDState.Rotating, SRDMSG.StopRotation, StopRotation, SRDState.Stopping); Transition(SRDState.Stopping, FSM_MSG.TIMER, StopRotationTimeout, SRDState.Idle); //Abort Transition(SRDState.ProcessReciping, SRDMSG.Abort, AbortProcessRecipe, SRDState.Abort); Transition(SRDState.PresenceTesting, SRDMSG.Abort, AbortPresenceTest, SRDState.Abort); Transition(SRDState.AWCCycling, SRDMSG.Abort, AbortAWCCycle, SRDState.Abort); //PresenceTestStart Transition(SRDState.Idle, SRDMSG.PresenceTestStart, PresenceTest, SRDState.PresenceTesting); Transition(SRDState.PresenceTesting, FSM_MSG.TIMER, PresenceTestTimeout, SRDState.Idle); //AWC Cycle Transition(SRDState.Idle, SRDMSG.AWCCycleStart, AWCCycle, SRDState.AWCCycling); Transition(SRDState.AWCCycling, FSM_MSG.TIMER, AWCCycleTimeout, SRDState.Idle); Transition(SRDState.AWCCycling, SRDMSG.HomeAll, HomeAll, SRDState.AWCHoming); Transition(SRDState.AWCHoming, FSM_MSG.TIMER, HomingTimeout, SRDState.AWCCycling); //Retry Transition(SRDState.Error, SRDMSG.Retry, NullFunc, SRDState.Retrying); Transition(SRDState.Retrying, FSM_MSG.TIMER, SRDRetry, SRDState.Retrying); Transition(SRDState.Retrying, SRDMSG.ProcessRecipe, RetryRunRecipe, SRDState.ProcessReciping); //ConfirmComplete Transition(SRDState.Init, SRDMSG.ConfirmComplete, ClearModuleAlarm, SRDState.Init); Transition(SRDState.Idle, SRDMSG.ConfirmComplete, ClearModuleAlarm, SRDState.Idle); Transition(SRDState.Error, SRDMSG.ConfirmComplete, NullFunc, SRDState.ConfirmCompleting); Transition(SRDState.ConfirmCompleting, FSM_MSG.TIMER, ConfirmComplete, SRDState.ConfirmCompleting); Transition(SRDState.ConfirmCompleting, SRDMSG.ProcessRecipe, ConfirmProcessRecipe, SRDState.Idle); //Enter Init Transition(SRDState.Idle, SRDMSG.Init, NullFunc, SRDState.Init); EnumLoop.ForEach((item) => { fsm.MapState((int)item, item.ToString()); }); EnumLoop.ForEach((item) => { fsm.MapMessage((int)item, item.ToString()); }); } /// /// 初始化Routine /// private void InitialRoutine() { _initializeHomeRoutine = new SRDInitializeHomeRoutine(Module.ToString()); _homeRoutine = new SRDHomeRoutine(Module.ToString()); _switchOnRoutine = new SRDSwitchOnRoutine(Module.ToString()); _switchOffRoutine = new SRDSwitchOffRoutine(Module.ToString()); _initializeRoutine = new SRDInitializeRoutine(Module.ToString()); _positionRoutine = new SRDPositionRoutine(Module); _rotationRoutine = new SRDRotationRoutine(Module, _rotationAxis); _presenceTestRoutine = new SRDPresenceTestRoutine(Module.ToString()); _processRecipeRoutine = new SRDProcessRecipeRoutine(Module.ToString(), _rotationAxis, _armAxis, _srdCommon); _awcCycleRoutine = new SRDAWCCycleRoutine(Module); _processErrorRoutine=new SRDProcessErrorRoutine(Module.ToString()); } /// /// 初始化操作 /// private void InitialOperation() { OP.Subscribe($"{Module}.HomeAll", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.HomeAll); }); OP.Subscribe($"{Module}.InitializeHome", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.InitializeHome); }); OP.Subscribe($"{Module}.SwitchOnAll", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.SwitchOn); }); OP.Subscribe($"{Module}.SwitchOffAll", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.SwitchOff); }); OP.Subscribe($"{Module}.CycleManualProcessRecipe", (cmd, args) => { SrdRecipe recipe = RecipeFileManager.Instance.LoadGenericityRecipe(args[0].ToString()); if (recipe == null) { LOG.WriteLog(eEvent.ERR_SRD, Module.ToString(), $"{args[0]} recipe is null"); return false; } object[] objects = new object[args.Length]; objects[0] = recipe; for (int i = 1; i < args.Length; i++) { objects[i] = args[i]; } return CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.ProcessRecipe, objects); }); //OP.Subscribe($"{Module}.Arm.GotoSavedPosition", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.GoToSavedPosition, "Arm", args); }); //OP.Subscribe($"{Module}.Rotation.GotoSavedPosition", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.GoToSavedPosition, "Rotation", args); }); OP.Subscribe($"{Module}.Abort", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.Abort); }); OP.Subscribe($"{Module}.StartRotation", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.StartRotation, "Rotation", args); }); OP.Subscribe($"{Module}.StopRotation", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.StopRotation); }); OP.Subscribe($"{Module}.PresenceTestStart", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.PresenceTestStart, args); }); OP.Subscribe($"{Module}.AWCCycle", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.AWCCycleStart, args); }); } /// /// Enter Init /// public void EnterInit() { if ((SRDState)fsm.State != SRDState.Idle) return; else { CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.Init); } } /// /// 进入Error状态 /// /// /// private bool EnterError(object[] param) { _isHomed = false; return true; } #region Initialized /// /// Initialize /// /// /// private bool InitializeAll(object[] param) { if (fsm.State == (int)MetalState.Initializing) { LOG.WriteLog(eEvent.WARN_SRD, Module.ToString(), "state is Initializing,cannot do initialize"); return false; } return _initializeRoutine.Start() == RState.Running; } /// /// Initialize 监控 /// /// /// private bool InitializeAllTimeout(object[] param) { RState ret = _initializeRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(SRDMSG.Error); return false; } bool result = ret == RState.End; if (result) { _isHomed = false; } return result; } #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(SRDMSG.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(SRDMSG.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; return _homeRoutine.Start() == RState.Running; } /// /// Home超时 /// /// /// private bool HomingTimeout(object[] param) { RState ret = _homeRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(SRDMSG.Error); return false; } bool result = ret == RState.End; if (result) { _isHomed = true; } return result; } #endregion #region Process Recipe /// /// ProcessRecipe /// /// /// private bool ProcessRecipe(object[] param) { SrdRecipe recipe= param[0] as SrdRecipe; if(param.Length >= 2) _cycle = (int)param[1]; bool result = _processRecipeRoutine.Start(param) == RState.Running; if (result) { if (CellItemRecipeTimeManager.Instance.ContainRecipe(recipe.Ppid)) { _recipeTime = _cycle * CellItemRecipeTimeManager.Instance.GetRecipeTotalTime(recipe.Ppid); } else { _recipeTime = 0; } _currentRecipe = recipe; _runRecipeStartTime = DateTime.Now; FaModuleNotifier.Instance.NotifySRDRecipeStart(Module, recipe.Ppid); } return result; } /// /// ProcessRecipe超时 /// /// /// private bool ProcessRecipeTimeout(object[] param) { RState ret = _processRecipeRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(SRDMSG.ProcessError); //记录LotTrack _runRecipeCompleteTime = DateTime.Now; _processRecipeRoutine.SRDLotTrackHeaderDatas.ProcessTime = (_runRecipeCompleteTime - _runRecipeStartTime).TotalSeconds.ToString("F2"); SRDLotTrackUtil.ExportSRDLotTrack(Module.ToString(), _processRecipeRoutine.SRDLotTrackDatas, _processRecipeRoutine.SRDLotTrackHeaderDatas, IsAuto); if (Singleton.Instance.IsAutoRunning) { AlarmList alarmList = new AlarmList(Module.ToString(), ((SRDState)fsm.State).ToString(), (int)SRDMSG.ProcessRecipe, _processRecipeRoutine.ErrorMsg, _processRecipeRoutine.ErrorStep, (int)AlarmType.Error); AlarmListManager.Instance.AddAlarm(alarmList); } if (_currentRecipe != null) { FaModuleNotifier.Instance.NotifySRDRecipeFailed(Module, _currentRecipe.Ppid); } return false; } bool result = ret == RState.End; if (result) { double elapsedMilliseconds = _processRecipeRoutine.ElapsedMilliseconds; int recipeTime = (int)Math.Floor(elapsedMilliseconds / _cycle / 1000); CellItemRecipeTimeManager.Instance.UpdateRecipeTime(_currentRecipe.Ppid, recipeTime); //记录LotTrack _runRecipeCompleteTime = DateTime.Now; _processRecipeRoutine.SRDLotTrackHeaderDatas.ProcessTime = (_runRecipeCompleteTime - _runRecipeStartTime).TotalSeconds.ToString("F2"); SRDLotTrackUtil.ExportSRDLotTrack(Module.ToString(), _processRecipeRoutine.SRDLotTrackDatas, _processRecipeRoutine.SRDLotTrackHeaderDatas, IsAuto); if (_currentRecipe != null) { FaModuleNotifier.Instance.NotifySRDRecipeEnd(Module, _currentRecipe.Ppid); } _currentRecipe = null; AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), SRDState.ProcessReciping.ToString()); } return result; } /// /// Abort Recipe /// /// /// private bool AbortProcessRecipe(object[] param) { _processRecipeRoutine.Abort(); //记录LotTrack _runRecipeCompleteTime = DateTime.Now; _processRecipeRoutine.SRDLotTrackHeaderDatas.ProcessTime = (_runRecipeCompleteTime - _runRecipeStartTime).TotalSeconds.ToString("F2"); SRDLotTrackUtil.ExportSRDLotTrack(Module.ToString(), _processRecipeRoutine.SRDLotTrackDatas, _processRecipeRoutine.SRDLotTrackHeaderDatas, IsAuto); return true; } /// /// 计算剩余时间 /// /// private double CalculateTimeRemain() { if (IsBusy) { return _recipeTime != 0 ? (_recipeTime - Math.Floor((double)_processRecipeRoutine.ElapsedMilliseconds / 1000)) : 0; } else { return 0; } } /// /// ProcessError /// /// /// private bool ProcessError(object[] param) { return _processErrorRoutine.Start(param)==RState.Running; } /// /// Process Error监控 /// /// /// private bool ProcessErrorMonitor(object[] param) { RState state = _processErrorRoutine.Monitor(); if (state == RState.End||state==RState.Failed||state==RState.Timeout) { return true; } return false; } /// /// Retry RunRecipe /// /// /// private bool RetryRunRecipe(object[] param) { int stepIndex = (int)param[0]; bool result = _processRecipeRoutine.Retry(stepIndex) == RState.Running; if (result) { if (_currentRecipe != null) { if (CellItemRecipeTimeManager.Instance.ContainRecipe(_currentRecipe.Ppid)) { _recipeTime = _cycle * CellItemRecipeTimeManager.Instance.GetRecipeTotalTime(_currentRecipe.Ppid); } else { _recipeTime = 0; } _runRecipeStartTime = DateTime.Now; } } return result; } /// /// 确认ProcessRecipe是否完成 /// /// /// private bool ConfirmProcessRecipe(object[] param) { int stepIdex = (int)param[0]; bool result = _processRecipeRoutine.CheckCompleteCondition(stepIdex); if (!result) { if (Singleton.Instance.IsAutoRunning) { AlarmList alarmList = new AlarmList(Module.ToString(), ((SRDState)fsm.State).ToString(), (int)SRDMSG.ProcessRecipe, _processRecipeRoutine.ErrorMsg, _processRecipeRoutine.ErrorStep, (int)AlarmType.Error); AlarmListManager.Instance.AddAlarm(alarmList); } PostMsg(SRDMSG.Error); } else { if (Singleton.Instance.IsAutoRunning) { AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), SRDState.ProcessReciping.ToString()); } } return result; } #endregion #region AWC Cycle /// /// AWC Cycle /// /// private bool AWCCycle(object[] param) { return _awcCycleRoutine.Start(param) == RState.Running; } /// /// AWC Cycle超时 /// /// /// private bool AWCCycleTimeout(object[] param) { RState ret = _awcCycleRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { _isAWCCycling = false; PostMsg(SRDMSG.Error); return false; } //设置IsPresenceTesting if (ret == RState.Running) { _isAWCCycling = true; } else { _isAWCCycling = false; } return ret == RState.End; } /// /// Abort AWC Cycle /// /// /// private bool AbortAWCCycle(object[] param) { _awcCycleRoutine.Abort(); return true; } #endregion #region InitializeHome /// /// InitializeHome /// /// /// private bool InitializeHome(object[] param) { _isHomed = false; return _initializeHomeRoutine.Start() == RState.Running; } /// /// InitializeHome超时 /// /// /// private bool InitializeHomeTimeout(object[] param) { RState ret = _initializeHomeRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(SRDMSG.Error); return false; } bool result = ret == RState.End; if (result) { _isHomed = true; } return result; } #endregion #region RunRecipeRetry /// /// Retry /// /// /// private bool SRDRetry(object[] param) { AlarmList alarmList = AlarmListManager.Instance.GetAlarmListByModule(Module.ToString()); if (alarmList != null) { CheckToPostMessage(eEvent.ERR_SRD, 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 == SRDState.ProcessReciping.ToString()) { CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.ProcessRecipe, alarmList.ModuleStep); } else { PostMsg(SRDState.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_SRD, Module.ToString(), (int)SRDMSG.InitializeHome)) { return (int)SRDMSG.Initialize; } else { return (int)FSM_MSG.NONE; } case "Retry": if (CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.Retry, args)) { return (int)SRDMSG.Retry; } else { return (int)FSM_MSG.NONE; } case "ConfirmComplete": if (CheckToPostMessage(eEvent.ERR_SRD, Module.ToString(), (int)SRDMSG.ConfirmComplete, args)) { return (int)SRDMSG.ConfirmComplete; } else { return (int)FSM_MSG.NONE; } } return (int)FSM_MSG.NONE; } #region GoToPosition /// /// Go to Position /// /// /// private bool GotoPosition(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) { return _positionRoutine.Start(result.axis, position) == RState.Running; } else { return false; } } /// /// 检验GotoPosition前置条件 /// /// /// /// private (bool result, JetAxisBase axis) CheckGotoPositionPreCondition(string axis, string position) { switch (axis) { case "Rotation": return (_rotationAxis.CheckGotoPosition(position), _rotationAxis); case "Arm": return (_armAxis.CheckGotoPosition(position), _armAxis); default: return (false, null); } } /// /// GotoPosition超时 /// /// /// private bool GotoPositionTimeout(object[] param) { RState ret = _positionRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { return true; } return ret == RState.End; } #endregion #region 旋转 /// /// 开始旋转 /// /// /// private bool StartRotation(object[] param) { string axis = param[0].ToString(); object[] objs = (object[])param[1]; double time = double.Parse(objs[0].ToString()); double speed = double.Parse(objs[1].ToString()); return _rotationRoutine.Start(_rotationAxis, time, speed) == RState.Running; } /// /// RotationTimeout /// /// /// private bool RotationTimeout(object[] param) { RState ret = _rotationRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { //PostMsg(SRDMSG.Error); return true; } return ret == RState.End; } /// /// 停止旋转 /// /// /// private bool StopRotation(object[] param) { _rotationAxis.StopPositionOperation(); return _rotationAxis.Status == RState.Running; } /// /// 停止旋转监控 /// /// /// private bool StopRotationTimeout(object[] param) { RState ret = _rotationAxis.Status; if (ret == RState.Failed || ret == RState.Timeout) { //PostMsg(SRDMSG.Error); return true; } return ret == RState.End; } #endregion #region PresenceTest private bool PresenceTest(object[] param) { _recipeTime = 0; return _presenceTestRoutine.Start(param) == RState.Running; } private bool PresenceTestTimeout(object[] param) { RState ret = _presenceTestRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { _isPresenceTesting = false; PostMsg(SRDMSG.Error); return false; } //设置IsPresenceTesting if (ret == RState.Running) { _isPresenceTesting = true; } else { _isPresenceTesting = false; } return ret == RState.End; } /// /// Abort PresenceTest /// /// /// private bool AbortPresenceTest(object[] param) { _presenceTestRoutine.Abort(); return true; } #endregion /// /// 获取当前子状态机 /// private string GetCurrentStateMachine() { string state = ""; switch ((SRDState)fsm.State) { case SRDState.Init: state = "Init"; break; case SRDState.Initializing: state = _initializeRoutine.CurrentStateMachine; break; case SRDState.Homing: state = _homeRoutine.CurrentStateMachine; break; case SRDState.SwitchOning: state = _switchOnRoutine.CurrentStateMachine; break; case SRDState.SwitchOffing: state = _switchOffRoutine.CurrentStateMachine; break; case SRDState.Positioning: state = _positionRoutine.CurrentStateMachine; break; case SRDState.Rotating: state = _rotationRoutine.CurrentStateMachine; break; case SRDState.PresenceTesting: state = _presenceTestRoutine.CurrentStateMachine; break; case SRDState.ProcessReciping: state = _processRecipeRoutine.CurrentStateMachine; break; case SRDState.AWCCycling: state = _awcCycleRoutine.CurrentStateMachine; break; default: state = Enum.GetName(typeof(SRDState),fsm.State); break; } return state; } /// /// 设置IsAWCCycling /// /// public void SetIsAWCCycling(bool flag) { _isAWCCycling = flag; } } public enum SRDMSG { Initialize, InitializeHome, ProcessRecipe, ResumeError, SwitchOn, SwitchOff, HomeAll, Error, GoToSavedPosition, Abort, StartRotation, StopRotation, PresenceTestStart, PresenceTestStop, AWCCycleStart, Init, ProcessError, Retry, ConfirmComplete } }