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.EFEMs.Routines.Base; using SicModules.LLs.Routines; namespace SicModules.EFEMs.Routines { public class TrayRobotPickRoutine : EfemBaseRoutine { /* Pick From Cassette,LoadLock(需要开门),Aligner/Unload(需要开门) * 1.判断目标是否有Wafer * 2.判断是否需要开门(包括气压等) * 3.判断顶针是否上升 * 4.伸出,吸住 * 5.ActionDone * 6.关门 * */ //private LoadLock _loadLock; private EfemSlitValveRoutine _efemSlitValveOpenRoutine = new EfemSlitValveRoutine(); private EfemSlitValveRoutine _efemSlitValveCloseRoutine = new EfemSlitValveRoutine(); private LoadLockLiftRoutine _loadLockLiftDown = new LoadLockLiftRoutine(); private ModuleName _source; private int _sourceSlot; private int _pickTimeout; enum RoutineStep { OpenSlitValve, SetLiftUp, CheckRobotReady, PickComplete, SetLiftDown, TimeDelay1, CloseSlitValve, SetExtendToDo, Pick, CheckTrayStatuBeforePick, ClearRobortExtendToDo } public TrayRobotPickRoutine() { Module = ModuleName.EFEM.ToString(); Name = "TrayRobortPick"; } public void Init(ModuleName source, int sourceSlot) { _source = source; _sourceSlot = sourceSlot; } public override Result Start(params object[] objs) { Reset(); if (WaferManager.Instance.CheckHasTray(ModuleName.TrayRobot, 0)) { Stop("Can not pick,TrayRobot has wafer"); return Result.FAIL; } //Pick之前先,根据Sensor检测是否有盘 if (!WaferManager.Instance.CheckHasTray(_source, _sourceSlot)) { EV.PostWarningLog(Module, $"Can not pick, {_source} slot {_sourceSlot} no tray"); return Result.FAIL; } if (TrayRobot.RobotState != RobotStateEnum.Idle) { EV.PostWarningLog(Module, $"Can not pick, WaferRobot is not Idle"); return Result.FAIL; } if (_source == ModuleName.CassBL) { //检测凸片Sensor和有无Sensor if (_cassBLWaferConvex.Value) { EV.PostWarningLog(Module, $"Can not pick,{_source} check wafer convex"); return Result.FAIL; } if (!_cassBL6Inch.Value) { EV.PostWarningLog(Module, $"Can not pick,{_source} sensor check no cassette"); return Result.FAIL; } } if (_source == ModuleName.LoadLock && !_llLift.IsDown) { EV.PostWarningLog(Module, $"Can not pick,{_source} lift is not in down position!"); return Result.FAIL; } _efemSlitValveOpenRoutine.Init(_source, ModuleName.TrayRobot, true); _efemSlitValveCloseRoutine.Init(_source, ModuleName.TrayRobot, false); _loadLockLiftDown.Init(false); _pickTimeout = SC.GetConfigItem($"{ModuleName.TrayRobot}.MotionTimeout").IntValue; return Result.RUN; } public override Result Monitor() { try { if (_source == ModuleName.LoadLock) { CheckRobotReady((int)RoutineStep.CheckRobotReady, TrayRobot, _pickTimeout); CheckTrayStatuBeforePick((int)RoutineStep.CheckTrayStatuBeforePick, TrayRobot, 10); //Pick前先检查 ExecuteRoutine((int)RoutineStep.OpenSlitValve, _efemSlitValveOpenRoutine); //打开闸板阀 SetTrayRobortExtendToDO((int)RoutineStep.SetExtendToDo, _source, 10); //设置ExtendToDO,用于检测InterLock Pick((int)RoutineStep.Pick, TrayRobot, _source, _sourceSlot, _pickTimeout); ClearRobortExtendToDO((int)RoutineStep.ClearRobortExtendToDo); TimeDelay((int)RoutineStep.TimeDelay1, 1); ExecuteRoutine((int)RoutineStep.CloseSlitValve, _efemSlitValveCloseRoutine); //关闭闸板阀 } else { CheckRobotReady((int)RoutineStep.CheckRobotReady, TrayRobot, _pickTimeout); CheckTrayStatuBeforePick((int)RoutineStep.CheckTrayStatuBeforePick, TrayRobot, 10); //Pick前先检查 Pick((int)RoutineStep.Pick, TrayRobot, _source, _sourceSlot, _pickTimeout); //机械手到位,夹爪打开 ClearRobortExtendToDO((int)RoutineStep.ClearRobortExtendToDo); } } catch (RoutineBreakException) { return Result.RUN; } catch (RoutineFaildException ex) { LOG.Error(ex.ToString()); return Result.FAIL; } Notify($"Finish"); return Result.DONE; } public override void Abort() { TrayRobot.Abort(); base.Abort(); } } }