using Aitex.Core.RT.Fsm;
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.PUF;
using CyberX8_RT.Modules;
using CyberX8_RT.Schedulers.EfemRobot;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CyberX8_RT.Modules.Loader;
using Aitex.Core.RT.Log;
using MECF.Framework.Common.SubstrateTrackings;
using Aitex.Core.Common;
using MECF.Framework.Common.Utilities;
using CyberX8_RT.Devices.AXIS;
using Aitex.Core.RT.Device;
using CyberX8_RT.Dispatch;
using MECF.Framework.Common.RecipeCenter;
namespace CyberX8_RT.Schedulers.Puf
{
public class SchedulerPuf : SchedulerModule
{
private enum OperationStep
{
None,
ReadyForSwap,
WaitForLoaderUnloadComplete,
Swap,
CheckSwapComplete,
GotoRobotForPick,
WaitForRobotPick,
PufBackToPark,
CheckParkComplete
}
#region 内部变量
private PUFEntity _pufEntity;
private LoaderEntity _loaderEntity;
private OperationStep _currentOperation;
private EfemEntity _efemEntity;
private bool _forward = false;
private bool _isProductionWafer = false;
#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 SchedulerPuf(ModuleName moduleName) : base(moduleName.ToString())
{
_efemEntity = Singleton.Instance.EFEM;
_pufEntity = Singleton.Instance.GetModule(moduleName.ToString());
_loaderEntity = Singleton.Instance.GetModule(ModuleName.Loader1.ToString());
}
///
/// 执行
///
///
///
public override bool RunProcess(object recipe, object parameter, List syncMessages)
{
_isProductionWafer = false;
_forward = (bool)parameter;
if (_forward)
{
_currentOperation = OperationStep.ReadyForSwap;
//B面是否有片
if (WaferManager.Instance.CheckHasWafer(Module, 1))
{
_state = RState.Running;
return _pufEntity.CheckToPostMessage(eEvent.ERR_PUF, Module.ToString(),
(int)PUFMSG.ReadyForSwap);
}
return false;
}
else
{
_currentOperation = OperationStep.None;
return true;
}
}
///
/// 监控执行
///
///
public override bool MonitorProcess(SchedulerSequence schedulerSequence, bool hasMatchWafer)
{
//当前状态为ReadyForSwap
if (_currentOperation == OperationStep.ReadyForSwap)
{
//若Puf已经完成ReadyForSwap动作,状态变更为WaitForSwap
if (_pufEntity.State == (int)PUFSTATE.WaitForSwap)
{
//当前操作变量为WaitFor LoaderUnload Complete
_currentOperation = OperationStep.WaitForLoaderUnloadComplete;
LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is WaitForLoaderUnloadComplete");
}
}
else if (_currentOperation == OperationStep.WaitForLoaderUnloadComplete)
{
//Loader Entity Unload all
if (CheckDualPufStateCanExecuteLoaderUnloadAll(hasMatchWafer))
{
PostLoaderEntityUnloadAllSide();
}
}
//puf 进行Swap
else if(_currentOperation==OperationStep.Swap)
{
bool result = _pufEntity.CheckToPostMessage(eEvent.ERR_PUF, Module.ToString(),
(int)PUFMSG.Swap);
if(result)
{
_currentOperation = OperationStep.CheckSwapComplete;
LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is CheckSwapComplete");
}
}
else if(_currentOperation==OperationStep.CheckSwapComplete)
{
//puf完成Swap后运动至Robot让Robot取片
PostPufEntityGotoRobotForPick();
}
else if(_currentOperation==OperationStep.GotoRobotForPick)
{
//Efem 将Dummy片运输至Dummy Casstete
PostEfemRobotTransferToDummyCassete();
}
else if(_currentOperation==OperationStep.WaitForRobotPick)
{
//等待Efem Robot完成传片
if (RobotMoveHelper.Instance.IsBusy)
{
RobotMoveHelper.Instance.Monitor(Module.ToString());
}
if(RobotMoveHelper.Instance.IsPickCompleted)
{
_currentOperation = OperationStep.PufBackToPark;
LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is PufBackToBack");
}
}
else if(_currentOperation==OperationStep.PufBackToPark)
{
if (RobotMoveHelper.Instance.IsBusy)
{
RobotMoveHelper.Instance.Monitor(Module.ToString());
}
//Puf运动至Park安全位置
bool result = _pufEntity.CheckToPostMessage(eEvent.ERR_PUF, Module.ToString(),
(int)PUFMSG.RobotPickComplete);
if (result)
{
_currentOperation = OperationStep.CheckParkComplete;
LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is CheckParkComplete");
}
}
else if(_currentOperation==OperationStep.CheckParkComplete)
{
if (RobotMoveHelper.Instance.IsBusy)
{
RobotMoveHelper.Instance.Monitor(Module.ToString());
}
//判定Puf运动是否完成
if (_pufEntity.IsIdle&&RobotMoveHelper.Instance.IsIdle)
{
_state = RState.End;
}
}
return false;
}
///
/// 检验Dual puf 是不是都处于WaitForSwap 状态,保证Loader可以UnloadAll
///
///
private bool CheckDualPufStateCanExecuteLoaderUnloadAll(bool hasMatchWafer)
{
bool puf1ready = true;
if(ModuleHelper.IsInstalled(ModuleName.PUF1))
{
PUFEntity puf1Entity = Singleton.Instance.GetModule(ModuleName.PUF1.ToString());
if(hasMatchWafer)
{
//B面有Wafer
if (WaferManager.Instance.CheckHasWafer(ModuleName.PUF1,1))
{
puf1ready = puf1Entity.State == (int)PUFSTATE.WaitForSwap;
}
else
{
puf1ready = false;
}
}
else
{
//任务仅一片Wafer,同时模块为PUF2
if(Module==ModuleName.PUF2)
{
puf1ready = puf1Entity.IsIdle;
}
}
}
if(!puf1ready)
{
return false;
}
bool puf2ready = true;
if (ModuleHelper.IsInstalled(ModuleName.PUF2))
{
PUFEntity puf2Entity = Singleton.Instance.GetModule(ModuleName.PUF2.ToString());
if(hasMatchWafer)
{
//B面有Wafer
if (WaferManager.Instance.CheckHasWafer(ModuleName.PUF2, 1))
{
puf2ready = puf2Entity.State == (int)PUFSTATE.WaitForSwap;
}
else
{
puf2ready = false;
}
}
else
{
//任务仅一片Wafer,同时模块为PUF1
if (Module == ModuleName.PUF1)
{
puf2ready = puf2Entity.IsIdle;
}
}
}
if(!puf2ready)
{
return false;
}
//Loader中没有WaferHolder
if(_loaderEntity.WaferHolderInfo==null)
{
return false;
}
if (_loaderEntity.State == (int)LOADERSTATE.WaitForUnload)
{
JetAxisBase _loadTransporterGantryAxis = DEVICE.GetDevice($"{ModuleName.Transporter2}.Gantry");
if (_loadTransporterGantryAxis != null && !_loadTransporterGantryAxis.JudgeCompareTargetStation("Loader", "Right"))
{
return false;
}
}
return true;
}
///
/// LoaderEntity Unload All
///
private void PostLoaderEntityUnloadAllSide()
{
//当前loader状态机为WaitForUnload
if (_loaderEntity.State == (int)LOADERSTATE.WaitForUnload&&_currentOperation==OperationStep.WaitForLoaderUnloadComplete)
{
//触发loaderEntity UnloadAll
_loaderEntity.CheckToPostMessage(eEvent.WARN_LOADER, ModuleName.Loader1.ToString(),
(int)LoaderMSG.UnloadAll);
}
//若Loader Unload操作完成,状态变更为WaitForLoad,puf操作变更为Swap
else if (_loaderEntity.State == (int)LOADERSTATE.WaitForLoad)
{
_currentOperation = OperationStep.Swap;
LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is Swap");
}
else if (_loaderEntity.State == (int)LOADERSTATE.Unloading)
{
return;
}
//else
//{
// LOG.WriteLog(eEvent.ERR_PUF, Module.ToString(), $"Loader1 Current State {(LOADERSTATE)_loaderEntity.State} is not avaible");
// _state = RState.Failed;
//}
}
///
/// PUF Entity运动至Robot准备让robot pick
///
private void PostPufEntityGotoRobotForPick()
{
if (_pufEntity.Module == ModuleName.PUF2)
{
if (_pufEntity.State == (int)PUFSTATE.AferSwapParkStation)
{
bool result = _pufEntity.CheckToPostMessage(eEvent.ERR_PUF, Module.ToString(),
(int)PUFMSG.ReadyForRobotPick);
if (result)
{
NotifyWaferTaskSchedulerLoaderComplete();
_currentOperation = OperationStep.GotoRobotForPick;
LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is GotoRobotForPick");
}
}
}
else
{
if (_pufEntity.State == (int)PUFSTATE.AferSwapParkStation)
{
JetAxisBase loaderRotationAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.Rotation");
if (loaderRotationAxis != null && loaderRotationAxis.CheckPositionIsInStation(loaderRotationAxis.MotionData.MotorPosition, "TRNPA"))
{
if (_loaderEntity.State == (int)LOADERSTATE.Loading || _loaderEntity.IsIdle)
{
bool result = _pufEntity.CheckToPostMessage(eEvent.ERR_PUF, Module.ToString(),
(int)PUFMSG.ReadyForRobotPick);
if (result)
{
NotifyWaferTaskSchedulerLoaderComplete();
_currentOperation = OperationStep.GotoRobotForPick;
LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is GotoRobotForPick");
}
}
}
}
}
}
///
/// 通知Wafer对应的SchedulerLoader工序已经完成
///
private void NotifyWaferTaskSchedulerLoaderComplete()
{
//puf A面是否存在Wafer
if (WaferManager.Instance.CheckHasWafer(_pufEntity.Module, 0))
{
WaferInfo waferInfo = WaferManager.Instance.GetWafer(_pufEntity.Module, 0);
if (waferInfo!=null&&waferInfo.WaferType==WaferType.Production)
{
_isProductionWafer = true;
WaferTask waferTask = WaferTaskManager.Instance.GetWaferTask(waferInfo.WaferID);
if (waferTask!=null)
{
waferTask.UpdateLoaderSchedulerSequenceComplete();
}
}
}
}
///
/// 将Dummy片移动至Dummy Cassete
///
private void PostEfemRobotTransferToDummyCassete()
{
if (_pufEntity.State == (int)PUFSTATE.WaitForRobotPick)
{
//生产片待EfemRobot取完片进行PufBackToPark状态
if (_isProductionWafer)
{
bool hasWafer = WaferManager.Instance.CheckHasWafer(_pufEntity.Module, 0);
if (!hasWafer)
{
_currentOperation = OperationStep.PufBackToPark;
LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is PufBackToPark");
}
}
else
{
//A面Wafer
WaferInfo waferInfo = WaferManager.Instance.GetWafer(_pufEntity.Module, 0);
if (waferInfo == null)
{
return;
}
//Dummy片
if (waferInfo.WaferType == WaferType.Assit)
{
if (_efemEntity.IsIdle)
{
var result = SchedulerSequenceManager.Instance.GetAvaibleDummySlots();
if (result.moduleName != ModuleName.Unknown)
{
MoveItem moveItem = new MoveItem(_pufEntity.Module, 0, result.moduleName, result.slot, Aitex.Sorter.Common.Hand.Blade1);
if(RobotMoveHelper.Instance.IsIdle)
{
RobotMoveHelper.Instance.Start(moveItem,Module.ToString());
_currentOperation = OperationStep.WaitForRobotPick;
LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is WaitForRobotPick");
}
}
else
{
LOG.WriteBackgroundLog(eEvent.WARN_PUF, Module.ToString(), "dummy slot is empty");
}
}
else
{
LOG.WriteBackgroundLog(eEvent.WARN_PUF, Module.ToString(), $"wafer {waferInfo.WaferID} efem is not idle");
}
}
else
{
LOG.WriteBackgroundLog(eEvent.WARN_PUF, Module.ToString(), $"wafer {waferInfo.WaferID} is not dummy wafer");
}
}
}
}
///
/// 检验前置条件
///
///
///
///
public override bool CheckPrecondition(List schedulerSequences, int sequenceIndex, object parameter, string materialId, ref string reason)
{
if (_state == RState.Running)
{
reason = "scheduler module is already running";
return false;
}
if (_pufEntity==null)
{
reason = "Puf entity is null";
return false;
}
bool forward=(bool)parameter;
if(forward)
{
if (_pufEntity.State == (int)PUFSTATE.WaitForRobotPlace)
{
return true;
}
else
{
reason = $"{_pufEntity.Module} forward,but state is not WaitForRobotPlace";
return false;
}
}
else
{
if (_pufEntity.State == (int)PUFSTATE.WaitForRobotPick)
{
return true;
}
else
{
reason = $"{_pufEntity.Module} backward,but state is not WaitForRobotPick";
return false;
}
}
}
///
/// 获取可用资源
///
///
///
///
public override bool GetAvaibleMaterial(int sequenceIndex, object parameter)
{
return true;
}
}
}