using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using Aitex.Core.RT.Routine; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Routine; using MECF.Framework.Common.Utilities; using CyberX8_Core; using CyberX8_RT.Devices.AXIS; using CyberX8_RT.Devices.Loader; using CyberX8_RT.Devices.PUF; using CyberX8_RT.Devices.TransPorter; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CyberX8_RT.Modules.PUF { public class PufPickFromLoaderRoutine : RoutineBase,IRoutine { #region 常量 private const string SideA = "SideA"; private const string SideB = "SideB"; private const string CURRENT_STATION_LIST = "CurrentStationList"; #endregion #region 内部变量 private string _side; private JetAxisBase _flipAxis; private JetAxisBase _rotationAxis; private JetAxisBase _verticalAxis; private JetAxisBase _gantryAxis; private LoaderSideDevice _loaderSide; private PufVacuum _vacuum; private IRoutine _routine; private PufNoWaferPickRoutine _noWaferPickRoutine; private PufWaferPickRoutine _pufWaferPickRoutine; #endregion /// <summary> /// 构造函数 /// </summary> /// <param name="module"></param> /// <param name="pufEntity"></param> public PufPickFromLoaderRoutine(string module) : base(module) { _noWaferPickRoutine =new PufNoWaferPickRoutine(module); _pufWaferPickRoutine=new PufWaferPickRoutine(module); } /// <summary> /// 中止 /// </summary> public void Abort() { _routine.Abort(); } /// <summary> /// 监控 /// </summary> /// <returns></returns> public RState Monitor() { return _routine.Monitor(); } /// <summary> /// 启动 /// </summary> /// <param name="objs"></param> /// <returns></returns> public RState Start(params object[] objs) { _side = objs[0].ToString(); _flipAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Flip"); _rotationAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Rotation"); _verticalAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Vertical"); _vacuum = DEVICE.GetDevice<PufVacuum>($"{Module}.Vacuum"); _gantryAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Transporter2}.Gantry"); GetLoaderSide(); if (CheckCondition()) { if (CheckReverseWafer()) { _routine = _pufWaferPickRoutine; } else { _routine = _noWaferPickRoutine; } _routine.Start(_side); return RState.Running; } else { return RState.Failed; } } /// <summary> /// 检验条件 /// </summary> /// <returns></returns> private bool CheckCondition() { //Loader1.Rotation 在LOADA bool isLoaderInstall = ModuleHelper.IsInstalled(ModuleName.Loader1); if (isLoaderInstall) { JetAxisBase loaderRotationAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.Rotation"); double loaderRotationPosition = loaderRotationAxis.MotionData.MotorPosition; if (!loaderRotationAxis.CheckPositionIsInStation(loaderRotationPosition, "LOADA")) { LOG.WriteLog(eEvent.ERR_PUF, Module, $"Loader Rotation {loaderRotationPosition} is not in LOADA"); return false; } if (Module == ModuleName.PUF1.ToString()) { //Loader1.SwingA 在Open JetAxisBase loaderShuttleAAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.ShuttleA"); double loaderShuttleAPosition = loaderShuttleAAxis.MotionData.MotorPosition; if (!loaderShuttleAAxis.CheckPositionIsInStation(loaderShuttleAPosition, "OPEN")) { LOG.WriteLog(eEvent.ERR_PUF, Module, $"Loader ShuttleA {loaderShuttleAPosition} is not in OPEN"); return false; } //Loader1.TiltA 在HORI JetAxisBase loaderTiltAAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.TiltA"); double loaderTiltAPosition = loaderTiltAAxis.MotionData.MotorPosition; if (!loaderTiltAAxis.CheckPositionIsInStation(loaderTiltAPosition, "HORI")) { LOG.WriteLog(eEvent.ERR_PUF, Module, $"Loader TiltA {loaderTiltAPosition} is not in HORI"); return false; } } if (Module == ModuleName.PUF2.ToString()) { //Loader1.ShuttleB 在Open JetAxisBase loaderShuttleBAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.ShuttleB"); double loaderShuttleBPosition = loaderShuttleBAxis.MotionData.MotorPosition; if (!loaderShuttleBAxis.CheckPositionIsInStation(loaderShuttleBPosition, "OPEN")) { LOG.WriteLog(eEvent.ERR_PUF, Module, $"Loader ShuttleB {loaderShuttleBPosition} is not in OPEN"); return false; } //Loader1.TiltB 在HORI JetAxisBase loaderTiltBAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.TiltB"); double loaderTiltBPosition = loaderTiltBAxis.MotionData.MotorPosition; if (!loaderTiltBAxis.CheckPositionIsInStation(loaderTiltBPosition, "HORI")) { LOG.WriteLog(eEvent.ERR_PUF, Module, $"Loader TiltB {loaderTiltBPosition} is not in HORI"); return false; } } //Loader Handle Wafer状态确认 // Lip Seal Vacuum "ON" if (!_loaderSide.SideData.CRSVacuum) { LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 LS Vacuum is off"); return false; } //Bernoulli Bladder "ON",Retracted Green Light if (!_loaderSide.SideData.BernoulliBladder) { LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 Bernoulli Bladder is off"); return false; } if (_loaderSide.SideData.BernoulliExtended) { LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 Bernoulli Retracted is off"); return false; } //其他SideA/B均为OFF if (_loaderSide.SideData.BernoulliN2) { LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 Bernoulli N2 is on"); return false; } if (!_loaderSide.SideData.DoorUnlock) { LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 Door is Locked"); return false; } if (_loaderSide.SideData.WHBladder) { LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 WS Bladder is on"); return false; } if (_loaderSide.SideData.TransBladder) { LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 Translate Bladder is on"); return false; } if (_loaderSide.SideData.TransHigh) { LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 Translate High Pre is on"); return false; } } //Loader Transporter在Loader右侧 bool loaderTransporterInstalled = ModuleHelper.IsInstalled(ModuleName.Transporter2); if (loaderTransporterInstalled && !_gantryAxis.JudgeCompareTargetStation("Loader", "Right")) { LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader Transporter is not in Loader right position"); return false; } double verticalPosition = _verticalAxis.MotionData.MotorPosition; if (!_verticalAxis.CheckPositionIsInStation(verticalPosition,"Park")) { LOG.WriteLog(eEvent.ERR_PUF,Module, $"vertical axis {verticalPosition} is not at Park Station"); return false; } double rotationPosition = _rotationAxis.MotionData.MotorPosition; if(_rotationAxis.CheckPositionIsEmpty(rotationPosition)) { LOG.WriteLog(eEvent.ERR_PUF,Module, $"rotation axis {rotationPosition} is not at Station"); return false; } double flipPosition = _flipAxis.MotionData.MotorPosition; if(_flipAxis.CheckPositionIsEmpty(flipPosition)) { LOG.WriteLog( eEvent.ERR_PUF,Module, $"flip axis {flipPosition} is not at Station"); return false; } return true; } /// <summary> /// 检验反面Wafer Present /// </summary> /// <returns></returns> private bool CheckReverseWafer() { if(_side == SideA) { return _vacuum.ChuckBWaferPresent; } else if(_side == SideB) { return _vacuum.ChuckAWaferPresent; } else { return false; } } /// <summary> /// 获取LoaderSide /// </summary> private void GetLoaderSide() { if( Module == ModuleName.PUF1.ToString()) { _loaderSide= DEVICE.GetDevice<LoaderSideDevice>($"{ModuleName.Loader1}.SideA"); } else { _loaderSide = DEVICE.GetDevice<LoaderSideDevice>($"{ModuleName.Loader1}.SideB"); } } } }