using Aitex.Core.RT.Device;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.Routine;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using MECF.Framework.Common.Beckhoff.Station;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Layout;
using MECF.Framework.Common.Routine;
using MECF.Framework.Common.Utilities;
using MECF.Framework.Common.WaferHolder;
using CyberX8_Core;
using CyberX8_RT.Devices.AXIS;
using CyberX8_RT.Devices.AXIS.CANOpen;
using CyberX8_RT.Devices.Facilities;
using CyberX8_RT.Devices.Loader;
using CyberX8_RT.Devices.TransPorter;
using CyberX8_RT.Modules.Loader;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CyberX8_RT.Devices.Metal;
using CyberX8_RT.Devices.Rinse;
namespace CyberX8_RT.Modules.Transporter
{
public class TransporterPickDownToRoutine : RoutineBase, IRoutine
{
private enum PutDownStep
{
CheckPreStatus,
TargetCellUnclamp,
TargetCellUnclampWait,
ElevatorUp,
ElevatorUpWait,
ImmobilizeExtend,
ImmobilizeExtendWait,
SafeMoveTo,
CheckMoveToStatus,
GantryPosition,
GantryPositiolWait,
CalculatePlaceSpeed,
PlaceDelay,
ImmobilizeRetract,
ImmobilizeRetractWait,
ElevatorPosition,
ElevatorPositionWait,
UnlockClamp,
UnlockClampWait,
ElevatorLow,
ElevatorLowWait,
ConfirmWHPresent,
LockClamp,
LockClampWait,
UpdateWaferHolder,
GantryPositionPark,
GantryPositionParkWait,
End
}
#region 内部变量
private string _cellName;
private JetAxisBase _gantryAxis;
private JetAxisBase _elevatorAxis;
private LoaderEntity _loaderEntity;
private JetAxisBase _loaderRotationAxis;
private SystemFacilities _facilities;
private TransporterUnlockRoutine _unlockRoutine;
private TransporterLockRoutine _lockRoutine;
private TransporterCommon _transporterCommon;
private TransporterExtendRoutine _extendRoutine;
private TransporterRetractRoutine _retractRoutine;
private TransporterConflictRoutine _conflictRoutine;
private LoaderPreTransferUnclampRoutine _preTransferUnclampRoutine;
ProcessLayoutCellItem _cellItem;
private int _placeTime;
private int _placeDelayTime;
private int _velocity;
private int _acceleration;
#endregion
///
/// 构造函数
///
///
public TransporterPickDownToRoutine(string module) : base(module)
{
}
///
/// 中止
///
public void Abort()
{
Runner.Stop("Manual Abort");
}
///
/// 监控
///
///
public RState Monitor()
{
Runner.Run(PutDownStep.CheckPreStatus,CheckStartPreConfition,_delay_1ms)
.Run(PutDownStep.TargetCellUnclamp, TargetCellUnclamp, _delay_1ms)
.WaitWithStopCondition(PutDownStep.TargetCellUnclampWait,TargetCellUnclampEndStatus,TargetCellUnclampStopStatus)
//1.1 Elevator Position Up
.Run(PutDownStep.ElevatorUp, ElevatorGotoUp, _delay_1ms)
.WaitWithStopCondition(PutDownStep.ElevatorUpWait, CheckVerticalPositionStatus, CheckVerticalPositionRunStop)
//1.2 Immobilized Extend
.Run(PutDownStep.ImmobilizeExtend, () => { return _extendRoutine.Start(null) == RState.Running; }, NullFun, _delay_1ms)
.WaitWithStopCondition(PutDownStep.ImmobilizeExtendWait, () => { return CommonFunction.CheckRoutineEndState(_extendRoutine); },
CheckImmobilizeRoutineStopStatus)
//1.3 Move to 安全
.Run(PutDownStep.SafeMoveTo, SafeMoveTo, _delay_1ms)
.WaitWithStopCondition(PutDownStep.CheckMoveToStatus, () => CommonFunction.CheckRoutineEndState(_conflictRoutine),
CheckSafeMoveToStopStatus)
//1.3 Gantry 移动
.Run(PutDownStep.GantryPosition, GantryPositionToCell, _delay_1ms)
.WaitWithStopCondition(PutDownStep.GantryPositiolWait, CheckGantryPositionStatus, CheckGantryPositionRunStop)
//1.4 确认Place 速度和加速度
.Run(PutDownStep.CalculatePlaceSpeed, CalculatePownDownSpeed, _delay_1ms)
//1.5 Pickup delay
.Delay(PutDownStep.PlaceDelay, _placeDelayTime * 1000)
//1.6 Immobilize Retract
.Run(PutDownStep.ImmobilizeRetract, () => { return _retractRoutine.Start(null) == RState.Running; }, NullFun, _delay_1ms)
.WaitWithStopCondition(PutDownStep.ImmobilizeRetractWait, ()=> CommonFunction.CheckRoutineEndState(_retractRoutine),
CheckRetractStopStatus)
//.WaitWithStopCondition(PutDownStep.CellRetractedWait, CheckCellRetractRoutineEndState, CheckCellRetractRoutineStopState)
//1.7 Elevator 移动至cell
.Run(PutDownStep.ElevatorPosition, () => { return VerticalPositionToCell(); }, NullFun, _delay_1ms)
.WaitWithStopCondition(PutDownStep.ElevatorPositionWait, CheckVerticalPositionStatus, CheckVerticalPositionRunStop)
//1.8 Unlock clamp
.Run(PutDownStep.UnlockClamp, () => { return _unlockRoutine.Start(null) == RState.Running; },_delay_1ms)
.WaitWithStopCondition(PutDownStep.UnlockClampWait,()=>CommonFunction.CheckRoutineEndState(_unlockRoutine),
CheckUnlockRoutineStopStatus)
//1.9 Elevator Position Low
.Run(PutDownStep.ElevatorLow, ElevatorGotoLow, _delay_1ms)
.WaitWithStopCondition(PutDownStep.ElevatorLowWait, CheckVerticalPositionStatus, CheckVerticalPositionRunStop)
//2.0 确认WhPresent信号
.Wait(PutDownStep.ConfirmWHPresent,ConfirmWHPresentSensorOff,_delay_2s)
//2.1 Lock clamp
.Run(PutDownStep.LockClamp, () => { return _lockRoutine.Start(null) == RState.Running; },_delay_1ms)
.WaitWithStopCondition(PutDownStep.LockClampWait,()=>CommonFunction.CheckRoutineEndState(_lockRoutine),
CheckLockRoutineStopStatus)
//2.2 Wafer Holder location update
.Run(PutDownStep.UpdateWaferHolder,WaferHolderTransfer,_delay_1ms)
//2.3 Gantry Position To Park
.Run(PutDownStep.GantryPositionPark,GantryBackToPark,_delay_1ms)
.WaitWithStopCondition(PutDownStep.GantryPositionParkWait,CheckGantryParkPositionStatus,CheckGantryParkPositionRunStop)
.End(PutDownStep.End,NullFun,100);
return Runner.Status;
}
///
/// 目标cell unclamp
///
///
private bool TargetCellUnclamp()
{
if (_cellName == "Loader")
{
bool result= _preTransferUnclampRoutine.Start() == RState.Running;
if (!result)
{
NotifyError(eEvent.ERR_TRANSPORTER, "Loader Unclamp failed", 0);
}
return result;
}
else
{
_cellItem = ProcessLayoutManager.Instance.GetProcessLayoutCellItemByModuleName(_cellName);
if (_cellItem != null)
{
if (Enum.TryParse(_cellItem.ModuleName, out ModuleName cellModuleName))
{
if (ModuleHelper.IsRinse(cellModuleName))
{
RinseDevice rinseDevice = DEVICE.GetDevice(_cellItem.ModuleName);
if (rinseDevice != null)
{
bool result = rinseDevice.WaferHolderClampValveOff();
if (!result)
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{_cellItem.ModuleName} Clamp off failed", 0);
}
return result;
}
}
else if (ModuleHelper.IsMetal(cellModuleName))
{
MetalCellDevice metalCellDevice = DEVICE.GetDevice(_cellItem.ModuleName);
if (metalCellDevice != null)
{
bool result = metalCellDevice.WaferHolderClampOff();
if (!result)
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{_cellItem.ModuleName} Clamp off failed", 0);
}
return result;
}
}
}
}
}
return true;
}
///
/// 目标Cell Unclamp状态
///
///
private bool TargetCellUnclampEndStatus()
{
if(_cellName=="Loader")
{
return CommonFunction.CheckRoutineEndState(_preTransferUnclampRoutine);
}
else
{
_cellItem = ProcessLayoutManager.Instance.GetProcessLayoutCellItemByModuleName(_cellName);
if (_cellItem != null)
{
if (Enum.TryParse(_cellItem.ModuleName, out ModuleName cellModuleName))
{
if (ModuleHelper.IsRinse(cellModuleName))
{
RinseDevice rinseDevice = DEVICE.GetDevice(_cellItem.ModuleName);
if (rinseDevice != null)
{
return rinseDevice.RinseData.WaferHolderClamp==false;
}
}
else if (ModuleHelper.IsMetal(cellModuleName))
{
MetalCellDevice metalCellDevice = DEVICE.GetDevice(_cellItem.ModuleName);
if (metalCellDevice != null)
{
return metalCellDevice.ClampOff;
}
}
}
}
}
return true;
}
///
/// 目标Cell Unclamp运行中止状态
///
///
private bool TargetCellUnclampStopStatus()
{
if (_cellName == "Loader")
{
bool result = CommonFunction.CheckRoutineStopState(_preTransferUnclampRoutine);
if (result)
{
NotifyError(eEvent.ERR_TRANSPORTER, "Loader Unclamp failed", 0);
}
return result;
}
return false;
}
///
/// Elevator goto Up
///
///
private bool ElevatorGotoUp()
{
bool result= _elevatorAxis.PositionStation("UP", false);
if (!result)
{
NotifyError(eEvent.ERR_TRANSPORTER, "elevator goto up failed", 0);
}
return result;
}
///
/// 检验前置条件
///
///
private bool CheckPreCondition()
{
if(!_gantryAxis.IsSwitchOn)
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} gantry axis is not switch on ", -1);
return false;
}
if (!_gantryAxis.IsHomed)
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} gantry axis is not homed ",-1);
return false;
}
if (!_elevatorAxis.IsSwitchOn)
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} elevator axis is not switch on ", -1);
return false;
}
if (!_elevatorAxis.IsHomed)
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} elevator axis is not homed ",-1);
return false;
}
return true;
}
///
/// 安全避障移动
///
///
private bool SafeMoveTo()
{
_cellItem = ProcessLayoutManager.Instance.GetProcessLayoutCellItemByModuleName(_cellName);
string stationName = _cellName;
if (_cellItem != null)
{
if (_cellName.ToLower() != "loader" && _cellName.ToLower() != "park")
{
stationName = $"Cell{_cellItem.CellId}";
}
}
else
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{_cellName} not in layout",0);
return false;
}
var result = _gantryAxis.GetPositionByStation(stationName);
if (result.success)
{
bool isPositive = false;
if (_gantryAxis.MotionData.MotorPosition < result.position)
{
isPositive = true;
}
return _conflictRoutine.Start(result.position, isPositive) == RState.Running;
}
else
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{_cellName} not in station list",0);
return false;
}
}
///
/// 检验安全避让异常结束状态
///
///
private bool CheckSafeMoveToStopStatus()
{
bool result = CommonFunction.CheckRoutineStopState(_conflictRoutine);
if (result)
{
NotifyError(eEvent.ERR_TRANSPORTER, "Safe Move failed", 0);
}
return result;
}
///
/// Gantry Position To cell
///
///
private bool GantryPositionToCell()
{
_cellItem= ProcessLayoutManager.Instance.GetProcessLayoutCellItemByModuleName(_cellName);
bool result = false;
if (_cellItem != null)
{
if (_cellName.ToLower() != "loader"&&_cellName.ToLower()!="park")
{
result= _gantryAxis.PositionStation($"Cell{_cellItem.CellId}",false);
}
else
{
result = _gantryAxis.PositionStation(_cellName,false);
}
if (!result)
{
NotifyError(eEvent.ERR_TRANSPORTER, "gantry axis motion failed", 0);
}
return result;
}
else
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{_cellName} not in layout",0);
return false;
}
}
///
/// Elevator Position to cell
///
///
private bool VerticalPositionToCell()
{
bool result= false;
if( _cellItem != null )
{
if (_cellName.ToLower()!="loader")
{
result= _elevatorAxis.PositionStation($"Cell{_cellItem.CellId}",false,_velocity,_acceleration,_acceleration);
}
else
{
result= _elevatorAxis.PositionStation(_cellName,false,_velocity,_acceleration,_acceleration);
}
if (!result)
{
NotifyError(eEvent.ERR_TRANSPORTER, "elevator axis motion failed", 0);
}
return result;
}
else
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{_cellName} not in layout",0);
return false;
}
}
///
/// 检验Vertical移动状态
///
///
private bool CheckVerticalPositionStatus()
{
return _elevatorAxis.Status == RState.End;
}
///
/// 检验Vertical是否还在运动
///
///
private bool CheckVerticalPositionRunStop()
{
bool result= _elevatorAxis.Status == RState.Failed||_elevatorAxis.Status==RState.Timeout;
if(result)
{
NotifyError(eEvent.ERR_TRANSPORTER, "elevator axis motion failed", 0);
}
return result;
}
///
/// 检验Immobile异常状态
///
///
private bool CheckImmobilizeRoutineStopStatus()
{
bool result= CommonFunction.CheckRoutineStopState(_extendRoutine);
if (result)
{
NotifyError(eEvent.ERR_TRANSPORTER, "extend failed", 0);
}
return result;
}
///
/// 检验unlock异常状态
///
///
private bool CheckUnlockRoutineStopStatus()
{
bool result = CommonFunction.CheckRoutineStopState(_unlockRoutine);
if (result)
{
NotifyError(eEvent.ERR_TRANSPORTER, "unlock failed", 0);
}
return result;
}
///
/// Elevator goto low
///
///
private bool ElevatorGotoLow()
{
bool result= _elevatorAxis.PositionStation("LOW", false);
if(!result)
{
NotifyError(eEvent.ERR_TRANSPORTER, "elevator goto low failed", 0);
}
return result;
}
///
/// 检验Gantry移动状态
///
///
private bool CheckGantryPositionStatus()
{
return _gantryAxis.Status == RState.End;
}
///
/// 检验Gantry是否还在运动
///
///
private bool CheckGantryPositionRunStop()
{
bool result= _gantryAxis.Status == RState.Failed||_gantryAxis.Status==RState.Timeout;
if(result)
{
NotifyError(eEvent.ERR_TRANSPORTER, "gantry axis motion failed", 0);
}
return result;
}
///
/// 计算放下速度
///
///
private bool CalculatePownDownSpeed()
{
if(_placeTime==0)
{
return true;
}
BeckhoffStationAxis stationAxis = BeckhoffStationLocationManager.Instance.GetStationAxis(Module, "Elevator", 0);
Station upStation = stationAxis.Stations.Find(O => O.Name.EndsWith("UP")); Station cellStation = null;
if (_cellName == "Loader")
{
cellStation = stationAxis.Stations.Find(O => O.Name.EndsWith("Loader"));
}
else
{
cellStation = stationAxis.Stations.Find(O => O.Name.EndsWith($"Cell{_cellItem.CellId}"));
}
if (upStation==null)
{
NotifyError(eEvent.ERR_TRANSPORTER, "UP is not in Station List",0);
return false;
}
if(cellStation==null)
{
NotifyError(eEvent.ERR_TRANSPORTER, $"Cell{_cellItem.CellId} is not in Station List",0);
return false;
}
if(!double.TryParse(cellStation.Position,out double cellStationPosition))
{
NotifyError(eEvent.ERR_TRANSPORTER, $"Cell{_cellItem.CellId} Station Position is invalid",0);
return false;
}
if (!double.TryParse(upStation.Position, out double upStationPosition))
{
NotifyError(eEvent.ERR_TRANSPORTER, $"Cell{_cellItem.CellId} Station Position is invalid",0);
return false;
}
int distance =(int)(Math.Round(Math.Abs(cellStationPosition - upStationPosition)));
double tmpVelocity = (double) distance/ _placeTime;
_velocity = _elevatorAxis.CalculateMultiplySpeedRatio(_elevatorAxis.CalculateValueMultiplyScale(tmpVelocity));
double tmpAccelaration = (double)(2 * distance) / Math.Pow(_placeTime, 2);
_acceleration = _elevatorAxis.CalculateMultiplyAccelerationRatio(_elevatorAxis.CalculateValueMultiplyScale(tmpAccelaration));
LOG.WriteBackgroundLog(eEvent.INFO_TRANSPORTER, Module, "adjust profile speed");
return true;
}
///
/// 检验Retract 异常状态
///
///
private bool CheckRetractStopStatus()
{
bool result = CommonFunction.CheckRoutineStopState(_retractRoutine);
if (result)
{
NotifyError(eEvent.ERR_TRANSPORTER, "retract failed", 0);
}
return result;
}
///
/// 更新WaferHolder移动信息
///
///
private bool WaferHolderTransfer()
{
bool result= WaferHolderManager.Instance.TransferWaferHolder(Module,Module, _cellName);
if (!result)
{
NotifyError(eEvent.ERR_TRANSPORTER, "tranfer waferHolder message failed", 0);
}
else
{
if (Singleton.Instance.IsAutoRunning)
{
WaferHolderInfo waferHolderInfo = WaferHolderManager.Instance.GetWaferHolder(_cellName);
if (waferHolderInfo != null)
{
string strTime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
waferHolderInfo.SchedulerModules.Add($"{strTime} {Module} => {_cellName}");
}
}
}
return result;
}
///
/// 确认WH Present Sensor off
///
///
private bool ConfirmWHPresentSensorOff()
{
bool result= !_transporterCommon.TransporterData.WhPresent1 &&!_transporterCommon.TransporterData.WhPresent2;
if(!result)
{
NotifyError(eEvent.ERR_TRANSPORTER, "confirm WS Present sensor failed",0);
}
return result;
}
///
/// 检验Lock异常状态
///
///
private bool CheckLockRoutineStopStatus()
{
bool result = CommonFunction.CheckRoutineStopState(_lockRoutine);
if(result)
{
NotifyError(eEvent.ERR_TRANSPORTER, "lock failed", 0);
}
return result;
}
///
/// Gabtry是否需要回到
///
///
private bool NeedGantryBackToPark()
{
switch(_cellName)
{
case "Loader":
case "Prewet":
return true;
default:
return false;
}
}
///
/// Gantry 回至Park
///
///
private bool GantryBackToPark()
{
if (NeedGantryBackToPark())
{
bool result= _gantryAxis.PositionStation("Park", false);
if(!result)
{
NotifyError(eEvent.ERR_TRANSPORTER, "gantry back to park failed",0);
}
return result;
}
else
{
return true;
}
}
///
/// 检验Gantry Park移动状态
///
///
private bool CheckGantryParkPositionStatus()
{
if (NeedGantryBackToPark())
{
return _gantryAxis.Status == RState.End;
}
else
{
return true;
}
}
///
/// 检验Gantry Park是否还在运动
///
///
private bool CheckGantryParkPositionRunStop()
{
if (NeedGantryBackToPark())
{
bool result = _gantryAxis.Status == RState.Failed||_gantryAxis.Status==RState.Timeout;
if(result)
{
NotifyError(eEvent.ERR_TRANSPORTER, "gantry motion failed", 0);
}
return result;
}
else
{
return false;
}
}
///
/// 启动
///
///
///
public RState Start(params object[] objs)
{
_cellName = objs[0].ToString();
_velocity = 0;
_acceleration = 0;
InitializeParameters();
string preConfig = SC.GetConfigPreContent(_cellName);
if (SC.ContainsItem($"{preConfig}.PlaceTimeSeconds"))
{
_placeTime = SC.GetValue($"{preConfig}.PlaceTimeSeconds");
}
if (SC.ContainsItem($"{preConfig}.PlaceDelaySeconds"))
{
_placeDelayTime = SC.GetValue($"{preConfig}.PlaceDelaySeconds");
}
return Runner.Start(Module, $"Pun Down To {_cellName}");
}
///
/// 初始化参数
///
private void InitializeParameters()
{
_elevatorAxis = DEVICE.GetDevice($"{Module}.Elevator");
_gantryAxis = DEVICE.GetDevice($"{Module}.Gantry");
_loaderEntity = Singleton.Instance.GetModule(ModuleName.Loader1.ToString());
_loaderRotationAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.Rotation");
_facilities = DEVICE.GetDevice("System.Facilities");
_unlockRoutine = new TransporterUnlockRoutine(Module);
_lockRoutine = new TransporterLockRoutine(Module);
_extendRoutine = new TransporterExtendRoutine(Module);
_retractRoutine = new TransporterRetractRoutine(Module);
_conflictRoutine = new TransporterConflictRoutine(Module);
_transporterCommon = DEVICE.GetDevice($"{Module}.Common");
_preTransferUnclampRoutine = new LoaderPreTransferUnclampRoutine(ModuleName.Loader1.ToString());
}
///
/// 启动校验条件
///
///
private bool CheckStartPreConfition()
{
bool result = CheckPreCondition();
if(!result)
{
return false;
}
double elevatorPosition = _elevatorAxis.MotionData.MotorPosition;
if (!_elevatorAxis.CheckPositionIsInStation(elevatorPosition, "Up"))
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} elevator axis {elevatorPosition} is not int Up station",-1);
return false;
}
if (!_loaderEntity.IsHomed)
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{ModuleName.Loader1} is not homed", -1);
return false;
}
if (_cellName == "Loader")
{
double loaderRotationPosition = _loaderRotationAxis.MotionData.MotorPosition;
if (!_loaderRotationAxis.CheckPositionIsInStation(loaderRotationPosition, "TRNPA") &&
!_loaderRotationAxis.CheckPositionIsInStation(loaderRotationPosition, "TRNPB"))
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{ModuleName.Loader1} rotation axis {loaderRotationPosition} is not int TRNPA or TRNPB station", -1);
return false;
}
}
if (!WaferHolderManager.Instance.HasWaferHolder(Module))
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} does not has wafer Shuttle",-1);
return false;
}
if (WaferHolderManager.Instance.HasWaferHolder(_cellName))
{
NotifyError(eEvent.ERR_TRANSPORTER, $"Cell {_cellName} already has wafer Shuttle", -1);
return false;
}
//检验Facilities
var faciltiesResult = _facilities.CheckCDA();
if (!faciltiesResult.result)
{
NotifyError(eEvent.ERR_TRANSPORTER, faciltiesResult.reason, -1);
return false;
}
//检验Lock和WH Present Sensor
if (!_transporterCommon.TransporterData.Locked1)
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} lock1 sensor is off ", -1);
return false;
}
if (!_transporterCommon.TransporterData.Locked2)
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} lock2 sensor is off ",-1);
return false;
}
if (!_transporterCommon.TransporterData.WhPresent1)
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} WS Present1 sensor is off ", -1);
return false;
}
if (!_transporterCommon.TransporterData.WhPresent2)
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} WS Present2 sensor is off ",-1);
return false;
}
return true;
}
///
/// 重试
///
///
public RState Retry(int step)
{
InitializeParameters();
List preStepIds = new List();
return Runner.Retry(PutDownStep.CheckPreStatus, preStepIds, Module, "PickUp Moveto Retry");
}
///
/// 检验前面Unload完成状态
///
///
public bool CheckCompleteCondition(int index)
{
TransporterEntity transporterEntity = Singleton.Instance.GetModule(Module);
if (transporterEntity.WaferHolderInfo != null)
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} has waferholder", index);
return false;
}
if (!WaferHolderManager.Instance.HasWaferHolder(_cellName))
{
NotifyError(eEvent.ERR_TRANSPORTER, $"{_cellName} does not have waferholder", index);
return false;
}
return true;
}
}
}