using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots; using SicModules.LLs; namespace SicModules.TMs { public class TMRobotPlaceRoutine : TMBaseRoutine { enum RoutineStep { WaitOpenSlitValveInterlock, OpenSlitValve, CheckBeforePlace, Place, PrepareTransfer, Extend, Handoff, HandoffDelay, Retract, UpdateWaferInfoByHandoff, RequestWaferPresent, BeforePlaceRequestWaferPresent, AfterPlaceRequestWaferPresent, CheckWaferInfoByRobotSensor, BeforePlaceCheckWaferInfoByRobotSensor, AfterPlaceCheckWaferInfoByRobotSensor, RequestAWCData, SetRobortExtendToDo, ClearRobortExtendToDo, WaitCloseSlitValveInterlock, CloseSlitValve, WaitPMSensor, PostTransfer, OpenShutter, CloseShutter, Delay1, Delay2, VceMoveToSlot, RobotGotoNotWait, PrepareTransferNotWait, CheckRobotReady, CheckTransferPrepared, LoadRatation, TrayClamp, TrayUnClamp, TimeDelay1, TimeDelay2, TimeDelay3, SuspectorCheck } private ModuleName _target; private int _targetSlot; private RobotArmEnum _blade; private int _placeTimeout; private int _postTransferTimeout; private bool _requestAWCData; private double _shutterAndSlitValveMotionInterval; private bool _autoHand; private TMSlitValveRoutine _openSlitValveRoutine = new TMSlitValveRoutine(); private TMSlitValveRoutine _closeSlitValveRoutine = new TMSlitValveRoutine(); //private VCEMoveToSlotRoutine _vceMoveToSlotRoutine; private LoadRotationHomeOffsetRoutine loadRotationHomeRoutine = new LoadRotationHomeOffsetRoutine(); private LoadLockTrayClawRoutine _trayClamp = new LoadLockTrayClawRoutine(); private LoadLockTrayClawRoutine _trayUnClamp = new LoadLockTrayClawRoutine(); private bool _isShutterAndSlitValveMotionOneByOne; private SicTM _tm; public TMRobotPlaceRoutine() { Module = "TMRobot"; Name = "Place"; _tm = DEVICE.GetDevice($"{ ModuleName.System.ToString()}.{ ModuleName.TM.ToString()}"); } public void Init(ModuleName target, int targetSlot, RobotArmEnum blade) { Init(target, targetSlot, blade, false); } public void Init(ModuleName target, int targetSlot, int blade) { Init(target, targetSlot, blade == 0 ? RobotArmEnum.Blade1 : RobotArmEnum.Blade2, false); } public void Init(ModuleName target, int targetSlot) { Init(target, targetSlot, RobotArmEnum.Blade1, true); } private void Init(ModuleName target, int targetSlot, RobotArmEnum blade, bool autoHand) { _autoHand = autoHand; _target = target; _targetSlot = targetSlot; _blade = blade; _openSlitValveRoutine.Init(target.ToString(), true); _closeSlitValveRoutine.Init(target.ToString(), false); } public override Result Start(params object[] objs) { Reset(); if (RobotDevice.RobotState != RobotStateEnum.Idle) { EV.PostWarningLog(Module, $"Can not place, TMRobot Is Not IDLE"); return Result.FAIL; } _placeTimeout = SC.GetValue("TMRobot.PlaceTimeout"); _requestAWCData = SC.GetValue("System.RequestAWCDataAfterPlace"); if (!WaferManager.Instance.CheckNoTray(_target, _targetSlot)) { EV.PostWarningLog(Module, $"Can not place, should no tray at {_target}, {_targetSlot + 1}"); return Result.FAIL; } if (_autoHand) { if (WaferManager.Instance.CheckHasWafer(Module, 0)) { _blade = RobotArmEnum.Blade1; } else if (WaferManager.Instance.CheckHasWafer(Module, 1)) { _blade = RobotArmEnum.Blade2; } else { EV.PostWarningLog(Module, $"Can not place, Robot both arm no wafer"); return Result.FAIL; } } int slot = _blade == RobotArmEnum.Blade1 ? 0 : 1; if (WaferManager.Instance.CheckNoTray(ModuleHelper.Converter(Module), slot)) { EV.PostWarningLog(Module, $"Can not place, Robot arm {slot + 1} no tray"); return Result.FAIL; } //顶针必须在低位 // if (_target == ModuleName.LoadLock || _target == ModuleName.Load) // { // if (!LoadLift.IsDown) // { // EV.PostWarningLog(Module, $"Can not place, Load Lift must in down Position!"); // return Result.FAIL; // } // } // else if (_target == ModuleName.UnLoad) // { // if (!UnLoadLift.IsDown) // { // EV.PostWarningLog(Module, $"Can not place, UnLoad Lift must in down Position!"); // return Result.FAIL; // } // } //Place之前先,根据Sensor检测是否有盘 if (!SC.GetValue("System.IsSimulatorMode")) { if (_target ==ModuleName.LoadLock&& SensorLLTrayPresence.Value) { EV.PostWarningLog(Module, $"Can not place, LLTrayPresence sensor has tray"); return Result.FAIL; } //if (_target == ModuleName.UnLoad && SensorUnloadWaferPresence.Value) //{ // EV.PostWarningLog(Module, $"Can not place, UnloadWaferPresence sensor has wafer"); // return Result.FAIL; //} if (ModuleHelper.IsBuffer(_target) && _targetSlot == 2&& SensorBufferHighWaferPresence.Value) { EV.PostWarningLog(Module, $"Can not place,BufferHighWaferPresence sensor check has wafer"); return Result.FAIL; } if (ModuleHelper.IsBuffer(_target) && _targetSlot == 1&& SensorBufferMiddleWaferPresence.Value) { EV.PostWarningLog(Module, $"Can not place,BufferMiddleWaferPresence sensor check has wafer"); return Result.FAIL; } if (ModuleHelper.IsBuffer(_target) && _targetSlot == 0&& SensorBufferLowWaferPresence.Value) { EV.PostWarningLog(Module, $"Can not place,BufferLowWaferPresence sensor check has wafer"); return Result.FAIL; } } // _trayClamp.Init(true); // _trayUnClamp.Init(false); Notify($"Start, Place to {_target} slot {_targetSlot + 1}, by {(_blade == RobotArmEnum.Blade1 ? "Blade1" : "Blade2")}"); return Result.RUN; } public override void Abort() { _tm.CloseAllVentPumpValue(); if (!IsPicking) { RobotDevice.Stop(); } Notify("Abort"); } public override Result Monitor() { try { WaitSlitValveOpenInterlock((int)RoutineStep.WaitOpenSlitValveInterlock, TMDevice.GetSlitValve(_target), _placeTimeout); RobotGotoNotWait((int)RoutineStep.RobotGotoNotWait, RobotDevice, _target, _targetSlot, _blade, _placeTimeout); if (!ModuleHelper.IsBuffer(_target)) { ExecuteRoutine((int)RoutineStep.OpenSlitValve, _openSlitValveRoutine); } //如果是PM腔,放盘前检查传感器DI_ReactorSuspectorCheck //如果有,则不能放盘 if (ModuleHelper.IsPm(_target)) { CheckReactorSuspector((int)RoutineStep.SuspectorCheck,_target); } CheckRobotReady((int)RoutineStep.CheckRobotReady, RobotDevice, _placeTimeout); CheckBeforePlace((int)RoutineStep.CheckBeforePlace, _target, _targetSlot, _blade); RobotRequestWaferPresent((int)RoutineStep.BeforePlaceRequestWaferPresent, RobotDevice, _blade, _placeTimeout); CheckWaferInfoByRobotRQ((int)RoutineStep.BeforePlaceCheckWaferInfoByRobotSensor, RobotDevice, _blade, 10); WaitPMReadySensor((int)RoutineStep.WaitPMSensor, _target, 5); SetRobortExtendToDO((int)RoutineStep.SetRobortExtendToDo, _target, 2); CheckRobotReady((int)RoutineStep.CheckRobotReady, RobotDevice, _placeTimeout); Place((int)RoutineStep.Place, RobotDevice, _target, _targetSlot, _blade, _placeTimeout); IsPicking = false; TimeDelay((int)RoutineStep.TimeDelay1, 1); RobotRequestWaferPresent((int)RoutineStep.RequestWaferPresent, RobotDevice, _blade, _placeTimeout); CheckWaferInfoByRobotRQ((int)RoutineStep.CheckWaferInfoByRobotSensor, RobotDevice, _blade, 10); if (_requestAWCData) { RobotRequestWaferAWCData((int)RoutineStep.RequestAWCData, RobotDevice, _placeTimeout); } ClearRobortExtendToDO((int)RoutineStep.ClearRobortExtendToDo); TimeDelay((int)RoutineStep.TimeDelay2, 1); // if (_target == ModuleName.Load || _target == ModuleName.LoadLock) // { // //对中 // ExecuteRoutine((int)RoutineStep.TrayClamp, _trayClamp); //夹爪关闭 // TimeDelay((int)RoutineStep.TimeDelay3, 1);//延迟1s // ExecuteRoutine((int)RoutineStep.TrayUnClamp, _trayUnClamp); //夹爪打开 // //ExecuteRoutine((int)RoutineStep.LoadRatation, loadRotationHomeRoutine); // } if (!ModuleHelper.IsBuffer(_target)) { ExecuteRoutine((int)RoutineStep.CloseSlitValve, _closeSlitValveRoutine); } } catch (RoutineBreakException) { return Result.RUN; } catch (RoutineFaildException ex) { LOG.Error(ex.ToString()); RobotDevice.Stop(); return Result.FAIL; } Notify($"Finish, Place to {_target} slot {_targetSlot + 1}, by {_blade}"); return Result.DONE; } } }