using Aitex.Core.RT.Fsm; using Aitex.Core.Util; using MECF.Framework.Common.CommonData; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using CyberX8_Core; using CyberX8_RT.Modules; using CyberX8_RT.Modules.Loader; using CyberX8_RT.Modules.Transporter; using CyberX8_RT.Modules.PUF; using System; using System.Collections.Generic; using System.Linq; using System.ServiceModel.Syndication; using System.Text; using System.Threading.Tasks; using CyberX8_RT.Modules.Prewet; using Aitex.Core.RT.Device; using CyberX8_RT.Devices.AXIS; using MECF.Framework.Common.WaferHolder; using Aitex.Core.RT.Log; namespace CyberX8_RT.Schedulers.Transporter { public class SchedulerLoaderTransporter : SchedulerModule { private enum TransBufferToLoaderStep { None, NotifyLoaderPrepare, WaitLoaderPrePare, PickUpValidate, PickUpValidateMoveto, Place, End } #region 内部变量 private LoaderEntity _loaderEntity; private TransporterEntity _loaderTransporterEntity; private TransporterEntity _processTransporterEntity; private TransBufferToLoaderStep _transBufferToLoaderStep = TransBufferToLoaderStep.None; private SchedulerPostMsg _schedulerPostMsg = new SchedulerPostMsg(); private bool _postMsgResult = false; #endregion #region 属性 public override bool IsIdle { get { return _state == RState.End; } } public bool IsBusy { get { return _state == RState.Running; } } public override bool IsError { get { return _state==RState.Failed||_state==RState.Timeout; } } #endregion /// /// 构造函数 /// /// public SchedulerLoaderTransporter(ModuleName module) : base(module.ToString()) { _loaderEntity = Singleton.Instance.GetModule(ModuleName.Loader1.ToString()); _loaderTransporterEntity = Singleton.Instance.GetModule(ModuleName.Transporter2.ToString()); _processTransporterEntity = Singleton.Instance.GetModule(ModuleName.Transporter1.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) { SchedulerProcessTransporter schedulerProcessTransporter = (SchedulerProcessTransporter)SchedulerManager.Instance.GetScheduler(ModuleName.Transporter1); if(schedulerProcessTransporter.IsBusy&&_processTransporterEntity.IsIdle) { return false; } if (!_loaderTransporterEntity.CheckOtherEntityStatus(waferHolderMoveItem.SourceModule.ToString())) { return false; } if (!_loaderTransporterEntity.CheckOtherEntityStatus(waferHolderMoveItem.DestModule.ToString())) { return false; } string strSource = waferHolderMoveItem.SourceModule.ToString(); if(waferHolderMoveItem.SourceModule==ModuleName.Loader1) { strSource = "Loader"; } //由于PickUpValidate可能存在校验失败的现象 if (!WaferHolderManager.Instance.HasWaferHolder(strSource)&&_loaderTransporterEntity.State!=(int)TransporterState.PickUpValidateComplete) { return false; } string strDest = waferHolderMoveItem.DestModule.ToString(); if(waferHolderMoveItem.DestModule==ModuleName.Loader1) { strDest = "Loader"; } if(WaferHolderManager.Instance.HasWaferHolder(strDest)) { return false; } if (waferHolderMoveItem.DestModule==ModuleName.Loader1) { return TransferWaferHolderToLoader(waferHolderMoveItem); } else if(waferHolderMoveItem.SourceModule==ModuleName.Loader1) { return TransWaferHolderFromLoader(waferHolderMoveItem); } else if(waferHolderMoveItem.SourceModuleType!=ModuleType.Loader&&waferHolderMoveItem.DestModuleType!=ModuleType.Loader) { return TransferWaferHolderNonLoader(waferHolderMoveItem); } } return true; } /// /// WaferHolder从Loader移动至Buffer /// private bool TransWaferHolderFromLoader(WaferHolderMoveItem waferHolderMoveItem) { if (_loaderEntity.IsBusy) { return false; } if (_loaderEntity.WaferHolderInfo == null) { return false; } bool result = _loaderTransporterEntity.CheckToPostMessage(Aitex.Core.RT.Log.eEvent.WARN_TRANSPORTER, Module.ToString(), (int)TransporterMSG.Transfer, "Loader", waferHolderMoveItem.DestModule.ToString()); if (result) { _state = RState.Running; _schedulerPostMsg.Reset(); _postMsgResult = false; } return result; } /// /// WaferHolder从Buffer移动至Loader /// private bool TransferWaferHolderToLoader(WaferHolderMoveItem waferHolderMoveItem) { if (_loaderEntity.WaferHolderInfo != null) { return false; } if (_loaderEntity.IsIdle) { bool loaderResult = _loaderEntity.CheckToPostMessage(Aitex.Core.RT.Log.eEvent.WARN_LOADER, _loaderEntity.Module.ToString(), (int)LoaderMSG.PrepareForPlace); if (loaderResult) { _transBufferToLoaderStep = TransBufferToLoaderStep.WaitLoaderPrePare; } return false; } else if(_loaderEntity.State == (int)LOADERSTATE.WaitForUnload&&_transBufferToLoaderStep(Aitex.Core.RT.Log.eEvent.WARN_TRANSPORTER, Module.ToString(), (int)TransporterMSG.PickUpValidate, waferHolderMoveItem.SourceModule.ToString()); if (result) { _transBufferToLoaderStep= TransBufferToLoaderStep.PickUpValidateMoveto; _state = RState.Running; _schedulerPostMsg.Reset(); _postMsgResult = false; return true; } } return false; } /// /// 传输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; } if (moduleEntity.Module == ModuleName.Prewet1) { PrewetEntity prewetEntity = moduleEntity as PrewetEntity; if(prewetEntity.State!=(int)PrewetState.WaitForPlace) { return false; } } else { if (!moduleEntity.IsIdle) { return false; } } if (waferHolderMoveItem.SourceModule != ModuleName.Unknown) { if (!_loaderTransporterEntity.CheckOtherEntityStatus(waferHolderMoveItem.SourceModule.ToString())) { return false; } } if (waferHolderMoveItem.DestModule != ModuleName.Unknown) { if (!_loaderTransporterEntity.CheckOtherEntityStatus(waferHolderMoveItem.DestModule.ToString())) { return false; } } bool result = _loaderTransporterEntity.CheckToPostMessage(Aitex.Core.RT.Log.eEvent.WARN_TRANSPORTER, Module.ToString(), (int)TransporterMSG.Transfer, 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 moveItem=schedulerSequence.Parameters as WaferHolderMoveItem; //检验PostMsg的结果 if (!_postMsgResult) { if (_loaderTransporterEntity.IsError) { return false; } _postMsgResult = CheckPostMsg(moveItem); if (!_postMsgResult) { return false; } } if (moveItem.DestModule == ModuleName.Loader1) { if (_transBufferToLoaderStep == TransBufferToLoaderStep.PickUpValidateMoveto) { if (_loaderTransporterEntity.IsIdle) { _state = RState.Failed; _transBufferToLoaderStep = TransBufferToLoaderStep.None; return false; } if (_loaderTransporterEntity.State == (int)TransporterState.PickUpValidateComplete) { if (!_loaderTransporterEntity.CheckOtherEntityStatus("Loader")) { return false; } bool result = _loaderTransporterEntity.CheckToPostMessage(Aitex.Core.RT.Log.eEvent.WARN_TRANSPORTER, Module.ToString(), (int)TransporterMSG.MoveTo, "Loader"); if (result) { _transBufferToLoaderStep = TransBufferToLoaderStep.Place; } } return true; } else if (_transBufferToLoaderStep == TransBufferToLoaderStep.Place) { if (_loaderTransporterEntity.State == (int)TransporterState.ValidateMoveToComplete) { bool result = _loaderTransporterEntity.CheckToPostMessage(Aitex.Core.RT.Log.eEvent.WARN_TRANSPORTER, Module.ToString(), (int)TransporterMSG.Place, "Loader"); if (result) { _transBufferToLoaderStep = TransBufferToLoaderStep.End; } } return true; } } if (_loaderTransporterEntity.IsIdle) { if(_loaderTransporterEntity.WaferHolderInfo!=null) { return false; } PrewetPickComplete(schedulerSequence); _state = RState.End; } return true; } /// /// 检验PostMsg的结果 /// /// /// private bool CheckPostMsg(WaferHolderMoveItem waferHolderMoveItem) { if (waferHolderMoveItem.DestModule == ModuleName.Loader1) { return _schedulerPostMsg.PostMsg(_loaderTransporterEntity, _loaderTransporterEntity.State, eEvent.WARN_TRANSPORTER,Module.ToString(), (int)TransporterMSG.PickUpValidate, (int)TransporterState.PickUpValidating, waferHolderMoveItem.SourceModule.ToString()); } else { return _schedulerPostMsg.PostMsg(_loaderTransporterEntity, _loaderTransporterEntity.State, eEvent.WARN_TRANSPORTER, Module.ToString(), (int)TransporterMSG.Transfer, (int)TransporterState.Transfering, waferHolderMoveItem.SourceModule.ToString(),waferHolderMoveItem.DestModule.ToString()); } } /// /// PrewetPick完成事件 /// private void PrewetPickComplete(SchedulerSequence sequence) { if (sequence.Parameters is WaferHolderMoveItem) { WaferHolderMoveItem waferHolderMoveItem = (WaferHolderMoveItem)sequence.Parameters; if (waferHolderMoveItem.SourceModule == ModuleName.Prewet1) { PrewetEntity prewetEntity = Singleton.Instance.GetModule(ModuleName.Prewet1.ToString()); if (prewetEntity.State == (int)PrewetState.WaitForPick) { prewetEntity.CheckToPostMessage(Aitex.Core.RT.Log.eEvent.WARN_PREWET, ModuleName.Prewet1.ToString(), (int)PrewetMsg.PickComplete); } } } } /// /// 检验前置条件 /// /// /// /// public override bool CheckPrecondition(List schedulerSequences, int sequenceIndex, object parameter, string materialId, ref string reason) { _state = RState.Init; if(!(parameter is WaferHolderMoveItem)) { reason = "parameter is not WaferHolderMoveItem"; return false; } if (_state == RState.Running) { reason = "scheduler module is already running"; return false; } if (_loaderTransporterEntity.IsBusy) { reason = "loader transporter entity is busy"; return false; } if (_loaderTransporterEntity.WaferHolderInfo != null&& _loaderTransporterEntity.State != (int)TransporterState.PickUpValidateComplete) { reason = "loader transporter has wafer shuttle,but state is not PickUpValidateComplete"; return false; } //电机是否还在执行动作 JetAxisBase gantryAxis = DEVICE.GetDevice($"{ModuleName.Transporter2}.Gantry"); if (gantryAxis == null) { reason = "loader transporter gantry is null"; return false; } if (gantryAxis.Status == RState.Running) { reason = "loader transporter gantry is running"; return false; } JetAxisBase elevatorAxis = DEVICE.GetDevice($"{ModuleName.Transporter2}.Elevator"); if (elevatorAxis == null) { reason = "loader transporter elevator is null"; return false; } if (elevatorAxis.Status == RState.Running) { reason = "loader transporter elevator is running"; return false; } WaferHolderMoveItem waferHolderMoveItem = (WaferHolderMoveItem)parameter; //更新未知目标模块 bool result= UpdateUnkownTargetModule(schedulerSequences,waferHolderMoveItem,sequenceIndex, materialId); if(!result) { reason = "loader transporter moveitem target module is unknown"; return false; } //更新未知源模块 UpdateUnkownSourceModule(schedulerSequences, waferHolderMoveItem, sequenceIndex,materialId); if (waferHolderMoveItem.SourceModule != ModuleName.Unknown) { if (!_loaderTransporterEntity.CheckOtherEntityStatus(waferHolderMoveItem.SourceModule.ToString())) { reason = $"loader transporter {waferHolderMoveItem.SourceModule} conflict process transporter"; return false; } } if (waferHolderMoveItem.DestModule != ModuleName.Unknown) { if (!_loaderTransporterEntity.CheckOtherEntityStatus(waferHolderMoveItem.DestModule.ToString())) { reason = $"loader transporter {waferHolderMoveItem.DestModule} conflict process transporter"; return false; } } //目标为Prewet if (waferHolderMoveItem.DestModule == ModuleName.Prewet1) { bool prewetCondition= CheckTargetPrewetCondition(); if (!prewetCondition) { reason = "loader transporter destmodule prewet condition is not avaible"; } return prewetCondition; } //源为Prewet if (waferHolderMoveItem.SourceModule == ModuleName.Prewet1) { bool prewetCondition= CheckSourcePrewetCondition(); if (!prewetCondition) { reason = "loader transporter sourcemodule prewet condition is not avaible"; } } return true; } /// /// 更新未知目标模块 /// private bool UpdateUnkownTargetModule(List schedulerSequences, WaferHolderMoveItem waferHolderMoveItem, int sequenceIndex,string materialId) { SchedulerSequence currentSequence = schedulerSequences[sequenceIndex]; if (waferHolderMoveItem.DestModule == ModuleName.Unknown) { ModuleName moduleName = SchedulerSequenceManager.Instance.GetAvaibleEmptyModuleCell(waferHolderMoveItem.DestModuleType,currentSequence.SequenceType); if (moduleName == ModuleName.Unknown) { return false; } else { waferHolderMoveItem.DestModule = moduleName; if (sequenceIndex + 1 < schedulerSequences.Count) { SchedulerSequence sequence = schedulerSequences[sequenceIndex + 1]; if (sequence.SchedulerModule == null) { sequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(moduleName); sequence.ModuleName = moduleName; LOG.WriteLog(eEvent.INFO_TRANSPORTER, Module.ToString(), $"{materialId} loadertransporter confirm source module {moduleName}"); } } } } return true; } /// /// 更新未知源模块 /// private void UpdateUnkownSourceModule(List schedulerSequences, WaferHolderMoveItem waferHolderMoveItem,int sequenceIndex,string materialId) { if (waferHolderMoveItem.SourceModule == ModuleName.Unknown) { if (sequenceIndex >= 1 && sequenceIndex - 1 < schedulerSequences.Count) { SchedulerSequence preSchedulerSequence = schedulerSequences[sequenceIndex - 1]; if (preSchedulerSequence != null && preSchedulerSequence.SchedulerModule != null) { waferHolderMoveItem.SourceModule = preSchedulerSequence.SchedulerModule.Module; LOG.WriteLog(eEvent.INFO_TRANSPORTER, Module.ToString(), $"{materialId} loadertransporter confirm source module {preSchedulerSequence.SchedulerModule.Module}"); } } } } /// /// 检验目标Prewet前置条件 /// /// private bool CheckTargetPrewetCondition() { PrewetEntity prewetEntity = Singleton.Instance.GetModule(ModuleName.Prewet1.ToString()); if(prewetEntity.IsIdle) { prewetEntity.CheckToPostMessage(Aitex.Core.RT.Log.eEvent.WARN_PREWET, ModuleName.Prewet1.ToString(), (int)PrewetMsg.PrepareToPlace); } else if(prewetEntity.State==(int)PrewetState.WaitForPlace) { return true; } return false; } /// /// 检验源Prewet前置条件 /// /// private bool CheckSourcePrewetCondition() { PrewetEntity prewetEntity = Singleton.Instance.GetModule(ModuleName.Prewet1.ToString()); if (prewetEntity.State == (int)PrewetState.WaitForPick||prewetEntity.IsError) { return true; } return false; } public override void ResetTask() { base.ResetTask(); _schedulerPostMsg.Reset(); _postMsgResult = false; } } }