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 Aitex.Core.RT.Log;
using MECF.Framework.Common.Utilities;
using MECF.Framework.Common.CommonData.Loader;
using MECF.Framework.Common.CommonData;
using Aitex.Core.RT.DataCenter;
namespace CyberX8_RT.Modules.Loader
{
public class LoaderUnloadAllSideRoutine : RoutineBase, IRoutine
{
private enum UnloadStep
{
RotationGoToLOADA,
RotationGoToLOADAWait,
SideAUnload,
Delay,
SideBUnload,
UnloadAllWait,
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 LoaderUnloadRoutine _sideAUnloadRoutine;
private LoaderUnloadRoutine _sideBUnloadRoutine;
private bool _isSideAUnloaded = false;
private bool _isSideBunloaded = 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();
#endregion
#region 属性
///
/// UnLoad LotTrackData
///
public List UnloadLotTrackDatas { get { return _datas; } }
#endregion
///
/// 构造函数
///
///
public LoaderUnloadAllSideRoutine(string module) : base(module)
{
}
///
/// 中止
///
public void Abort()
{
}
///
/// 监控
///
///
public RState Monitor()
{
LottrackRecord();
Runner.Run(UnloadStep.RotationGoToLOADA,RotationGotoLOADA,_delay_1ms)
.WaitWithStopCondition(UnloadStep.RotationGoToLOADAWait,CheckRotationPositionStatus,CheckRotationPositionRunStop)
.Run(UnloadStep.SideAUnload, () => StartUnloadRoutine(_sideAUnloadRoutine,_isSideAUnloaded), _delay_1ms)
.Delay(UnloadStep.Delay,500)
.Run(UnloadStep.SideBUnload, () => StartUnloadRoutine(_sideBUnloadRoutine,_isSideBunloaded), _delay_1ms)
.WaitWithStopCondition(UnloadStep.UnloadAllWait, CheckUnloadAllRoutineEndStatus,CheckUnloadAllRoutineStopStatus)
.End(UnloadStep.End, NullFun, _delay_1ms);
return Runner.Status;
}
///
/// Rotation Goto LOADA
///
///
private bool RotationGotoLOADA()
{
bool result = _rotationAxis.PositionStation("LOADA", false);
if (!result)
{
NotifyError(eEvent.ERR_LOADER, "rotation start goto LOADA failed", 0);
}
return result;
}
///
/// 检验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",0);
}
return result;
}
///
/// 启动Unload routine
///
///
///
private bool StartUnloadRoutine(LoaderUnloadRoutine unloadRoutine,bool isSideUnloaded)
{
if (isSideUnloaded)
{
return true;
}
bool result= unloadRoutine.Start()==RState.Running;
if(!result)
{
NotifyError(eEvent.ERR_LOADER, unloadRoutine.ErrorMsg, 0);
}
return result;
}
///
/// 检验UnloadAll完成状态
///
///
private bool CheckUnloadAllRoutineEndStatus()
{
bool sideAResult = true;
if (!_isSideAUnloaded)
{
sideAResult = CheckUnloadRoutineEndStatus(_sideAUnloadRoutine);
}
bool sideBResult = true;
if (!_isSideBunloaded)
{
sideBResult = CheckUnloadRoutineEndStatus(_sideBUnloadRoutine);
}
return sideAResult && sideBResult;
}
///
/// 检查UnloadAll停止状态
///
///
private bool CheckUnloadAllRoutineStopStatus()
{
bool sideAComplete = false;
if (!_isSideAUnloaded&&!_isSideAStop)
{
RState ret = _sideAUnloadRoutine.Monitor();
_isSideAStop = ret == RState.Failed || ret == RState.Timeout;
sideAComplete = (ret != RState.Running);
if (_isSideAStop)
{
NotifyError(eEvent.ERR_LOADER, $"unload A failed\r\n{_sideAUnloadRoutine.ErrorMsg}", 1);
}
}
bool sideBComplete = false;
if(!_isSideBunloaded&&!_isSideBStop)
{
RState ret = _sideBUnloadRoutine.Monitor();
_isSideBStop = ret == RState.Failed || ret == RState.Timeout;
sideBComplete = (ret != RState.Running);
if (_isSideBunloaded)
{
NotifyError(eEvent.ERR_LOADER, $"unload B failed\r\n{_sideBUnloadRoutine.ErrorMsg}", 1);
}
}
return (_isSideAStop && sideBComplete) || (_isSideBStop && sideAComplete);
}
///
/// 检验routine完成状态
///
///
///
private bool CheckUnloadRoutineEndStatus(LoaderUnloadRoutine unloadRoutine)
{
return unloadRoutine.Monitor() == RState.End;
}
///
/// 检验Routine结束状态
///
///
///
private bool CheckUnloadRoutineStopStatus(LoaderUnloadRoutine unloadRoutine,string side)
{
RState state=unloadRoutine.Monitor();
if (state == RState.Failed || state == RState.Timeout)
{
NotifyError(eEvent.ERR_LOADER, $"{side} Unload failed", 0);
return true;
}
return false;
}
///
/// 启动
///
///
///
public RState Start(params object[] objs)
{
InitializeParameters();
_loaderCommon = DEVICE.GetDevice($"{Module}.Common");
_loaderSideA = DEVICE.GetDevice($"{Module}.SideA");
_loaderSideB = DEVICE.GetDevice($"{Module}.SideB");
return Runner.Start(Module, "Start UnloadAll");
}
///
/// 初始化参数
///
private void InitializeParameters()
{
_rotationAxis = DEVICE.GetDevice($"{Module}.Rotation");
_sideAUnloadRoutine = new LoaderUnloadRoutine(ModuleName.Loader1.ToString(), "SideA");
_sideBUnloadRoutine = new LoaderUnloadRoutine(ModuleName.Loader1.ToString(), "SideB");
_isSideAUnloaded = false;
_isSideBunloaded = false;
_isSideAStop = false;
_isSideBStop = false;
}
///
/// 重试
///
///
public RState Retry(int step)
{
InitializeParameters();
List preStepIds = new List();
if (step == 0||step==-1)
{
return Runner.Retry(UnloadStep.RotationGoToLOADA,preStepIds,Module,"UnloadAll Retry");
}
else
{
_isSideAUnloaded = CheckSideUnloadCondition("A", step,false);
_isSideBunloaded= CheckSideUnloadCondition("B", step,false);
AddPreSteps(UnloadStep.SideAUnload, preStepIds);
return Runner.Retry(UnloadStep.SideBUnload,preStepIds, Module, $"UnloadAll step {UnloadStep.SideBUnload} Retry");
}
}
///
/// 忽略前
///
///
///
private void AddPreSteps(UnloadStep step,List preStepIds)
{
for(int i = 0;i<(int)step;i++)
{
preStepIds.Add((UnloadStep)i);
}
}
///
/// 检验前面Unload完成状态
///
///
public bool CheckCompleteCondition(int index)
{
if (!CheckSideUnloadCondition("A", index,true))
{
return false;
}
if (!CheckSideUnloadCondition("B", index, true))
{
return false;
}
return true;
}
///
/// 检验Side Unload情况
///
///
///
///
private bool CheckSideUnloadCondition(string side, int index,bool showError)
{
JetAxisBase shuttleAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.Shuttle{side}");
double shuttlePosition = shuttleAxis.MotionData.MotorPosition;
if (!shuttleAxis.CheckPositionIsInStation(shuttlePosition, "OPEN"))
{
if (showError)
{
NotifyError(eEvent.ERR_LOADER, $"shuttle{side} {shuttlePosition} is not in open", index);
}
return false;
}
JetAxisBase tiltAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.Tilt{side}");
double tiltPosition = tiltAxis.MotionData.MotorPosition;
if (!tiltAxis.CheckPositionIsInStation(tiltPosition, "HORI"))
{
if (showError)
{
NotifyError(eEvent.ERR_LOADER, $"tilt{side} {tiltPosition} is not in HORI", index);
return false;
}
}
JetAxisBase crsAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.LS{side}");
double crsPosition = crsAxis.MotionData.MotorPosition;
if (!crsAxis.CheckPositionIsInStation(crsPosition, "Unlock"))
{
if (showError)
{
NotifyError(eEvent.ERR_LOADER, $"LS{side} {crsPosition} is not in Unlock", index);
}
return false;
}
LoaderSideDevice loaderSideDevice = DEVICE.GetDevice($"{ModuleName.Loader1}.Side{side}");
if (loaderSideDevice.SideData.DoorLowerLocked || loaderSideDevice.SideData.DoorUpperLocked)
{
if (showError)
{
NotifyError(eEvent.ERR_LOADER, $"side{side} door locked", 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()
{
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);
}
}
}