using Aitex.Core.RT.Device;
using Aitex.Core.RT.Routine;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Routine;
using CyberX8_Core;
using CyberX8_RT.Devices.AXIS;
using CyberX8_RT.Devices.Loader;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MECF.Framework.Common.Utilities;
using Aitex.Core.RT.Log;
using MECF.Framework.Common.CommonData.Loader;
using CyberX8_RT.Modules.Dryer;
using MECF.Framework.Common.Persistent.Temperature;
using MECF.Framework.Common.WaferHolder;
namespace CyberX8_RT.Modules.Loader
{
public class LoaderLoadAllSideRoutine : RoutineBase, IRoutine
{
private enum LoadStep
{
SideALoad,
Delay,
SideBLoad,
SideAllLoadWait,
LeakTest,
LeakTestWait,
RotationGoToTRNPA,
RotationGoToTRNPAWait,
UnclampWaferHolder,
End
}
#region 常量
private const string SIDE_A = "SideA";
private const string SIDE_B = "SideB";
private const int LOTTRACK_TIME = 1000;
#endregion
#region 内部变量
private JetAxisBase _rotationAxis;
private LoaderLoadRoutine _sideALoadRoutine;
private LoaderLoadRoutine _sideBLoadRoutine;
private LoaderCommonDevice _loaderCommonDevice;
private bool _isSideALoaded = false;
private bool _isSideBLoaded = false;
private bool _isSideAStop = false;
private bool _isSideBStop = false;
///
/// lotTrack time
///
private DateTime _lotTackTime = DateTime.Now;
///
/// Loader Common
///
private LoaderCommonDevice _loaderCommon;
///
/// LoaderSide A
///
private LoaderSideDevice _loaderSideA;
///
/// LoaderSide B
///
private LoaderSideDevice _loaderSideB;
///
/// Loader LotTrackData
///
private List _datas = new List();
///
/// Flow LotTrackData
///
private List _flowDatas = new List();
///
/// Loader Start and Finish Time
///
private List _loadTimeList = new List();
#endregion
#region 属性
///
/// UnLoad LotTrackData
///
public List LoadLotTrackDatas { get { return _datas; } }
///
/// Flow LotTrackData
///
public List FlowLotTrackDatas { get { return _flowDatas; } }
///
/// LoadTimeList
///
public List LoadTimeList { get { return _loadTimeList; } }
#endregion
///
/// 构造函数
///
///
public LoaderLoadAllSideRoutine(string module) : base(module)
{
}
///
/// 中止
///
public void Abort()
{
}
///
/// 监控
///
///
public RState Monitor()
{
//记录Lot track
LottrackRecord();
Runner.Run(LoadStep.SideALoad, () => StartLoadRoutine(_sideALoadRoutine,_isSideALoaded), _delay_1ms)
.Delay(LoadStep.Delay,500)
.Run(LoadStep.SideBLoad, () => StartLoadRoutine(_sideBLoadRoutine,_isSideBLoaded), _delay_1ms)
.WaitWithStopCondition(LoadStep.SideAllLoadWait, CheckLoadAllRoutineEndStatus,CheckLoadAllRoutineStopStatus)
.Run(LoadStep.LeakTest, StartFlowTest, _delay_1ms)
.WaitWithStopCondition(LoadStep.LeakTestWait, CheckFlowTestEndStatus, CheckFlowTestStopStatus)
.Run(LoadStep.RotationGoToTRNPA,RotationGotoTransporterA,_delay_1s)
.WaitWithStopCondition(LoadStep.RotationGoToTRNPAWait,CheckRotationPositionStatus,CheckRotationPositionRunStop)
.Run(LoadStep.UnclampWaferHolder,WaferHolderClampOffAction,_delay_1ms)
.End(LoadStep.End, UpdateWaferHolderUse, _delay_1ms);
return Runner.Status;
}
///
/// 检验Rotation移动状态
///
///
private bool CheckRotationPositionStatus()
{
return _rotationAxis.Status == RState.End;
}
///
/// 检验Rotation是否还在运动
///
///
private bool CheckRotationPositionRunStop()
{
bool result= _rotationAxis.Status == RState.Failed||_rotationAxis.Status==RState.Timeout;
if (result)
{
NotifyError(eEvent.ERR_LOADER, "rotation goto position failed", 2);
}
return result;
}
///
/// 启动load routine
///
///
///
private bool StartLoadRoutine(LoaderLoadRoutine loadRoutine,bool isSideLoaded)
{
if (isSideLoaded)
{
return true;
}
bool result= loadRoutine.Start()==RState.Running;
if (!result)
{
NotifyError(eEvent.ERR_LOADER, loadRoutine.ErrorMsg, 0);
}
return result;
}
///
/// 检验LoadAll完成状态
///
///
private bool CheckLoadAllRoutineEndStatus()
{
bool sideAResult = true;
if (!_isSideALoaded)
{
sideAResult = CheckLoadRoutineEndStatus(_sideALoadRoutine);
}
bool sideBResult = true;
if(!_isSideBLoaded)
{
sideBResult= CheckLoadRoutineEndStatus(_sideBLoadRoutine);
}
if (sideAResult && sideBResult)
{
_loadTimeList.Add(DateTime.Now);
}
return sideAResult && sideBResult;
}
///
/// 检验LoadAll停止状态
///
///
private bool CheckLoadAllRoutineStopStatus()
{
bool sideAComplete = false;
if(!_isSideALoaded&&!_isSideAStop)
{
RState ret = _sideALoadRoutine.Monitor();
_isSideAStop = ret == RState.Failed || ret == RState.Timeout;
sideAComplete = (ret != RState.Running);
if (_isSideAStop)
{
NotifyError(eEvent.ERR_LOADER, $"load A failed\r\n{_sideALoadRoutine.ErrorMsg}", 0);
}
}
bool sideBComplete = false;
if (!_isSideBLoaded&&!_isSideBStop)
{
RState ret = _sideBLoadRoutine.Monitor();
_isSideBStop = ret == RState.Failed || ret == RState.Timeout;
sideBComplete = (ret != RState.Running);
if (_isSideBStop)
{
NotifyError(eEvent.ERR_LOADER, $"load B failed\r\n{_sideBLoadRoutine.ErrorMsg}", 0);
}
}
return (_isSideAStop&&sideBComplete)||(_isSideBStop&&sideAComplete);
}
///
/// 检验routine完成状态
///
///
///
private bool CheckLoadRoutineEndStatus(LoaderLoadRoutine loadRoutine)
{
return loadRoutine.Monitor() == RState.End;
}
///
/// 启动Flowtest
///
///
private bool StartFlowTest()
{
bool result= _loaderCommonDevice.StartFlowTestAction();
if (!result)
{
NotifyError(eEvent.ERR_LOADER, "Start Flow Test failed", 1);
}
return result;
}
///
/// 检验FlowTest停止状态
///
///
private bool CheckFlowTestStopStatus()
{
if (_loaderCommonDevice.Status == RState.Failed || _loaderCommonDevice.Status == RState.Timeout)
{
NotifyError(eEvent.ERR_LOADER, "Flow Test failed",1);
return true;
}
return false;
}
///
/// 检验FlowTest完成状态
///
///
private bool CheckFlowTestEndStatus()
{
bool result = _loaderCommonDevice.Status == RState.End;
if (result)
{
_flowDatas = _loaderCommonDevice.FlowLotTrackDatas;
}
return result;
}
///
/// Rotation 运动至TRNPA
///
///
private bool RotationGotoTransporterA()
{
bool result = _rotationAxis.PositionStation("TRNPA", false);
if (!result)
{
NotifyError(eEvent.ERR_LOADER, "rotation start goto TRNPA failed", 2);
}
return result;
}
///
/// Wafer Holder Clamp Off
///
///
public bool WaferHolderClampOffAction()
{
bool result = _loaderCommonDevice.WaferHolderClampOffAction();
if (!result)
{
NotifyError(eEvent.ERR_LOADER, "Wafer Shuttle Clamp Off failed", 2);
}
return result;
}
///
/// 更新WaferHolder总用量
///
///
private bool UpdateWaferHolderUse()
{
WaferHolderInfo waferHolderInfo = WaferHolderManager.Instance.GetWaferHolder("Loader");
if(waferHolderInfo != null)
{
waferHolderInfo.TotalUses += 1;
WaferHolderManager.Instance.UpdateWaferHolderInfo(waferHolderInfo);
}
return true;
}
///
/// 启动
///
///
///
public RState Start(params object[] objs)
{
InitializeParameters();
_loaderCommon = DEVICE.GetDevice($"{Module}.Common");
_loaderSideA = DEVICE.GetDevice($"{Module}.SideA");
_loaderSideB = DEVICE.GetDevice($"{Module}.SideB");
//清除lotTrack数据
_datas.Clear();
_flowDatas.Clear();
_loadTimeList.Clear();
_loadTimeList.Add(DateTime.Now);
return Runner.Start(Module, "Start LoadAll");
}
///
/// 初始化参数
///
private void InitializeParameters()
{
_isSideALoaded = false;
_isSideBLoaded = false;
_isSideAStop = false;
_isSideBStop = false;
_rotationAxis = DEVICE.GetDevice($"{Module}.Rotation");
_sideALoadRoutine = new LoaderLoadRoutine(ModuleName.Loader1.ToString(), SIDE_A);
_sideBLoadRoutine = new LoaderLoadRoutine(ModuleName.Loader1.ToString(), SIDE_B);
_loaderCommonDevice = DEVICE.GetDevice($"{ModuleName.Loader1}.Common");
}
///
/// 重试
///
///
public RState Retry(int step)
{
InitializeParameters();
List preStepIds = new List();
_datas.Clear();
if (step == 0 || step == -1)
{
_isSideALoaded = CheckSideLoadCondition("A", step,false);
_isSideBLoaded=CheckSideLoadCondition("B", step,false);
return Runner.Retry(LoadStep.SideALoad, preStepIds, Module, "LoadAll Retry");
}
else if (step == 1)
{
AddPreSteps(LoadStep.LeakTest, preStepIds);
return Runner.Retry(LoadStep.LeakTest, preStepIds, Module, $"LoadAll step {LoadStep.LeakTest} start Retry");
}
else
{
AddPreSteps(LoadStep.RotationGoToTRNPA, preStepIds);
return Runner.Retry(LoadStep.RotationGoToTRNPA, preStepIds, Module, $"LoadAll step {LoadStep.RotationGoToTRNPA} start Retry");
}
}
///
/// 忽略前
///
///
///
private void AddPreSteps(LoadStep step, List preStepIds)
{
for (int i = 0; i < (int)step; i++)
{
preStepIds.Add((LoadStep)i);
}
}
///
/// 检验前面Unload完成状态
///
///
public bool CheckCompleteCondition(int index)
{
if (!CheckSideLoadCondition("A", index,true))
{
return false;
}
if (!CheckSideLoadCondition("B", index,true))
{
return false;
}
JetAxisBase loaderRotationAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.Rotation");
double loaderRotationPosition = loaderRotationAxis.MotionData.MotorPosition;
if (!loaderRotationAxis.CheckPositionIsInStation(loaderRotationPosition, "TRNPA"))
{
NotifyError(eEvent.ERR_LOADER, $"loader rotation {loaderRotationPosition} not in TRNPA", index);
}
return true;
}
///
/// 检验Side Unload情况
///
///
///
///
private bool CheckSideLoadCondition(string side, int index,bool showError)
{
JetAxisBase shuttleAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.Shuttle{side}");
double shuttlePosition = shuttleAxis.MotionData.MotorPosition;
if (!shuttleAxis.CheckPositionIsInStation(shuttlePosition, "CLOSED"))
{
if (showError)
{
NotifyError(eEvent.ERR_LOADER, $"shuttle{side} {shuttlePosition} is not in closed", index);
}
return false;
}
JetAxisBase tiltAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.Tilt{side}");
double tiltPosition = tiltAxis.MotionData.MotorPosition;
if (tiltAxis.CheckPositionIsInStation(tiltPosition, "VERT"))
{
if (showError)
{
NotifyError(eEvent.ERR_LOADER, $"tilt{side} {tiltPosition} is not in VERT", index);
}
return false;
}
JetAxisBase crsAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.LS{side}");
double crsPosition = crsAxis.MotionData.MotorPosition;
if (!crsAxis.CheckPositionIsInStation(crsPosition, "Setup"))
{
if (showError)
{
NotifyError(eEvent.ERR_LOADER, $"LS{side} {crsPosition} is not in Setup", index);
}
return false;
}
LoaderSideDevice loaderSideDevice = DEVICE.GetDevice($"{ModuleName.Loader1}.Side{side}");
if (loaderSideDevice.SideData.DoorLowerUnlocked || loaderSideDevice.SideData.DoorUpperUnlocked)
{
if (showError)
{
NotifyError(eEvent.ERR_LOADER, $"side{side} door unlocked", index);
}
}
return true;
}
///
/// 记录Lottrack
///
private void LottrackRecord()
{
//记录Lottrack
if (DateTime.Now.Subtract(_lotTackTime).TotalMilliseconds >= LOTTRACK_TIME)
{
AddLotTrackData();
_lotTackTime = DateTime.Now;
}
}
///
/// 获取Lot Track数据
///
///
private void AddLotTrackData()
{
LoadStep step = (LoadStep)Runner.CurrentStep;
if (step <= LoadStep.SideAllLoadWait)
{
LoaderLotTrackData data = new LoaderLotTrackData();
data.TimeStamp = DateTime.Now;
data.LoaderABernoulliBladderEnable = _loaderSideA.SideData.BernoulliBladder;
data.LoaderABernoulliExtended = _loaderSideA.SideData.BernoulliExtended;
data.LoaderABernoulliBladderPressure = _loaderSideA.SideData.BernoulliBladderPressure;
data.LoaderABernoulliN2Pressure = _loaderSideA.SideData.BernoulliPressure;
data.LoaderACRSVacuum = _loaderSideA.SideData.CRSVacuum;
data.LoaderACRSVacuumAnlg = _loaderSideA.SideData.CRSVacuumValue;
data.LoaderAWHPressure = _loaderSideA.SideData.WHBladderPressure;
data.LoaderATranslatePressure = _loaderSideA.SideData.TransPressure;
data.LoaderBBernoulliBladderEnable = _loaderSideB.SideData.BernoulliBladder;
data.LoaderBBernoulliExtended = _loaderSideB.SideData.BernoulliExtended;
data.LoaderBBernoulliBladderPressure = _loaderSideB.SideData.BernoulliBladderPressure;
data.LoaderBBernoulliN2Pressure = _loaderSideB.SideData.BernoulliPressure;
data.LoaderBCRSVacuum = _loaderSideB.SideData.CRSVacuum;
data.LoaderBCRSVacuumAnlg = _loaderSideB.SideData.CRSVacuumValue;
data.LoaderBWHPressure = _loaderSideB.SideData.WHBladderPressure;
data.LoaderBTranslatePressure = _loaderSideB.SideData.TransPressure;
data.LoaderWHClamped = _loaderCommon.CommonData.WaferHolderClamp;
_datas.Add(data);
}
}
}
}