using Aitex.Core.RT.Device; using Aitex.Core.RT.Fsm; using Aitex.Core.RT.Log; using Aitex.Core.Util; using CyberX8_Core; using CyberX8_RT.Devices.AXIS; using CyberX8_RT.Modules; using CyberX8_RT.Modules.Loader; using CyberX8_RT.Modules.Metal; using CyberX8_RT.Modules.Prewet; using CyberX8_RT.Modules.Transporter; using CyberX8_RT.Schedulers.EfemRobot; using MECF.Framework.Common.CommonData; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.RecipeCenter; using MECF.Framework.Common.Schedulers; using MECF.Framework.Common.WaferHolder; using MECF.Framework.RT.Core.Equipments; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Markup; namespace CyberX8_RT.Schedulers.Transporter { public class SchedulerProcessTransporter : SchedulerModule { #region 内部变量 /// /// Process Transporter /// private TransporterEntity _processTransporterEntity; /// /// Loader transporterEntity /// private TransporterEntity _loaderTransporterEntity; /// /// 调度发送消息 /// private SchedulerPostMsg _schedulerPostMsg=new SchedulerPostMsg(); /// /// 推送消息结果 /// private bool _postMsgResult = false; #endregion #region 属性 /// /// 是否空闲 /// public override bool IsIdle { get { return _state == RState.End; } } /// /// 是否错误 /// public override bool IsError { get { return _state == RState.Failed || _state == RState.Timeout; } } public bool IsBusy { get { return _state == RState.Running; } } #endregion /// /// 构造函数 /// /// public SchedulerProcessTransporter(ModuleName module) : base(module.ToString()) { _processTransporterEntity = Singleton.Instance.GetModule(module.ToString()); _loaderTransporterEntity = Singleton.Instance.GetModule(ModuleName.Transporter2.ToString()); } /// /// 执行 /// /// /// public override bool RunProcess(object recipe, object parameter, List syncMessages) { if (parameter == null || !(parameter is WaferHolderMoveItem)) { return false; } WaferHolderMoveItem waferHolderMoveItem = (WaferHolderMoveItem)parameter; if (waferHolderMoveItem.SourceModule != ModuleName.Unknown && waferHolderMoveItem.DestModule != ModuleName.Unknown) { SchedulerLoaderTransporter schedulerLoaderTransporter = (SchedulerLoaderTransporter)SchedulerManager.Instance.GetScheduler(ModuleName.Transporter2); if (schedulerLoaderTransporter.IsBusy && _loaderTransporterEntity.IsIdle) { return false; } if (!_processTransporterEntity.CheckOtherEntityStatus(waferHolderMoveItem.SourceModule.ToString())) { return false; } if (!_processTransporterEntity.CheckOtherEntityStatus(waferHolderMoveItem.DestModule.ToString())) { return false; } if (!WaferHolderManager.Instance.HasWaferHolder(waferHolderMoveItem.SourceModule.ToString())) { return false; } if (WaferHolderManager.Instance.HasWaferHolder(waferHolderMoveItem.DestModule.ToString())) { return false; } return TransferWaferHolderNonLoader(waferHolderMoveItem); } return true; } /// /// 传输WaferHolder(无WaferHolder) /// /// private bool TransferWaferHolderNonLoader(WaferHolderMoveItem waferHolderMoveItem) { IModuleEntity moduleEntity = Singleton.Instance.GetModule(waferHolderMoveItem.DestModule.ToString()); if (moduleEntity != null) { if (waferHolderMoveItem.SourceModule == ModuleName.Unknown || waferHolderMoveItem.DestModule == ModuleName.Unknown) { return false; } bool result = false; if (waferHolderMoveItem.DestModuleType != ModuleType.Metal) { result = _processTransporterEntity.CheckToPostMessage(eEvent.WARN_TRANSPORTER, Module.ToString(), (int)TransporterMSG.Transfer, waferHolderMoveItem.SourceModule.ToString(), waferHolderMoveItem.DestModule.ToString()); } else { result = _processTransporterEntity.CheckToPostMessage(eEvent.WARN_TRANSPORTER, Module.ToString(), (int)TransporterMSG.PickUpMoveTo, waferHolderMoveItem.SourceModule.ToString(), waferHolderMoveItem.DestModule.ToString()); } if (result) { _state = RState.Running; _postMsgResult = false; _schedulerPostMsg.Reset(); } return result; } return false; } /// /// 监控执行 /// /// public override bool MonitorProcess(SchedulerSequence schedulerSequence,bool hasMatchWafer) { WaferHolderMoveItem waferHolderMoveItem = (WaferHolderMoveItem)schedulerSequence.Parameters; //检验PostMsg的结果 if (!_postMsgResult) { if (_processTransporterEntity.IsError) { return false; } _postMsgResult = CheckPostMsg(waferHolderMoveItem); if (!_postMsgResult) { return false; } } if (waferHolderMoveItem.DestModuleType != ModuleType.Metal) { if (_processTransporterEntity.IsIdle) { if (_processTransporterEntity.WaferHolderInfo != null) { return false; } if (waferHolderMoveItem.SourceModuleType == ModuleType.Prewet) { PrewetPickComplete(); } _state = RState.End; } } else { if (waferHolderMoveItem.SourceModuleType == ModuleType.Prewet) { if (_processTransporterEntity.WaferHolderInfo != null) { PrewetPickComplete(); } } //ProcessTransporter完成PickUp和MoveTo if (_processTransporterEntity.State == (int)TransporterState.PickUpMoveToComplete) { MetalEntity metalEntity = Singleton.Instance.GetModule(waferHolderMoveItem.DestModule.ToString()); if (metalEntity != null) { //关闭FlowValve if (metalEntity.State == (int)MetalState.WaitCloseFlow) { metalEntity.CheckToPostMessage(eEvent.WARN_METAL, waferHolderMoveItem.DestModule.ToString(), (int)MetalMsg.CloseFlowValve); } //完成FlowValve关闭后状态变更为等待打开FlowValve,执行Place else if (metalEntity.State == (int)MetalState.WaitOpenFlow) { _processTransporterEntity.CheckToPostMessage(eEvent.WARN_TRANSPORTER, Module.ToString(), (int)TransporterMSG.Place, waferHolderMoveItem.DestModule.ToString()); } } } //Transporter完成Place后 else if (_processTransporterEntity.IsIdle) { if(_processTransporterEntity.WaferHolderInfo!=null) { return false; } MetalEntity metalEntity = Singleton.Instance.GetModule(waferHolderMoveItem.DestModule.ToString()); if (metalEntity != null) { //打开FlowValve,完成传输任务 if (metalEntity.State == (int)MetalState.WaitOpenFlow) { bool result= metalEntity.CheckToPostMessage(eEvent.WARN_METAL, waferHolderMoveItem.DestModule.ToString(), (int)MetalMsg.OpenFlowValve); if(result) { _state = RState.End; } } } } } return true; } /// /// 检验PostMsg的结果 /// /// /// private bool CheckPostMsg(WaferHolderMoveItem waferHolderMoveItem) { if (waferHolderMoveItem.DestModuleType == ModuleType.Metal) { return _schedulerPostMsg.PostMsg(_processTransporterEntity, _processTransporterEntity.State, eEvent.WARN_TRANSPORTER, Module.ToString(), (int)TransporterMSG.PickUpMoveTo, (int)TransporterState.PickUpMoveToing, waferHolderMoveItem.SourceModule.ToString(), waferHolderMoveItem.DestModule.ToString()); } else { return _schedulerPostMsg.PostMsg(_processTransporterEntity, _processTransporterEntity.State, eEvent.WARN_TRANSPORTER, Module.ToString(), (int)TransporterMSG.Transfer, (int)TransporterState.Transfering, waferHolderMoveItem.SourceModule.ToString(), waferHolderMoveItem.DestModule.ToString()); } } /// /// PrewetPick完成事件 /// private void PrewetPickComplete() { PrewetEntity prewetEntity = Singleton.Instance.GetModule(ModuleName.Prewet1.ToString()); if (prewetEntity.State == (int)PrewetState.WaitForPick) { prewetEntity.CheckToPostMessage(eEvent.WARN_PREWET, ModuleName.Prewet1.ToString(), (int)PrewetMsg.PickComplete); } } /// /// 检验前置条件 /// /// /// /// public override bool CheckPrecondition(List schedulerSequences, int sequenceIndex, object parameter, string materialId,ref string reason) { if (!(parameter is WaferHolderMoveItem)) { reason = "parameter is not WaferHolderMoveItem"; return false; } if (_state == RState.Running) { reason = "scheduler module is already running"; return false; } if (_processTransporterEntity.WaferHolderInfo != null) { reason = "process transporter has wafer shuttle"; return false; } //电机是否还在执行动作 JetAxisBase gantryAxis = DEVICE.GetDevice($"{ModuleName.Transporter1}.Gantry"); if(gantryAxis==null) { reason = "process transporter gantry is null"; return false; } if (gantryAxis.Status == RState.Running) { reason = "process transporter gantry is running"; return false; } JetAxisBase elevatorAxis = DEVICE.GetDevice($"{ModuleName.Transporter1}.Elevator"); if (elevatorAxis == null) { reason = "process transporter elevator is null"; return false; } if (elevatorAxis.Status == RState.Running) { reason = "process transporter elevator is running"; return false; } if (_processTransporterEntity.IsBusy) { reason = "process transporter entity is busy"; return false; } WaferHolderMoveItem waferHolderMoveItem = (WaferHolderMoveItem)parameter; bool result = false; //更新未知源模块 UpdateUnkownSourceModule(schedulerSequences, waferHolderMoveItem, sequenceIndex); //源为Prewet if (waferHolderMoveItem.SourceModule == ModuleName.Prewet1) { result= CheckSourcePrewetCondition(); if(!result) { reason = "process transporter sourcemodule prewet condition is not avaible"; return false; } } bool existEnableCell = false; //更新未知目标模块 result = UpdateUnkownTargetModule(schedulerSequences, waferHolderMoveItem, sequenceIndex,materialId,ref existEnableCell); if (!result) { reason = "process transporter moveitem target module is unknown"; return false; } if (waferHolderMoveItem.DestModuleType==ModuleType.Metal) { if(!ModuleHelper.IsMetal(waferHolderMoveItem.DestModule)) { reason = "process transporter target module is not metal"; return false; } UpdateNextMetalScheduler(schedulerSequences, sequenceIndex, waferHolderMoveItem.DestModule); result= CheckTargetMetalCondition(waferHolderMoveItem.DestModule.ToString(),waferHolderMoveItem, schedulerSequences, sequenceIndex); if(!result) { reason = $"process transporter target module {waferHolderMoveItem.DestModule} condition is false"; return false; } } return true; } /// /// 更新下一块Metal /// /// /// private void UpdateNextMetalScheduler(List schedulerSequences,int sequenceIndex,ModuleName metalName) { if(sequenceIndex+1 /// 更新未知目标模块 /// private bool UpdateUnkownTargetModule(List schedulerSequences, WaferHolderMoveItem waferHolderMoveItem, int sequenceIndex,string materialId,ref bool existEnableCell) { if (waferHolderMoveItem.DestModule == ModuleName.Unknown) { if (sequenceIndex + 1 < schedulerSequences.Count) { SchedulerSequence sequence = schedulerSequences[sequenceIndex + 1]; ModuleName moduleName = ModuleName.Unknown; if (waferHolderMoveItem.DestModuleType == ModuleType.Metal) { if (sequence.Recipe != null && sequence.Recipe is DepRecipe) { //获取可用的Metal以及Rinse DepRecipe depRecipe = (DepRecipe)sequence.Recipe; ModuleName tmpName = SchedulerSequenceManager.Instance.CalculateAvaibleMetalCellByChemistry(depRecipe.Chemistry, waferHolderMoveItem.SourceModule.ToString(),sequence.SequenceType,ref existEnableCell); if (tmpName != ModuleName.Unknown) { IModuleEntity moduleEntity = Singleton.Instance.GetModule(tmpName.ToString()); if (SchedulerSequenceManager.Instance.CheckMetalCellRecipeTimeAvaible(moduleEntity, depRecipe)) { moduleName = tmpName; } } } } else if(waferHolderMoveItem.DestModuleType==ModuleType.Rinse) { if (waferHolderMoveItem.SourceModuleType == ModuleType.Metal) { moduleName = SchedulerSequenceManager.Instance.GetAvaibleEmptyModuleCell(waferHolderMoveItem.DestModuleType,sequence.SequenceType,waferHolderMoveItem.SourceModule); } else { for(int i = sequenceIndex - 1; i >= 0; i--) { SchedulerSequence tmp=schedulerSequences[i]; if (tmp.ModuleType == ModuleType.Metal&&ModuleHelper.IsMetal(tmp.ModuleName)) { moduleName = SchedulerSequenceManager.Instance.GetAvaibleEmptyModuleCell(waferHolderMoveItem.DestModuleType,tmp.SequenceType, tmp.ModuleName); break; } } } } else { moduleName = SchedulerSequenceManager.Instance.GetAvaibleEmptyModuleCell(waferHolderMoveItem.DestModuleType,sequence.SequenceType,waferHolderMoveItem.SourceModule); } if (moduleName == ModuleName.Unknown) { return false; } else { LOG.WriteLog(eEvent.EV_SCHEDULER, Module.ToString(), $"{materialId} ProcessTransporter Confirm Next Cell {moduleName}"); waferHolderMoveItem.DestModule = moduleName; if (sequence.SchedulerModule == null) { sequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(moduleName); sequence.ModuleName = moduleName; } } } } return true; } /// /// 更新未知源模块 /// private void UpdateUnkownSourceModule(List schedulerSequences, WaferHolderMoveItem waferHolderMoveItem, int sequenceIndex) { if (waferHolderMoveItem.SourceModule == ModuleName.Unknown) { for (int i = sequenceIndex - 1; i >= 0; i--) { SchedulerSequence preSchedulerSequence = schedulerSequences[i]; if (preSchedulerSequence.State == RState.End) { if (i == sequenceIndex - 1) { if (preSchedulerSequence != null && preSchedulerSequence.SchedulerModule != null) { waferHolderMoveItem.SourceModule = preSchedulerSequence.SchedulerModule.Module; break; } } else { //用于Metal出错后跳过了几个步骤,transporter源模块取至前面跳过的transporter1的目标模块 if(preSchedulerSequence.ModuleName==ModuleName.Transporter1) { WaferHolderMoveItem preWaferHolderMoveItem = preSchedulerSequence.Parameters as WaferHolderMoveItem; if (preSchedulerSequence != null && preWaferHolderMoveItem.DestModule!=ModuleName.Unknown) { waferHolderMoveItem.SourceModule = preWaferHolderMoveItem.DestModule; break; } } } } } } } /// /// 检验源Prewet前置条件 /// /// private bool CheckSourcePrewetCondition() { PrewetEntity prewetEntity = Singleton.Instance.GetModule(ModuleName.Prewet1.ToString()); if (prewetEntity.State == (int)PrewetState.WaitForPick) { return true; } return false; } /// /// 检验目标Metal前置条件 /// /// private bool CheckTargetMetalCondition(string metalName,WaferHolderMoveItem waferHolderMoveItem,List schedulerSequences,int sequenceIndex) { MetalEntity metalEntity = Singleton.Instance.GetModule(metalName); if (metalEntity.IsIdle) { metalEntity.CheckToPostMessage(eEvent.WARN_METAL, metalName, (int)MetalMsg.CurrentShortTest); } else if (metalEntity.State == (int)MetalState.WaitCloseFlow) { return true; } else if (metalEntity.IsError) { waferHolderMoveItem.DestModule = ModuleName.Unknown; SchedulerSequence nextSequence = schedulerSequences[sequenceIndex + 1]; if (nextSequence != null) { nextSequence.SchedulerModule = null; nextSequence.ModuleName = ModuleName.Unknown; } } return false; } public override void ResetTask() { base.ResetTask(); _schedulerPostMsg.Reset(); _postMsgResult = false; } } }