| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425 |
- 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 PunkHPX8_Core;
- using PunkHPX8_RT.Modules;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using MECF.Framework.Common.SubstrateTrackings;
- using PunkHPX8_RT.Modules.SRD;
- using PunkHPX8_RT.Modules.VpwMain;
- using PunkHPX8_RT.Modules.VpwCell;
- using MECF.Framework.Common.RecipeCenter;
- using PunkHPX8_RT.Modules.PlatingCell;
- using Aitex.Sorter.Common;
- using PunkHPX8_RT.Dispatch;
- using MECF.Framework.Common.ToolLayout;
- using Aitex.Core.Common;
- using PunkHPX8_RT.Devices.VpwMain;
- namespace PunkHPX8_RT.Schedulers.EfemRobot
- {
- public class SchedulerRobot : SchedulerModule
- {
- private enum SchedulerRobotOperation
- {
- None,
- Pick,
- PickWait,
- Place,
- PlaceWait
- }
- #region 内部变量
- private EfemEntity _efemEntity;
- #endregion
- #region 属性
- /// <summary>
- /// 是否空闲
- /// </summary>
- public override bool IsIdle
- {
- get { return _state == RState.End; }
- }
- /// <summary>
- /// 是否错误
- /// </summary>
- public override bool IsError
- {
- get { return _state == RState.Failed || _state == RState.Timeout; }
- }
- #endregion
- /// <summary>
- /// 构造函数
- /// </summary>
- /// <param name="module"></param>
- public SchedulerRobot(ModuleName module) : base(module.ToString())
- {
- _efemEntity = Singleton<RouteManager>.Instance.EFEM;
- }
- /// <summary>
- /// 执行
- /// </summary>
- /// <param name="parameter"></param>
- /// <returns></returns>
- public override bool RunProcess(object recipe, object parameter, List<SchedulerSyncModuleMessage> 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;
- }
- /// <summary>
- /// 监控执行
- /// </summary>
- /// <returns></returns>
- public override bool MonitorProcess(SchedulerSequence schedulerSequence, bool hasMatchWafer)
- {
- RobotMoveHelper.Instance.Monitor(Module.ToString());
- if (RobotMoveHelper.Instance.IsIdle)
- {
- _state = RState.End;
- }
- return true;
- }
-
- /// <summary>
- /// 检验前置条件
- /// </summary>
- /// <param name="sequenceIndex"></param>
- /// <param name="parameter"></param>
- /// <returns></returns>
- public override bool CheckPrecondition(List<SchedulerSequence> 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;
- }
- MoveItem moveItem = (MoveItem)parameter;
- if(WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, (int)Hand.Blade1))
- {
- reason = "robot lower hand has wafer";
- return false;
- }
- if (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, (int)Hand.Blade2))
- {
- reason = "robot upper hand has wafer";
- return false;
- }
- if (!CheckPreTaskComplete(materialId,schedulerSequences,sequenceIndex))
- {
- reason = "last wafer task has not completed";
- 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 (!WaferManager.Instance.CheckHasWafer(moveItem.SourceModule, moveItem.SourceSlot))
- {
- reason = $"{moveItem.SourceModule} slot {moveItem.SourceSlot} has no wafer";
- return false;
- }
- if (WaferManager.Instance.CheckHasWafer(moveItem.DestinationModule, moveItem.DestinationSlot))
- {
- reason = $"{moveItem.DestinationModule} slot {moveItem.DestinationSlot} has wafer";
- return false;
- }
- if (ModuleHelper.IsVPWCell(moveItem.DestinationModule))
- {
- return CheckVpw(moveItem, schedulerSequences, sequenceIndex, ref reason);
- }
- return true;
- }
- /// <summary>
- /// 检验VPW
- /// </summary>
- /// <param name="moveItem"></param>
- /// <param name="schedulerSequences"></param>
- /// <param name="sequenceIndex"></param>
- /// <param name="reason"></param>
- /// <returns></returns>
- private bool CheckVpw(MoveItem moveItem,List<SchedulerSequence> schedulerSequences, int sequenceIndex,ref string reason)
- {
- VpwCellEntity vpwEntity = Singleton<RouteManager>.Instance.GetModule<VpwCellEntity>(moveItem.DestinationModule.ToString());
- if (vpwEntity != null)
- {
- bool nextVpwRecipe = false;
- if (sequenceIndex + 1 < schedulerSequences.Count)
- {
- SchedulerSequence nextSequence = schedulerSequences[sequenceIndex + 1];
- if (nextSequence.ModuleType == ModuleType.VPW)
- {
- nextVpwRecipe = true;
- }
- }
- if (nextVpwRecipe)
- {
- if (vpwEntity.State == (int)VPWCellState.WaitForRunRecipe)
- {
- return true;
- }
- else
- {
- if (vpwEntity.IsIdle)
- {
- SchedulerSequence nextSequence = schedulerSequences[sequenceIndex + 1];
- vpwEntity.CheckToPostMessage<VPWCellState, VPWCellMsg>(eEvent.INFO_VPW, Module.ToString(),
- (int)VPWCellMsg.Prepare, nextSequence.Recipe);
- }
- reason = $"{vpwEntity.Module} state is not WaitForRunRecipe";
- return false;
- }
- }
- else
- {
- VpwMainEntity vpwMainEntity = Singleton<RouteManager>.Instance.GetModule<VpwMainEntity>(ModuleName.VPWMain1.ToString());
- if (vpwEntity.IsIdle)
- {
- if (vpwMainEntity.IsChamberOpened)
- {
- return true;
- }
- else
- {
- vpwEntity.CheckToPostMessage<VPWCellState, VPWCellMsg>(eEvent.INFO_VPW, Module.ToString(), (int)VPWCellMsg.ChamberDown);
- reason = $"{vpwEntity.Module} chamber is not opened";
- return false;
- }
- }
- else
- {
- reason = $"{vpwEntity.Module} is not idle";
- return false;
- }
- }
- }
- else
- {
- reason = $"{moveItem.DestinationModule} is null";
- }
- return false;
- }
- /// <summary>
- /// 更新未知源模块
- /// </summary>
- private void UpdateUnkownSourceModule(List<SchedulerSequence> 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;
- }
- }
- }
- }
- /// <summary>
- /// 更新未知目标模块
- /// </summary>
- private bool UpdateUnkownTargetModule(List<SchedulerSequence> schedulerSequences, MoveItem moveItem, int sequenceIndex)
- {
- SchedulerSequence currentSchedulerSequence= schedulerSequences[sequenceIndex];
- if (sequenceIndex >= schedulerSequences.Count - 1)
- {
- return false;
- }
- SchedulerSequence nextSequence=schedulerSequences[sequenceIndex+1];
- ModuleName moduleName = ModuleName.Unknown;
- if (moveItem.DestinationType == ModuleType.SRD)
- {
- SRDEntity srd1Entity = Singleton<RouteManager>.Instance.GetModule<SRDEntity>(ModuleName.SRD1.ToString());
- if (srd1Entity != null&&srd1Entity.IsIdle&&srd1Entity.IsAuto&&WaferManager.Instance.CheckNoWafer(ModuleName.SRD1.ToString(),0))
- {
- moduleName = ModuleName.SRD1;
- }
- else
- {
- SRDEntity srd2Entity= Singleton<RouteManager>.Instance.GetModule<SRDEntity>(ModuleName.SRD2.ToString());
- if (srd2Entity != null && srd2Entity.IsIdle&&srd2Entity.IsAuto && WaferManager.Instance.CheckNoWafer(ModuleName.SRD2.ToString(), 0))
- {
- moduleName=ModuleName.SRD2;
- }
- }
- }
- else if (moveItem.DestinationType == ModuleType.PlatingCell)
- {
- DepRecipe depRecipe = (DepRecipe)nextSequence.Recipe;
- List<PlatingCellEntity> platingCellEntities= SchedulerSequenceManager.Instance.GetAvaiblePlatingCellList(depRecipe.Chemistry, nextSequence.SequenceType, nextSequence.WaferSize, true);
- if (platingCellEntities.Count > 0)
- {
- moduleName = platingCellEntities[0].Module;
- }
- }
- else
- {
- return false;
- }
-
- if (moduleName == ModuleName.Unknown)
- {
- return false;
- }
- else
- {
- if(WaferManager.Instance.CheckHasWafer(moduleName,0))
- {
- return false;
- }
- IModuleEntity moduleEntity = Singleton<RouteManager>.Instance.GetModule<IModuleEntity>(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;
- }
- /// <summary>
- /// 检验上一个任务是否完成
- /// </summary>
- /// <param name="materialId"></param>
- /// <returns></returns>
- private bool CheckPreTaskComplete(string materialId, List<SchedulerSequence> schedulerSequences, int sequenceIndex)
- {
- WaferTask waferTask = WaferTaskManager.Instance.GetWaferTask(materialId);
- if(waferTask == null)
- {
- return true;
- }
- WaferInfo waferInfo = WaferManager.Instance.GetWaferByWaferId(materialId);
- if (waferInfo == null || waferInfo.IsEmpty)
- {
- return true;
- }
- if (!string.IsNullOrEmpty(waferTask.MateWaferTask))
- {
- return true;
- }
- if (sequenceIndex < 1)
- {
- return true;
- }
- SchedulerSequence preSequence=schedulerSequences[sequenceIndex-1];
- if (preSequence==null)
- {
- return true;
- }
- if (preSequence.ModuleName!=ModuleName.Aligner1)
- {
- return true;
- }
- List<string> platingCells = PlatingCellItemManager.Instance.InstalledModules;
- foreach(string item in platingCells)
- {
- PlatingCellEntity platingCellEntity = Singleton<RouteManager>.Instance.GetModule<PlatingCellEntity>(item);
- if (!platingCellEntity.IsAuto)
- {
- continue;
- }
- if (platingCellEntity.MetalWaferSize != (int)waferInfo.Size)
- {
- continue;
- }
- if (WaferManager.Instance.CheckHasWafer(item, 0))
- {
- return false;
- }
- }
- List<string> vpwCells = VpwCellItemManager.Instance.InstalledModules;
- foreach (string item in vpwCells)
- {
- VpwCellEntity entity = Singleton<RouteManager>.Instance.GetModule<VpwCellEntity>(item);
- if (!entity.IsAuto)
- {
- continue;
- }
- if (entity.VpwWaferSize != (int)waferInfo.Size)
- {
- continue;
- }
- if (WaferManager.Instance.CheckHasWafer(item, 0))
- {
- return false;
- }
- }
- return true;
- }
- public override void ResetTask()
- {
- base.ResetTask();
- RobotMoveHelper.Instance.Reset();
- }
- }
- }
|