using System; using Aitex.Core.Common; using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Sorter.Common; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robot; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts; using Aitex.Sorter.RT.SorterCommonFrame.Modules; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Aligners.AlignersBase; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase; using System.Threading; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase; using Aitex.Core.RT.Log; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Flipper.FlipperBase; namespace Aitex.Sorter.RT.SorterCommonFrame.Routines { public class PlaceRoutine : CommonRoutineSorter, IRoutine { enum Place { QueryState, TurnReady, WaitTurnReady, CheckBeforePlace, WaitTurnOver, UnGrip, WaitUnGrip, PlaceWafer, WaitPlace, Grip, WaitGrip, CheckAfterPlace, RetractRobot, WaitRetractRobot, TurnOver, Finish, RaiseAligner, SetAlignerWaferSize, CheckWaferOnTurnOver, } public PlaceRoutine(string module, string name) { Module = module; Name = name; } public bool Initalize() { Reset(); IsRoutineActive = false; return true; } public ModuleName Station { get; set; } public ModuleName RobotModulename { get; set; } = ModuleName.Robot; public int Slot { get; set; } public Hand Blade { get; set; } private bool _isTurnOverGripped; private bool _isTurnOverOn0deg; private bool _isNeedAlignerPrepare = false; private bool _isNeedToCheckAlginerWaferSize = false; private WaferSize _currentWaferSize; public Result Start(params object[] objs) { Reset(); if(WaferManager.Instance.CheckHasWafer(Station, Slot)) { EV.PostWarningLog(ModuleName.System.ToString(), $"Can not execute {Name}, destination:{Station} detect wafer."); return Result.FAIL; } if (Station == ModuleName.TurnOverStation && _ioTurnOver.IsPlacement) { EV.PostAlarmLog(ModuleName.System.ToString(), $"Can not execute {Name}, destination:{Station} detect wafer."); return Result.FAIL; } Robot = DEVICE.GetDevice(RobotModulename.ToString()); FixedTurnOverPosition = SC.ContainsItem("Process.FixedTurnOverPosition") ? SC.GetValue("Process.FixedTurnOverPosition") : true; if (Blade == Hand.Blade1 && !Robot.Blade1Enable) { EV.PostAlarmLog(ModuleName.System.ToString(), $"Can not {Name}, {Blade} is not enable"); return Result.FAIL; } if (Blade == Hand.Blade2 && !Robot.Blade2Enable) { EV.PostAlarmLog(ModuleName.System.ToString(), $"Can not {Name}, {Blade} is not enable"); return Result.FAIL; } if (!RobotOffsetConfig.Instance.GetPlaceOffset(Station, ref _offsetX, ref _offsetY, ref _offsetZ, out string reason)) { EV.PostWarningLog(ModuleName.System.ToString(), $"Can not execute {Name}, {reason}"); return Result.FAIL; } if (ModuleHelper.IsTurnOverStation(Station)) { _isTurnOverGripped = _ioTurnOver.CurrentGripperPositon == GripPosEnum.Close; _isTurnOverOn0deg = _ioTurnOver.CurrentFlipperPosition == FlipperPosEnum.FrontSide; if(_ioTurnOver.IsPlacement) { EV.PostWarningLog(ModuleName.System.ToString(), $"Can not execute {Name}, Wafer on flipper."); return Result.FAIL; } } if (ModuleHelper.IsAligner(Station)) { if (!DEVICE.GetDevice(Station.ToString()).IsReady()) { EV.PostAlarmLog(Station.ToString(), $"{Station} is not ready."); return Result.FAIL; } if(DEVICE.GetDevice(Station.ToString()).IsWaferPresent(0)) { EV.PostAlarmLog(Station.ToString(), $"{Station} wafer present."); return Result.FAIL; } _isNeedAlignerPrepare = Aligner.IsNeedPrepareBeforePlaceWafer(); if (Blade == Hand.Both) { _currentWaferSize = WaferManager.Instance.GetWaferSize(Robot.RobotModuleName, 0); _isNeedToCheckAlginerWaferSize = Aligner.IsNeedChangeWaferSize(_currentWaferSize); } else { _currentWaferSize = WaferManager.Instance.GetWaferSize(Robot.RobotModuleName, (int)Blade); _isNeedToCheckAlginerWaferSize = Aligner.IsNeedChangeWaferSize(_currentWaferSize); } } if (ModuleHelper.IsLoadPort(Station)) { var lp = DEVICE.GetDevice(Station.ToString()); if (lp.IsForbidAccessSlotAboveWafer() && Slot > 0 && WaferManager.Instance.CheckHasWafer(Station, Slot - 1)) { EV.PostAlarmLog(ModuleName.System.ToString(), "Access dennied to the slot above wafer."); return Result.FAIL; } if (!lp.IsEnableTransferWafer(out reason)) { EV.PostAlarmLog(ModuleName.System.ToString(), $"{Station} is not ready to transfer wafer:{reason}."); return Result.FAIL; } } EV.PostInfoLog("System", $"Start placing wafer to station:{Station} slot:{Slot + 1} with blade {Blade}"); IsRoutineActive = true; return Monitor(); } public Result Monitor() { if (!IsRoutineActive) return Result.DONE; var ret = MonitorRoutine(); if (ret == Result.FAIL) { IsRoutineActive = false; } if (ret == Result.DONE) { IsRoutineActive = false; } return ret; } private Result MonitorRoutine() { try { if (!ModuleHelper.IsTurnOverStation(Station)) { if (ModuleHelper.IsAligner(Station) && _isNeedToCheckAlginerWaferSize) { RtAlignerSetWaferSize((int)Place.SetAlignerWaferSize, _currentWaferSize, Aligner.TimeLimitAlignWafer, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } } if (ModuleHelper.IsAligner(Station) && _isNeedAlignerPrepare) { RtAlignerPrepareAccept((int)Place.RaiseAligner, Aligner.TimeLimitAlignWafer, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } } RtPlaceWafer((int)Place.PlaceWafer, "Place wafer", Station, Slot, Blade, Robot.RobotCommandTimeout, _offsetX, _offsetY, _offsetZ, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } } else { if (_isTurnOverGripped) { //RtTurnOverUnGripWafer((int)Place.UnGrip, Notify, Stop); //if (ExecuteResult.Item1) //{ // if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; // if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; // if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; // if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; //} //RtWaitTurnOverUnGrip((int)Place.WaitUnGrip, _ioTurnOver, _ioTurnOver.TimelimitAction, Notify, Stop); //if (ExecuteResult.Item1) //{ // if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; // if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; // if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; // if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; //} } if (FixedTurnOverPosition) { if (!_isTurnOverOn0deg) { RtTurnOverTurnBack((int)Place.TurnReady, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtWaitTurnOverTurnTo0((int)Place.WaitTurnReady, _ioTurnOver, _ioTurnOver.TimelimitAction, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } } RtTurnOverUnGripWafer((int)Place.UnGrip, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtWaitTurnOverUnGrip((int)Place.WaitUnGrip, _ioTurnOver, _ioTurnOver.TimelimitAction, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtDeliverWaferToGrip((int)Place.PlaceWafer, Station, Slot, Blade, Robot.RobotCommandTimeout, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtTurnOverGripWafer((int)Place.Grip, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtWaitTurnOverGrip((int)Place.WaitGrip, _ioTurnOver, _ioTurnOver.TimelimitAction, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtRetractRobotArmForTurning((int)Place.RetractRobot, Station, Slot, Blade, Robot.RobotCommandTimeout, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtCheckWaferOnTurn((int)Place.CheckWaferOnTurnOver, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtTurnOverTurn((int)Place.TurnOver, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } } else { RtTurnOverUnGripWafer((int)Place.UnGrip, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtWaitTurnOverUnGrip((int)Place.WaitUnGrip, _ioTurnOver, _ioTurnOver.TimelimitAction, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } if (_isTurnOverOn0deg) { RtDeliverWaferToGrip((int)Place.PlaceWafer, Station, Slot, Blade, Robot.RobotCommandTimeout, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtTurnOverGripWafer((int)Place.Grip, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtWaitTurnOverGrip((int)Place.WaitGrip, _ioTurnOver, _ioTurnOver.TimelimitAction, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtRetractRobotArmForTurning((int)Place.RetractRobot, Station, Slot, Blade, Robot.RobotCommandTimeout, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtCheckWaferOnTurn((int)Place.CheckWaferOnTurnOver, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } if (_ioTurnOver.CurrentFlipperPosition == FlipperPosEnum.FrontSide) { RtTurnOverTurn((int)Place.TurnOver, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } } if (_ioTurnOver.CurrentFlipperPosition == FlipperPosEnum.BackSide) { RtTurnOverTurnBack((int)Place.TurnOver, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } } } else { RtDeliverWaferToGrip((int)Place.PlaceWafer, Station, Slot, Blade, Robot.RobotCommandTimeout, Notify, Stop, PutWaferOffsetForTurnOverOn180()); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtTurnOverGripWafer((int)Place.Grip, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtWaitTurnOverGrip((int)Place.WaitGrip, _ioTurnOver, _ioTurnOver.TimelimitAction, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtRetractRobotArmForTurning((int)Place.RetractRobot, Station, Slot, Blade, Robot.RobotCommandTimeout, Notify, Stop, PutWaferOffsetForTurnOverOn180()); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } RtCheckWaferOnTurn((int)Place.CheckWaferOnTurnOver, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } if (_ioTurnOver.CurrentFlipperPosition == FlipperPosEnum.FrontSide) { RtTurnOverTurn((int)Place.TurnOver, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } } if (_ioTurnOver.CurrentFlipperPosition == FlipperPosEnum.BackSide) { RtTurnOverTurnBack((int)Place.TurnOver, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } } } } } RtUpdateWaferSingleStepProcessState((int)Place.Finish, "Update step process state", Station, Slot, Blade, EnumWaferProcessStatus.Wait, Notify, Stop); if (ExecuteResult.Item1) { if (ExecuteResult.Item2 == Result.RUN) return Result.RUN; if (ExecuteResult.Item2 == Result.FAIL) return Result.FAIL; if (ExecuteResult.Item2 == Result.TIMEOUT) return Result.FAIL; if (ExecuteResult.Item2 == Result.DONE) return Result.DONE; } EV.PostInfoLog("System", $"Complete placing wafer to station:{Station} slot:{Slot + 1} with blade {Blade}."); IsRoutineActive = false; return Result.DONE; } catch (Exception ex) { LOG.Write(ex); EV.PostAlarmLog("System", $"Failed to place wafer to station:{Station} slot:{Slot + 1} with blade {Blade}."); IsRoutineActive = false; return Result.FAIL; } } /// /// prepare process failed /// /// /// } }