using Aitex.Core.RT.Log; using Aitex.Core.Util; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.Common.WaferHolder; using CyberX8_Core; using CyberX8_RT.Modules.Loader; using CyberX8_RT.Modules.PUF; using CyberX8_RT.Modules; using CyberX8_RT.Schedulers; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Documents; using Aitex.Core.Common; using MECF.Framework.Common.CommonData; using MECF.Framework.Common.Jobs; using Aitex.Core.RT.Fsm; using MECF.Framework.Common.RecipeCenter; using MECF.Framework.Common.ToolLayout; using Aitex.Core.RT.Routine; namespace CyberX8_RT.Dispatch { public enum WaferHolderTaskState { Created, Processing, End, Error, Canceled } /// /// WaferHolder /// /// /// public delegate void WaferHolderSchedulerComplete(WaferHolderInfo info, SchedulerSequence schedulerSequence); /// /// WaferHolderTask完成 /// /// public delegate void WaferHolderTaskComplete(string id); public class WaferHolderTask { #region 内部变量 /// /// 调度步骤 /// private List _schedulerSequences; /// /// 当前步骤索引 /// private int _currentSequenceIndex = 0; /// /// PUF实例 /// private PUFEntity _puf1Entity; /// /// PUF实例 /// private PUFEntity _puf2Entity; /// /// 是否开始执行 /// private bool _isStart = false; /// /// 暂停时的索引 /// private int _pausedIndex = -1; /// /// 错误上升触发 /// private R_TRIG _sequenceErrorTigger = new R_TRIG(); /// /// Sequence类型 /// private string _sequenceType = ""; /// /// FA回复 /// private SchedulerFACallback _schedulerFACallback = new SchedulerFACallback(); #endregion #region 属性 /// /// ID /// public string ID { get;private set; } /// /// WaferHolder属性 /// public WaferHolderInfo WaferHolderInfo { get;private set; } /// /// Process Job信息 /// public ProcessJobInfo ProcessJobInfo { get;private set; } /// /// 状态 /// public WaferHolderTaskState State { get; private set; } /// /// 步骤完成事件 /// public event WaferHolderSchedulerComplete OnSchedulerComplete; /// /// 任务完成事件 /// public event WaferHolderTaskComplete OnTaskComplete; /// /// 调度集合 /// public List SchedulerSequences { get { return _schedulerSequences; } } #endregion /// /// 构造函数 /// /// /// public WaferHolderTask(WaferHolderInfo waferHolderInfo,ProcessJobInfo processJobInfo,List schedulerSequences) { ID=Guid.NewGuid().ToString(); WaferHolderInfo=waferHolderInfo; WaferHolderInfo.Status = WaferHolderStatus.Normal; if (processJobInfo != null) { WaferHolderInfo.SequenceId = processJobInfo.SequenceRecipe.Ppid; WaferHolderInfo.SequenceRecipe = processJobInfo.SequenceRecipe; _sequenceType = processJobInfo.SequenceRecipe.SequenceType; WaferHolderInfo.CurrentControlJobId = processJobInfo.ControlJobName; WaferHolderInfo.LotId = processJobInfo.LotName; } else { AnalyseProductionProcessJobInfo(); } ProcessJobInfo=processJobInfo; _schedulerSequences = schedulerSequences; State = WaferHolderTaskState.Created; _puf1Entity = Singleton.Instance.GetModule(ModuleName.PUF1.ToString()); _puf2Entity = Singleton.Instance.GetModule(ModuleName.PUF2.ToString()); } /// /// 分析生产片的ProcessJob信息 /// private void AnalyseProductionProcessJobInfo() { if (string.IsNullOrEmpty(WaferHolderInfo.WaferAId)) { WaferInfo waferAInfo = WaferManager.Instance.GetWaferByWaferId(WaferHolderInfo.WaferAId); if (waferAInfo != null && waferAInfo.WaferType == WaferType.Production) { ProcessJobInfo = waferAInfo.ProcessJob; _sequenceType = ProcessJobInfo.SequenceRecipe.SequenceType; WaferHolderInfo.CurrentControlJobId = ProcessJobInfo.ControlJobName; WaferHolderInfo.LotId = ProcessJobInfo.LotName; return; } } if (string.IsNullOrEmpty(WaferHolderInfo.WaferBId)) { WaferInfo waferBInfo = WaferManager.Instance.GetWaferByWaferId(WaferHolderInfo.WaferBId); if (waferBInfo != null && waferBInfo.WaferType == WaferType.Production) { ProcessJobInfo = waferBInfo.ProcessJob; _sequenceType = ProcessJobInfo.SequenceRecipe.SequenceType; WaferHolderInfo.CurrentControlJobId = ProcessJobInfo.ControlJobName; WaferHolderInfo.LotId = ProcessJobInfo.LotName; } } } /// /// 执行 /// public void Run() { if(_currentSequenceIndex>=_schedulerSequences.Count) { State = WaferHolderTaskState.End; if(OnTaskComplete!=null) { OnTaskComplete(ID); } FaModuleNotifier.Instance.NotifyWaferShuttleJobEnd(WaferHolderInfo); LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"WaferHolder {WaferHolderInfo.Id} task complete"); return; } if (!_isStart) { bool preCondition = CheckStartCondition(); if (!preCondition) { return; } LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"{WaferHolderInfo.Id} prepare Start {_currentSequenceIndex + 1} sequence"); _isStart = true; if (WaferHolderInfo.SchedulerModules == null) { WaferHolderInfo.SchedulerModules = new List(); } WaferHolderInfo.SchedulerModules.Clear(); } SchedulerSequence sequence = _schedulerSequences[_currentSequenceIndex]; //暂停中 if (sequence.State == RState.Init && _currentSequenceIndex >= _pausedIndex && _pausedIndex != -1) { return; } if (_currentSequenceIndex == _schedulerSequences.Count - 1 && sequence.State == RState.End) { State=WaferHolderTaskState.End; if (OnTaskComplete != null) { OnTaskComplete(ID); } FaModuleNotifier.Instance.NotifyWaferShuttleJobEnd(WaferHolderInfo); LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"WaferHolder {WaferHolderInfo.Id} task complete"); return; } if(_currentSequenceIndex<_schedulerSequences.Count) { if(sequence.State==RState.Init) { if(sequence.SchedulerModule==null) { return; } if(!BufferWaferHolderJudgeResource(sequence)) { return; } string reason = ""; bool sequeceCondition = sequence.SchedulerModule.CheckPrecondition(_schedulerSequences, _currentSequenceIndex, sequence.Parameters,WaferHolderInfo.Id,ref reason); if (sequeceCondition) { bool result = sequence.SchedulerModule.RunProcess(sequence.Recipe,sequence.Parameters, sequence.SynchronousModuleMessages); if (result) { if (State == WaferHolderTaskState.Created) { State = WaferHolderTaskState.Processing; FaModuleNotifier.Instance.NotifyWaferShuttleJobStart(WaferHolderInfo); } sequence.State = RState.Running; sequence.StartTime = DateTime.Now; LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"{WaferHolderInfo.Id} Start {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module}"); } else { if (sequence.ModuleName == ModuleName.Transporter1&&sequence.NextModuleType==ModuleType.Metal) { if (!CheckAfterMetalAvaible()) { LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"{WaferHolderInfo.Id} {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module} has no avaible metal"); WaferHolderMoveItem waferHolderMoveItem = sequence.Parameters as WaferHolderMoveItem; waferHolderMoveItem.DestModuleType = ModuleType.Dryer; waferHolderMoveItem.DestModule = ModuleName.Unknown; LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"{WaferHolderInfo.Id} {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module} next sequence changed to dryer"); } } } } else { _sequenceErrorTigger.CLK = !sequeceCondition; if (_sequenceErrorTigger.Q) { LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferHolderInfo.Id} Start {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module} failed,{reason}"); } } } else if(sequence.State==RState.Running) { sequence.SchedulerModule.MonitorProcess(sequence,false); _sequenceErrorTigger.CLK = sequence.SchedulerModule.IsError; if (sequence.SchedulerModule.IsError) { //用于LoadTransporter取的WaferHolder Id不一致,则取消当前WaferHolderTask if (sequence.ModuleName == ModuleName.Transporter2) { LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"{WaferHolderInfo.Id} {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module} failed,task canceled"); State = WaferHolderTaskState.Canceled; return; } if (_sequenceErrorTigger.Q) { AnalyseSchedulerErrorState(sequence); } } else if(sequence.SchedulerModule.IsIdle) { sequence.EndTime = DateTime.Now; sequence.State = RState.End; sequence.ProcessMilliSeconds=sequence.EndTime.Subtract(sequence.StartTime).TotalMilliseconds; if(sequence.IsProcessSequece) { UpdateWaferHolderProcessingStatus(); } if(sequence.IsLastProcessSequence) { UpdateWaferHolderProcessComplete(); } if (OnSchedulerComplete != null) { OnSchedulerComplete(WaferHolderInfo, sequence); } UpdateLoaderToBufferWaferHolderToloaderStatus(sequence); LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferHolderInfo.Id} {_currentSequenceIndex + 1} sequence {sequence.ModuleName} complete, time length {sequence.ProcessMilliSeconds}"); _currentSequenceIndex++; AutoChangeLoaderTransporterScheduler(); //检验rinse后面是否存在可用的Metal if (sequence.ModuleType == ModuleType.Rinse) { AnalyseRinseAfterMetalAvaible(sequence); } else if (sequence.ModuleType == ModuleType.Prewet) { AnalysePrewetAfterMetalAvaible(sequence); } } } else if (sequence.State == RState.End) { LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} {_currentSequenceIndex + 1} sequence is End"); _currentSequenceIndex++; } } } /// /// 更新任务结束 /// public void UpdateDryerLastSchedulerComplete() { SchedulerSequence sequence = _schedulerSequences[_currentSequenceIndex]; sequence.EndTime = DateTime.Now; sequence.State = RState.End; sequence.ProcessMilliSeconds = sequence.EndTime.Subtract(sequence.StartTime).TotalMilliseconds; LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferHolderInfo.Id} {_currentSequenceIndex+1} sequence {sequence.ModuleName} complete, time length {sequence.ProcessMilliSeconds}"); State = WaferHolderTaskState.End; if (OnTaskComplete != null) { OnTaskComplete(ID); } LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"WaferHolder {WaferHolderInfo.Id} task complete"); } /// /// 更新从Loader到Buffer的WaferHolder更新为不可以拉回至Loader /// /// private void UpdateLoaderToBufferWaferHolderToloaderStatus(SchedulerSequence sequence) { string currentLocation = WaferHolderInfo.CurrentLocation; if(!Enum.TryParse(currentLocation,out ModuleName locationName)) { return; } if (!ModuleHelper.IsBuffer(locationName)) { return; } if (sequence.ModuleName == ModuleName.Transporter2) { WaferHolderMoveItem waferHolderMoveItem = sequence.Parameters as WaferHolderMoveItem; if (waferHolderMoveItem.SourceModule == ModuleName.Loader1&&waferHolderMoveItem.DestModuleType==ModuleType.Buffer) { WaferHolderInfo.IsToLoader = false; LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} IsToLoader Changed to false;"); } else if (waferHolderMoveItem.DestModuleType == ModuleType.Buffer && waferHolderMoveItem.SourceModuleType != ModuleType.Loader) { WaferHolderInfo.IsToLoader = true; LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} IsToLoader Changed to true;"); } } } /// /// 分析错误状态下的调度 /// private void AnalyseSchedulerErrorState(SchedulerSequence sequence) { if (sequence.ModuleType == ModuleType.Prewet) { AnalyseSchedulerPrewetErrorState(sequence); } else if (sequence.ModuleType == ModuleType.Dryer) { AnalyseSchedulerDryerErrorState(sequence); } else if (sequence.ModuleType == ModuleType.Rinse) { AnalyseSchedulerRinseErrorState(sequence); } else if (sequence.ModuleType == ModuleType.Metal) { AnalyseSchedulerMetalErrorState(sequence); } } /// /// 判定Buffer中WaferHolder的后面工序是否存在可用资源,不存在的话,则Task直接结束 /// /// private bool BufferWaferHolderJudgeResource(SchedulerSequence sequence) { string currentLocation = WaferHolderInfo.CurrentLocation; if (Enum.TryParse(currentLocation, out ModuleName moduleName)) { //当前WaferHolder处于Buffer中,当前步骤不是第一步,当前调度模块为transporter2 if (ModuleHelper.IsBuffer(moduleName)&&_currentSequenceIndex!=0&&sequence.ModuleName==ModuleName.Transporter2) { if (!SchedulerSequenceRecipeManager.Instance.ExistAvaibleProcessCell(WaferHolderInfo.SequenceRecipe, false)) { for (int i = _currentSequenceIndex; i < _schedulerSequences.Count; i++) { SchedulerSequence item = _schedulerSequences[i]; item.State = RState.End; } _currentSequenceIndex = _schedulerSequences.Count - 1; LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} exist no avaible cell"); WaferHolderInfo.IsToLoader = true; LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} IsToLoader Changed to true"); RemoveWaferHolderSRDScheduler(); UpdateWaferHolderMisProcessedStatus(); return false; } } } return true; } /// /// 检验Prewet后面的Metal是否存在可用 /// private void AnalysePrewetAfterMetalAvaible(SchedulerSequence schedulerSequence) { //获取可用的Metal以及Rinse if (!CheckAfterMetalAvaible()) { LOG.WriteLog(eEvent.WARN_SCHEDULER, "System", $"{WaferHolderInfo.Id} has no avaible metal after prewet"); SkipAfterMetal(schedulerSequence,true); RemoveWaferHolderSRDScheduler(); UpdateWaferHolderMisProcessedStatus(); //SchedulerSequence nextSchedulerSequence = _schedulerSequences[_currentSequenceIndex]; //if (nextSchedulerSequence.ModuleName != ModuleName.Transporter1) //{ // return; //} //WaferHolderMoveItem waferHolderMoveItem = nextSchedulerSequence.Parameters as WaferHolderMoveItem; //waferHolderMoveItem.DestModuleType = ModuleType.Dryer; //waferHolderMoveItem.DestModule = ModuleName.Unknown; } } /// /// 检验Rinse后面的Metal是否存在可用 /// /// private void AnalyseRinseAfterMetalAvaible(SchedulerSequence schedulerSequence) { //获取可用的Metal以及Rinse if(!CheckAfterMetalAvaible()) { LOG.WriteLog(eEvent.WARN_SCHEDULER, "System", $"{WaferHolderInfo.Id} has no avaible metal after rinse"); SkipAfterMetal(schedulerSequence,true); RemoveWaferHolderSRDScheduler(); UpdateWaferHolderMisProcessedStatus(); } } /// /// 检验后续Metal可用性 /// /// private bool CheckAfterMetalAvaible() { for (int i = _currentSequenceIndex + 1; i < _schedulerSequences.Count; i++) { SchedulerSequence sequence = _schedulerSequences[i]; if (sequence.ModuleType != ModuleType.Metal) { continue ; } if (sequence.Recipe == null || !(sequence.Recipe is DepRecipe)) { continue; } DepRecipe depRecipe = (DepRecipe)sequence.Recipe; bool result= SchedulerSequenceManager.Instance.CalculateAvaibleMetalCellByChemistry(depRecipe.Chemistry, sequence.SequenceType); if (!result) { return false; } } return true; } #region Analyse ErrorState Scheduler /// /// Prewet出错重新调度 /// /// private void AnalyseSchedulerPrewetErrorState(SchedulerSequence sequence) { SkipAfterSchedulerToDry(ModuleName.Transporter2); sequence.State = RState.End; sequence.EndTime = DateTime.Now; sequence.ProcessMilliSeconds= sequence.EndTime.Subtract(sequence.StartTime).TotalMilliseconds; RemoveWaferHolderSRDScheduler(); UpdateWaferHolderMisProcessedStatus(); LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Prewet meet error,scheduler changed to transporter2"); } /// /// 路过后面调度直接至Dryer /// private void SkipAfterSchedulerToDry(ModuleName transporterName) { for (int i = _currentSequenceIndex=1; i < _schedulerSequences.Count; i++) { SchedulerSequence item = _schedulerSequences[i]; if (item.ModuleName != ModuleName.Transporter1) { item.State = RState.End; item.ProcessMilliSeconds = 0; } else { if (item.Parameters is WaferHolderMoveItem) { WaferHolderMoveItem waferHolderMoveItem = item.Parameters as WaferHolderMoveItem; if (waferHolderMoveItem.DestModuleType == ModuleType.Dryer) { _currentSequenceIndex = i; item.SchedulerModule = SchedulerManager.Instance.GetScheduler(transporterName); waferHolderMoveItem.SourceModule = ModuleName.Prewet1; waferHolderMoveItem.SourceModuleType = ModuleType.Prewet; break; } else { item.State = RState.End; item.ProcessMilliSeconds = 0; } } } } } /// /// Dryer出错重新调度,上一步调度修改为transporter2,同时tranporter2搬运源目标为当前Module,目标类型也是Dryer /// /// private void AnalyseSchedulerDryerErrorState(SchedulerSequence sequence) { if (SchedulerSequenceManager.Instance.GetAvaibleModuleCell(_sequenceType,ModuleType.Dryer)!=ModuleName.Unknown) { sequence.State = RState.Init; SchedulerSequence preSchedulerSequence = GetPreSchedulerSequence(); preSchedulerSequence.State = RState.Init; preSchedulerSequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(ModuleName.Transporter2); WaferHolderMoveItem waferHolderMoveItem = preSchedulerSequence.Parameters as WaferHolderMoveItem; waferHolderMoveItem.SourceModule = waferHolderMoveItem.DestModule; waferHolderMoveItem.SourceModuleType = waferHolderMoveItem.DestModuleType; waferHolderMoveItem.DestModuleType = waferHolderMoveItem.DestModuleType; waferHolderMoveItem.DestModule = ModuleName.Unknown; sequence.SchedulerModule = null; _currentSequenceIndex--; LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Dryer meet error,rescheduler changed to transporter2"); } else { LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Dryer meet error,rescheduler has no avaible dryer"); } } /// /// Rinse出错重新调度,回退至上一步调度 /// /// private void AnalyseSchedulerRinseErrorState(SchedulerSequence sequence) { ModuleName metalName = SchedulerSequenceManager.Instance.GetPreMetalModuleName(_currentSequenceIndex, _schedulerSequences); if (metalName == ModuleName.Unknown) { return; } if (SchedulerSequenceManager.Instance.GetAvaibleModuleCell(_sequenceType, ModuleType.Rinse,metalName) != ModuleName.Unknown) { sequence.State = RState.Init; SchedulerSequence preSchedulerSequence = GetPreSchedulerSequence(); preSchedulerSequence.State = RState.Init; WaferHolderMoveItem waferHolderMoveItem = preSchedulerSequence.Parameters as WaferHolderMoveItem; waferHolderMoveItem.SourceModule = waferHolderMoveItem.DestModule; waferHolderMoveItem.SourceModuleType = waferHolderMoveItem.DestModuleType; waferHolderMoveItem.DestModuleType = waferHolderMoveItem.DestModuleType; waferHolderMoveItem.DestModule = ModuleName.Unknown; sequence.SchedulerModule = null; _currentSequenceIndex--; LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Rinse meet error,scheduler changed to transporter1"); } else { LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Rinse meet error,rescheduler has no avaible rinse"); } } /// /// Metal出错重新调度,回退至上一步调度 /// /// private void AnalyseSchedulerMetalErrorState(SchedulerSequence sequence) { //当前步骤结束,WaferHolder状态 UpdateWaferHolderErrorStatus(); sequence.EndTime = DateTime.Now; sequence.ProcessMilliSeconds= sequence.EndTime.Subtract(sequence.StartTime).TotalMilliseconds; sequence.State = RState.End; LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Metal meet error,rescheduler changed to next module"); //跳过后面的metal SkipAfterMetal(sequence,false); //移除SRD调度 RemoveWaferHolderSRDScheduler(); _currentSequenceIndex++; } /// /// 跳过后面的Metal /// private void SkipAfterMetal(SchedulerSequence schedulerSequence,bool isSetLastSequenceSourceModule) { int startIndex = -1; int endIndex = -1; //从下一个Metal直到碰到Dryer for (int i = _currentSequenceIndex + 1; i < _schedulerSequences.Count; i++) { SchedulerSequence item = _schedulerSequences[i]; if (item.ModuleType == ModuleType.Metal && startIndex == -1) { startIndex = i; } if (item.ModuleType == ModuleType.Dryer) { endIndex = i - 1;//Dryer前一步骤为Transporter,保留Dryer前面的transporter break; } } //将后面的Metal的步骤直接跳过,包含gh g 后面的transporter if (startIndex != -1) { for (int i = startIndex - 1; i < endIndex; i++) { SchedulerSequence item = _schedulerSequences[i]; item.State = RState.End; LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} skip {i+1} sequence {item.ModuleType}"); } } //是否设置最后调度的源模块 if (isSetLastSequenceSourceModule) { SchedulerSequence lastSchedulerSequence = _schedulerSequences[endIndex]; if (lastSchedulerSequence.ModuleType == ModuleType.Transporter) { WaferHolderMoveItem waferHolderMoveItem = lastSchedulerSequence.Parameters as WaferHolderMoveItem; if (schedulerSequence.SchedulerModule != null) { waferHolderMoveItem.SourceModule = schedulerSequence.ModuleName; waferHolderMoveItem.SourceModuleType = schedulerSequence.ModuleType; } } } } /// /// 移除SRD调度 /// private void RemoveWaferHolderSRDScheduler() { WaferTask waferATask = WaferTaskManager.Instance.GetWaferTask(WaferHolderInfo.WaferAId); if (waferATask != null) { waferATask.RemoveSrdScheduler(); } WaferTask waferBTask = WaferTaskManager.Instance.GetWaferTask(WaferHolderInfo.WaferBId); if (waferBTask != null) { waferBTask.RemoveSrdScheduler(); } } #endregion /// /// 自动更新LoaderTransporter的工序 /// private void AutoChangeLoaderTransporterScheduler() { if(_currentSequenceIndex>=_schedulerSequences.Count) { return; } if(_currentSequenceIndex+2>=_schedulerSequences.Count) { return; } SchedulerSequence schedulerSequence = _schedulerSequences[_currentSequenceIndex]; if (schedulerSequence == null) { return; } if(schedulerSequence.ModuleName==ModuleName.Transporter2) { if (schedulerSequence.Parameters == null || !(schedulerSequence.Parameters is WaferHolderMoveItem)) { return; } WaferHolderMoveItem waferHolderMoveItem = (WaferHolderMoveItem)schedulerSequence.Parameters; if(waferHolderMoveItem.DestModuleType!=ModuleType.Buffer) { return; } SchedulerSequence nextSchedulerSequence = _schedulerSequences[_currentSequenceIndex + 1]; if(nextSchedulerSequence.ModuleName!=ModuleName.Transporter2) { return; } if(nextSchedulerSequence.Parameters==null||!(nextSchedulerSequence.Parameters is WaferHolderMoveItem)) { return; } WaferHolderMoveItem nextWaferHolderMoveItem = (WaferHolderMoveItem)nextSchedulerSequence.Parameters; if(nextWaferHolderMoveItem.DestModule==ModuleName.Unknown) { if (ProcessJobInfo != null && ProcessJobInfo.SequenceRecipe != null) { //后面不存在资源,搬运至Buffer中,而不是进后面cell if (!SchedulerSequenceRecipeManager.Instance.ExistAvaibleProcessCell(ProcessJobInfo.SequenceRecipe, false)) { return; } } if (CheckBufferHasUnProcessedWaferHolder()) { return; } //若Buffer后面的cell存在资源,则直接搬运至Cell中 ModuleName avaibleModuleName = SchedulerSequenceManager.Instance.GetAvaibleEmptyModuleCell(nextWaferHolderMoveItem.DestModuleType,_sequenceType); if(avaibleModuleName==ModuleName.Unknown) { return; } else { schedulerSequence.State = RState.End; _currentSequenceIndex++; nextWaferHolderMoveItem.DestModule = avaibleModuleName; nextWaferHolderMoveItem.SourceModule = ModuleName.Loader1; nextWaferHolderMoveItem.SourceModuleType = ModuleType.Loader; UpdateNextSequenceModule(_currentSequenceIndex + 1,avaibleModuleName); } } else if(nextWaferHolderMoveItem.DestModule==ModuleName.Loader1) { LoaderEntity loaderEntity = Singleton.Instance.GetModule(ModuleName.Loader1.ToString()); if(loaderEntity==null) { return; } if(loaderEntity.WaferHolderInfo!=null) { return; } if(loaderEntity.IsBusy) { return; } schedulerSequence.State = RState.End; _currentSequenceIndex++; nextWaferHolderMoveItem.SourceModule = waferHolderMoveItem.SourceModule; nextWaferHolderMoveItem.SourceModuleType = waferHolderMoveItem.SourceModuleType; } } } /// /// 检验Buffer中是否存在未处理的WaferHolder /// /// private bool CheckBufferHasUnProcessedWaferHolder() { List bufferModules = BufferItemManager.Instance.InstalledModules; foreach (string module in bufferModules) { WaferHolderInfo item = WaferHolderManager.Instance.GetWaferHolder(module); if (item == null) { continue; } if (string.IsNullOrEmpty(item.WaferAId)) { continue; } if (string.IsNullOrEmpty(item.WaferBId)) { continue; } WaferInfo waferA=WaferManager.Instance.GetWaferByWaferId(item.WaferAId); if (waferA == null) { continue; } if (waferA.ProcessState == EnumWaferProcessStatus.Idle&&waferA.WaferType==WaferType.Production) { return true; } WaferInfo waferB = WaferManager.Instance.GetWaferByWaferId(item.WaferBId); if(waferB == null) { continue; } if (waferB.ProcessState == EnumWaferProcessStatus.Idle && waferB.WaferType == WaferType.Production) { return true; } } return false; } /// /// 更新下一工序的调度模块 /// /// /// private void UpdateNextSequenceModule(int sequenceIndex,ModuleName moduleName) { if(sequenceIndex<_schedulerSequences.Count) { SchedulerSequence schedulerSequence = _schedulerSequences[sequenceIndex]; if(schedulerSequence!=null&&schedulerSequence.SchedulerModule==null) { schedulerSequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(moduleName); schedulerSequence.ModuleName = moduleName; } } } /// /// 更新WaferHolder工序完成Wafer状态 /// private void UpdateWaferHolderProcessComplete() { if (WaferHolderInfo.Status != WaferHolderStatus.Completed) { UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus.Completed); WaferHolderInfo.Status = WaferHolderStatus.Completed; LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Status changed to {WaferHolderInfo.Status}"); } MaterialTrackerManager.Instance.UpdateModuleMaterial(WaferHolderInfo.CurrentLocation); } /// /// 更新WaferHolder工序正在加工 /// private void UpdateWaferHolderProcessingStatus() { if (WaferHolderInfo.Status == WaferHolderStatus.Normal) { UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus.InProcess); WaferHolderInfo.Status = WaferHolderStatus.Processing; LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Status changed to {WaferHolderInfo.Status}"); MaterialTrackerManager.Instance.UpdateModuleMaterial(WaferHolderInfo.CurrentLocation); } } /// /// 更新WaferHolder工序错误状态 /// /// private void UpdateWaferHolderErrorStatus() { UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus.Failed); WaferHolderInfo.Status = WaferHolderStatus.Failed; MaterialTrackerManager.Instance.UpdateModuleMaterial(WaferHolderInfo.CurrentLocation); } /// /// 更新WaferHolder工序MisProcessed状态 /// /// private void UpdateWaferHolderMisProcessedStatus() { UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus.MisProcessed); WaferHolderInfo.Status = WaferHolderStatus.MisProcessed; MaterialTrackerManager.Instance.UpdateModuleMaterial(WaferHolderInfo.CurrentLocation); } /// /// 更新WaferHolder处理状态 /// /// /// private void UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus processStatus) { if (Enum.TryParse(WaferHolderInfo.CurrentLocation, out ModuleName moduleName)) { if (!string.IsNullOrEmpty(WaferHolderInfo.WaferAId)) { WaferInfo waferInfo = WaferManager.Instance.GetWaferByWaferId(WaferHolderInfo.WaferAId); if (waferInfo != null && waferInfo.WaferType == WaferType.Production) { WaferManager.Instance.UpdateWaferProcessStatus(moduleName, 0, processStatus); LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{waferInfo.WaferID} status changed to {processStatus}"); } } if (!string.IsNullOrEmpty(WaferHolderInfo.WaferBId)) { WaferInfo waferInfo = WaferManager.Instance.GetWaferByWaferId(WaferHolderInfo.WaferBId); if (waferInfo != null && waferInfo.WaferType == WaferType.Production) { WaferManager.Instance.UpdateWaferProcessStatus(moduleName, 1, processStatus); LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{waferInfo.WaferID} status changed to {processStatus}"); } } } } /// /// 检验前置条件 /// /// private bool CheckStartCondition() { LoaderEntity loaderEntity = Singleton.Instance.GetModule(ModuleName.Loader1.ToString()); if (loaderEntity.WaferHolderInfo != null) { return false; } //if (ProcessJobInfo != null) //{ // if (!SchedulerSequenceRecipeManager.Instance.ExistAvaibleProcessCell(ProcessJobInfo.SequenceRecipe, false)) // { // _currentSequenceIndex = _schedulerSequences.Count; // LOG.WriteLog(eEvent.WARN_SCHEDULER, "System", $"WaferHolder {WaferHolderInfo.Id} start scheduler meet no avaible cell"); // return false; // } //} return true; } /// /// 释放资源 /// public void Dispose() { _schedulerSequences.Clear(); } /// /// 暂停 /// public void Pause() { _pausedIndex = _currentSequenceIndex; } /// /// 恢复 /// public void Resume() { _pausedIndex = -1; } /// /// 获取当前调度阶段 /// /// public SchedulerSequence GetCurrentSchedulerSequence() { return GetSchedulerSequenceByIndex(_currentSequenceIndex); } /// /// 获取前一个调度阶段 /// /// public SchedulerSequence GetPreSchedulerSequence() { return GetSchedulerSequenceByIndex(_currentSequenceIndex-1); } /// /// 根据索引获取调度阶段对象 /// /// /// private SchedulerSequence GetSchedulerSequenceByIndex(int index) { if (index == -1 || index >= _schedulerSequences.Count) { return null; } return _schedulerSequences[index]; } /// /// 是否调度完成Loader调度 /// /// public bool IsNotPassLoader() { return _currentSequenceIndex <= 1; } } }