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;
}
}
}