using Aitex.Core.RT.Device;
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 System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CyberX8_RT.Modules.PUF
{
public class PufOnlyPlaceToLoaderRoutine : RoutineBase, IRoutine
{
private enum PlaceStep
{
LipSealGotoUnlock,
LipSealGotoUnlockWait,
VacuumLevelCheck,
SideConditionRoutine,
SideConditionRoutineWait,
RotationGotoLoaderPlaceDown,
RotationGotoLoaderPlaceDownWait,
FirstPlaceVacuumCheck,
FirstPlaceVacuumCheckWait,
SecondPlaceVacuumCheck,
SecondPlaceVacuumCheckWait,
VacuumOff,
End
}
#region 常量
private const string SideA = "SideA";
private const string SideB = "SideB";
private const string WAFER_ABSENT = "WaferAbsent";
#endregion
#region 内部变量
private bool _isSecondPlaceVacuumCheck = false;
private string _side;
private JetAxisBase _flipAxis;
private JetAxisBase _rotationAxis;
private PufVacuum _vacuum;
private JetAxisBase _loaderCrsAxis;
private PufWaferPickSubRoutine _pufWaferPickSubRoutine;
private PufPlaceVacuumCheckRoutine _pufPlaceVacuumCheckRoutine;
#endregion
///
/// 构造函数
///
///
public PufOnlyPlaceToLoaderRoutine(string module) : base(module)
{
_pufWaferPickSubRoutine = new PufWaferPickSubRoutine(module);
}
///
/// 中止
///
public void Abort()
{
if (_pufWaferPickSubRoutine != null)
{
_pufWaferPickSubRoutine.Abort();
}
_flipAxis.StopPositionOperation();
_rotationAxis.StopPositionOperation();
Runner.Stop("Manual Abort");
}
///
/// 监控
///
///
public RState Monitor()
{
Runner.Run(PlaceStep.LipSealGotoUnlock, LipSealGotoUnlock, _delay_1ms)
.WaitWithStopCondition(PlaceStep.LipSealGotoUnlockWait, CheckLipSealEndStatus, CheckLipSealStopStatus)
.Run(PlaceStep.VacuumLevelCheck, CheckWaferPresent, _delay_1ms)
.RunConditionSubRoutine(PlaceStep.SideConditionRoutine, SideConditionIndex, new IRoutine[] { _pufWaferPickSubRoutine }, new object[] { _side })
.WaitConditionSubRoutine(PlaceStep.SideConditionRoutineWait)
.Run(PlaceStep.RotationGotoLoaderPlaceDown, () => _rotationAxis.PositionStation("LoaderPutDown"), _delay_1ms)
.WaitWithStopCondition(PlaceStep.RotationGotoLoaderPlaceDownWait, CheckRotationPositionStatus, CheckRotationPositionRunStop)
.Run(PlaceStep.FirstPlaceVacuumCheck, () => StartPlaceVacuumCheckRoutine(false, 1), _delay_1ms)
.WaitWithStopCondition(PlaceStep.FirstPlaceVacuumCheckWait, CheckFirstPlaceVacuumCheckRoutineStatus, () => { return false; })
.Run(PlaceStep.SecondPlaceVacuumCheck, StartSecondPlaceVacuumCheckRoutine, _delay_1ms)
.WaitWithStopCondition(PlaceStep.SecondPlaceVacuumCheckWait, CheckPlaceVacuumCheckRoutineEndStatus, CheckSecondPlaceVacuumCheckRoutineStopStatus)
.Run(PlaceStep.VacuumOff, VacuumOff, _delay_1ms)
.End(PlaceStep.End, NullFun, _delay_1ms);
return Runner.Status;
}
///
/// LipSeal Goto Unlock
///
///
private bool LipSealGotoUnlock()
{
if (ModuleHelper.IsInstalled(ModuleName.Loader1))
{
return _loaderCrsAxis.PositionStation("Unlock");
}
else
{
return true;
}
}
///
/// 检验Lip Seal完成状态
///
///
private bool CheckLipSealEndStatus()
{
if (ModuleHelper.IsInstalled(ModuleName.Loader1))
{
return _loaderCrsAxis.Status == RState.End;
}
else
{
return true;
}
}
///
/// 检验Lip Seal完成状态
///
///
private bool CheckLipSealStopStatus()
{
if (ModuleHelper.IsInstalled(ModuleName.Loader1))
{
bool result= _loaderCrsAxis.Status == RState.Failed;
if (result)
{
NotifyError(eEvent.ERR_PUF, $"lipsel axis goto unlock failed", 0);
}
return result;
}
else
{
return true;
}
}
///
/// 检验是否存在Wafer
///
///
private bool CheckWaferPresent()
{
if (_side == SideA)
{
if (!_vacuum.ChuckAWaferPresent)
{
LOG.WriteLog(eEvent.ERR_PUF, Module, $"{_side} has no Wafer");
return false;
}
}
else
{
if (!_vacuum.ChuckBWaferPresent)
{
LOG.WriteLog(eEvent.ERR_PUF, Module, $"{_side} has no Wafer");
return false;
}
}
return true;
}
///
/// Side条件获取SubRoutine索引
///
///
private int SideConditionIndex()
{
if (_flipAxis.CheckPositionIsInStation(_flipAxis.MotionData.MotorPosition, _side))
{
return 1;
}
else
{
return 0;
}
}
///
/// 检验Rotation移动状态
///
///
private bool CheckRotationPositionStatus()
{
return _rotationAxis.Status == RState.End;
}
///
/// 检验Rotation是否还在运动
///
///
private bool CheckRotationPositionRunStop()
{
return _rotationAxis.Status == RState.Failed;
}
///
/// 启动Place Vacuum Check routine
///
///
private bool StartPlaceVacuumCheckRoutine(bool showError, int times)
{
return _pufPlaceVacuumCheckRoutine.Start(_side, showError, times) == RState.Running;
}
///
/// 检验第一次Place Vacuum Check routine运行情况
///
///
private bool CheckFirstPlaceVacuumCheckRoutineStatus()
{
RState rsState = _pufPlaceVacuumCheckRoutine.Monitor();
if (rsState == RState.End)
{
return true;
}
if (rsState == RState.Failed || rsState == RState.Timeout)
{
_isSecondPlaceVacuumCheck = true;
return true;
}
return false;
}
///
/// 启动Place Vacuum Check routine完成状态
///
///
private bool CheckPlaceVacuumCheckRoutineEndStatus()
{
RState rsState = _pufPlaceVacuumCheckRoutine.Monitor();
return rsState == RState.End;
}
///
/// 启动第二次Place Vacuum Check routine
///
///
private bool StartSecondPlaceVacuumCheckRoutine()
{
if (_isSecondPlaceVacuumCheck)
{
return StartPlaceVacuumCheckRoutine(true, 2);
}
else
{
return true;
}
}
///
/// 检验第二次Place Vacuum Check routine错误状态
///
///
private bool CheckSecondPlaceVacuumCheckRoutineStopStatus()
{
RState rState = _pufPlaceVacuumCheckRoutine.Monitor();
if (rState == RState.Failed || rState == RState.Timeout)
{
return true;
}
return false;
}
///
/// 关闭Vacuum
///
///
private bool VacuumOff()
{
if (_side == "SideA")
{
return _vacuum.VacuumAOff();
}
else if (_side == "SideB")
{
return _vacuum.VacuumBOff();
}
return false;
}
///
/// 启动
///
///
///
public RState Start(params object[] objs)
{
_side = objs[0].ToString();
_flipAxis = DEVICE.GetDevice($"{Module}.Flip");
_rotationAxis = DEVICE.GetDevice($"{Module}.Rotation");
_vacuum = DEVICE.GetDevice($"{Module}.Vacuum");
GetCrsAxis();
_isSecondPlaceVacuumCheck = false;
_pufPlaceVacuumCheckRoutine = new PufPlaceVacuumCheckRoutine(Module);
return Runner.Start(Module, "Start Place To Loader");
}
///
/// 获取lipseal Axis
///
private void GetCrsAxis()
{
if (_side==SideA)
{
_loaderCrsAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.LSA");
}
else
{
_loaderCrsAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.LSB");
}
}
}
}