using Aitex.Core.Common; using Aitex.Core.RT.Device; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.Sorter.Common; using athosRT.Devices; using athosRT.FSM; using athosRT.Modules.EFEMs.Routine; using athosRT.Modules.LPs; using athosRT.tool; using Common.DataCenter; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.BufferStations; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase; using System; using System.Collections.Generic; using System.Linq; using static athosRT.Modules.FLP.FlipperEntity; using MoveItem = athosRT.Modules.SchedulerEfemRobot.MoveItem; namespace athosRT.Modules { public enum MovingStatus { Waiting,//等待开始 WaitAlign,//需要去Align Aligning,//Align执行 AlignDone,//Align完成 WaitFlip,//需要Flip Flipping,//Flip执行 FlipDone,//Flip完成 WaitProcess,//需要PM Processing,// PM执行 ProcessDone,//PM完成 WaitCool,//需要Cooling Cooling,// Cool执行 CoolDone,//Cool完成 Idle,//最后一步 回到LP后置 None,//空位 } public class AutoCycle : ModuleRoutineBase, IRoutine { enum EFEMCycle { start, End } enum ModuleType { //LP, Align, Flip, Cool, PM } ModuleName _source = ModuleName.LP1; ModuleName _destination = ModuleName.LP1; private LoadPortBaseDevice m_soucelp; private LoadPortBaseDevice m_destlp; private RobotBaseDevice m_Robot = null; private int cyclewafernum; private bool cyclecreated = false; Queue _moveQueue = new Queue(); SchedulerEfemRobot _efemRobot; List _efemMovingItems = new List(); private PickRoutine m_pickRoutine = null; private PlaceRoutine m_placeRoutine = null; private SwapRoutine m_swapRoutine = null; private LoadFoupRoutine m_sourceLoadRoutine = null; private LoadFoupRoutine m_destLoadRoutine = null; private string _name; private bool _isLowerArmEnable = true; private bool _isUpperArmEnable = true; private RState _cycleState; //两条基线 一是foup的计划点 二是设备需要经过的点 private List _movingStatus = new List(); private List _lstPass = new List(); //需要经过什么类型的点 private List _taskQueue = new List(); private List _hasFlipper = new List(); private List _flippertimes = new List(); private int CycleIndex; private int cyclenumber=0; public AutoCycle(ModuleName module) : base(module) { _name = "AutoCycle"; _cycleState = RState.Init; cyclenumber= SC.GetValue("Process.CycleCount"); DATA.Subscribe("Process.cyclenumber", () => cyclenumber); DATA.Subscribe("Process.CycleIndex", () => CycleIndex); //_efemRobot = (SchedulerEfemRobot)Singleton.Instance.GetScheduler(ModuleName.EfemRobot) ; } Dictionary module2type = new Dictionary(); /// /// objs 结构 要去的模块 起点 终点 经过点 /// /// /// public RState Start(params object[] objs) { m_Robot = DEVICE.GetDevice("Robot"); CycleIndex = 0; if (!SC.GetValue("Process.CycleEnable")) cyclenumber = 1; else cyclenumber = SC.GetValue("Process.CycleCount"); LogObject.Info("Cycle",$"cycle圈数:{cyclenumber}"); if (objs.Length == 3) { if (!Enum.TryParse(objs[0].ToString(), out _source)) { LogObject.Error(_name, $"{objs[0]} is invalid ModuleName, source undefined"); _cycleState = RState.Failed; } if (!Enum.TryParse(objs[1].ToString(), out _destination)) { LogObject.Error(_name, $"{objs[1]} is invalid ModuleName, destination undefined"); _cycleState = RState.Failed; } m_soucelp = DEVICE.GetDevice(_source.ToString()); m_destlp = DEVICE.GetDevice(_destination.ToString()); if (!m_soucelp.IsPlacement) { LogObject.Error(_name, $"{m_soucelp} is not Placed"); return RState.Failed; } else { m_sourceLoadRoutine = new LoadFoupRoutine(_source); } if (!m_destlp.IsPlacement) { LogObject.Error(_name, $"{m_destlp} is not Placed"); return RState.Failed; } else { m_destLoadRoutine = new LoadFoupRoutine(_destination); } _taskQueue = new List(); _taskQueue.Add(MovingStatus.Waiting); //路过的模块 模块的类型决定其是否需要经过 List pathmodules = (List)objs[2]; module2type.Clear(); _lstPass = (List)objs[2]; _lstPass.ForEach(x => LogObject.Info("cycle",$"Module=>{x}")); _taskQueue.Add(MovingStatus.Waiting); m_pickRoutine = new PickRoutine(ModuleName.System); m_placeRoutine = new PlaceRoutine(ModuleName.System); m_swapRoutine = new SwapRoutine(ModuleName.System); _isLowerArmEnable = SC.GetValue("Robot.Blade1Enable"); _isUpperArmEnable = SC.GetValue("Robot.Blade2Enable"); if (!_isLowerArmEnable && !_isUpperArmEnable) { LogObject.Error(_name, $"Robot both cannot Work"); return RState.Failed; } if (pathmodules.Exists(x => ModuleHelper.IsAligner(x))) { _taskQueue.Add(MovingStatus.WaitAlign); pathmodules.FindAll(x => ModuleHelper.IsAligner(x)).ForEach(x => module2type.Add(x, ModuleType.Align)); } if (pathmodules.Exists(x => ModuleHelper.IsLoadLock(x))) { _taskQueue.Add(MovingStatus.WaitProcess); pathmodules.FindAll(x => ModuleHelper.IsLoadLock(x)).ForEach(x => module2type.Add(x, ModuleType.PM)); } if (pathmodules.Exists(x => ModuleHelper.IsBuffer(x))) { _taskQueue.Add(MovingStatus.WaitCool); pathmodules.FindAll(x => ModuleHelper.IsBuffer(x)).ForEach(x => module2type.Add(x, ModuleType.Cool)); } if (pathmodules.Exists(x => ModuleHelper.IsTurnOverStation(x))) { _taskQueue.Add(MovingStatus.WaitFlip); pathmodules.FindAll(x => ModuleHelper.IsTurnOverStation(x)).ForEach(x => module2type.Add(x, ModuleType.Flip)); } cyclecreated = false; Reset(); _cycleState = RState.Running; } else { LogObject.Error(_name, $"illegal params length, cannot start"); _cycleState = RState.Failed; } return _cycleState; } public RState Monitor() { if (_cycleState == RState.Running) { if (!cyclecreated) { if(!LPTaskDone()) return _cycleState; else PrepareTask(); } RunOtherTask(); //与代码有所不同 //是利用各种逻辑进行的 主要依赖的waferinfo的nextstation以及robot的禁用状态 以及各个站点的状态 RunEFEMRobotTask(); } return _cycleState; } //检查所有晶圆是否完成传送 public bool CheckDone() { if (m_Robot.IsReady()) { WaferInfo[] wafers = Singleton.Instance.GetWafers(_source); WaferInfo[] array = wafers; WaferInfo[] _wafers = Singleton.Instance.GetWafers(_destination); WaferInfo[] _destinations = _wafers; if (_destinations.ToList().FindAll(wafer => !wafer.IsEmpty && wafer.SubstE90Status == EnumE90Status.Processed).Count() == cyclewafernum) { ++CycleIndex; //DATA.Subscribe("Process.CycleIndex", () => CycleIndex); if (CycleIndex >= cyclenumber) return true; else { ModuleName swapmd = _destination; _destination = _source; _source = swapmd; PrepareTask(); } } } return false; } /// /// 用于检查source和dest LP是否已经load且map /// /// public bool LPTaskDone() { if (!m_soucelp.IsMapped || !m_soucelp.IsLoaded) { if (m_sourceLoadRoutine.Monitor() == RState.Failed || m_sourceLoadRoutine.Monitor() == RState.Timeout) { LogObject.Error(_name, $"{_source} Load Failed or Timeout"); _cycleState = RState.Failed; return false; } if (m_sourceLoadRoutine.Monitor() == RState.Running) return false; } if (_source != _destination && (!m_destlp.IsMapped || !m_destlp.IsLoaded)) { if (m_destLoadRoutine.Monitor() == RState.Failed || m_destLoadRoutine.Monitor() == RState.Timeout) { LogObject.Error(_name, $"{_destination} Load Failed or Timeout"); _cycleState = RState.Failed; return false; } if (m_destLoadRoutine.Monitor() == RState.Running) return false; } //LogObject.Info(_name, "所有LP Load就绪 准备传送"); return true; } /// /// 用于判定任务 /// public void PrepareTask() { //检索所有source LP中的wafer信息 LogObject.Info(_name,"建立传送任务 确认需要传送的晶圆信息"); cyclewafernum = 0; _hasFlipper.Clear(); _flippertimes.Clear(); for (int i = 0; i < 25; i++) { _hasFlipper.Add(false); _flippertimes.Add(0); if (Singleton.Instance.CheckHasWafer(_source, i)) { cyclewafernum++; WaferInfo wafer= Singleton.Instance.GetWafer(_source, i); wafer.SubstE90Status = EnumE90Status.InProcess; wafer.DestinationStation = (int)_destination; wafer.DestinationSlot = i; wafer.IsChecked = false; Singleton.Instance.UpdateWaferProcessStatus(_source, i, EnumWaferProcessStatus.Wait); _movingStatus.Add(MovingStatus.Waiting); } else { _movingStatus.Add(MovingStatus.None); } } cyclecreated = true; } public RState EFEMRobotTask() { if (m_Robot.IsReady()) { LogObject.Info("cycle", "robot is Idle,prepare to have the Robot's Task"); //手臂全空取片 if (IsRobotEmpty()) { LogObject.Info("cycle","手臂全空"); WaferInfo firstwafer = GetFirstWafer(new List() { _source }, EnumE90Status.InProcess); //LP可以有片取cycle if (firstwafer != null) { LogObject.Info("cycle", "开始Pick from LP"); m_pickRoutine.Source = _source; m_pickRoutine.Slot = firstwafer.Slot; m_pickRoutine.Blade = Hand.Blade1; return m_pickRoutine.Start(); } // firstwafer = GetFirstWafer(_lstPass,EnumE90Status.InProcess); if (firstwafer != null) { LogObject.Info("cycle", "开始Pick from Pass"); m_pickRoutine.Blade = Hand.Blade1; LogObject.Info("cycle", $"确定station => {firstwafer.Station}"); m_pickRoutine.Source = (ModuleName)firstwafer.Station; LogObject.Info("cycle", $"确定slot => {firstwafer.Slot}"); m_pickRoutine.Slot = firstwafer.Slot; //如果是loadport if (ModuleHelper.IsLoadPort(m_pickRoutine.Source)) { return m_pickRoutine.Start(); } //如果是cooling if (ModuleHelper.IsCoolingBuffer(m_pickRoutine.Source)) { return m_pickRoutine.Start(); } if (ModuleHelper.IsLoadLock(m_pickRoutine.Source)) { return m_pickRoutine.Start(); } if (ModuleHelper.IsTurnOverStation(m_pickRoutine.Source) && _hasFlipper[firstwafer.OriginSlot] && _flippertimes[firstwafer.OriginSlot] == 1 && Singleton.Instance.GetFlipper().IsIdle) { return m_pickRoutine.Start(); } if (ModuleHelper.IsAligner(m_pickRoutine.Source)) { return m_pickRoutine.Start(); } if (ModuleHelper.IsBuffer(m_pickRoutine.Source)) { return m_pickRoutine.Start(); } } } //手臂全满放片 else if (IsRobotFull()) { LogObject.Info("cycle", "手臂全满"); WaferInfo Robotwafer = Singleton.Instance.GetWafer(ModuleName.Robot,0); if (Singleton.Instance.CheckHasWafer((ModuleName)Robotwafer.NextStation, Robotwafer.NextStationSlot)) { LogObject.Error("System","下一步有wafer 而手臂全满"); return RState.Failed; } m_placeRoutine.Blade = Hand.Blade1; m_placeRoutine.Station = (ModuleName)Robotwafer.NextStation; m_placeRoutine.Slot = Robotwafer.NextStationSlot; if (ModuleHelper.IsLoadPort(m_placeRoutine.Station)) { LoadPortBaseDevice LP = DEVICE.GetDevice(m_placeRoutine.Station.ToString()); if (LP.IsEnableTransferWafer(out _)) { return m_placeRoutine.Start(); } } if (ModuleHelper.IsCoolingBuffer(m_placeRoutine.Station)) { return m_placeRoutine.Start(null); } if (ModuleHelper.IsAligner(m_placeRoutine.Station)) { return m_placeRoutine.Start(null); } if (ModuleHelper.IsLoadLock(m_placeRoutine.Station)) { LoadLockDevice LL = DEVICE.GetDevice(m_placeRoutine.Station.ToString()); if (LL.IsEnableTransferWafer(out _)) { return m_placeRoutine.Start(); } } if (ModuleHelper.IsTurnOverStation(m_placeRoutine.Station)) { return m_placeRoutine.Start(); } } //手臂有空 swap或place else { LogObject.Info("cycle", "手臂一只手wafer 一只手空"); WaferInfo RobotWafer = GetFirstWafer(new List() { ModuleName.Robot }, EnumE90Status.InProcess); if (RobotWafer == null) { LogObject.Error(_name,"未能获取手臂wafer信息"); return RState.Failed; } //目标地没有wafer 直接place if (Singleton.Instance.CheckNoWafer((ModuleName)RobotWafer.NextStation, RobotWafer.NextStationSlot)) { m_placeRoutine.Blade = (Hand)RobotWafer.Slot; m_placeRoutine.Station = (ModuleName)RobotWafer.NextStation; m_placeRoutine.Slot = RobotWafer.NextStationSlot; if (ModuleHelper.IsLoadPort(m_placeRoutine.Station)) { LoadPortBaseDevice LP = DEVICE.GetDevice(m_placeRoutine.Station.ToString()); if (LP.IsEnableTransferWafer(out _)) { return m_placeRoutine.Start(); } } if (ModuleHelper.IsCoolingBuffer(m_placeRoutine.Station)) { return m_placeRoutine.Start(); } if (ModuleHelper.IsAligner(m_placeRoutine.Station)) { m_placeRoutine.Start(); } if (ModuleHelper.IsLoadLock(m_placeRoutine.Station)) { LoadLockDevice LL = DEVICE.GetDevice(m_placeRoutine.Station.ToString()); if (LL.IsEnableTransferWafer(out _)) { return m_placeRoutine.Start(); } } if (ModuleHelper.IsBuffer(m_placeRoutine.Station)) { SimpleBuffer buffer = DEVICE.GetDevice(m_placeRoutine.Station.ToString()); return m_placeRoutine.Start(); } if (ModuleHelper.IsTurnOverStation(m_placeRoutine.Station)) { return m_placeRoutine.Start(); } } //目标地有wafer 需要swap else { if (ModuleHelper.IsLoadPort((ModuleName)RobotWafer.NextStation)) { LogObject.Error(_name, "目标loadport 不可能swap"); return RState.Failed; } m_swapRoutine.Source = (ModuleName)RobotWafer.NextStation; m_swapRoutine.Slot = RobotWafer.NextStationSlot; if (RobotWafer.Slot == 0) { m_swapRoutine.PlaceBlade = Hand.Blade1; } else { m_swapRoutine.PlaceBlade = Hand.Blade2; } //if (ModuleHelper.IsLoadPort(m_swapRoutine.Source)) //{ // LoadPortBaseDevice LP = DEVICE.GetDevice(m_swapRoutine.Source.ToString()); // if (LP.IsEnableTransferWafer(out _)) // { // return m_swapRoutine.Start(); // } //} if (ModuleHelper.IsCoolingBuffer(m_swapRoutine.Source)) { return m_swapRoutine.Start(); } if (ModuleHelper.IsAligner(m_swapRoutine.Source)) { return m_swapRoutine.Start(); } if (ModuleHelper.IsBuffer(m_swapRoutine.Source)) { //BufferStation buffer = DEVICE.GetDevice(m_swapRoutine.Source.ToString()); //if (buffer.IsEnableTransferWafer(out _)) //{ // return m_swapRoutine.Start(); //} return m_swapRoutine.Start(); } if (ModuleHelper.IsLoadLock(m_swapRoutine.Source)) { LoadLockDevice LL = DEVICE.GetDevice(m_swapRoutine.Source.ToString()); if (LL.IsEnableTransferWafer(out _)) { return m_swapRoutine.Start(); } } if (ModuleHelper.IsTurnOverStation(m_swapRoutine.Source)) { return m_swapRoutine.Start(); } } } } return RState.Running; } private bool IsRobotEmpty() => WaferManager.Instance.CheckNoWafer(ModuleName.Robot,0) && WaferManager.Instance.CheckNoWafer(ModuleName.Robot, 1); private bool IsRobotFull() => WaferManager.Instance.CheckHasWafer(ModuleName.Robot,0) && WaferManager.Instance.CheckHasWafer(ModuleName.Robot, 1); private WaferInfo GetFirstWafer(List modules, EnumE90Status estatus) { foreach (ModuleName md in modules) { WaferInfo[] wafers = Singleton.Instance.GetWafers(md); WaferInfo[] copywafers = wafers; foreach (WaferInfo wafer in copywafers) { if (!wafer.IsEmpty && wafer.SubstE90Status == estatus) { wafer.Station = (int)md; return wafer; } } } return null; } //从lp中取出wafer public void GetWaferFromLP() { if (m_Robot.IsIdle) { //如果都没有wafer 可以pick if (WaferManager.Instance.CheckNoWafer(m_Robot.Module, (int)Hand.Blade1)) { if (_movingStatus.Exists(x => x == MovingStatus.Waiting)) { int slot = _movingStatus.FindIndex(x => x == MovingStatus.Waiting); m_pickRoutine.Source = _source; m_pickRoutine.Slot = slot; m_pickRoutine.Blade = Hand.Blade1; m_pickRoutine.Start(); } } else if (WaferManager.Instance.CheckNoWafer(m_Robot.Module, (int)Hand.Blade2)) { if (_movingStatus.Exists(x => x == MovingStatus.Waiting)) { int slot = _movingStatus.FindIndex(x => x == MovingStatus.Waiting); m_pickRoutine.Source = _source; m_pickRoutine.Slot = slot; m_pickRoutine.Blade = Hand.Blade1; if (m_pickRoutine.Start() == RState.Running) { _movingStatus[slot] = NextStation(MovingStatus.Waiting); } } } } } public Hand GetFreeHand() { if (WaferManager.Instance.CheckHasWafer(m_Robot.Module, 0)) { return Hand.Blade1; } if (WaferManager.Instance.CheckHasWafer(m_Robot.Module, 1)) { return Hand.Blade2; } return Hand.Both; } public MovingStatus NextStation(MovingStatus currentStation) { if (_taskQueue.Exists(x => x == currentStation)) { return _taskQueue[_taskQueue.FindIndex(x => x == currentStation)+1]; } else { LogObject.Error(_name, $"meet unknown Status:{currentStation}"); _cycleState = RState.Failed; return MovingStatus.None; } } public void RunEFEMRobotTask() { try { switch (m_pickRoutine.Monitor()) { case RState.Running: _cycleState = RState.Running; return; //break; case RState.Timeout: case RState.Failed: LogObject.Error(_name, "pick失败"); _cycleState = RState.Failed; return; //break; default: switch (m_placeRoutine.Monitor()) { case RState.Running: _cycleState = RState.Running; return; //break; case RState.Timeout: case RState.Failed: LogObject.Error(_name, "place失败"); _cycleState = RState.Failed; return; //break; default: switch (m_swapRoutine.Monitor()) { case RState.Running: _cycleState = RState.Running; return; //break; case RState.Timeout: case RState.Failed: LogObject.Error(_name, "swap失败"); _cycleState = RState.Failed; return; //break; default: if (CheckDone()) { _cycleState = RState.End; return; } if (m_Robot.IsReady()) { UpdataWaferNextStation(); RState ret = EFEMRobotTask(); switch (ret) { case RState.Failed: case RState.Timeout: _cycleState = RState.Failed; break; default: break; } } //策略开始 break; } break; } break; } } catch (Exception ex) { LogObject.Info("cycle", $"Cycle Exception: {ex.Message},Site:{ex.TargetSite}|Source:{ex.Source}"); } } public void RunOtherTask() { if (_lstPass.Contains(ModuleName.TurnOverStation) &&Singleton.Instance.GetFlipper().State == Devices.FLP.FlipperState.Idle &&WaferManager.Instance.CheckHasWafer(ModuleName.TurnOverStation,0) ) { WaferInfo flipperwafer = WaferManager.Instance.GetWafer(ModuleName.TurnOverStation, 0); //LogObject.Info("Cycle",$"Wafer on Flipperstatus:{flipwafer.IsChecked}|Empty:{flipwafer.IsEmpty}"); if (_flippertimes[flipperwafer.OriginSlot] < 1 && !_hasFlipper[flipperwafer.OriginSlot]) { LogObject.Info("Cycle",$"Flipper上有wafer且未翻面 可以旋转 Slot:{flipperwafer.OriginSlot}|hasFlip:{_hasFlipper[flipperwafer.OriginSlot]}"); Singleton.Instance.GetFlipper().PostMsg(FlipperMSG.TurnOver); //flipwafer.IsChecked = true; } } if ((Singleton.Instance.GetFlipper().State == Devices.FLP.FlipperState.Turning) && WaferManager.Instance.CheckHasWafer(ModuleName.TurnOverStation, 0)) { WaferInfo flipperwafer = WaferManager.Instance.GetWafer(ModuleName.TurnOverStation, 0); _hasFlipper[flipperwafer.OriginSlot] = true; } if ((Singleton.Instance.GetFlipper().State == Devices.FLP.FlipperState.Idle) && WaferManager.Instance.CheckHasWafer(ModuleName.TurnOverStation, 0)) { WaferInfo flipperwafer = WaferManager.Instance.GetWafer(ModuleName.TurnOverStation, 0); if (_hasFlipper[flipperwafer.OriginSlot] && _flippertimes[flipperwafer.OriginSlot] == 0) { _flippertimes[flipperwafer.OriginSlot] = 1; } if (!_hasFlipper[flipperwafer.OriginSlot] && _flippertimes[flipperwafer.OriginSlot] == 1) { _flippertimes[flipperwafer.OriginSlot] = 2; } } } //更新晶圆下一刻要去的位置 private void UpdataWaferNextStation() { //获取起始点的所有晶圆 WaferInfo[] wafers = Singleton.Instance.GetWafers(_source); WaferInfo[] array = wafers; LogObject.Info("cycle", "更新LP wafer下一刻状态"); foreach (WaferInfo waferInfo in array) { //有晶圆且状态为inprocess if (!waferInfo.IsEmpty && waferInfo.SubstE90Status == EnumE90Status.InProcess) { LogObject.Info("cycle", $"LP waferInfo:{waferInfo.OriginStation}|{waferInfo.OriginSlot}"); if (_lstPass.Count != 0) { waferInfo.NextStation = (int)_lstPass[0]; int slot = 0; if (ModuleHelper.IsBuffer((ModuleName)waferInfo.NextStation)) slot = CycleIndex % 10; waferInfo.NextStationSlot = slot; LogObject.Info("cycle", $"buffer cycle waferInfo:{waferInfo.NextStation}|{waferInfo.NextStationSlot}"); Singleton.Instance.UpdateWaferProcessStatus((ModuleName)waferInfo.Station, waferInfo.Slot, EnumWaferProcessStatus.InProcess); } else { //没有任务直接传送回目标 waferInfo.NextStation = waferInfo.DestinationStation; waferInfo.NextStationSlot = waferInfo.DestinationSlot; Singleton.Instance.UpdateWaferProcessStatus((ModuleName)waferInfo.Station, waferInfo.Slot, EnumWaferProcessStatus.InProcess); } } else { if (waferInfo.IsEmpty) { //LogObject.Info("Cycle",$"晶圆为空{waferInfo.Slot}"); } if (waferInfo.SubstE90Status != EnumE90Status.InProcess) { //LogObject.Info("Cycle", $"晶圆为非InProcess {waferInfo.Slot}"); } } } LogObject.Info("cycle", "更新Pass station wafer下一刻状态"); //_lstPass.ForEach(x => LogObject.Info("cycle", $"Module=>{x}")); for (int idx = 0; idx < _lstPass.Count(); idx++) { LogObject.Info("cycle", $"Pass waferInfo => Pass index:{idx} & Pass Module:{_lstPass[idx]}"); int slot = 0; if (ModuleHelper.IsBuffer(_lstPass[idx])) slot = CycleIndex % 10; WaferInfo wafer = Singleton.Instance.GetWafer(_lstPass[idx], slot); LogObject.Info("cycle", $"Pass waferInfo => Empty:{wafer.IsEmpty}"); if (!wafer.IsEmpty && wafer.SubstE90Status == EnumE90Status.InProcess) { LogObject.Info("cycle", $"Pass waferInfo:{_lstPass[idx]}|0"); if (idx == _lstPass.Count - 1) { wafer.NextStation = wafer.DestinationStation; wafer.NextStationSlot = wafer.DestinationSlot; } else { wafer.NextStation = (int)_lstPass[idx + 1]; wafer.NextStationSlot = 0; if (ModuleHelper.IsBuffer((ModuleName)wafer.NextStation)) wafer.NextStationSlot = CycleIndex % 10; //LogObject.Info("cycle", $"buff cycle:{wafer.NextStation}|{wafer.NextStationSlot}"); } } } } /// /// 当前的状态 /// 用于对一些子设备的模拟计时 /// /// /// private MovingStatus throughPath(MovingStatus currentStatus) { switch (currentStatus) { case MovingStatus.WaitAlign: return MovingStatus.Aligning; case MovingStatus.Aligning: return MovingStatus.AlignDone; case MovingStatus.WaitCool: return MovingStatus.Cooling; case MovingStatus.Cooling: return MovingStatus.CoolDone; case MovingStatus.WaitFlip: return MovingStatus.Flipping; case MovingStatus.Flipping: return MovingStatus.FlipDone; case MovingStatus.WaitProcess: return MovingStatus.Processing; case MovingStatus.Processing: return MovingStatus.ProcessDone; default: return MovingStatus.Idle; } } private bool IsModulesEmpty(List lstPassThrough) { foreach (ModuleName item in lstPassThrough) { if (Singleton.Instance.CheckHasWafer(item, 0)) { return false; } } return true; } public void Abort() { _cycleState = RState.End; } } public class TransferModule { protected SchedulerEfemRobot _efemRobot = new SchedulerEfemRobot(); //protected SchedulerTMRobot _tmRobot = new SchedulerTMRobot(); //protected SchedulerSETMRobot _setm; // //protected SchedulerLoadPort _lp1 = new SchedulerLoadPort(ModuleName.LP1); //protected SchedulerLoadPort _lp2 = new SchedulerLoadPort(ModuleName.LP2); //protected SchedulerLoadPort _lp3 = new SchedulerLoadPort(ModuleName.LP3); // //protected SchedulerLoadLock _lla = new SchedulerLoadLock(ModuleName.LLA); //protected SchedulerLoadLock _llb = new SchedulerLoadLock(ModuleName.LLB); // //protected SchedulerAligner _aligner1 = new SchedulerAligner(ModuleName.Aligner1); //protected SchedulerAligner _aligner2 = new SchedulerAligner(ModuleName.Aligner2); //protected SchedulerAligner _cooling1 = new SchedulerAligner(ModuleName.Cooling1); //protected SchedulerAligner _cooling2 = new SchedulerAligner(ModuleName.Cooling2); // //protected SchedulerPM _pma = new SchedulerPM(ModuleName.PMA); //protected SchedulerPM _pmb = new SchedulerPM(ModuleName.PMB); // //protected SchedulerPM _pmc = new SchedulerPM(ModuleName.PMC); //protected SchedulerPM _pmd = new SchedulerPM(ModuleName.PMD); public TransferModule() { } public SchedulerModule GetScheduler(ModuleName module) { switch (module) { case ModuleName.EfemRobot: return _efemRobot; } return null; } } }