using Aitex.Core.RT.Fsm; using Aitex.Core.RT.Log; using Aitex.Core.RT.Routine; using Aitex.Core.Util; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Schedulers; using CyberX8_Core; using CyberX8_RT.Modules; using CyberX8_RT.Modules.PUF; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using MECF.Framework.Common.SubstrateTrackings; using CyberX8_RT.Modules.Loader; using CyberX8_RT.Modules.SRD; namespace CyberX8_RT.Schedulers.EfemRobot { public class SchedulerRobot : SchedulerModule { private enum SchedulerRobotOperation { None, Pick, PickWait, Place, PlaceWait } #region 内部变量 private EfemEntity _efemEntity; private LoaderEntity _loaderEntity; private PUFEntity _puf1Entity; private PUFEntity _puf2Entity; #endregion #region 属性 /// /// 是否空闲 /// public override bool IsIdle { get { return _state == RState.End; } } /// /// 是否错误 /// public override bool IsError { get { return _state == RState.Failed || _state == RState.Timeout; } } #endregion /// /// 构造函数 /// /// public SchedulerRobot(ModuleName module) : base(module.ToString()) { _efemEntity = Singleton.Instance.EFEM; _loaderEntity = Singleton.Instance.GetModule(ModuleName.Loader1.ToString()); _puf1Entity = Singleton.Instance.GetModule(ModuleName.PUF1.ToString()); _puf2Entity = Singleton.Instance.GetModule(ModuleName.PUF2.ToString()); } /// /// 执行 /// /// /// public override bool RunProcess(object recipe, object parameter, List syncMessages) { if (_efemEntity.IsBusy) { return false; } MoveItem moveItem = (MoveItem)parameter; if (moveItem.SourceModule != ModuleName.Unknown&&moveItem.DestinationModule!=ModuleName.Unknown) { SynchorinzeModuleMessages(syncMessages); _state = RState.Running; if (RobotMoveHelper.Instance.IsIdle) { RobotMoveHelper.Instance.Start(moveItem, Module.ToString()); return true; } } return false; } /// /// 监控执行 /// /// public override bool MonitorProcess(SchedulerSequence schedulerSequence, bool hasMatchWafer) { RobotMoveHelper.Instance.Monitor(Module.ToString()); if (RobotMoveHelper.Instance.IsIdle) { _state = RState.End; } return true; } /// /// 检验前置条件 /// /// /// /// public override bool CheckPrecondition(List schedulerSequences, int sequenceIndex, object parameter,string materialId, ref string reason) { if (parameter == null) { reason = "parameter is null"; return true; } if (_state == RState.Running) { reason = "scheduler module is already running"; return false; } if(_efemEntity.IsBusy) { reason = "efem is busy"; return false; } if(_efemEntity.IsError) { reason = "efem is error"; return false; } if(_loaderEntity.IsError||_puf1Entity.IsError || _puf2Entity.IsError) { reason = "loader or puf is error"; return false; } MoveItem moveItem = (MoveItem)parameter; if(WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot,(int)moveItem.RobotHand)) { reason = "robot has wafer"; return false; } if (moveItem.SourceModule == ModuleName.Unknown) { UpdateUnkownSourceModule(schedulerSequences, moveItem, sequenceIndex); } if (moveItem.DestinationModule == ModuleName.Unknown) { bool result= UpdateUnkownTargetModule(schedulerSequences, moveItem, sequenceIndex); if (!result) { reason = "efem robot confirm target module failed"; return false; } } if (ModuleHelper.IsPUF(moveItem.DestinationModule)) { PUFEntity pufEntity = Singleton.Instance.GetModule(moveItem.DestinationModule.ToString()); if (pufEntity != null) { if (pufEntity.State == (int)PUFSTATE.WaitForRobotPlace) { return true; } else { if (pufEntity.IsIdle) { pufEntity.CheckToPostMessage(eEvent.ERR_PUF, Module.ToString(), (int)PUFMSG.ReadyForRobotPlace); } reason = $"{pufEntity.Module} state is not WaitForRobotPlace"; return false; } } else { reason = $"{moveItem.DestinationModule} puf is null"; } } else if (ModuleHelper.IsPUF(moveItem.SourceModule)) { PUFEntity pufEntity = Singleton.Instance.GetModule(moveItem.SourceModule.ToString()); if (pufEntity != null) { if (pufEntity.State == (int)PUFSTATE.WaitForRobotPick) { return true; } else { if (pufEntity.IsIdle) { pufEntity.CheckToPostMessage(eEvent.ERR_PUF, pufEntity.Module.ToString(), (int)PUFMSG.ReadyForRobotPick); } reason = $"{pufEntity.Module} state is not WaitForRobotPick"; return false; } } else { reason = $"{moveItem.SourceModule} puf is null"; return false; } } return true; } /// /// 更新未知源模块 /// private void UpdateUnkownSourceModule(List schedulerSequences, MoveItem moveItem, int sequenceIndex) { if (moveItem.SourceModule == ModuleName.Unknown) { if (sequenceIndex >= 1 && sequenceIndex - 1 < schedulerSequences.Count) { SchedulerSequence preSchedulerSequence = schedulerSequences[sequenceIndex - 1]; if (preSchedulerSequence != null && preSchedulerSequence.SchedulerModule != null) { moveItem.SourceModule = preSchedulerSequence.SchedulerModule.Module; } } } } /// /// 更新未知目标模块 /// private bool UpdateUnkownTargetModule(List schedulerSequences, MoveItem moveItem, int sequenceIndex) { SchedulerSequence currentSchedulerSequence= schedulerSequences[sequenceIndex]; ModuleName moduleName = ModuleName.Unknown; if (moveItem.DestinationType == ModuleType.SRD) { SRDEntity srd1Entity = Singleton.Instance.GetModule(ModuleName.SRD1.ToString()); if (srd1Entity != null&&srd1Entity.IsIdle&&srd1Entity.IsAuto&&WaferManager.Instance.CheckNoWafer(ModuleName.SRD1.ToString(),0)) { moduleName = ModuleName.SRD1; } else { SRDEntity srd2Entity= Singleton.Instance.GetModule(ModuleName.SRD2.ToString()); if (srd2Entity != null && srd2Entity.IsIdle&&srd2Entity.IsAuto && WaferManager.Instance.CheckNoWafer(ModuleName.SRD2.ToString(), 0)) { moduleName=ModuleName.SRD2; } } } else { return false; } if (moduleName == ModuleName.Unknown) { return false; } else { if(WaferManager.Instance.CheckHasWafer(moduleName,0)) { return false; } IModuleEntity moduleEntity = Singleton.Instance.GetModule(moduleName.ToString()); if (moduleEntity==null) { return false; } if (moduleEntity.IsBusy) { return false; } moveItem.DestinationModule = moduleName; if (sequenceIndex + 1 < schedulerSequences.Count) { SchedulerSequence sequence = schedulerSequences[sequenceIndex + 1]; if (sequence.SchedulerModule == null) { sequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(moduleName); sequence.ModuleName = moduleName; } } } return true; } public override void ResetTask() { base.ResetTask(); RobotMoveHelper.Instance.Reset(); } } }