using Aitex.Core.Common; using Aitex.Core.RT.IOCore; using Aitex.Core.RT.Log; using Aitex.Core.Util; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Jobs; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.Common.WaferHolder; using CyberX8_Core; using CyberX8_RT.Modules; using CyberX8_RT.Modules.Loader; using CyberX8_RT.Modules.PUF; using CyberX8_RT.Schedulers; using CyberX8_RT.Schedulers.EfemRobot; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using MECF.Framework.Common.RecipeCenter; using MECF.Framework.Common.Schedulers; using System.Windows; using MECF.Framework.RT.Core.Equipments; using CyberX8_RT.Modules.SRD; namespace CyberX8_RT.Dispatch { public enum WaferTaskState { Created, Processing, End, Paused, Error } /// /// WaferTask完成 /// /// public delegate void WaferTaskComplete(string id); /// /// WaferTask开始 /// /// public delegate void WaferTaskStart(string id); public class WaferTask { #region 内部变量 /// /// 调度步骤 /// private List _schedulerSequences; /// /// 当前步骤索引 /// private int _currentSequenceIndex = 0; /// /// PUF实例 /// private PUFEntity _pufEntity; /// /// 是否开始执行 /// private bool _isStart = false; /// /// 暂停时的索引 /// private int _pausedIndex = -1; /// /// 日志trigger /// private R_TRIG _sequenceConditionTrigger = new R_TRIG(); /// /// 错误上升触发 /// private R_TRIG _sequenceErrorTigger = new R_TRIG(); #endregion #region 属性 /// /// Wafer信息 /// public string WaferId { get; set; } /// /// 状态 /// public WaferTaskState State { get; private set; } /// /// 匹配WaferTask /// public string MateWaferTask { get; set; } /// /// 调度集合 /// public List SchedulerSequences { get { return _schedulerSequences; } } #endregion #region 事件 /// /// 任务完成事件 /// public event WaferTaskComplete OnTaskComplete; /// /// 任务启动 /// public event WaferTaskStart OnTaskStart; #endregion /// /// 构造函数 /// /// /// public WaferTask(WaferInfo waferInfo,PUFEntity pufEntity, List schedulerSequences) { this.WaferId = waferInfo.WaferID; _schedulerSequences = schedulerSequences; State = WaferTaskState.Created; _pufEntity = pufEntity; } /// /// 执行 /// public void Run() { if (State == WaferTaskState.Error) { return; } if (_currentSequenceIndex >= _schedulerSequences.Count) { State = WaferTaskState.End; if (OnTaskComplete != null) { OnTaskComplete(WaferId); } return; } SchedulerSequence sequence = _schedulerSequences[_currentSequenceIndex]; if (_currentSequenceIndex == _schedulerSequences.Count - 1 && sequence.State == RState.End) { State = WaferTaskState.End; if(OnTaskComplete!=null) { OnTaskComplete(WaferId); } return; } if (!_isStart) { bool preCondition = CheckStartCondition(); if (!preCondition) { return; } _isStart = true; WaferTaskManager.Instance.RemoveWaferIdMatchWaferHolderTaskDic(WaferId); } //暂停中 if(sequence.State==RState.Init&&_currentSequenceIndex>=_pausedIndex&&_pausedIndex!=-1) { return; } if(sequence.IsWaitNotify) { if (sequence.State == RState.End) { _currentSequenceIndex++; } return; } if(sequence.MaterialType==MaterialType.WaferHolder) { if(sequence.State==RState.End) { _currentSequenceIndex++; } return; } if (_currentSequenceIndex < _schedulerSequences.Count) { if (sequence.State == RState.Init) { string reason = ""; bool sequeceCondition = sequence.SchedulerModule.CheckPrecondition(_schedulerSequences, _currentSequenceIndex,sequence.Parameters,WaferId,ref reason); _sequenceConditionTrigger.CLK = !sequeceCondition; if (sequeceCondition) { bool result = sequence.SchedulerModule.RunProcess(sequence.Recipe,sequence.Parameters,sequence.SynchronousModuleMessages); if (result) { if (State == WaferTaskState.Created) { State = WaferTaskState.Processing; if(OnTaskStart!=null) { OnTaskStart(WaferId); } } sequence.State = RState.Running; sequence.StartTime = DateTime.Now; LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferId} Start {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module}"); } } else { if (_sequenceConditionTrigger.Q) { LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferId} Start {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module} failed,{reason}"); if (sequence.SchedulerModule.Module == ModuleName.EfemRobot) { AnalyseSchedulerSrdState(sequence); } } } } else if (sequence.State == RState.Running) { bool hasMatched=!string.IsNullOrEmpty(WaferTaskManager.Instance.GetMatchWaferIdByWaferId(this.WaferId)); sequence.SchedulerModule.MonitorProcess(sequence,hasMatched); _sequenceErrorTigger.CLK = sequence.SchedulerModule.IsError; if (sequence.SchedulerModule.IsIdle) { sequence.EndTime = DateTime.Now; sequence.State = RState.End; sequence.ProcessMilliSeconds = sequence.EndTime.Subtract(sequence.StartTime).TotalMilliseconds; LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferId} {_currentSequenceIndex + 1} sequence complete, time length {sequence.ProcessMilliSeconds}"); _currentSequenceIndex++; } } else if(sequence.State==RState.End) { LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferId} {_currentSequenceIndex + 1} sequence is End"); _currentSequenceIndex++; } } } /// /// 分析错误状态下的调度 /// private void AnalyseSchedulerSrdState(SchedulerSequence sequence) { if(!(sequence.Parameters is MoveItem)) { return; } MoveItem moveItem = sequence.Parameters as MoveItem; bool exsitSRD = false; if (moveItem.DestinationType == ModuleType.SRD) { SRDEntity srdEntity1 = Singleton.Instance.GetModule(ModuleName.SRD1.ToString()); if (srdEntity1 != null&&(srdEntity1.IsBusy||srdEntity1.IsIdle)&&srdEntity1.IsAuto) { exsitSRD = true; return; } SRDEntity srdEntity2 = Singleton.Instance.GetModule(ModuleName.SRD2.ToString()); if (srdEntity2 != null && (srdEntity2.IsBusy || srdEntity2.IsIdle) && srdEntity2.IsAuto) { exsitSRD = true; return; } if (!exsitSRD) { WaferInfo waferInfo = WaferManager.Instance.GetWaferByWaferId(WaferId); if (waferInfo == null || waferInfo.IsEmpty) { return; } WaferManager.Instance.UpdateWaferProcessStatus(moveItem.SourceModule, moveItem.SourceSlot, EnumWaferProcessStatus.MisSrdProcess); MaterialTrackerManager.Instance.UpdateModuleMaterial(moveItem.SourceModule.ToString()); LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{waferInfo.WaferID} status changed to {EnumWaferProcessStatus.MisSrdProcess}"); moveItem.DestinationModule = (ModuleName)waferInfo.OriginStation; moveItem.DestinationSlot = waferInfo.OriginSlot; moveItem.DestinationType = ModuleType.LoadPort; LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferId} has no avaible srd changed to {moveItem.DestinationModule}.{moveItem.DestinationSlot}"); for(int i = _currentSequenceIndex + 1; i < _schedulerSequences.Count; i++) { SchedulerSequence item = _schedulerSequences[i]; item.State = RState.End; LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferId} skip {i + 1} sequence {item.ModuleType}"); } } } } /// /// 释放资源 /// public void Dispose() { _schedulerSequences.Clear(); } /// /// 检验前置条件 /// /// private bool CheckStartCondition() { EfemEntity efemEntity = Singleton.Instance.EFEM; if(!efemEntity.IsIdle) { return false; } SchedulerRobot schedulerEfemRobot = (SchedulerRobot)SchedulerManager.Instance.GetScheduler(ModuleName.EfemRobot); if(schedulerEfemRobot==null) { return false; } if(!schedulerEfemRobot.IsIdle) { return false; } if(WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot,0)) { return false; } if(WaferManager.Instance.CheckHasWafer(ModuleName.Aligner1, 0)) { return false; } if(!_pufEntity.IsIdle) { return false; } //PUF B面无Wafer if(WaferManager.Instance.CheckHasWafer(_pufEntity.Module,1)) { return false; } //if(!WaferHolderManager.Instance.HasWaferHolder("Loader")) //{ // return false; //} LoaderEntity loaderEntity = Singleton.Instance.GetModule(ModuleName.Loader1.ToString()); if (loaderEntity == null) { return false; } if(loaderEntity.IsBusy&&loaderEntity.State!=(int)LOADERSTATE.WaitForUnload) { return false; } if(!string.IsNullOrEmpty(MateWaferTask)) { WaferTask mateTask=WaferTaskManager.Instance.GetWaferTask(MateWaferTask); if(mateTask!=null) { if(mateTask.State==WaferTaskState.Created) { return false; } } } //WaferHolderTask waferHolderTask = WaferTaskManager.Instance.GetWaferHolderTaskByWaferId(WaferId); //if (waferHolderTask != null) //{ // if(waferHolderTask.State==WaferHolderTaskState.Created||waferHolderTask.State==WaferHolderTaskState.Error) // { // return false; // } //} return true; } /// /// 同步更新Loader工序完成 /// public void UpdateLoaderSchedulerSequenceComplete() { SchedulerSequence schedulerSequence = _schedulerSequences[_currentSequenceIndex]; if (schedulerSequence != null) { if (schedulerSequence.ModuleType == ModuleType.PUF&&schedulerSequence.IsWaitNotify) { bool forward = (bool)schedulerSequence.Parameters; if (!forward) { schedulerSequence.StartTime = DateTime.Now; schedulerSequence.EndTime = DateTime.Now; schedulerSequence.State = RState.End; schedulerSequence.ProcessMilliSeconds = schedulerSequence.EndTime.Subtract(schedulerSequence.StartTime).TotalMilliseconds; LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferId} {_currentSequenceIndex + 1} puf sequence task synchronize notify complete"); } } } } /// /// 暂停 /// public void Pause() { _pausedIndex = _currentSequenceIndex; } /// /// 恢复 /// public void Resume() { _pausedIndex = -1; } /// /// 移除SRD调度 /// public void RemoveSrdScheduler() { WaferInfo waferInfo=WaferManager.Instance.GetWaferByWaferId(WaferId); if (waferInfo != null && waferInfo.WaferType == WaferType.Production&&waferInfo.ProcessJob!=null &&waferInfo.ProcessJob.SequenceRecipe!=null) { if (SequenceRecipeManager.Instance.IsContainedSrd(waferInfo.ProcessJob.SequenceRecipe)) { for(int i=_currentSequenceIndex;i<_schedulerSequences.Count;i++) { SchedulerSequence item= _schedulerSequences[i]; if(item.ModuleType==ModuleType.SRD&&i+1<_schedulerSequences.Count&&i>0) { SchedulerSequence preSequence = _schedulerSequences[i - 1]; SchedulerSequence nextSequence = _schedulerSequences[i + 1]; if (preSequence.ModuleName == ModuleName.EfemRobot&&nextSequence.ModuleName==ModuleName.EfemRobot) { MoveItem moveItem=preSequence.Parameters as MoveItem; MoveItem nextMoveItem=nextSequence.Parameters as MoveItem; moveItem.DestinationModule = nextMoveItem.DestinationModule; moveItem.DestinationSlot= nextMoveItem.DestinationSlot; moveItem.DestinationType= nextMoveItem.DestinationType; _schedulerSequences.RemoveAt(i + 1); _schedulerSequences.RemoveAt(i); LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"Wafer {WaferId} remove SRD Scheduler"); } break; } } } } } /// /// 步骤是否进入Loader及之后 /// /// public bool IsSchedulerForward() { //0-EfemRobot,1-Aligner,2-EfemRobot,3-Puf(正向),4-PUF(工艺结束返回) return _currentSequenceIndex < 4; } } }