| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493 | using Aitex.Core.Common;using Aitex.Core.RT.DataCenter;using Aitex.Core.RT.Device;using Aitex.Core.RT.Log;using Aitex.Core.RT.Routine;using Aitex.Core.Util;using MECF.Framework.Common.DBCore;using MECF.Framework.Common.Equipment;using MECF.Framework.Common.Routine;using MECF.Framework.Common.SubstrateTrackings;using MECF.Framework.Common.Utilities;using MECF.Framework.Common.WaferHolder;using CyberX8_Core;using CyberX8_RT.Devices.AXIS;using CyberX8_RT.Devices.Loader;using CyberX8_RT.Devices.PUF;using CyberX8_RT.Modules.Loader;using System;using System.Collections.Generic;using System.Linq;using System.Reflection;using System.Text;using System.Threading.Tasks;using Aitex.Core.RT.SCCore;namespace CyberX8_RT.Modules.PUF{    public class PufSwapRoutine : RoutineBase, IRoutine    {        private enum SwapStep        {            CheckPreStatus,            RotationLoaderPickup,            RotationLoaderPickupWait,            ChuckOut,            CheckChuckOut,            SideAVacuumOn,            ChuckIn,            CheckChuckIn,            StickDistanceCheck,            RotationFlip,            WaitRotationFlip,            FlipSideB,            WaitFlipSideB,            PlaceToLoader,            PlaceToLoaderWait,            End        }        #region 常量         private const string CURRENT_STATION_LIST = "CurrentStationList";        private const string WAFER_PRESENT = "WaferPresent";        private const string SIDE_A = "SideA";        private const string SIDE_B = "SideB";        #endregion        #region 内部变量        private LoaderEntity _loaderEntity;        private JetAxisBase _flipAxis;        private JetAxisBase _rotationAxis;        private LoaderSideDevice _loaderSideDevice;        private PufVacuum _vacuum;        private PufDistanceSensor _distanceSensor;        private PufPlaceToLoaderRoutine _placeToLoaderRoutine;        private PufChuckRoutine _chuckRoutine;        private string _loaderSide;        private bool _enableCheckStickDistanceStatus = true;        #endregion        /// <summary>        /// 构造函数        /// </summary>        /// <param name="module"></param>        public PufSwapRoutine(string module) : base(module)        {            _placeToLoaderRoutine = new PufPlaceToLoaderRoutine(Module);            _chuckRoutine = new PufChuckRoutine(Module);        }        /// <summary>        /// 中止        /// </summary>        public void Abort()        {            Runner.Stop("Manual Abort");        }        /// <summary>        /// 监控        /// </summary>        /// <returns></returns>        public RState Monitor()        {            Runner.Run(SwapStep.CheckPreStatus, CheckCondition, _delay_1ms)                .Run(SwapStep.RotationLoaderPickup, () => { return AxisGotoPosition(_rotationAxis, "LoaderPickup", 0); }, _delay_1ms)                .WaitWithStopCondition(SwapStep.RotationLoaderPickupWait, () => { return _rotationAxis.Status == RState.End; },                    () => { return CheckRotationStopStatus(0); })                .Run(SwapStep.ChuckOut, () => { return _chuckRoutine.Start(true) == RState.Running; }, NullFun, 100)                .WaitWithStopCondition(SwapStep.CheckChuckOut, () => CommonFunction.CheckRoutineEndState(_chuckRoutine),                    () => { return CheckChuckRoutineStopStatus(true, 0); })                .Run(SwapStep.SideAVacuumOn, SideAVacuumOn, CheckSideAWaferPresent, 5000)                .Wait(SwapStep.StickDistanceCheck, CheckStickDistanceStatus, 1000)                .Run(SwapStep.ChuckIn, () => { return _chuckRoutine.Start(false) == RState.Running; }, NullFun, 100)                .WaitWithStopCondition(SwapStep.CheckChuckIn, () => CommonFunction.CheckRoutineEndState(_chuckRoutine),                    () => { return CheckChuckRoutineStopStatus(false, 1); })                .Run(SwapStep.RotationFlip, () => { return AxisGotoPosition(_rotationAxis,"Flip",1); }, _delay_1ms)                .WaitWithStopCondition(SwapStep.WaitRotationFlip, () => { return _rotationAxis.Status == RState.End; },                     () => { return CheckRotationStopStatus(1); })                .Run(SwapStep.FlipSideB, () => { return AxisGotoPosition(_flipAxis,"SideB", 1); }, _delay_1ms)                .WaitWithStopCondition(SwapStep.WaitFlipSideB, () => { return _flipAxis.Status == RState.End; },                     () => { return CheckFlipStopStatus(1); })                .Run(SwapStep.PlaceToLoader, () => _placeToLoaderRoutine.Start("SideB") == RState.Running, _delay_1ms)                .WaitWithStopCondition(SwapStep.PlaceToLoaderWait, ()=>CommonFunction.CheckRoutineEndState(_placeToLoaderRoutine),                    CheckPlaceToRoutineStopStatus)                .End(SwapStep.End, NullFun, _delay_1ms);            return Runner.Status;        }        /// <summary>        /// Side a打开真空        /// </summary>        /// <returns></returns>        private bool SideAVacuumOn()        {            bool result= _vacuum.VacuumAOn();            if (!result)            {                NotifyError(eEvent.ERR_PUF, "side A Vacuum on failed", 0);            }            return result;        }        /// <summary>        /// 检验SideA是否存在Wafer        /// </summary>        /// <returns></returns>        private bool CheckSideAWaferPresent()        {            bool result= _vacuum.ChuckAVacuumStatus == WAFER_PRESENT;            if(result)            {                LoaderEntity loaderEntity = Singleton<RouteManager>.Instance.GetModule<LoaderEntity>(ModuleName.Loader1.ToString());                if(loaderEntity!=null)                {                    WaferHolderInfo waferHolder = loaderEntity.WaferHolderInfo;                    if(_loaderSideDevice.Name==SIDE_A)                    {                        if (WaferManager.Instance.CheckHasWafer(ModuleName.Loader1, 0))                        {                            WaferManager.Instance.WaferMoved(ModuleName.Loader1, 0, ModuleHelper.Converter(Module), 0);                        }                        else                        {                            NotifyError(eEvent.ERR_PUF, "Loader sideA has no wafer",0);                            return false;                        }                    }                    else                    {                        if (WaferManager.Instance.CheckHasWafer(ModuleName.Loader1, 1))                        {                            WaferManager.Instance.WaferMoved(ModuleName.Loader1, 1, ModuleHelper.Converter(Module), 0);                        }                        else                        {                            NotifyError(eEvent.ERR_PUF, "Loader sideA has no wafer", 0);                            return false;                        }                    }                }            }            return result;        }        /// <summary>        /// Stick Distance检验结果        /// </summary>        /// <returns></returns>        private bool CheckStickDistanceStatus()        {            if (_enableCheckStickDistanceStatus)            {                WaferSize waferSize = WaferSize.WS0;                WaferInfo waferInfo = WaferManager.Instance.GetWafer(ModuleName.PUF1, 0);                if (waferInfo!=null&&!waferInfo.IsEmpty)                {                    waferSize =waferInfo.Size;                }                //非8寸的Wafer不检验                if (waferSize != WaferSize.WS8)                {                    return true;                }                bool result = _distanceSensor.CheckStickDistanceStatus();                if (!result)                {                    NotifyError(eEvent.ERR_PUF, "check stick distance failed", 0);                }                return result;            }            else            {                return true;            }        }        /// <summary>        /// Axis goto position        /// </summary>        /// <param name="axis"></param>        /// <param name="position"></param>        /// <param name="index"></param>        /// <returns></returns>        private bool AxisGotoPosition(JetAxisBase axis,string position,int index)        {            bool result = axis.PositionStation(position);            if(!result)            {                NotifyError(eEvent.ERR_PUF, $"{axis.Module} goto {position} failed",index);            }            return result;        }        /// <summary>        /// 检验Flip异常状态        /// </summary>        /// <returns></returns>        private bool CheckFlipStopStatus(int index)        {            bool result = _flipAxis.Status == RState.Failed || _flipAxis.Status == RState.Timeout;            if (result)            {                NotifyError(eEvent.ERR_PUF, "flip motion failed", index);            }            return result;        }        /// <summary>        /// 检验Rotation异常状态        /// </summary>        /// <returns></returns>        private bool CheckRotationStopStatus(int index)        {            bool result = _rotationAxis.Status == RState.Failed || _rotationAxis.Status == RState.Timeout;            if (result)            {                NotifyError(eEvent.ERR_PUF, "rotation motion failed", index);            }            return result;        }        /// <summary>        /// 检验PlaceToLoader异常状态        /// </summary>        /// <returns></returns>        private bool CheckChuckRoutineStopStatus(bool chuck,int index)        {            bool result = CommonFunction.CheckRoutineStopState(_chuckRoutine);            string chuckContent = chuck ? "Chuck Out" : "Chuck In";            if (result)            {                NotifyError(eEvent.ERR_PUF,$"{chuckContent} failed", index);            }            return result;        }        /// <summary>        /// 检验PlaceToLoader异常状态        /// </summary>        /// <returns></returns>        private bool CheckPlaceToRoutineStopStatus()        {            bool result = CommonFunction.CheckRoutineStopState(_placeToLoaderRoutine);            if (result)            {                NotifyError(eEvent.ERR_PUF, "place wafer failed", 2);            }            return result;        }        /// <summary>        /// 启动        /// </summary>        /// <param name="objs"></param>        /// <returns></returns>        public RState Start(params object[] objs)        {            InitializeParameters();            return Runner.Start(Module, "Start Swap");        }        /// <summary>        /// 初始化参数        /// </summary>        private void InitializeParameters()        {            _loaderEntity = Singleton<RouteManager>.Instance.GetModule<LoaderEntity>(ModuleName.Loader1.ToString());            _flipAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Flip");            _rotationAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Rotation");            _vacuum = DEVICE.GetDevice<PufVacuum>($"{Module}.Vacuum");            _distanceSensor = DEVICE.GetDevice<PufDistanceSensor>($"{Module}.DistanceSensor");            _enableCheckStickDistanceStatus = SC.GetValue<bool>($"{Module}.EnableCheckStickDistanceStatus");        }        /// <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.CheckPositionInStationIgnoreWaferSize(loaderRotationPosition, "LOAD"))                {                    NotifyError(eEvent.ERR_PUF, $"Loader Rotation {loaderRotationPosition} is not in LOAD",-1);                    return false;                }                bool isLoadA = loaderRotationAxis.CheckPositionInStationIgnoreWaferSize(loaderRotationPosition, "LOADA");                bool isLoadB = loaderRotationAxis.CheckPositionInStationIgnoreWaferSize(loaderRotationPosition, "LOADB");                _loaderSide = isLoadA ? SIDE_A : SIDE_B;                GetLoaderSide();                string side = isLoadA ? "A" : "B";                if (Module == ModuleName.PUF1.ToString())                {                    //Loader1.SwingA 在Open                    JetAxisBase loaderShuttleAAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.Shuttle{side}");                    if (loaderShuttleAAxis != null)                    {                        double loaderShuttleAPosition = loaderShuttleAAxis.MotionData.MotorPosition;                        if (!loaderShuttleAAxis.CheckPositionInStationIgnoreWaferSize(loaderShuttleAPosition, "OUT"))                        {                            NotifyError(eEvent.ERR_PUF, $"Loader Shuttle{side} {loaderShuttleAPosition} is not in OUT", -1);                            return false;                        }                    }                    //Loader1.TiltA 在HORI                    JetAxisBase loaderTiltAAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.Tilt{side}");                    double loaderTiltAPosition = loaderTiltAAxis.MotionData.MotorPosition;                    if (!loaderTiltAAxis.CheckPositionIsInStation(loaderTiltAPosition, "HORI"))                    {                        NotifyError(eEvent.ERR_PUF, $"Loader Tilt {loaderTiltAPosition} is not in HORI",-1);                        return false;                    }                }                //Loader Handle Wafer状态确认                // Lip Seal Vacuum "ON"                if (!_loaderSideDevice.SideData.CRSVacuum)                {                    NotifyError(eEvent.ERR_PUF, "Loader1 LS Vacuum is off",-1);                    return false;                }                //Bernoulli Bladder "ON",Retracted Green Light                if (!_loaderSideDevice.SideData.BernoulliBladder)                {                    NotifyError(eEvent.ERR_PUF, "Loader1 Bernoulli Bladder is off",-1);                    return false;                }                if (_loaderSideDevice.SideData.BernoulliExtended)                {                    NotifyError(eEvent.ERR_PUF, "Loader1 Bernoulli Retracted is off",-1);                    return false;                }                //其他SideA/B均为OFF                if (_loaderSideDevice.SideData.BernoulliN2)                {                    NotifyError(eEvent.ERR_PUF, "Loader1 Bernoulli N2 is on",-1);                    return false;                }                //if (_loaderSide.SideData.WHBladder)                //{                //    NotifyError(eEvent.ERR_PUF,, "Loader1 WS Bladder is on");                //    return false;                //}                if (_loaderSideDevice.SideData.TransBladder)                {                    NotifyError(eEvent.ERR_PUF, "Loader1 Translate Bladder is on",-1);                    return false;                }                if (_loaderSideDevice.SideData.TransHigh)                {                    NotifyError(eEvent.ERR_PUF, "Loader1 Translate High Pre is on",-1);                    return false;                }            }            double rotaionPosition = _rotationAxis.MotionData.MotorPosition;            if (_rotationAxis.CheckPositionIsEmpty(rotaionPosition))            {                NotifyError(eEvent.ERR_PUF, $"rotation axis {rotaionPosition} is not at Station",-1);                return false;            }            double flipPosition = _flipAxis.MotionData.MotorPosition;            if (_flipAxis.CheckPositionIsEmpty(flipPosition))            {                NotifyError(eEvent.ERR_PUF, $"flip axis {flipPosition} is not at Station",-1);                return false;            }            //A面            if (_loaderSideDevice.Name == SIDE_A)            {                if (WaferManager.Instance.CheckNoWafer(ModuleName.Loader1, 0))                {                    NotifyError(eEvent.ERR_PUF, "loader side A has no wafer",-1);                    return false;                }            }            else            {                if (WaferManager.Instance.CheckNoWafer(ModuleName.Loader1, 1))                {                    NotifyError(eEvent.ERR_PUF, "loader side B has no wafer",-1);                    return false;                }            }            return true;        }        /// <summary>        /// 获取LoaderSide        /// </summary>        private void GetLoaderSide()        {            if (_loaderSide==SIDE_A)            {                _loaderSideDevice = DEVICE.GetDevice<LoaderSideDevice>($"{ModuleName.Loader1}.SideA");            }            else            {                _loaderSideDevice = DEVICE.GetDevice<LoaderSideDevice>($"{ModuleName.Loader1}.SideB");            }        }        /// <summary>        /// 重试        /// </summary>        /// <param name="step"></param>        public RState Retry(int step)        {            InitializeParameters();            List<Enum> preStepIds = new List<Enum>();            if (step == 0||step==-1)            {                return Runner.Retry(SwapStep.CheckPreStatus, preStepIds, Module, "Swap Retry");            }            else if (step == 1)            {                AddPreSteps(SwapStep.CheckChuckIn, preStepIds);                return Runner.Retry(SwapStep.ChuckIn, preStepIds, Module, $"Swap step {SwapStep.ChuckIn} Retry");            }            else            {                AddPreSteps(SwapStep.PlaceToLoader, preStepIds);                return Runner.Retry(SwapStep.PlaceToLoader, preStepIds, Module, $"Swap step {SwapStep.PlaceToLoader} Retry");            }        }        /// <summary>        /// 忽略前        /// </summary>        /// <param name="step"></param>        /// <param name="preStepIds"></param>        private void AddPreSteps(SwapStep step, List<Enum> preStepIds)        {            for (int i = 0; i < (int)step; i++)            {                preStepIds.Add((SwapStep)i);            }        }        /// <summary>        /// 检验完成情况         /// </summary>        /// <returns></returns>        public bool CheckCompleteCondition()        {            if (WaferManager.Instance.CheckHasWafer(Module, 1))            {                NotifyError(eEvent.ERR_PUF, "Side B has wafer", 0);                return false;            }            if (Module == ModuleName.PUF1.ToString())            {                if (WaferManager.Instance.CheckNoWafer(ModuleName.Loader1, 0))                {                    NotifyError(eEvent.ERR_PUF, "Loader Side A has wafer", 0);                    return false;                }            }            else            {                if (WaferManager.Instance.CheckNoWafer(ModuleName.Loader1, 1))                {                    NotifyError(eEvent.ERR_PUF, "Loader Side B has wafer", 0);                    return false;                }            }            return true;        }    }}
 |