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