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 PunkHPX8_Core; using PunkHPX8_RT.Modules; using PunkHPX8_RT.Schedulers; using PunkHPX8_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 PunkHPX8_RT.Modules.SRD; namespace PunkHPX8_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; /// /// 是否开始执行 /// private bool _isStart = false; /// /// 暂停时的索引 /// private int _pausedIndex = -1; /// /// 日志trigger /// private R_TRIG _sequenceConditionTrigger = new R_TRIG(); /// /// 错误上升触发 /// private R_TRIG _sequenceErrorTigger = new R_TRIG(); /// /// 创建时间 /// private DateTime _createTime = DateTime.Now; #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; } } /// /// 当前索引 /// public int CurrentSequenceIndex { get { return _currentSequenceIndex; } } /// /// ProcessJob对象 /// public ProcessJobInfo ProcessJobInfo { get; internal set; } /// /// 创建时间 /// public DateTime CreateTime { get { return _createTime; } } #endregion #region 事件 /// /// 任务完成事件 /// public event WaferTaskComplete OnTaskComplete; /// /// 任务启动 /// public event WaferTaskStart OnTaskStart; #endregion /// /// 构造函数 /// /// /// public WaferTask(WaferInfo waferInfo, List schedulerSequences) { WaferId = waferInfo.WaferID; _schedulerSequences = schedulerSequences; State = WaferTaskState.Created; ProcessJobInfo = waferInfo.ProcessJob; } /// /// 执行 /// 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; } //暂停中 if(sequence.State==RState.Init&&_currentSequenceIndex>=_pausedIndex&&_pausedIndex!=-1) { return; } if(sequence.IsWaitNotify) { 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(WaferId)); sequence.SchedulerModule.MonitorProcess(sequence,hasMatched); _sequenceErrorTigger.CLK = sequence.SchedulerModule.IsError; if (sequence.SchedulerModule.IsError) { 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; LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferId} {_currentSequenceIndex + 1} sequence complete, time length {sequence.ProcessMilliSeconds}"); if (sequence.IsProcessSequece) { UpdateWaferProcessingStatus(); } if (sequence.IsLastProcessSequence) { UpdateWaferProcessComplete(); } _currentSequenceIndex++; } } else if(sequence.State==RState.End) { LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferId} {_currentSequenceIndex + 1} sequence is End"); _currentSequenceIndex++; } } } /// /// 分析错误状态下的调度 /// private void AnalyseSchedulerErrorState(SchedulerSequence sequence) { if (sequence.ModuleType == ModuleType.PlatingCell) { AnalyseSchedulerPlatingCellErrorState(sequence); } } /// /// Metal出错重新调度,移至下一步调度 /// /// private void AnalyseSchedulerPlatingCellErrorState(SchedulerSequence sequence) { //当前步骤结束,WaferHolder状态 UpdateWaferErrorStatus(); sequence.EndTime = DateTime.Now; sequence.ProcessMilliSeconds = sequence.EndTime.Subtract(sequence.StartTime).TotalMilliseconds; sequence.State = RState.End; LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferId} PlatingCell meet error,rescheduler changed to next module"); //跳过后面的metal SkipAfterMetal(sequence, true); //移除SRD调度 RemoveSrdScheduler(); _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.PlatingCell && startIndex == -1) { startIndex = i; } if (item.ModuleType == ModuleType.SRD) { endIndex = i - 1;//SRD前一步骤为Robot,保留Dryer前面的Robot break; } } //将后面的Metal的步骤直接跳过,包含后面的Robot 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", $"{WaferId} skip {i} sequence {item.ModuleType}"); } } //是否设置最后调度的源模块 if (isSetLastSequenceSourceModule && endIndex != -1) { SchedulerSequence lastSchedulerSequence = _schedulerSequences[endIndex]; if (lastSchedulerSequence.ModuleType == ModuleType.EfemRobot) { MoveItem waferHolderMoveItem = lastSchedulerSequence.Parameters as MoveItem; if (schedulerSequence.SchedulerModule != null) { waferHolderMoveItem.SourceModule = schedulerSequence.ModuleName; waferHolderMoveItem.SourceType = schedulerSequence.ModuleType; } } } } /// /// 更新WaferHolder工序完成Wafer状态 /// private void UpdateWaferProcessComplete() { WaferInfo waferInfo = WaferManager.Instance.GetWaferByWaferId(WaferId); if (waferInfo == null || waferInfo.IsEmpty) { return; } if (waferInfo.ProcessState == EnumWaferProcessStatus.InProcess) { WaferManager.Instance.UpdateWaferProcessStatus(WaferId, EnumWaferProcessStatus.Completed); } LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{waferInfo.WaferID} Status changed to {EnumWaferProcessStatus.Completed}"); } /// /// 更新WaferHolder工序完成Wafer状态 /// private void UpdateWaferErrorStatus() { WaferInfo waferInfo = WaferManager.Instance.GetWaferByWaferId(WaferId); if (waferInfo == null || waferInfo.IsEmpty) { return; } if (waferInfo.ProcessState == EnumWaferProcessStatus.InProcess) { WaferManager.Instance.UpdateWaferProcessStatus(WaferId, EnumWaferProcessStatus.Failed); } LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{waferInfo.WaferID} Status changed to {EnumWaferProcessStatus.Failed}"); } /// /// 更新WaferHolder工序正在加工 /// private void UpdateWaferProcessingStatus() { WaferInfo waferInfo = WaferManager.Instance.GetWaferByWaferId(WaferId); if (waferInfo == null || waferInfo.IsEmpty) { return; } if (waferInfo.ProcessState == EnumWaferProcessStatus.Idle) { WaferManager.Instance.UpdateWaferProcessStatus(WaferId, EnumWaferProcessStatus.InProcess); } LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{waferInfo.WaferID} Status changed to {EnumWaferProcessStatus.InProcess}"); } /// /// 分析错误状态下的调度 /// 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(!string.IsNullOrEmpty(MateWaferTask)) { WaferTask mateTask=WaferTaskManager.Instance.GetWaferTask(MateWaferTask); if(mateTask!=null) { if(mateTask.State==WaferTaskState.Created) { return false; } } } return true; } /// /// 暂停 /// 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; } } } } } /// /// 获取任务索引 /// /// public int GetCurrentSchedulerIndex() { return _currentSequenceIndex; } /// /// 获取当前调度阶段 /// /// public SchedulerSequence GetCurrentSchedulerSequence() { return GetSchedulerSequenceByIndex(_currentSequenceIndex); } /// /// 根据索引获取Sequence /// /// /// public SchedulerSequence GetSchedulerSequenceByIndex(int index) { if (index >= _schedulerSequences.Count || index < 0) { return null; } return _schedulerSequences[index]; } } }