using System; using System.Collections.Generic; using System.Linq; using Aitex.Core.Common; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Event; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Sorter.Common; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Schedulers; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.ModuleLibrary.SystemModules; using EfemDualSchedulerLib.Schedulers; namespace EfemDualSchedulerLib { public class TMCycle : SchedulerModuleFactory, IRoutine { Dictionary _checkPosition = new Dictionary() { {ModuleName.TMRobot, 2}, {ModuleName.PMA, 2}, {ModuleName.PMB, 2}, }; Queue tmRobotActions = new Queue() { }; private List _lstPms = new List(); private List _lstLls = new List(); public bool PMAIsInstalled { get { return SC.GetValueOrDefault("System.SetUp.PMA.IsInstalled"); } } public bool PMBIsInstalled { get { return SC.GetValueOrDefault("System.SetUp.PMB.IsInstalled"); } } public TMCycle(EquipmentManager equipment) : base() { DATA.Subscribe("TMCylce.RemainedCycleCount", () => { return cycleCount - 1; }); //有优先级,先处理pmb后pma if (PMBIsInstalled) _lstPms.Add(_pm2); if (PMAIsInstalled) _lstPms.Add(_pm1); _lstLls.Add(_loadlockA); _lstLls.Add(_loadlockB); tmRobotActions.Enqueue(MonitorTmRobotLoadLockPickTask); tmRobotActions.Enqueue(MonitorTMRobotPMPlaceTask); tmRobotActions.Enqueue(MonitorTMRobotPMPickTask); tmRobotActions.Enqueue(MonitorTmRobotLoadLockPlaceTask); } List tmCycleRoutine = new List() { "LLA", "PMA", "PMB", "LLB" }; int cycleCount = 1; public Result Start(params object[] objs) { if (objs.Length == 2) { tmCycleRoutine = ((string[])objs[0]).ToList(); cycleCount = (int)objs[1]; } //if (!PMAIsInstalled && !PMBIsInstalled) //{ // EV.PostWarningLog("System", $"TM Cycle, PMA & PMB Both UnInstalled."); // return Result.FAIL; //} if (!PMAIsInstalled && tmCycleRoutine.Contains("PMA")) { EV.PostWarningLog("System", $"TM Cycle, PMA is UnInstalled."); return Result.FAIL; } if (!PMBIsInstalled && tmCycleRoutine.Contains("PMB")) { EV.PostWarningLog("System", $"TM Cycle, PMB is UnInstalled."); return Result.FAIL; } foreach (var positions in _checkPosition) { for (int i = 0; i < positions.Value; i++) { WaferInfo wafer = WaferManager.Instance.GetWafer(positions.Key, i); if (!wafer.IsEmpty) { EV.PostWarningLog("System", $"TM Cycle, {positions.Key}.{i + 1} can not has wafer."); return Result.FAIL; } } } WaferInfo[] OriginWafers = WaferManager.Instance.GetWafers(ModuleHelper.Converter(tmCycleRoutine.First())); WaferInfo[] DestinationWafers = WaferManager.Instance.GetWafers(ModuleHelper.Converter(tmCycleRoutine.Last())); for (int i = 0; i < OriginWafers.Length; i++) { if (!OriginWafers[i].IsEmpty) { OriginWafers[i].OriginStation = (int)ModuleHelper.Converter(tmCycleRoutine.First()); OriginWafers[i].OriginSlot = i; OriginWafers[i].ProcessState = EnumWaferProcessStatus.InProcess; OriginWafers[i].NextSequenceStep = 0; if (tmCycleRoutine.First() != tmCycleRoutine.Last() && !DestinationWafers[i].IsEmpty) { EV.PostWarningLog("System", $"TM Cycle, {tmCycleRoutine.Last()}.{i + 1} already has wafer."); return Result.FAIL; } } } if (tmCycleRoutine.First() != tmCycleRoutine.Last()) { tmCycleRoutine.Add(tmCycleRoutine.First()); } return Result.RUN; } public Result Monitor() { MonitorModuleTasks(); if (MonitorTaskDone()) { return Result.DONE; } return Result.RUN; } public void Clear() { } public void Abort() { } public Result MonitorModuleTasks() { MonitorPMTask(); MonitorTMRobotTask(); return Result.RUN; } private void MonitorTMRobotTask() { if (!_tmRobot.IsAvailable) return; //_tmRobot is idle, release all the target foreach (var ll in _lstLls) { if (ll.IsWaitTransfer(ModuleName.TMRobot)) ll.StopWaitTransfer(ModuleName.TMRobot); } foreach (var pm in _lstPms) { if (pm.IsWaitTransfer(ModuleName.TMRobot)) pm.StopWaitTransfer(ModuleName.TMRobot); } if (!_tmRobot.IsAvailable) return; var act = tmRobotActions.Peek(); act.Invoke(); if (!_tmRobot.IsAvailable) return; tmRobotActions.Enqueue(tmRobotActions.Dequeue()); //MonitorTMRobotPMTask(); //if (!_tmRobot.IsAvailable) // return; //MonitorTMRobotLoadLockTask(); } private void MonitorTmRobotLoadLockPlaceTask() { if (!_tmRobot.IsAvailable) return; //place to ll bool blade0HasWaferAndProcessed = _tmRobot.Blade1Enable && WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0); bool blade1HasWaferAndProcessed = _tmRobot.Blade2Enable && WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 1); if (blade0HasWaferAndProcessed || blade1HasWaferAndProcessed) { Hand placeBlade = blade0HasWaferAndProcessed ? Hand.Blade1 : Hand.Blade2; foreach (var ll in _lstLls) { if (!ll.IsAvailable) continue; if (!CheckWaferNextStep(ModuleName.TMRobot, (int)placeBlade, ll.Module)) continue; var wafer = WaferManager.Instance.GetWafer(ModuleName.TMRobot, (int)placeBlade); var slot = wafer.OriginSlot; if (ll.IsReadyForPlace(ModuleName.TMRobot, placeBlade, (int)slot)) { if (_tmRobot.Place(ll.Module, (int)slot, placeBlade, 0, 0, false)) { if (wafer.NextSequenceStep >= tmCycleRoutine.Count-1) wafer.ProcessState = EnumWaferProcessStatus.Completed; ll.WaitTransfer(ModuleName.TMRobot); return; } } } } } private void MonitorTmRobotLoadLockPickTask() { if (!_tmRobot.IsAvailable) return; //pick from ll if (WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0) || WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 1)) { Hand pickBlade; if (_tmRobot.Blade1Enable && WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0)) { pickBlade = Hand.Blade1; } else if (_tmRobot.Blade2Enable && WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 1)) { pickBlade = Hand.Blade2; } else { return; } foreach (var ll in _lstLls) { if (!ll.IsAvailable) continue; var wafers = WaferManager.Instance.GetWafers(ll.Module); for (int pickSlot = 0; pickSlot < wafers.Length; pickSlot++) { if (wafers[pickSlot].NextSequenceStep == 0) { ModuleName nextModule = ModuleHelper.Converter(tmCycleRoutine[1]); if (WaferManager.Instance.GetWafers(nextModule).All(x => !x.IsEmpty)) return; } if (wafers[pickSlot].ProcessState != EnumWaferProcessStatus.InProcess) continue; if (ll.IsReadyForPick(ModuleName.TMRobot, pickBlade, pickSlot)) { if (_tmRobot.Pick(ll.Module, pickSlot, pickBlade, 0, 0, false)) { wafers[pickSlot].NextSequenceStep++; ll.WaitTransfer(ModuleName.TMRobot); return; } } } } } } private void MonitorTMRobotLoadLockTask() { if (!_tmRobot.IsAvailable) return; //place to llb { bool blade1HasWafer = _tmRobot.Blade1Enable && WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0) && WaferManager.Instance.GetWafer(ModuleName.TMRobot, 0).NextStation == (int)ModuleName.LLB; bool blade2HasWafer = _tmRobot.Blade2Enable && WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 1) && WaferManager.Instance.GetWafer(ModuleName.TMRobot, 1).NextStation == (int)ModuleName.LLB; if (blade1HasWafer || blade2HasWafer) { Hand placeBlade = blade1HasWafer ? Hand.Blade1 : Hand.Blade2; var wafer = WaferManager.Instance.GetWafer(ModuleName.TMRobot, (int)placeBlade); { if (!_loadlockB.IsAvailable) return; var slot = wafer.OriginSlot; if (_loadlockB.IsReadyForPlace(ModuleName.TMRobot, placeBlade, (int)slot)) { if (_tmRobot.Place(_loadlockB.Module, (int)slot, placeBlade, 0, 0, false)) { _loadlockB.WaitTransfer(ModuleName.TMRobot); return; } } } } } if (!_tmRobot.IsAvailable) return; //pick from lla if (PMAIsInstalled && PMBIsInstalled && WaferManager.Instance.CheckHasWafer(ModuleName.PMA, 0) && WaferManager.Instance.CheckHasWafer(ModuleName.PMA, 1)) return; if (WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0) || WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 1)) { Hand pickBlade; if (_tmRobot.Blade2Enable && WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 1)) { pickBlade = Hand.Blade2; } else if (_tmRobot.Blade1Enable && WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 0)) { pickBlade = Hand.Blade1; } else { return; } { if (!_loadlockA.IsAvailable) return; var wafers = WaferManager.Instance.GetWafers(_loadlockA.Module); for (int pickSlot = 0; pickSlot < wafers.Length; pickSlot++) { if (_loadlockA.IsReadyForPick(ModuleName.TMRobot, pickBlade, pickSlot)) { if (_tmRobot.Pick(_loadlockA.Module, pickSlot, pickBlade, 0, 0, false)) { _loadlockA.WaitTransfer(ModuleName.TMRobot); return; } } } } } } private void MonitorTMRobotPMPlaceTask() { if (!_tmRobot.IsAvailable) return; //place to pm bool blade0HasWafer = _tmRobot.Blade1Enable && WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0); bool blade1HasWafer = _tmRobot.Blade2Enable && WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 1); if (blade0HasWafer || blade1HasWafer) { Hand placeBlade = blade0HasWafer ? Hand.Blade1 : Hand.Blade2; var wafer = WaferManager.Instance.GetWafer(ModuleName.TMRobot, (int)placeBlade); foreach (var schedulerPm in _lstPms) { if (!schedulerPm.IsAvailable) continue; if (!CheckWaferNextStep(ModuleName.TMRobot, (int)placeBlade, schedulerPm.Module)) continue; var pmWafer0 = WaferManager.Instance.GetWafer(schedulerPm.Module, 0); var pmWafer1 = WaferManager.Instance.GetWafer(schedulerPm.Module, 1); //如果腔体中两片都满了,则不允许放入 if (!pmWafer0.IsEmpty && !pmWafer1.IsEmpty) continue; if (WaferManager.Instance.CheckNoWafer(schedulerPm.Module, 0)) { if (_tmRobot.Place(schedulerPm.Module, 0, placeBlade, 0, 0, false)) { schedulerPm.WaitTransfer(ModuleName.TMRobot); return; } } if (WaferManager.Instance.CheckNoWafer(schedulerPm.Module, 1)) { if (_tmRobot.Place(schedulerPm.Module, 1, placeBlade, 0, 0, false)) { schedulerPm.WaitTransfer(ModuleName.TMRobot); return; } } } } } private void MonitorTMRobotPMPickTask() { //pick from pm { bool blade1Empty = _tmRobot.Blade1Enable && WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0); bool blade2Empty = _tmRobot.Blade2Enable && WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 1); if (blade1Empty || blade2Empty) { Hand pickBlade = blade1Empty ? Hand.Blade1 : Hand.Blade2; foreach (var pm in _lstPms) { if (!pm.IsAvailable) continue; var wafers = WaferManager.Instance.GetWafers(pm.Module); for (int slot = 0; slot < wafers.Length; slot++) { if (pm.IsReadyForPick(ModuleName.TMRobot, pickBlade, slot)) { if (_tmRobot.Pick(pm.Module, slot, pickBlade, 0, 0, false)) { wafers[slot].NextSequenceStep++; pm.WaitTransfer(ModuleName.TMRobot); return; } } } } } } } private void MonitorTMRobotPMTask() { if (!_tmRobot.IsAvailable) return; //place to pm bool blade0HasWafer = _tmRobot.Blade1Enable && WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0); bool blade1HasWafer = _tmRobot.Blade2Enable && WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 1); if (blade0HasWafer || blade1HasWafer) { Hand placeBlade = blade0HasWafer ? Hand.Blade1 : Hand.Blade2; var wafer = WaferManager.Instance.GetWafer(ModuleName.TMRobot, (int)placeBlade); foreach (var schedulerPm in _lstPms) { if (!schedulerPm.IsAvailable) continue; if (wafer.NextStation != (int)schedulerPm.Module) continue; var pmWafer0 = WaferManager.Instance.GetWafer(schedulerPm.Module, 0); var pmWafer1 = WaferManager.Instance.GetWafer(schedulerPm.Module, 1); //如果腔体中两片都满了,则不允许放入 if (!pmWafer0.IsEmpty && !pmWafer1.IsEmpty) continue; if (WaferManager.Instance.CheckNoWafer(schedulerPm.Module, 0)) { if (_tmRobot.Place(schedulerPm.Module, 0, placeBlade, 0, 0, false)) { schedulerPm.WaitTransfer(ModuleName.TMRobot); return; } } if (WaferManager.Instance.CheckNoWafer(schedulerPm.Module, 1)) { if (_tmRobot.Place(schedulerPm.Module, 1, placeBlade, 0, 0, false)) { schedulerPm.WaitTransfer(ModuleName.TMRobot); return; } } } } if (!_tmRobot.IsAvailable) return; //pick from pm { bool blade1Empty = _tmRobot.Blade1Enable && WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0); bool blade2Empty = _tmRobot.Blade2Enable && WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 1); if (blade1Empty || blade2Empty) { Hand pickBlade = blade1Empty ? Hand.Blade1 : Hand.Blade2; foreach (var pm in _lstPms) { if (!pm.IsAvailable) continue; var wafers = WaferManager.Instance.GetWafers(pm.Module); for (int slot = 0; slot < wafers.Length; slot++) { if (pm.IsReadyForPick(ModuleName.TMRobot, pickBlade, slot)) { if (_tmRobot.Pick(pm.Module, slot, pickBlade, 0, 0, false)) { wafers[slot].NextSequenceStep++; pm.WaitTransfer(ModuleName.TMRobot); return; } } } } } } } private bool MonitorTaskDone() { foreach (var positions in _checkPosition) { for (int i = 0; i < positions.Value; i++) { WaferInfo wafer = WaferManager.Instance.GetWafer(positions.Key, i); if (!wafer.IsEmpty) { return false; } } } foreach (var ll in _lstLls) { var llWafers = WaferManager.Instance.GetWafers(ll.Module); for (int i = 0; i < llWafers.Length; i++) { if (!llWafers[i].IsEmpty && llWafers[i].ProcessState != EnumWaferProcessStatus.Completed) return false; } } if (!_tmRobot.IsAvailable) return false; WaferInfo[] originWafers = WaferManager.Instance.GetWafers(ModuleHelper.Converter(tmCycleRoutine.First())); if (cycleCount > 1 && originWafers.All(x => x.IsEmpty || x.ProcessState == EnumWaferProcessStatus.Completed)) { cycleCount--; foreach (WaferInfo wafer in originWafers) { wafer.NextSequenceStep = 0; wafer.ProcessState = EnumWaferProcessStatus.InProcess; } return false; } return true; } private void MonitorPMTask() { foreach (var pm in _lstPms) { if (!pm.IsAvailable) continue; if (pm.Module == ModuleName.PMA && !PMAIsInstalled) continue; if (pm.Module == ModuleName.PMB && !PMBIsInstalled) continue; var wafers = WaferManager.Instance.GetWafers(pm.Module); for (int i = 0; i < wafers.Length; i++) { if (!pm.IsAvailable) break; if (!wafers[i].IsEmpty && !pm.IsReadyForPick(ModuleName.TMRobot, Hand.Blade1, i)) { pm.PrepareTransfer(ModuleName.TMRobot, EnumTransferType.Pick, i); return; } if (wafers[i].IsEmpty && !pm.IsReadyForPlace(ModuleName.TMRobot, Hand.Blade1, i)) { pm.PrepareTransfer(ModuleName.TMRobot, EnumTransferType.Place, i); return; } } } } private bool CheckWaferNextStep(ModuleName module, int slot, ModuleName nextModule) { if (!WaferManager.Instance.CheckHasWafer(module, slot)) return false; WaferInfo wafer = WaferManager.Instance.GetWafer(module, slot); if (wafer.NextSequenceStep >= tmCycleRoutine.Count) return false; if (tmCycleRoutine[wafer.NextSequenceStep] != nextModule.ToString()) return false; return true; } } }