using Aitex.Core.RT.Fsm;
using Aitex.Core.RT.Log;
using Aitex.Core.Util;
using MECF.Framework.Common.CommonData;
using MECF.Framework.Common.Equipment;
using CyberX8_Core;
using CyberX8_RT.Modules;
using CyberX8_RT.Modules.Loader;
using CyberX8_RT.Modules.PUF;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MECF.Framework.Common.SubstrateTrackings;
using CyberX8_RT.Modules.Metal;
using CyberX8_RT.Devices.AXIS;
using Aitex.Core.RT.Device;
using MECF.Framework.Common.WaferHolder;
using Aitex.Core.Common;
using CyberX8_RT.Dispatch;
namespace CyberX8_RT.Schedulers.Loader
{
public class SchedulerLoader : SchedulerModule
{
private enum SchedulerStep
{
None,
WaitUnload,
WaitLoad,
LoadingFirst,
ReadyForPuf,
LoadingSecond
}
#region 内部变量
private LoaderEntity _loaderEntity;
private PUFEntity _puf1Entity;
private SchedulerStep _currentStep;
private int _currentWaferIndex = 1;
private string _waferGroup = "";
#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 SchedulerLoader(ModuleName module) : base(module.ToString())
{
_loaderEntity = Singleton.Instance.GetModule(module.ToString());
_puf1Entity = Singleton.Instance.GetModule(ModuleName.PUF1.ToString());
}
///
/// 执行
///
///
///
public override bool RunProcess(object recipe, object parameter, List syncModuleMessages)
{
_state = RState.Running;
_currentStep = SchedulerStep.WaitUnload;
_currentWaferIndex = 1;
_waferGroup = "";
return true;
}
///
/// 监控执行
///
///
public override bool MonitorProcess(SchedulerSequence schedulerSequence, bool hasMatchWafer)
{
if (_currentStep == SchedulerStep.WaitUnload)
{
if (_loaderEntity.State == (int)LOADERSTATE.WaitForUnload && WaferHolderManager.Instance.HasWaferHolder("Loader"))
{
JetAxisBase _loadTransporterGantryAxis = DEVICE.GetDevice($"{ModuleName.Transporter2}.Gantry");
if (_loadTransporterGantryAxis != null && _loadTransporterGantryAxis.JudgeCompareTargetStation("Loader", "Right"))
{
WaferInfo preLoaderWaferInfo = WaferHolderTaskManager.Instance.GetPreLoaderHasWafer();
//触发loaderEntity UnloadAll
if (preLoaderWaferInfo != null && !string.IsNullOrEmpty(preLoaderWaferInfo.LoaderSide))
{
_waferGroup = AnalyseWaferGroup(preLoaderWaferInfo);
_loaderEntity.CheckToPostMessage(eEvent.WARN_LOADER, ModuleName.Loader1.ToString(),
(int)LoaderMSG.UnloadSide, preLoaderWaferInfo.LoaderSide,_waferGroup);
}
}
}
else if(_loaderEntity.State==(int)LOADERSTATE.Unloading)
{
_currentStep = SchedulerStep.WaitLoad;
}
else if (_loaderEntity.State == (int)LOADERSTATE.WaitForLoad)
{
_currentStep = SchedulerStep.WaitLoad;
}
return true;
}
LoaderParameter loaderParameter =(LoaderParameter)schedulerSequence.Parameters;
bool loadComplete = loaderParameter.WaferCount == _currentWaferIndex;
bool needFlip = loaderParameter.NeedWaitFlip;
if (_currentStep == SchedulerStep.WaitLoad)
{
if (_loaderEntity.State != (int)LOADERSTATE.WaitForLoad)
{
return false;
}
if (_puf1Entity.State == (int)PUFSTATE.AferSwapParkStation)
{
bool result = ExecuteLoadSide(loadComplete, loaderParameter.LoadCompleteToTransporterSide);
if (result)
{
_currentStep = SchedulerStep.LoadingFirst;
}
}
}
else if (_currentStep == SchedulerStep.LoadingFirst)
{
if (_loaderEntity.IsIdle)
{
if (loaderParameter.WaferCount == 1)
{
if (needFlip)
{
bool loaderResult= _loaderEntity.CheckToPostMessage(eEvent.WARN_LOADER, Module.ToString(),
(int)LoaderMSG.WaitFlip);
if (loaderResult)
{
_state = RState.End;
_currentStep = SchedulerStep.None;
}
}
else
{
_state = RState.End;
_currentStep = SchedulerStep.None;
}
}
else
{
EnterReadyForPuf();
}
}
else if (_loaderEntity.State == (int)LOADERSTATE.WaitForUnload)
{
ExecuteForSecondUnload();
}
else if (_loaderEntity.State == (int)LOADERSTATE.Unloading)
{
_currentStep = SchedulerStep.ReadyForPuf;
_currentWaferIndex = 2;
}
}
else if (_currentStep == SchedulerStep.ReadyForPuf)
{
if (_loaderEntity.State == (int)LOADERSTATE.WaitForLoad)
{
if (_puf1Entity.State == (int)PUFSTATE.AferSwapParkStation)
{
bool result = ExecuteLoadSide(true, loaderParameter.LoadCompleteToTransporterSide);
if (result)
{
_currentStep = SchedulerStep.LoadingSecond;
}
}
}
}
else if (_currentStep == SchedulerStep.LoadingSecond)
{
if (_loaderEntity.IsIdle)
{
_state = RState.End;
_currentStep = SchedulerStep.None;
}
}
return true;
}
///
/// 分析得到Wafer组
///
///
///
private string AnalyseWaferGroup(WaferInfo waferInfo)
{
string matchWaferId = WaferTaskManager.Instance.GetMatchWaferIdByWaferId(waferInfo.WaferID);
string cycleStr = "";
if (waferInfo.WaferType == WaferType.Production)
{
int cycleCount = CycleManager.Instance.GetLoadportCycleCount($"LP{waferInfo.OriginStation}");
int cycleSetPoint = CycleManager.Instance.GetLoadportCycleSetPoint($"LP{waferInfo.OriginStation}");
cycleStr = cycleSetPoint > 1 ? $"_Cycle-{cycleCount + 1}" : "";
}
if (string.IsNullOrEmpty(matchWaferId))
{
return $"{waferInfo.LotId}_LP{waferInfo.OriginStation}-{waferInfo.OriginSlot}-0{cycleStr}";
}
else
{
WaferInfo matchedWafer = WaferManager.Instance.GetWaferByWaferId(matchWaferId);
if (matchedWafer != null && !matchedWafer.IsEmpty)
{
if (matchedWafer.WaferType == WaferType.Assit)
{
return $"{waferInfo.LotId}_LP{waferInfo.OriginStation}-{waferInfo.OriginSlot+1}{cycleStr}";
}
else
{
int cycleCountM = CycleManager.Instance.GetLoadportCycleCount($"LP{matchedWafer.OriginStation}");
int cycleSetPointM = CycleManager.Instance.GetLoadportCycleSetPoint($"LP{matchedWafer.OriginStation}");
string cycleStrM = cycleSetPointM > 1 ? $"_Cycle-{cycleCountM + 1}" : "";
if ((waferInfo.OriginStation > matchedWafer.OriginStation) || (waferInfo.OriginStation == matchedWafer.OriginStation && waferInfo.OriginSlot > matchedWafer.OriginSlot))
{
string lotStr = waferInfo.LotId == matchedWafer.LotId ? "" : $"_{waferInfo.LotId}";
return $"{matchedWafer.LotId}_LP{matchedWafer.OriginStation}-{matchedWafer.OriginSlot + 1}{cycleStrM}{lotStr}_LP{waferInfo.OriginStation}-{waferInfo.OriginSlot + 1}{cycleStr}";
}
else
{
string lotStr = waferInfo.LotId == matchedWafer.LotId ? "" : $"_{matchedWafer.LotId}";
return $"{waferInfo.LotId}_LP{waferInfo.OriginStation}-{waferInfo.OriginSlot + 1}{cycleStr}{lotStr}_LP{matchedWafer.OriginStation}-{matchedWafer.OriginSlot + 1}{cycleStrM}";
}
}
}
else
{
return $"{waferInfo.LotId}_LP{waferInfo.SourceStation}-{waferInfo.OriginSlot+1}{cycleStr}";
}
}
}
///
/// 执行Loader Load动作
///
///
///
///
private bool ExecuteLoadSide(bool loadComplete,string completeSide)
{
if (_puf1Entity.State == (int)PUFSTATE.AferSwapParkStation || (_puf1Entity.IsIdle && _puf1Entity.IsBackToParkStation))
{
JetAxisBase tiltAAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.TiltA");
JetAxisBase tiltBAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.TiltB");
double tiltAPosition = tiltAAxis.MotionData.MotorPosition;
double tiltBPosition = tiltBAxis.MotionData.MotorPosition;
bool tiltAHori = tiltAAxis.CheckPositionIsInStation(tiltAPosition, "HORI");
bool tiltBHori = tiltBAxis.CheckPositionIsInStation(tiltBPosition, "HORI");
string side = tiltAHori ? "SideA" : (tiltBHori ? "SideB" : "");
if (string.IsNullOrEmpty(side))
{
return false;
}
return _loaderEntity.CheckToPostMessage(eEvent.WARN_LOADER, Module.ToString(),
(int)LoaderMSG.LoadSide, side, loadComplete,completeSide,_waferGroup);
}
return false;
}
///
/// 第二次进入WaitForUnload
///
///
private void EnterReadyForPuf()
{
_loaderEntity.CheckToPostMessage(eEvent.WARN_LOADER, ModuleName.Loader1.ToString(),
(int)LoaderMSG.ReadyForPuf);
}
///
/// 执行第二次unload
///
///
private void ExecuteForSecondUnload()
{
if (_loaderEntity.State == (int)LOADERSTATE.WaitForUnload)
{
if (!WaferHolderManager.Instance.HasWaferHolder("Loader"))
{
return;
}
JetAxisBase _loadTransporterGantryAxis = DEVICE.GetDevice($"{ModuleName.Transporter2}.Gantry");
if (_loadTransporterGantryAxis != null && _loadTransporterGantryAxis.JudgeCompareTargetStation("Loader", "Right"))
{
WaferInfo preLoaderWaferInfo = WaferHolderTaskManager.Instance.GetPreLoaderHasWafer();
//触发loaderEntity UnloadAll
if (preLoaderWaferInfo != null && !string.IsNullOrEmpty(preLoaderWaferInfo.LoaderSide))
{
bool result = _loaderEntity.CheckToPostMessage(eEvent.WARN_LOADER, ModuleName.Loader1.ToString(),
(int)LoaderMSG.UnloadSide, preLoaderWaferInfo.LoaderSide, _waferGroup);
}
}
}
}
///
/// 检验前置条件
///
///
///
///
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 (_loaderEntity.IsIdle)
{
reason = "loader is idle";
return false;
}
if (_loaderEntity.WaferHolderInfo == null)
{
reason = "loader has no wafer shuttle";
return false;
}
if (_loaderEntity.WaferHolderInfo.Id != materialId)
{
reason = $"{_loaderEntity.Module} wafer shuttle {_loaderEntity.WaferHolderInfo.Id} is not matched with {materialId}";
return false;
}
return true;
}
}
}