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;
using Aitex.Core.RT.SCCore;
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";
private const string WAFER_PRESENT = "WaferPresent";
#endregion
private enum PufPickStep
{
SideConditionRoutine,
SideConditionRoutineWait,
RotationLoaderPickup,
RotationLoaderPickupWait,
ChuckOut,
CheckChuckOut,
VacuumOn,
ChuckIn,
CheckChuckIn,
StickDistanceCheck,
RotationHomeStation,
RotationHomeStationWait,
End
}
#region 内部变量
private string _loaderSide;
private string _pufSide;
private JetAxisBase _flipAxis;
private JetAxisBase _rotationAxis;
private JetAxisBase _gantryAxis;
private LoaderSideDevice _loaderSideDevice;
private PufVacuum _vacuum;
private PufWaferPickSubRoutine _pufWaferPickSubRoutine;
private PufChuckRoutine _chuckRoutine;
private PufDistanceSensor _distanceSensor;
private bool _enableCheckStickDistanceStatus = false;
#endregion
///
/// 构造函数
///
///
///
public PufPickFromLoaderRoutine(string module) : base(module)
{
}
///
/// 中止
///
public void Abort()
{
Runner.Stop("Manual Abort");
}
public RState Monitor()
{
Runner.RunConditionSubRoutine(PufPickStep.SideConditionRoutine, SideConditionIndex, new IRoutine[] { _pufWaferPickSubRoutine }, new object[] { _pufSide })
.WaitConditionSubRoutine(PufPickStep.SideConditionRoutineWait)
.Run(PufPickStep.RotationLoaderPickup, () => { return _rotationAxis.PositionStation("LoaderPickup"); }, NullFun, 100)
.WaitWithStopCondition(PufPickStep.RotationLoaderPickupWait, () => { return _rotationAxis.Status == RState.End; }, () => { return _rotationAxis.Status == RState.Failed; })
.Run(PufPickStep.ChuckOut, () => { return _chuckRoutine.Start(true) == RState.Running; }, NullFun, 100)
.WaitWithStopCondition(PufPickStep.CheckChuckOut, () => CommonFunction.CheckRoutineEndState(_chuckRoutine), () => CommonFunction.CheckRoutineStopState(_chuckRoutine))
.Run(PufPickStep.VacuumOn, VacuumOn, CheckWaferPresent, 5000)
.Run(PufPickStep.ChuckIn, () => { return _chuckRoutine.Start(false) == RState.Running; }, NullFun, 100)
.WaitWithStopCondition(PufPickStep.CheckChuckIn, () => CommonFunction.CheckRoutineEndState(_chuckRoutine), () => CommonFunction.CheckRoutineStopState(_chuckRoutine))
.Wait(PufPickStep.StickDistanceCheck, CheckStickDistanceStatus, 1000)
.Run(PufPickStep.RotationHomeStation, () => { return _rotationAxis.PositionStation("Home"); }, NullFun, 100)
.WaitWithStopCondition(PufPickStep.RotationHomeStationWait, () => { return _rotationAxis.Status == RState.End; }, () => { return _rotationAxis.Status == RState.Failed; })
.End(PufPickStep.End, NullFun);
return Runner.Status;
}
///
/// Side条件获取SubRoutine索引
///
///
private int SideConditionIndex()
{
if (_flipAxis.CheckPositionIsInStation(_flipAxis.MotionData.MotorPosition, _pufSide))
{
return 1;
}
else
{
return 0;
}
}
///
/// 检验VacuumLevel
///
///
private bool CheckVacuumLevel()
{
if (_pufSide == SideA)
{
return _vacuum.ChuckBVacuumStatus == WAFER_PRESENT;
}
else if (_pufSide == SideB)
{
return _vacuum.ChuckAVacuumStatus == WAFER_PRESENT;
}
else
{
return false;
}
}
///
/// 检验存在Wafer
///
///
private bool CheckWaferPresent()
{
if (_pufSide == SideA)
{
return _vacuum.ChuckAVacuumStatus == WAFER_PRESENT;
}
else if (_pufSide == SideB)
{
return _vacuum.ChuckBVacuumStatus == WAFER_PRESENT;
}
else
{
return false;
}
}
///
/// 打开Vacuum
///
///
private bool VacuumOn()
{
if (_pufSide == SideA)
{
_vacuum.VacuumAOn();
return true;
}
else if (_pufSide == SideB)
{
_vacuum.VacuumBOn();
return true;
}
return false;
}
///
/// Stick Distance检验结果
///
///
private bool CheckStickDistanceStatus()
{
if (_enableCheckStickDistanceStatus)
{
return _distanceSensor.CheckStickDistanceStatus();
}
else
{
return true;
}
}
///
/// 启动
///
///
///
public RState Start(params object[] objs)
{
_pufSide = objs[0].ToString();
_flipAxis = DEVICE.GetDevice($"{Module}.Flip");
_rotationAxis = DEVICE.GetDevice($"{Module}.Rotation");
_vacuum = DEVICE.GetDevice($"{Module}.Vacuum");
_gantryAxis = DEVICE.GetDevice($"{ModuleName.Transporter2}.Gantry");
_distanceSensor = DEVICE.GetDevice($"{Module}.DistanceSensor");
_pufWaferPickSubRoutine = new PufWaferPickSubRoutine(Module);
_enableCheckStickDistanceStatus = SC.GetValue($"{Module}.EnableCheckStickDistanceStatus");
_chuckRoutine = new PufChuckRoutine(Module);
if (CheckCondition())
{
return Runner.Start(Module, "PickFrom Loader");
}
else
{
return RState.Failed;
}
}
///
/// 检验条件
///
///
private bool CheckCondition()
{
//Loader1.Rotation 在LOADA
bool isLoaderInstall = ModuleHelper.IsInstalled(ModuleName.Loader1);
if (isLoaderInstall)
{
JetAxisBase loaderRotationAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.Rotation");
double loaderRotationPosition = loaderRotationAxis.MotionData.MotorPosition;
if (!loaderRotationAxis.CheckPositionInStationIgnoreWaferSize(loaderRotationPosition, "LOAD"))
{
LOG.WriteLog(eEvent.ERR_PUF, Module, $"Loader Rotation {loaderRotationPosition} is not in LOAD");
return false;
}
bool isLoadA = loaderRotationAxis.CheckPositionInStationIgnoreWaferSize(loaderRotationPosition, "LOADA");
bool isLoadB = loaderRotationAxis.CheckPositionInStationIgnoreWaferSize(loaderRotationPosition, "LOADB");
string side = isLoadA ? "A" : "B";
_loaderSide = isLoadA ? SideA : SideB;
_loaderSideDevice = DEVICE.GetDevice($"{ModuleName.Loader1}.{_loaderSide}");
//Loader1.SwingA 在Open
JetAxisBase loaderShuttleAAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.Shuttle{side}");
double loaderShuttleAPosition = loaderShuttleAAxis.MotionData.MotorPosition;
if (!loaderShuttleAAxis.CheckPositionInStationIgnoreWaferSize(loaderShuttleAPosition, "OUT"))
{
LOG.WriteLog(eEvent.ERR_PUF, Module, $"Loader ShuttleA {loaderShuttleAPosition} is not in OUT");
return false;
}
//Loader1.TiltA 在HORI
JetAxisBase loaderTiltAAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.Tilt{side}");
double loaderTiltAPosition = loaderTiltAAxis.MotionData.MotorPosition;
if (!loaderTiltAAxis.CheckPositionIsInStation(loaderTiltAPosition, "HORI"))
{
LOG.WriteLog(eEvent.ERR_PUF, Module, $"Loader Tilt{side} {loaderTiltAPosition} is not in HORI");
return false;
}
//Loader Handle Wafer状态确认
// Lip Seal Vacuum "ON"
if (!_loaderSideDevice.SideData.CRSVacuum)
{
LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 LS Vacuum is off");
return false;
}
//Bernoulli Bladder "ON",Retracted Green Light
if (!_loaderSideDevice.SideData.BernoulliBladder)
{
LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 Bernoulli Bladder is off");
return false;
}
//其他SideA/B均为OFF
if (_loaderSideDevice.SideData.BernoulliN2)
{
LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 Bernoulli N2 is on");
return false;
}
if (_loaderSideDevice.SideData.WHBladder)
{
LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 WS Bladder is on");
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;
}
}
}