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.RT.SCCore; using Aitex.Core.Util; using Aitex.Core.Utilities; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.Common.Utilities; using MECF.Framework.Common.WaferHolder; using CyberX8_Core; using CyberX8_RT.Devices.AXIS; using CyberX8_RT.Devices.Loader; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using MECF.Framework.Common.Alarm; using MECF.Framework.Common.CommonData; using MECF.Framework.Common.Routine; using System.Collections; using System.Windows.Markup; using MECF.Framework.Common.CommonData.Loader; using Aitex.Core.Common; using MECF.Framework.RT.Core.Equipments; using CyberX8_RT.Modules.Dryer; using System.Runtime.CompilerServices; namespace CyberX8_RT.Modules.Loader { public class LoaderEntity : Entity, IEntity, IModuleEntity { public enum LotTrackDatasStatus { None, Half, Complete } #region 属性 public ModuleName Module { get; private set; } public bool IsInit { get { return fsm.State == (int)LOADERSTATE.Init; } } public bool IsIdle { get { return fsm.State == (int)LOADERSTATE.Idle; } } public bool IsError { get { return fsm.State == (int)LOADERSTATE.Error; } } public bool IsBusy { get { return !IsInit && !IsError && !IsIdle; } } public bool IsAuto { get; } = true; /// /// 是否为工程模式 /// public bool IsEngineering { get; } = false; /// /// 是否为产品模式 /// public bool IsProduction { get; } = true; public bool IsHomed { get { return _isHomed; } } /// /// 当前状态机状态 /// public int State { get { return fsm.State; } } /// /// 是否禁用 /// public bool IsDisable { get; internal set; } /// /// Rotation是否SwitchOn /// public bool IsRotationSwitchOn { get { return _rotationAxis.IsSwitchOn; } } /// /// ShuttleA是否SwitchOn /// public bool IsShuttleASwitchOn { get { return _shuttleAAxis.IsSwitchOn; } } /// /// ShuttleB是否SwitchOn /// public bool IsShuttleBSwitchOn { get { return _shuttleBAxis.IsSwitchOn; } } /// /// TiltA是否SwitchOn /// public bool IsTiltASwitchOn { get { return _tiltAAxis.IsSwitchOn; } } /// /// TiltB是否SwitchOn /// public bool IsTiltBSwitchOn { get { return _tiltBAxis.IsSwitchOn; } } /// /// CrsA是否SwitchOn /// public bool IsCrsASwitchOn { get { return _crsAAxis.IsSwitchOn; } } /// /// CrsB是否SwitchOn /// public bool IsCrsBSwitchOn { get { return _crsBAxis.IsSwitchOn; } } /// /// WaferHolder信息 /// public WaferHolderInfo WaferHolderInfo { get { return WaferHolderManager.Instance.GetWaferHolder("Loader"); } } /// /// A面Wafer尺寸 /// public int SideAWaferSize { get { return _sideAWaferSize; } } /// /// B面Wafer尺寸 /// public int SideBWaferSize { get { return _sideBWaferSize; } } #endregion #region 内部变量 private bool _isHomed = false; private IRoutine _currentRoutine; /// /// Loader当前unload、load操作Slot /// private Dictionary> _loaderOperatingWaferInfosList = new Dictionary> { { "unload", new List(new string[2]) }, { "load", new List(new string[2]) } }; #region Axis JetAxisBase _shuttleAAxis; JetAxisBase _shuttleBAxis; JetAxisBase _tiltAAxis; JetAxisBase _tiltBAxis; JetAxisBase _crsAAxis; JetAxisBase _crsBAxis; JetAxisBase _rotationAxis; LoaderSideDevice _sideA; LoaderSideDevice _sideB; LoaderCommonDevice _loaderCommon; int _sideAWaferSize; int _sideBWaferSize; #endregion #region routine private LoaderHomeAllRoutine _homeAllRoutine; private LoaderSwitchAllOnRoutine _switchAllOnRoutine; private LoaderSwitchAllOffRoutine _switchAllOffRoutine; private LoaderUnloadSideRoutine _unloadSideRoutine; private LoaderLoadSideRoutine _loadSideRoutine; #endregion #region LotTrackDatas /// /// Load LotTrackData /// private List _loaderLotTrackDatas = new List(); /// /// Flow Test LotTrackData /// private List _flowLotTrackDatas = new List(); /// /// Load / Unload Time /// private List _timeList = new List(); /// /// Load Start Time(file name) /// private DateTime _startTime; /// /// LotTrackHead /// private LotTrackFileHeaderCommonData _headerdata; /// /// Load Datas Status private LotTrackDatasStatus _datasStatus = LotTrackDatasStatus.None; /// /// Flow Test Datas status /// private LotTrackDatasStatus _flowDatasStatus = LotTrackDatasStatus.None; /// /// WaferGroup str /// private string _preWaferGroup = ""; #endregion #endregion /// /// 构造函数 /// /// public LoaderEntity(ModuleName module) { this.Module = module; _shuttleAAxis = DEVICE.GetDevice($"{module}.ShuttleA"); _shuttleBAxis = DEVICE.GetDevice($"{module}.ShuttleB"); _tiltAAxis = DEVICE.GetDevice($"{module}.TiltA"); _tiltBAxis = DEVICE.GetDevice($"{module}.TiltB"); _crsAAxis = DEVICE.GetDevice($"{module}.LSA"); _crsBAxis = DEVICE.GetDevice($"{module}.LSB"); _rotationAxis = DEVICE.GetDevice($"{module}.Rotation"); _sideA = DEVICE.GetDevice($"{Module}.SideA"); _sideB = DEVICE.GetDevice($"{Module}.SideB"); _loaderCommon = DEVICE.GetDevice($"{module}.Common"); WaferManager.Instance.SubscribeLocation(Module, 2); _sideAWaferSize = SC.GetValue("Loader1.SideAWaferSize"); _sideBWaferSize = SC.GetValue("Loader1.SideBWaferSize"); InitialOperation(); InitializeRoutine(); InitialDATA(); InitialFsm(); } /// /// 初始化操作 /// private void InitialOperation() { OP.Subscribe($"{Module}.Abort", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_LOADER, Module.ToString(), (int)LoaderMSG.Abort); }); OP.Subscribe($"{Module}.ClearError", (cmd, args) => { return CheckToPostMessage(eEvent.ERR_LOADER, Module.ToString(), (int)LoaderMSG.ClearError); }); OP.Subscribe($"{Module}.Common.HomeAll", (cmd, args) => { PostMsg((int)LoaderMSG.HomeAll); return true; }); OP.Subscribe($"{Module}.Common.SwitchOnAll", (cmd, args) => { PostMsg((int)LoaderMSG.SwitchOnAll); return true; }); OP.Subscribe($"{Module}.Common.SwitchOffAll", (cmd, args) => { PostMsg((int)LoaderMSG.SwitchOffAll); return true; }); } /// /// 初始化Routine /// private void InitializeRoutine() { _homeAllRoutine=new LoaderHomeAllRoutine(Module.ToString()); _switchAllOnRoutine=new LoaderSwitchAllOnRoutine(Module.ToString()); _switchAllOffRoutine=new LoaderSwitchAllOffRoutine(Module.ToString()); _unloadSideRoutine = new LoaderUnloadSideRoutine(Module.ToString()); _loadSideRoutine=new LoaderLoadSideRoutine(Module.ToString()); } /// /// 初始化数据 /// private void InitialDATA() { InitializeSvid(); DATA.Subscribe($"{Module}.FsmState", () => ((LOADERSTATE)fsm.State).ToString(), SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.IsHomed", () => _isHomed, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.IsError", () => IsError, SubscriptionAttribute.FLAG.IgnoreSaveDB); } /// /// 初始化SVID /// private void InitializeSvid() { DATA.Subscribe($"{Module}.State", () => ((LOADERSTATE)fsm.State).ToString(), SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.LotID", () => WaferHolderInfo?.LotId, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.WSID", () => WaferHolderInfo?.Id, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.LSAID", () => WaferHolderInfo?.CrsAId, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.LSBID", () => WaferHolderInfo?.CrsBId, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.SequenceRecipe", () => WaferHolderInfo?.SequenceId, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.WaferAID", () => WaferHolderInfo?.WaferAId, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.WaferBID", () => WaferHolderInfo?.WaferBId, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.Task", () => WaferHolderInfo?.CurrentControlJobId, SubscriptionAttribute.FLAG.IgnoreSaveDB); } /// /// 检验所有电机是否已经完成Home /// /// private bool CheckAllAxisIsHomed() { bool shuttleAIsHomed = _shuttleAAxis.CheckAxisIsAreadyHomed(); if (!shuttleAIsHomed) { return false; } bool shuttleAMid = _shuttleAAxis.CheckPositionIsInStation(_shuttleAAxis.MotionData.MotorPosition, "MID"); if (!shuttleAMid) { return false; } bool shuttleBIsHomed = _shuttleBAxis.CheckAxisIsAreadyHomed(); if (!shuttleAIsHomed) { return false; } bool shuttleBMid = _shuttleBAxis.CheckPositionIsInStation(_shuttleBAxis.MotionData.MotorPosition, "MID"); if (!shuttleAMid) { return false; } bool tiltAIsHomed = _tiltAAxis.CheckAxisIsAreadyHomed(); if (!tiltAIsHomed) { return false; } bool tiltAVert = _tiltAAxis.CheckPositionIsInStation(_tiltAAxis.MotionData.MotorPosition, "VERT"); if (!tiltAVert) { return false; } bool tiltBIsHomed = _tiltBAxis.CheckAxisIsAreadyHomed(); if (!tiltBIsHomed) { return false; } bool tiltBVert = _tiltBAxis.CheckPositionIsInStation(_tiltBAxis.MotionData.MotorPosition, "VERT"); if (!tiltBVert) { return false; } bool crsAIsHomed = _crsAAxis.CheckAxisIsAreadyHomed(); if (!crsAIsHomed) { return false; } bool crsASetUp = _crsAAxis.CheckPositionIsInStation(_crsAAxis.MotionData.MotorPosition, $"Setup{SideAWaferSize}"); if (!crsASetUp) { return false; } bool crsBIsHomed = _crsBAxis.CheckAxisIsAreadyHomed(); if (!crsBIsHomed) { return false; } bool crsBSetUp = _crsBAxis.CheckPositionInStationIgnoreWaferSize(_crsBAxis.MotionData.MotorPosition, $"Setup{SideBWaferSize}"); if (!crsBSetUp) { return false; } bool rotationIsHomed = _rotationAxis.CheckAxisIsAreadyHomed(); if (!rotationIsHomed) { return false; } bool rotationClosed = _rotationAxis.CheckPositionIsInStation(_rotationAxis.MotionData.MotorPosition, "TRNPA"); if (!crsASetUp) { return false; } return true; } /// /// 初始化状态机 /// private void InitialFsm() { if (CheckAllAxisIsHomed()) { _isHomed = true; fsm = new StateMachine(Module.ToString(), (int)LOADERSTATE.Idle, 100); } else { fsm = new StateMachine(Module.ToString(), (int)LOADERSTATE.Init, 100); } fsm.EnableRepeatedMsg(true); AnyStateTransition(LoaderMSG.Error, EnterError, LOADERSTATE.Error); AnyStateTransition(LoaderMSG.ReturnInit, EnterInit, LOADERSTATE.Init); AnyStateTransition(LoaderMSG.ReturnIdle, NullFunc, LOADERSTATE.Idle); AnyStateTransition(LoaderMSG.Abort, Abort, LOADERSTATE.Init); //clear error Transition(LOADERSTATE.Error, LoaderMSG.ClearError, ResumeError, LOADERSTATE.Init); //HomeAll AnyStateTransition(LoaderMSG.HomeAll, HomeAll, LOADERSTATE.Homing); Transition(LOADERSTATE.Homing, FSM_MSG.TIMER, HomeAllMonitor, LOADERSTATE.Idle); //Switch On All Transition(LOADERSTATE.Error, LoaderMSG.SwitchOnAll, SwitchOnAll, LOADERSTATE.SwitchOning); Transition(LOADERSTATE.Init, LoaderMSG.SwitchOnAll, SwitchOnAll, LOADERSTATE.SwitchOning); Transition(LOADERSTATE.Idle, LoaderMSG.SwitchOnAll, SwitchOnAll, LOADERSTATE.SwitchOning); Transition(LOADERSTATE.SwitchOning, FSM_MSG.TIMER, SwitchOnAllMonitor, LOADERSTATE.Init); //Switch Off All Transition(LOADERSTATE.Error, LoaderMSG.SwitchOffAll, SwitchOffAll, LOADERSTATE.SwitchOffing); Transition(LOADERSTATE.Init, LoaderMSG.SwitchOffAll, SwitchOffAll, LOADERSTATE.SwitchOffing); Transition(LOADERSTATE.Idle, LoaderMSG.SwitchOffAll, SwitchOffAll, LOADERSTATE.SwitchOffing); Transition(LOADERSTATE.SwitchOffing, FSM_MSG.TIMER, SwitchOffAllMonitor, LOADERSTATE.Init); //Prepare for Place Transition(LOADERSTATE.Idle, LoaderMSG.PrepareForPlace, PrePareForPlace, LOADERSTATE.PrepreForPlacing); Transition(LOADERSTATE.PrepreForPlacing, FSM_MSG.TIMER, PrepareForPlaceMonitor, LOADERSTATE.WaitForUnload); Transition(LOADERSTATE.Idle, LoaderMSG.ReadyForPuf, NullFunc, LOADERSTATE.WaitForUnload); Transition(LOADERSTATE.WaitForUnload, LoaderMSG.UnloadSide, UnloadSide, LOADERSTATE.Unloading); Transition(LOADERSTATE.Unloading, FSM_MSG.TIMER, UnloadSideMonitor, LOADERSTATE.WaitForLoad); Transition(LOADERSTATE.WaitForLoad, LoaderMSG.LoadSide, LoadSide, LOADERSTATE.Loading); Transition(LOADERSTATE.Loading, FSM_MSG.TIMER, LoadSideMonitor, LOADERSTATE.Idle); //Flip Transition(LOADERSTATE.Idle, LoaderMSG.WaitFlip, NullFunc, LOADERSTATE.WaitForFlip); Transition(LOADERSTATE.WaitForFlip,LoaderMSG.PrepareForPlace, PrePareForPlace, LOADERSTATE.PrepreForPlacing); //Retry Transition(LOADERSTATE.Error, LoaderMSG.Retry, NullFunc, LOADERSTATE.Retrying); Transition(LOADERSTATE.Retrying,FSM_MSG.TIMER,LoaderRetry,LOADERSTATE.Retrying); Transition(LOADERSTATE.Retrying, LoaderMSG.UnloadSide, RetryUnloadSide, LOADERSTATE.Unloading); Transition(LOADERSTATE.Retrying, LoaderMSG.LoadSide, RetryLoadSide, LOADERSTATE.Loading); //ConfirmComplete Transition(LOADERSTATE.Init, LoaderMSG.ConfirmComplete, ClearModuleAlarm, LOADERSTATE.Init); Transition(LOADERSTATE.Idle, LoaderMSG.ConfirmComplete, ClearModuleAlarm, LOADERSTATE.Idle); Transition(LOADERSTATE.Error, LoaderMSG.ConfirmComplete, NullFunc, LOADERSTATE.ConfirmCompleting); Transition(LOADERSTATE.ConfirmCompleting,FSM_MSG.TIMER,ConfirmComplete, LOADERSTATE.ConfirmCompleting); Transition(LOADERSTATE.ConfirmCompleting, LoaderMSG.PrepareForPlace, NullFunc, LOADERSTATE.WaitForUnload); Transition(LOADERSTATE.ConfirmCompleting,LoaderMSG.UnloadSide,ConfirmUnloadSide, LOADERSTATE.WaitForLoad); Transition(LOADERSTATE.ConfirmCompleting, LoaderMSG.LoadSide, ConfirmLoadSide, LOADERSTATE.Idle); EnumLoop.ForEach((item) => { fsm.MapState((int)item, item.ToString()); }); EnumLoop.ForEach((item) => { fsm.MapMessage((int)item, item.ToString()); }); } /// /// 恢复错误 /// /// /// private bool ResumeError(object[] param) { if (_isHomed) { PostMsg(LoaderMSG.ReturnIdle); return false; } return true; } /// /// 检验Loader两边waferSize不一致 /// /// public bool CheckLoaderWaferSizeNotEqual() { return _sideAWaferSize != _sideBWaferSize; } #region Abort private bool Abort(object parameter) { bool preHomed = IsHomed; _shuttleAAxis.StopPositionOperation(); _shuttleBAxis.StopPositionOperation(); _tiltAAxis.StopPositionOperation(); _tiltBAxis.StopPositionOperation(); _crsAAxis.StopPositionOperation(); _crsBAxis.StopPositionOperation(); _rotationAxis.StopPositionOperation(); if (_currentRoutine != null) { _currentRoutine.Abort(); _currentRoutine = null; } if (preHomed) { PostMsg(LoaderMSG.ReturnIdle); return false; } //Header信息 if (_headerdata != null) { WaferHolderInfo info = WaferHolderManager.Instance.GetWaferHolder(Module.ToString()); _headerdata.SequenceRecipe = (info != null ? $"{info.SequenceRecipe.SequenceType}\\" + $"{info.SequenceRecipe.Ppid}.seq.rcp" : null); _headerdata.ProcessTransferList = (info != null ? info.SchedulerModules : null); WaferInfo waferInfo = WaferManager.Instance.GetWafer(Module, _unloadSideRoutine.IsSideA ? 0 : 1); LoaderLotTrackUtil.ExportLoaderLotTrack(Module.ToString(), _headerdata, _loaderLotTrackDatas, _datasStatus, _timeList, waferInfo, "SeqGroup", false, _startTime, _flowLotTrackDatas, _flowDatasStatus); } return true; } #endregion /// /// 进入错误状态 /// /// /// private bool EnterError(object param) { return true; } /// /// 进入初始化状态 /// /// /// private bool EnterInit(object param) { _isHomed = false; return true; } #region HomeAll /// /// Home All /// /// /// private bool HomeAll(object[] param) { _isHomed = false; bool result= _homeAllRoutine.Start(param) == RState.Running; if (result) { _currentRoutine = _homeAllRoutine; } return result; } /// /// Load All监控 /// /// /// private bool HomeAllMonitor(object[] param) { RState state = _homeAllRoutine.Monitor(); if (state==RState.Failed||state==RState.Timeout) { _currentRoutine = null; PostMsg(LoaderMSG.Error); return false; } bool result= state == RState.End; if(result) { _currentRoutine = null; _isHomed = true; } return result; } #endregion #region Switch On All private bool SwitchOnAll(object[] param) { return _switchAllOnRoutine.Start(param) == RState.Running; } private bool SwitchOnAllMonitor(object[] param) { RState state = _switchAllOnRoutine.Monitor(); if (state == RState.Failed || state == RState.Timeout) { PostMsg(LoaderMSG.ReturnInit); return false; } bool result= state == RState.End; if(result) { _isHomed = false; } return result; } #endregion #region Switch Off All private bool SwitchOffAll(object[] param) { return _switchAllOffRoutine.Start(param) == RState.Running; } private bool SwitchOffAllMonitor(object[] param) { RState state = _switchAllOffRoutine.Monitor(); if (state == RState.Failed || state == RState.Timeout) { PostMsg(LoaderMSG.ReturnInit); return false; } bool result = state == RState.End; if (result) { _isHomed = false; } return result; } #endregion #region Prepare for Place /// /// Prepare For Place /// /// private bool PrePareForPlace(object[] param) { //默认"TRNPA" string str = (param==null||param.Length==0)? "TRNPA":param[0].ToString(); return _rotationAxis.PositionStation(str); } /// /// Prepare For Place监控 /// /// /// private bool PrepareForPlaceMonitor(object param) { RState ret = _rotationAxis.Status; if (ret == RState.End) { return true; } if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(LoaderMSG.Error); } return false; } #endregion #region Unload Side /// /// Unload Side /// /// /// private bool UnloadSide(object[] param) { bool result= _unloadSideRoutine.Start(param) == RState.Running; if(result) { _currentRoutine = _unloadSideRoutine; InitLotTrackDatas(); _timeList.Add(DateTime.Now); } return result; } /// /// Retry UloadSide /// /// /// private bool RetryUnloadSide(object[] param) { int stepIndex = (int)param[0]; bool result = _unloadSideRoutine.Retry(stepIndex)==RState.Running; if (result) { _datasStatus = LotTrackDatasStatus.Half; _loaderLotTrackDatas.Clear(); _currentRoutine = _unloadSideRoutine; } return result; } /// /// Unload Side监控 /// /// /// private bool UnloadSideMonitor(object param) { RState ret = _unloadSideRoutine.Monitor(); if (ret == RState.End) { AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), LOADERSTATE.Unloading.ToString()); _loaderLotTrackDatas.AddRange(_unloadSideRoutine.UnloadLotTrackDatas); _timeList.Add(DateTime.Now); //Header信息 WaferHolderInfo info = WaferHolderManager.Instance.GetWaferHolder(Module.ToString()); _headerdata.SequenceRecipe = ((info != null && info.SequenceRecipe != null) ? $"{info.SequenceRecipe.SequenceType}\\" + $"{info.SequenceRecipe.Ppid}.seq.rcp" : ""); if (info != null) { _headerdata.ProcessTransferList.AddRange(info.SchedulerModules); info.SchedulerModules.Clear(); } WaferInfo waferInfo = WaferManager.Instance.GetWafer(Module, _unloadSideRoutine.IsSideA ? 0 : 1); LoaderLotTrackUtil.ExportLoaderLotTrack(Module.ToString(), _headerdata, _loaderLotTrackDatas, _datasStatus, _timeList, waferInfo, _unloadSideRoutine.WaferGroup, false, _startTime); return true; } if (ret == RState.Failed || ret == RState.Timeout) { if (Singleton.Instance.IsAutoRunning) { AlarmList alarmList = new AlarmList(Module.ToString(), ((LOADERSTATE)fsm.State).ToString(), (int)LoaderMSG.UnloadSide, _unloadSideRoutine.ErrorMsg, _unloadSideRoutine.ErrorStep, (int)AlarmType.Error); AlarmListManager.Instance.AddAlarm(alarmList); } PostMsg(LoaderMSG.Error); _loaderLotTrackDatas.AddRange(_unloadSideRoutine.UnloadLotTrackDatas); ////Header信息 WaferHolderInfo info = WaferHolderManager.Instance.GetWaferHolder(Module.ToString()); _headerdata.SequenceRecipe = ((info != null && info.SequenceRecipe != null) ? $"{info.SequenceRecipe.SequenceType}\\" + $"{info.SequenceRecipe.Ppid}.seq.rcp" : ""); if (info != null) { _headerdata.ProcessTransferList.AddRange(info.SchedulerModules); info.SchedulerModules.Clear(); } WaferInfo waferInfo = WaferManager.Instance.GetWafer(Module, _unloadSideRoutine.IsSideA ? 0 : 1); LoaderLotTrackUtil.ExportLoaderLotTrack(Module.ToString(), _headerdata, _loaderLotTrackDatas, _datasStatus, _timeList, waferInfo, _unloadSideRoutine.WaferGroup, false, _startTime); } return false; } /// /// 确认UnloadAll是否完成 /// /// /// private bool ConfirmUnloadSide(object[] param) { int stepIdex=(int)param[0]; bool result = _unloadSideRoutine.CheckCompleteCondition(stepIdex); if(!result) { if (Singleton.Instance.IsAutoRunning) { AlarmList alarmList = new AlarmList(Module.ToString(), ((LOADERSTATE)fsm.State).ToString(), (int)LoaderMSG.UnloadSide, _unloadSideRoutine.ErrorMsg, _unloadSideRoutine.ErrorStep, (int)AlarmType.Error); AlarmListManager.Instance.AddAlarm(alarmList); } PostMsg(LoaderMSG.Error); } else { if (Singleton.Instance.IsAutoRunning) { AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), LOADERSTATE.Unloading.ToString()); } } return result; } #endregion #region Load Side /// /// Load Side /// /// /// private bool LoadSide(object[] param) { bool result= _loadSideRoutine.Start(param) == RState.Running; if(result) { _currentRoutine = _loadSideRoutine; InitLotTrackDatas(); } return result; } /// /// Retry LoadSide /// /// /// private bool RetryLoadSide(object[] param) { int stepIndex = (int)param[0]; bool result = _loadSideRoutine.Retry(stepIndex) == RState.Running; if (result) { SetLotTrackDatasStatus(stepIndex); _currentRoutine = _loadSideRoutine; } return result; } /// /// 监控LoadSide /// /// /// private bool LoadSideMonitor(object param) { RState ret = _loadSideRoutine.Monitor(); if (ret == RState.End) { AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(), LOADERSTATE.Loading.ToString()); _loaderLotTrackDatas.AddRange(_loadSideRoutine.LoadLotTrackDatas); _timeList.AddRange(_loadSideRoutine.LoadTimeList); _flowLotTrackDatas.AddRange(_loadSideRoutine.FlowLotTrackDatas); //Header信息 WaferHolderInfo info = WaferHolderManager.Instance.GetWaferHolder(Module.ToString()); _headerdata.SequenceRecipe = ((info != null && info.SequenceRecipe != null) ? $"{info.SequenceRecipe.SequenceType}\\" + $"{info.SequenceRecipe.Ppid}.seq.rcp" : ""); if (info != null) { _headerdata.ProcessTransferList.AddRange(info.SchedulerModules); info.SchedulerModules.Clear(); } WaferInfo waferInfo = WaferManager.Instance.GetWafer(Module, _loadSideRoutine.IsSideA ? 0 : 1); CheckStartTime(_loadSideRoutine.WaferGroup); LoaderLotTrackUtil.ExportLoaderLotTrack(Module.ToString(), _headerdata, _loaderLotTrackDatas, _datasStatus, _timeList, waferInfo, _loadSideRoutine.WaferGroup, true, _startTime, _flowLotTrackDatas, _flowDatasStatus); return true; } if (ret == RState.Failed || ret == RState.Timeout) { if (Singleton.Instance.IsAutoRunning) { AlarmList alarmList = new AlarmList(Module.ToString(), ((LOADERSTATE)fsm.State).ToString(), (int)LoaderMSG.LoadSide, _loadSideRoutine.ErrorMsg, _loadSideRoutine.ErrorStep, (int)AlarmType.Error); AlarmListManager.Instance.AddAlarm(alarmList); } PostMsg(LoaderMSG.Error); _loaderLotTrackDatas.AddRange(_loadSideRoutine.LoadLotTrackDatas); _timeList.AddRange(_loadSideRoutine.LoadTimeList); _flowLotTrackDatas.AddRange(_loadSideRoutine.FlowLotTrackDatas); //Header信息 WaferHolderInfo info = WaferHolderManager.Instance.GetWaferHolder(Module.ToString()); _headerdata.SequenceRecipe = ((info != null && info.SequenceRecipe != null) ? $"{info.SequenceRecipe.SequenceType}\\" + $"{info.SequenceRecipe.Ppid}.seq.rcp" : ""); if (info != null) { _headerdata.ProcessTransferList.AddRange(info.SchedulerModules); info.SchedulerModules.Clear(); } WaferInfo waferInfo = WaferManager.Instance.GetWafer(Module, _loadSideRoutine.IsSideA ? 0 : 1); LoaderLotTrackUtil.ExportLoaderLotTrack(Module.ToString(), _headerdata, _loaderLotTrackDatas, _datasStatus, _timeList, waferInfo, _loadSideRoutine.WaferGroup, true, _startTime, _flowLotTrackDatas, _flowDatasStatus); } return false; } /// /// 确认UnloadSide是否完成 /// /// /// private bool ConfirmLoadSide(object[] param) { int stepIdex = (int)param[0]; bool result = _loadSideRoutine.CheckCompleteCondition(stepIdex); if (!result) { if (Singleton.Instance.IsAutoRunning) { AlarmList alarmList = new AlarmList(Module.ToString(), ((LOADERSTATE)fsm.State).ToString(), (int)LoaderMSG.LoadSide, _loadSideRoutine.ErrorMsg, _loadSideRoutine.ErrorStep, (int)AlarmType.Error); AlarmListManager.Instance.AddAlarm(alarmList); } PostMsg(LoaderMSG.Error); } else { if (Singleton.Instance.IsAutoRunning) { AlarmListManager.Instance.CheckModuleAlamAndRemove(Module.ToString(),LOADERSTATE.Loading.ToString()); } } return result; } #endregion #region LotTrack /// /// Init LotTrackDatas /// private void InitLotTrackDatas() { _loaderLotTrackDatas.Clear(); _flowLotTrackDatas.Clear(); _timeList.Clear(); //Header信息 _headerdata = new LotTrackFileHeaderCommonData(); _headerdata.SoftWareVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(); if (SC.ContainsItem("System.ToolID")) _headerdata.ToolID = SC.GetStringValue("System.ToolID"); _headerdata.ProcessTransferList = new List(); _datasStatus = LotTrackDatasStatus.None; _flowDatasStatus = LotTrackDatasStatus.None; } /// /// Set LotTrack Datas Status /// /// private void SetLotTrackDatasStatus(int stepIndex) { if (stepIndex == 0 || stepIndex == -1) { _datasStatus = LotTrackDatasStatus.Half; _flowDatasStatus = LotTrackDatasStatus.None; } else if (stepIndex == 1) { _datasStatus = LotTrackDatasStatus.Complete; _flowDatasStatus = LotTrackDatasStatus.None; } else { _datasStatus = LotTrackDatasStatus.Complete; _flowDatasStatus = LotTrackDatasStatus.Complete; } _loaderLotTrackDatas.Clear(); _flowLotTrackDatas.Clear(); } /// /// Check WaferGroup change /// /// /// private void CheckStartTime(string currentWaferGroup) { if (!currentWaferGroup.Equals(_preWaferGroup)) { _preWaferGroup = currentWaferGroup; _startTime = _timeList[0]; } } #endregion #region LoaderRetry /// /// Retry /// /// /// private bool LoaderRetry(object[] param) { AlarmList alarmList = AlarmListManager.Instance.GetAlarmListByModule(Module.ToString()); if (alarmList != null) { CheckToPostMessage(eEvent.ERR_LOADER, 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==LOADERSTATE.Unloading.ToString()) { CheckToPostMessage(eEvent.ERR_LOADER, Module.ToString(),(int)LoaderMSG.UnloadSide,alarmList.ModuleStep); } else if(alarmList.ModuleState==LOADERSTATE.Loading.ToString()) { CheckToPostMessage(eEvent.ERR_LOADER, Module.ToString(), (int)LoaderMSG.LoadSide,alarmList.ModuleStep); } else if (alarmList.ModuleState == LOADERSTATE.PrepreForPlacing.ToString()) { CheckToPostMessage(eEvent.ERR_LOADER, Module.ToString(), (int)LoaderMSG.PrepareForPlace, alarmList.ModuleStep); } else { PostMsg(LoaderMSG.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_LOADER, Module.ToString(), (int)LoaderMSG.HomeAll)) { return (int)FSM_MSG.NONE; } else { return (int)FSM_MSG.ALARM; } case "Abort": CheckToPostMessage(eEvent.ERR_LOADER, Module.ToString(), (int)LoaderMSG.Abort); return (int)FSM_MSG.NONE; case "PrepareForPlace": if (State == (int)LOADERSTATE.WaitForUnload||State==(int)LOADERSTATE.PrepreForPlacing) { return (int)LoaderMSG.PrepareForPlace; } if (CheckToPostMessage(eEvent.WARN_LOADER, Module.ToString(), (int)LoaderMSG.PrepareForPlace,args)) { return (int)LoaderMSG.PrepareForPlace; } else { return (int)FSM_MSG.NONE; } case "Retry": if (CheckToPostMessage(eEvent.ERR_LOADER, Module.ToString(), (int)LoaderMSG.Retry,args)) { return (int)LoaderMSG.Retry; } else { return (int)FSM_MSG.NONE; } case "ConfirmComplete": if (CheckToPostMessage(eEvent.ERR_LOADER, Module.ToString(), (int)LoaderMSG.ConfirmComplete, args)) { return (int)LoaderMSG.ConfirmComplete; } else { return (int)FSM_MSG.NONE; } } return (int)FSM_MSG.NONE; } } public enum LoaderMSG { ReturnInit, ReturnIdle, Abort, HomeAll, GoToSavedPosition, StopFlow, SwitchOnAll, SwitchOffAll, Error, ClearError, PrepareForPlace, ReadyForPuf, UnloadSide, LoadSide, Retry, ConfirmComplete, WaitFlip, } }