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