using System; using Aitex.Core.RT.Event; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.Sorter.Common; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Schedulers; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots; using MECF.Framework.RT.EquipmentLibrary.LogicUnits; using MECF.Framework.RT.ModuleLibrary.PMModules; using MECF.Framework.RT.ModuleLibrary.SystemModules; namespace JetEfemLib.Efems { public class EfemPickAndPlaceRoutine : ModuleRoutineBase, IStepRoutine { enum RoutineStep { CheckBeforePick, PickWafer, CheckBeforePlace, PlaceWafer, PostTransfer, PickExtend, PickRetract, PlaceExtend, PlaceRetract, PickLiftUp, PickLiftDown, PlaceLiftUp, PlaceLiftDown, End, } private EfemModule _robotModule; private ITransferTarget _target; private Hand _pickBlade; private Hand _placeBlade; private ModuleName _targetModule; private int _pickSlot; private int _placeSlot; private int _pickTimeout; private int _placeTimeout; private int _postTransferTimeout; public EfemPickAndPlaceRoutine(EfemModule robotModule) : base(ModuleName.EfemRobot.ToString()) { Name = "Pick"; _robotModule = robotModule; } public RState Start(params object[] objs) { _pickTimeout = SC.GetValue("EFEM.EfemRobot.PickTimeout") * 1000; _placeTimeout = SC.GetValue("EFEM.EfemRobot.PlaceTimeout"); if (ModuleHelper.IsPm(_targetModule)) { _postTransferTimeout = SC.GetValue($"PM.PostTransferTimeout"); } Reset(); if (!WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, (int)_pickBlade)) { EV.PostWarningLog(Module, $"Can not pick by {_pickBlade}, found wafer on"); return RState.Failed; } if (!WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, (int)_placeBlade)) { EV.PostWarningLog(Module, $"Can not place by {_placeBlade}, no wafer on"); return RState.Failed; } if (_pickSlot != _placeSlot) { if (!WaferManager.Instance.CheckHasWafer(_targetModule, _pickSlot)) { EV.PostWarningLog(Module, $"Can not pick from {_targetModule} slot {_pickSlot + 1}, no wafer on"); return RState.Failed; } if (!WaferManager.Instance.CheckNoWafer(_targetModule, _placeSlot)) { EV.PostWarningLog(Module, $"Can not place to {_targetModule} slot {_placeSlot + 1}, found wafer on"); return RState.Failed; } } else { if (!WaferManager.Instance.CheckHasWafer(_targetModule, _placeSlot)) { { EV.PostWarningLog(Module, $"Can not pick&place from {_targetModule} slot {_placeSlot + 1}, no wafer on"); return RState.Failed; } } } Notify($"Start, swap wafer,pick: {_pickBlade} slot {_pickSlot + 1}, place: {_placeBlade} slot {_placeSlot+1}"); return Runner.Start(ModuleName.EfemRobot.ToString(), Name); } public void Init(ModuleName targetModule, Hand pickBlade, int pickSlot, Hand placeBlade, int placeSlot) { _pickBlade = pickBlade; _placeBlade = placeBlade; _targetModule = targetModule; _pickSlot = pickSlot; _placeSlot = placeSlot; //_target = Singleton.Instance.Modules[targetModule] as ITransferTarget; } public void Abort() { if (_target != null) { _target.NoteTransferStop(ModuleName.EfemRobot, Hand.Blade1, 0, EnumTransferType.Pick); } _target = null; Notify("Abort"); } public RState Monitor() { if (ModuleHelper.IsPm(_targetModule)) { Runner.Wait(RoutineStep.CheckBeforePick, CheckBeforePick) .Run(RoutineStep.PickExtend, RobotExtendForPick, CheckRobotExtend, _pickTimeout) .Run(RoutineStep.PickLiftDown, MovePinDown, CheckMovePinDown, _pickTimeout) .Run(RoutineStep.PickRetract, RobotRetractForPick, CheckRobotRetract, _pickTimeout) .Run(RoutineStep.PlaceExtend, RobotExtendForPlace, CheckRobotExtend, _pickTimeout) .Run(RoutineStep.PlaceLiftUp, MovePinUp, CheckMovePinUp, _pickTimeout) .Run(RoutineStep.PlaceRetract, RobotRetractForPlace, CheckRobotRetract, _pickTimeout) .Run(RoutineStep.PostTransfer, PostTransfer, CheckPostTransfer, _postTransferTimeout) .End(RoutineStep.End, NullFun, _delay_50ms); } else { Runner.Wait(RoutineStep.CheckBeforePick, CheckBeforePick) .Run(RoutineStep.PickWafer, PickWafer, CheckPickWafer, _pickTimeout) .Wait(RoutineStep.CheckBeforePlace, CheckBeforePlace) .Run(RoutineStep.PlaceWafer, PlaceWafer, CheckPlaceWafer, _pickTimeout) .End(RoutineStep.End, NullFun, _delay_50ms); } if (Runner.Status == RState.End) { _target.NoteTransferStop(ModuleName.EfemRobot, Hand.Blade1, 0, EnumTransferType.Pick); Notify($"complete, swap wafer,pick: {_pickBlade} slot {_pickSlot + 1}, place: {_placeBlade} slot {_placeSlot + 1}"); } return Runner.Status; } bool CheckBeforePick() { var blade = _pickBlade; var slot = _pickSlot; var source = _targetModule; Notify("Check pick is enabled"); string reason = string.Empty; if (!_target.CheckReadyForTransfer(ModuleName.EfemRobot, blade, slot, EnumTransferType.Pick, out reason)) { Stop(reason); return false; } if (blade == Hand.Blade1) { if (!WaferManager.Instance.CheckHasWafer(source, slot)) { Stop("Source no wafer"); return false; } if (!WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 0)) { Stop("Blade has wafer"); return false; } } else if (blade == Hand.Blade2) { if (!WaferManager.Instance.CheckHasWafer(source, slot)) { Stop("Source no wafer"); return false; } if (!WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 1)) { Stop("Blade has wafer"); return false; } } else { for (int i = 0; i < 2; i++) { if (!WaferManager.Instance.CheckHasWafer(source, slot + i)) { Stop("Source no wafer"); return false; } if (!WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, i)) { Stop("Blade has wafer"); return false; } } } return true; } bool RobotExtendForPick() { Notify("robot execute goto command"); var chamber = _targetModule; var slot = _pickSlot; var hand = _pickBlade; var robotPostion = RobotPostionEnum.PickExtendLow; //string reason; //if (!_robotModule.RobotDevice.GotoRE(chamber, hand, slot, robotPostion, out reason)) //{ // Stop(reason); // return false; //} return true; } bool CheckRobotExtend() { return !_robotModule.RobotDevice.IsError && _robotModule.RobotDevice.IsIdle; } bool MovePinDown() { var pm = _target as PMModuleBase; Notify($"{pm.Name} lift pin down"); //if (!pm.ChamberLiftPin.MoveDown(out string reason)) //{ // Stop(reason); // return false; //} return true; } bool CheckMovePinDown() { var pm = _target as PMModuleBase; //if (pm.ChamberLiftPin.IsDown) // return true; return false; } bool RobotRetractForPick() { Notify("robot execute goto command"); var chamber = _targetModule; var slot = _pickSlot; var hand = _pickBlade; var robotPostion = RobotPostionEnum.PickRetracted; //string reason; //if (!_robotModule.RobotDevice.GotoRE(chamber, hand, slot, robotPostion, out reason)) //{ // Stop(reason); // return false; //} return true; } bool CheckRobotRetract() { return !_robotModule.RobotDevice.IsError && _robotModule.RobotDevice.IsIdle; } public bool RobotExtendForPlace() { Notify("robot execute goto command"); var chamber = _targetModule; var slot = _placeSlot; var hand = _placeBlade; var robotPostion = RobotPostionEnum.PlaceExtendUp; //string reason; //if (!_robotModule.RobotDevice.GotoRE(chamber, hand, slot, robotPostion, out reason)) //{ // Stop(reason); // return false; //} return true; } bool MovePinUp() { var pm = _target as PMModuleBase; Notify($"{pm.Name} lift pin up "); //if (!pm.ChamberLiftPin.MoveUp(out string reason)) //{ // Stop(reason); // return false; //} return true; } bool CheckMovePinUp() { //if (pm.ChamberLiftPin.IsUp) // return true; return false; } bool RobotRetractForPlace() { Notify("robot execute goto command"); var chamber = _targetModule; var slot = _placeSlot; var hand = _placeBlade; var robotPostion = RobotPostionEnum.PlaceRetract; //string reason; //if (!_robotModule.RobotDevice.GotoRE(chamber, hand, slot, robotPostion, out reason)) //{ // Stop(reason); // return false; //} return true; } bool PostTransfer() { var pm = _target as PMModuleBase; var type = EnumTransferType.Place; Notify($"{pm.Name} post transfer "); if (!pm.PostTransfer(ModuleName.EfemRobot, _placeBlade, new int[] { _placeSlot }, type, out string reason)) { Stop(reason); return false; } return true; } bool CheckPostTransfer() { var pm = _target as PMModuleBase; return !pm.IsError && pm.IsReady; } bool PickWafer() { Notify("robot execute pick command"); var chamber = _targetModule; var slot = _pickSlot; var hand = _pickBlade; _target.NoteTransferStart(ModuleName.EfemRobot, hand, slot, EnumTransferType.Pick); string reason; if (!_robotModule.RobotDevice.Pick(chamber, hand, slot, out reason)) { Stop(reason); return false; } return true; } bool CheckPickWafer() { return !_robotModule.RobotDevice.IsError && _robotModule.RobotDevice.IsIdle; } bool CheckBeforePlace() { var source = _targetModule; var slot = _placeSlot; var blade = _placeBlade; Notify("Check place condition"); string reason = string.Empty; if (!_target.CheckReadyForTransfer(ModuleName.EfemRobot, blade, slot, EnumTransferType.Place, out reason)) { Stop(reason); return false; } if (blade == Hand.Blade1) { if (!WaferManager.Instance.CheckNoWafer(source, slot)) { Stop("Source has wafer"); return false; } if (!WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 0)) { Stop("Blade 1 no wafer"); return false; } } else if (blade == Hand.Blade2) { if (!WaferManager.Instance.CheckNoWafer(source, slot)) { Stop("Source has wafer"); return false; } if (!WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 1)) { Stop("Blade no wafer"); return false; } } else { for (int i = 0; i < 2; i++) { if (!WaferManager.Instance.CheckNoWafer(source, slot + i)) { Stop("Source has wafer"); return false; } if (!WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, i)) { Stop("Blade no wafer"); return false; } } } return true; } bool PlaceWafer() { Notify("robot start execute place command"); string reason; var chamber = _targetModule; var slot = _placeSlot; var hand = _placeBlade; _target.NoteTransferStart(ModuleName.EfemRobot, hand, slot, EnumTransferType.Place); if (!_robotModule.RobotDevice.Place(chamber, hand, slot, out reason)) { Stop(reason); return false; } return true; } bool CheckPlaceWafer() { return !_robotModule.RobotDevice.IsError && _robotModule.RobotDevice.IsIdle; } } }