123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- using Aitex.Common.Util;
- using Aitex.Core.RT.ConfigCenter;
- using Aitex.Core.RT.Log;
- using Aitex.Core.Util;
- using MECF.Framework.Common.Equipment;
- using MECF.Framework.Common.RecipeCenter;
- using CyberX8_Core;
- using CyberX8_RT.Modules;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using CyberX8_RT.Modules.Prewet;
- using MECF.Framework.Common.CommonData;
- using Aitex.Core.RT.Fsm;
- using Aitex.Core.RT.SCCore;
- using CyberX8_RT.Modules.Rinse;
- namespace CyberX8_RT.Schedulers.Prewet
- {
- public class SchedulerPrewet : SchedulerModule
- {
- private enum PrewetOperation
- {
- None,
- RunRecipe,
- WaitForPick,
- Keepwet
- }
- #region 内部变量
- /// <summary>
- /// Prewet实体
- /// </summary>
- private PrewetEntity _prewetEntity;
- /// <summary>
- /// keep wet次数
- /// </summary>
- private int _keepwetCount = 0;
- /// <summary>
- /// keep wet限制次数
- /// </summary>
- private int _keepwetLimit = 0;
- /// <summary>
- /// 当前操作
- /// </summary>
- private PrewetOperation _currentOperation=PrewetOperation.None;
- #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 SchedulerPrewet(ModuleName moduleName) : base(moduleName.ToString())
- {
- _prewetEntity = Singleton<RouteManager>.Instance.GetModule<PrewetEntity>(moduleName.ToString());
- }
- /// <summary>
- /// 执行
- /// </summary>
- /// <param name="parameter"></param>
- /// <returns></returns>
- public override bool RunProcess(object recipe, object parameter, List<SchedulerSyncModuleMessage> syncModuleMessages)
- {
- if (!(recipe is PwtRecipe))
- {
- _state = RState.Failed;
- LOG.WriteLog(eEvent.ERR_PREWET, Module.ToString(), "recipe is invalid");
- return false;
- }
- _keepwetCount = 0;
- _keepwetLimit = SC.GetValue<int>("Prewet.KeepWetMaxLimit");
- PwtRecipe pwtRecipe = (PwtRecipe)recipe;
- bool result = _prewetEntity.CheckToPostMessage<PrewetState, PrewetMsg>(eEvent.ERR_PREWET, Module.ToString(), (int)PrewetMsg.RunRecipe, pwtRecipe,1);
- if (result)
- {
- _state = RState.Running;
- _currentOperation = PrewetOperation.RunRecipe;
- }
- return result;
- }
- /// <summary>
- /// 监控执行
- /// </summary>
- /// <returns></returns>
- public override bool MonitorProcess(SchedulerSequence schedulerSequence, bool hasMatchWafer)
- {
- bool exsitEnableCell = false;
- if (_prewetEntity.IsError)
- {
- _state=RState.Failed;
- return true;
- }
- if (_prewetEntity.State == (int)PrewetState.WaitForPick || (_prewetEntity.IsIdle && _prewetEntity.WaferHolderInfo == null))
- {
- _state = RState.End;
- _currentOperation = PrewetOperation.None;
- return true;
- }
- if (_prewetEntity.State==(int)PrewetState.RunRecipeComplete&&_currentOperation==PrewetOperation.RunRecipe)
- {
- CheckNextModuleCondition(schedulerSequence,ref exsitEnableCell);
- }
- else if((_prewetEntity.State==(int)PrewetState.DelayKeepwetComplete)&&_currentOperation==PrewetOperation.Keepwet)
- {
- if(_keepwetCount>_keepwetLimit)
- {
- LOG.WriteLog(eEvent.ERR_PREWET, Module.ToString(), $"keepwet count {_keepwetCount} over limit {_keepwetLimit}");
- _state = RState.Failed;
- }
- else
- {
- CheckNextModuleTimeToReady(schedulerSequence,ref exsitEnableCell);
- }
- }
- else if (_prewetEntity.State == (int)PrewetState.DelayKeepweting && _currentOperation == PrewetOperation.Keepwet)
- {
- CheckNextModuleTimeToReady(schedulerSequence, ref exsitEnableCell);
- }
- return true;
- }
- /// <summary>
- /// 检验下一个
- /// </summary>
- /// <param name="sequence"></param>
- /// <returns></returns>
- private void CheckNextModuleCondition(SchedulerSequence sequence,ref bool existEnableCell)
- {
- PwtRecipe pwtRecipe = (PwtRecipe)sequence.Recipe;
- if(!pwtRecipe.KeepWet)
- {
- NotifyPrewetReadyForPick("prewet no keepwet");
- return;
- }
- CheckNextModuleTimeToReady(sequence,ref existEnableCell);
- }
- /// <summary>
- /// 检验下一模块剩余时间
- /// </summary>
- /// <param name="sequence"></param>
- private void CheckNextModuleTimeToReady(SchedulerSequence sequence,ref bool existEnableCell)
- {
- int idleKeepwetPauseBetweenScanSeconds = SC.GetValue<int>("Prewet.IdleKeepwetPauseBetweenScanSeconds");
- ModuleType nextModuleType = sequence.NextModuleType;
- if (nextModuleType == ModuleType.Metal)
- {
- if (!(sequence.NextRecipe is DepRecipe))
- {
- NotifyPrewetReadyForPick("sequence nextRecipe is not deprecipe");
- }
- else
- {
- DepRecipe depRecipe = sequence.NextRecipe as DepRecipe;
- ModuleName moduleName = SchedulerSequenceManager.Instance.CalculateAvaibleMetalCellByChemistry(depRecipe.Chemistry, "",sequence.SequenceType,ref existEnableCell);
- if (moduleName != ModuleName.Unknown)
- {
- IModuleEntity moduleEntity = Singleton<RouteManager>.Instance.GetModule<IModuleEntity>(moduleName.ToString());
- if (SchedulerSequenceManager.Instance.CheckMetalCellRecipeTimeAvaible(moduleEntity, depRecipe))
- {
- if (moduleEntity.IsIdle)
- {
- NotifyPrewetReadyForPick($"{moduleEntity.Module} Is idle");
- }
- else
- {
- NotifyPrewetReadyForPick($"{moduleEntity.Module} remain seconds {moduleEntity.TimeToReady}");
- }
- }
- else
- {
- NotifyPrewetKeepWet();
- }
- }
- else
- {
- if (existEnableCell)
- {
- NotifyPrewetKeepWet();
- }
- else
- {
- NotifyPrewetReadyForPick($"no enable metal");
- }
- }
- }
- }
- else
- {
- ModuleName moduleName = SchedulerSequenceManager.Instance.GetAvaibleEmptyModuleCell(nextModuleType,sequence.SequenceType);
- if (moduleName != ModuleName.Unknown)
- {
- IModuleEntity moduleEntity = Singleton<RouteManager>.Instance.GetModule<IModuleEntity>(moduleName.ToString());
- if (moduleEntity.IsIdle)
- {
- NotifyPrewetReadyForPick($"{moduleEntity.Module} is idle");
- }
- else
- {
- if (moduleEntity.TimeToReady <= idleKeepwetPauseBetweenScanSeconds)
- {
- NotifyPrewetReadyForPick($"{moduleEntity.Module} remain seconds {moduleEntity.TimeToReady}");
- }
- else
- {
- NotifyPrewetKeepWet();
- }
- }
- }
- else
- {
- NotifyPrewetKeepWet();
- }
- }
- }
- /// <summary>
- /// 通知Prewet准备Process for pick
- /// </summary>
- private void NotifyPrewetReadyForPick(string reason)
- {
- bool result= _prewetEntity.CheckToPostMessage<PrewetState, PrewetMsg>(eEvent.ERR_PREWET, Module.ToString(),
- (int)PrewetMsg.PrepareToPick);
- if (result)
- {
- _currentOperation = PrewetOperation.WaitForPick;
- LOG.WriteLog(eEvent.INFO_PREWET, Module.ToString(), reason);
- }
- }
- /// <summary>
- /// 通知Prewet准备Keep Wet
- /// </summary>
- private void NotifyPrewetKeepWet()
- {
- if (_prewetEntity.State == (int)PrewetState.DelayKeepweting)
- {
- return;
- }
- bool result= _prewetEntity.CheckToPostMessage<PrewetState, PrewetMsg>(eEvent.ERR_PREWET, ModuleName.Prewet1.ToString(),
- (int)PrewetMsg.DelayKeepwet);
- if(result)
- {
- if (_currentOperation != PrewetOperation.Keepwet)
- {
- _currentOperation = PrewetOperation.Keepwet;
- }
- _keepwetCount++;
- }
- }
- /// <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 (_state == RState.Running)
- {
- reason = "scheduler module is already running";
- return false;
- }
- if (_prewetEntity.State!=(int)PrewetState.WaitForPlace)
- {
- reason = "prewet state is not WaitForPlace";
- return false;
- }
- if(_prewetEntity.WaferHolderInfo==null)
- {
- reason = "prewet has no wafer shuttle";
- return false;
- }
- if (_prewetEntity.WaferHolderInfo.Id != materialId)
- {
- reason = $"{_prewetEntity.Module} wafer shuttle {_prewetEntity.WaferHolderInfo.Id} is not matched with {materialId}";
- return false;
- }
- _currentOperation = PrewetOperation.None;
- return true;
- }
- }
- }
|