1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015 |
- 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
- }
- /// <summary>
- /// WaferHolder
- /// </summary>
- /// <param name="info"></param>
- /// <param name="schedulerSequence"></param>
- public delegate void WaferHolderSchedulerComplete(WaferHolderInfo info, SchedulerSequence schedulerSequence);
- /// <summary>
- /// WaferHolderTask完成
- /// </summary>
- /// <param name="id"></param>
- public delegate void WaferHolderTaskComplete(string id);
- public class WaferHolderTask
- {
- #region 内部变量
- /// <summary>
- /// 调度步骤
- /// </summary>
- private List<SchedulerSequence> _schedulerSequences;
- /// <summary>
- /// 当前步骤索引
- /// </summary>
- private int _currentSequenceIndex = 0;
- /// <summary>
- /// PUF实例
- /// </summary>
- private PUFEntity _puf1Entity;
- /// <summary>
- /// PUF实例
- /// </summary>
- private PUFEntity _puf2Entity;
- /// <summary>
- /// 是否开始执行
- /// </summary>
- private bool _isStart = false;
- /// <summary>
- /// 暂停时的索引
- /// </summary>
- private int _pausedIndex = -1;
- /// <summary>
- /// 错误上升触发
- /// </summary>
- private R_TRIG _sequenceErrorTigger = new R_TRIG();
- /// <summary>
- /// Sequence类型
- /// </summary>
- private string _sequenceType = "";
- /// <summary>
- /// FA回复
- /// </summary>
- private SchedulerFACallback _schedulerFACallback = new SchedulerFACallback();
- #endregion
- #region 属性
- /// <summary>
- /// ID
- /// </summary>
- public string ID { get;private set; }
- /// <summary>
- /// WaferHolder属性
- /// </summary>
- public WaferHolderInfo WaferHolderInfo { get;private set; }
- /// <summary>
- /// Process Job信息
- /// </summary>
- public ProcessJobInfo ProcessJobInfo { get;private set; }
- /// <summary>
- /// 状态
- /// </summary>
- public WaferHolderTaskState State { get; private set; }
- /// <summary>
- /// 步骤完成事件
- /// </summary>
- public event WaferHolderSchedulerComplete OnSchedulerComplete;
- /// <summary>
- /// 任务完成事件
- /// </summary>
- public event WaferHolderTaskComplete OnTaskComplete;
- /// <summary>
- /// 调度集合
- /// </summary>
- public List<SchedulerSequence> SchedulerSequences { get { return _schedulerSequences; } }
- #endregion
- /// <summary>
- /// 构造函数
- /// </summary>
- /// <param name="waferHolderInfo"></param>
- /// <param name="schedulerSequences"></param>
- public WaferHolderTask(WaferHolderInfo waferHolderInfo,ProcessJobInfo processJobInfo)
- {
- 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;
- State = WaferHolderTaskState.Created;
- _puf1Entity = Singleton<RouteManager>.Instance.GetModule<PUFEntity>(ModuleName.PUF1.ToString());
- _puf2Entity = Singleton<RouteManager>.Instance.GetModule<PUFEntity>(ModuleName.PUF2.ToString());
- }
- /// <summary>
- /// 初始化调度步骤
- /// </summary>
- /// <param name="schedulers"></param>
- public void InitialSchedulers(List<SchedulerSequence> schedulers)
- {
- _schedulerSequences = schedulers;
- }
- /// <summary>
- /// 分析生产片的ProcessJob信息
- /// </summary>
- 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;
- }
- }
- }
- /// <summary>
- /// 执行
- /// </summary>
- 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<string>();
- }
- 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++;
- }
- }
- }
- /// <summary>
- /// 更新任务结束
- /// </summary>
- 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");
- }
- /// <summary>
- /// 更新从Loader到Buffer的WaferHolder更新为不可以拉回至Loader
- /// </summary>
- /// <param name="sequence"></param>
- 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;");
- }
- }
- }
- /// <summary>
- /// 分析错误状态下的调度
- /// </summary>
- 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);
- }
- }
- /// <summary>
- /// 判定Buffer中WaferHolder的后面工序是否存在可用资源,不存在的话,则Task直接结束
- /// </summary>
- /// <param name="sequence"></param>
- 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;
- }
- /// <summary>
- /// 检验Prewet后面的Metal是否存在可用
- /// </summary>
- 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;
- }
- }
- /// <summary>
- /// 检验Rinse后面的Metal是否存在可用
- /// </summary>
- /// <returns></returns>
- 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();
- }
- }
- /// <summary>
- /// 检验后续Metal可用性
- /// </summary>
- /// <returns></returns>
- 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
- /// <summary>
- /// Prewet出错重新调度
- /// </summary>
- /// <param name="sequence"></param>
- 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");
- }
- /// <summary>
- /// 路过后面调度直接至Dryer
- /// </summary>
- 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;
- }
- }
- }
- }
- }
- /// <summary>
- /// Dryer出错重新调度,上一步调度修改为transporter2,同时tranporter2搬运源目标为当前Module,目标类型也是Dryer
- /// </summary>
- /// <param name="sequence"></param>
- 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");
- }
- }
- /// <summary>
- /// Rinse出错重新调度,回退至上一步调度
- /// </summary>
- /// <param name="sequence"></param>
- 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");
- }
- }
- /// <summary>
- /// Metal出错重新调度,回退至上一步调度
- /// </summary>
- /// <param name="sequence"></param>
- 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++;
- }
- /// <summary>
- /// 跳过后面的Metal
- /// </summary>
- 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;
- }
- }
- }
- }
- /// <summary>
- /// 移除SRD调度
- /// </summary>
- 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
- /// <summary>
- /// 自动更新LoaderTransporter的工序
- /// </summary>
- 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<RouteManager>.Instance.GetModule<LoaderEntity>(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;
- }
- }
- }
- /// <summary>
- /// 检验Buffer中是否存在未处理的WaferHolder
- /// </summary>
- /// <returns></returns>
- private bool CheckBufferHasUnProcessedWaferHolder()
- {
- List<string> 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;
- }
- /// <summary>
- /// 更新下一工序的调度模块
- /// </summary>
- /// <param name="sequenceIndex"></param>
- /// <param name="moduleName"></param>
- 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;
- }
- }
- }
- /// <summary>
- /// 更新WaferHolder工序完成Wafer状态
- /// </summary>
- 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);
- }
- /// <summary>
- /// 更新WaferHolder工序正在加工
- /// </summary>
- 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);
- }
- }
- /// <summary>
- /// 更新WaferHolder工序错误状态
- /// </summary>
- /// <param name="sequence"></param>
- private void UpdateWaferHolderErrorStatus()
- {
- UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus.Failed);
- WaferHolderInfo.Status = WaferHolderStatus.Failed;
- MaterialTrackerManager.Instance.UpdateModuleMaterial(WaferHolderInfo.CurrentLocation);
- }
- /// <summary>
- /// 更新WaferHolder工序MisProcessed状态
- /// </summary>
- /// <param name="sequence"></param>
- private void UpdateWaferHolderMisProcessedStatus()
- {
- UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus.MisProcessed);
- WaferHolderInfo.Status = WaferHolderStatus.MisProcessed;
- MaterialTrackerManager.Instance.UpdateModuleMaterial(WaferHolderInfo.CurrentLocation);
- }
- /// <summary>
- /// 更新WaferHolder处理状态
- /// </summary>
- /// <param name="sequence"></param>
- /// <param name="processStatus"></param>
- 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}");
- }
- }
- }
- }
- /// <summary>
- /// 检验前置条件
- /// </summary>
- /// <returns></returns>
- private bool CheckStartCondition()
- {
- LoaderEntity loaderEntity = Singleton<RouteManager>.Instance.GetModule<LoaderEntity>(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;
- }
- /// <summary>
- /// 释放资源
- /// </summary>
- public void Dispose()
- {
- _schedulerSequences.Clear();
- }
- /// <summary>
- /// 暂停
- /// </summary>
- public void Pause()
- {
- _pausedIndex = _currentSequenceIndex;
- }
- /// <summary>
- /// 恢复
- /// </summary>
- public void Resume()
- {
- _pausedIndex = -1;
- }
- /// <summary>
- /// 获取当前调度阶段
- /// </summary>
- /// <returns></returns>
- public SchedulerSequence GetCurrentSchedulerSequence()
- {
- return GetSchedulerSequenceByIndex(_currentSequenceIndex);
- }
- /// <summary>
- /// 获取前一个调度阶段
- /// </summary>
- /// <returns></returns>
- public SchedulerSequence GetPreSchedulerSequence()
- {
- return GetSchedulerSequenceByIndex(_currentSequenceIndex-1);
- }
- /// <summary>
- /// 根据索引获取调度阶段对象
- /// </summary>
- /// <param name="index"></param>
- /// <returns></returns>
- private SchedulerSequence GetSchedulerSequenceByIndex(int index)
- {
- if (index == -1 || index >= _schedulerSequences.Count)
- {
- return null;
- }
- return _schedulerSequences[index];
- }
- /// <summary>
- /// 是否调度完成Loader调度
- /// </summary>
- /// <returns></returns>
- public bool IsNotPassLoader()
- {
- return _currentSequenceIndex <= 1;
- }
- }
- }
|