Browse Source

Enhance routing algorithm.

sangwq 1 year ago
parent
commit
73f0d306a7

+ 214 - 80
Venus/Venus_RT/Modules/AutoCycle.cs

@@ -630,7 +630,7 @@ namespace Venus_RT.Modules
 
         private void driveVacSystem()
         {
-            PumpingTMRobotTask();
+            //PumpingTMRobotTask();
             //ProcessTMRobotTask();
             RoutingInnerPart();
             RuningTMRobotTask();
@@ -1138,6 +1138,107 @@ namespace Venus_RT.Modules
             return _movingItems.Count > 0;
         }
 
+        private bool SearchOutLLSlot(ModuleName pm, ModuleName ll, out SlotItem outSlot)
+        {
+            outSlot = new SlotItem(ModuleName.System, -1);
+            var wafer = WaferManager.Instance.GetWafer(pm, 0);
+            if (wafer.IsEmpty || wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null || wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
+                return false;
+
+            if(wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(ll))
+            {
+                var slotNumber = ll == ModuleName.LLA ? _LLASlotNumber : _LLBSlotNumber;
+                for(int slot = 0; slot < slotNumber; slot++)
+                {
+                    if ((WaferManager.Instance.CheckNoWafer(ll, slot) && !_movingItems.Exists(item => item.DestinationModule == ll && item.DestinationSlot == slot)) ||
+                        (WaferManager.Instance.CheckHasWafer(ll, slot) && _movingItems.Exists(item => item.SourceModule == ll && item.SourceSlot == slot)))
+                    {
+                        outSlot.Module = ll;
+                        outSlot.Slot = slot;
+                        return true;
+                    }
+                }
+            }
+
+            return false;
+        }
+
+        private bool SearchValidInPM(ModuleName ll, int slot, out SlotItem inSlot)
+        {
+            inSlot = new SlotItem(ModuleName.System, -1);
+            var wafer = WaferManager.Instance.GetWafer(ll, slot);
+            if (wafer.IsEmpty || wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null || wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
+                return false;
+
+            foreach (var mod in _vacModules)
+            {
+                if(ModuleHelper.IsPm(mod.Key) && _vacSchedulers[mod.Key].IsAvailable && _vacModules[mod.Key].MovingStatus == MovingStatus.Idle)
+                {
+                    if (wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(mod.Key))
+                    {
+                        if ((WaferManager.Instance.CheckNoWafer(mod.Key, 0) && !_movingItems.Exists(item => item.DestinationModule == mod.Key)) ||
+                            (WaferManager.Instance.CheckHasWafer(mod.Key, 0) && _movingItems.Exists(item => item.SourceModule == mod.Key)))
+                        {
+                            inSlot.Module = mod.Key;
+                            inSlot.Slot = 0;
+                            return true;
+                        }
+                    }
+                }
+            }
+            return false;
+        }
+
+        private bool ForwardPMsWaferToLL(ModuleName ll)
+        {
+            int outWaferCount = 0;
+            foreach (var module in _vacModules)
+            {
+                if (outWaferCount >= 2)
+                    break;
+
+                if (ModuleHelper.IsPm(module.Key) && _vacSchedulers[module.Key].IsAvailable && _vacModules[module.Key].MovingStatus == MovingStatus.Idle)
+                {
+                    if(WaferManager.Instance.CheckHasWafer(module.Key, 0))
+                    {
+                        if(SearchOutLLSlot(module.Key, ll, out SlotItem outSlot))
+                        {
+                            outWaferCount++;
+                            _movingItems.Add(new MoveItem(module.Key, 0, outSlot.Module, outSlot.Slot, Hand.None));
+                        }
+                    }
+                }
+            }
+            
+            return _movingItems.Count > 0;
+        }
+
+        private bool ForwardLLWaferToPMs(ModuleName ll)
+        {
+            int inWaferCount = 0;
+            var slots =(_vacSchedulers[ll] as SchedulerLoadLock).GetOrderedOutSlot();
+            foreach(var slot in slots)
+            {
+                if (inWaferCount >= 2)
+                    break;
+
+                if(SearchValidInPM(ll, slot, out SlotItem inSlot))
+                {
+                    inWaferCount++;
+                    _movingItems.Add(new MoveItem(ll, slot, inSlot.Module, inSlot.Slot, Hand.None));
+                }
+            }
+                
+            return _movingItems.Count > 0;
+        }
+
+        private bool ExchangeLLWafersWithPMs(ModuleName ll)
+        {
+            ForwardPMsWaferToLL(ll);
+            ForwardLLWaferToPMs(ll);
+            return _movingItems.Count > 0;
+        }
+
         private void RoutingInnerPart()
         {
             if (PushTMRobotWafers())
@@ -1147,40 +1248,64 @@ namespace Venus_RT.Modules
             if (pmSlotStaus.Processed + pmSlotStaus.Empty == 0)
                 return;
 
-            if(pmSlotStaus.Empty == 0)
+            var llaSlotStatus = GetLLProcessStatusCount(ModuleName.LLA);
+            var llbSlotStatus = GetLLProcessStatusCount(ModuleName.LLB);
+            if(LLInOutPath == SequenceLLInOutPath.AInBOut || LLInOutPath == SequenceLLInOutPath.BInAOut)
             {
-                if (PushPmWafers())
+                ModuleName InModule = LLInOutPath == SequenceLLInOutPath.AInBOut ? ModuleName.LLA : ModuleName.LLB;
+                ModuleName OutModule = LLInOutPath == SequenceLLInOutPath.AInBOut ? ModuleName.LLB : ModuleName.LLA;
+                int InNumber = Math.Min(InModule == ModuleName.LLA ? llaSlotStatus.unprocessed : llbSlotStatus.unprocessed, pmSlotStaus.Empty);
+                int OutNumber = Math.Min(OutModule == ModuleName.LLA ? llaSlotStatus.empty : llbSlotStatus.empty,  pmSlotStaus.Processed);
+
+                if (InNumber + OutNumber == 0)
                     return;
+
+                if(IsLoadReadyForTM(InModule) && (!IsLoadReadyForTM(OutModule) || (!_vacSchedulers[OutModule].IsVac && InNumber == OutNumber) || InNumber > OutNumber))
+                {
+                    // move in wafer
+                    ForwardLLWaferToPMs(InModule);
+                }
+                else if(IsLoadReadyForTM(OutModule) && OutNumber > 0)
+                {
+                    // move out wafer
+                    ForwardPMsWaferToLL(OutModule);
+                }
             }
-            else if(pmSlotStaus.Processed == 0)
+            else if(LLInOutPath == SequenceLLInOutPath.AInAOut || LLInOutPath == SequenceLLInOutPath.BInBOut)
             {
-                if (PushLoadlockWafers())
-                    return;
+                ModuleName loadlock = LLInOutPath == SequenceLLInOutPath.AInAOut ? ModuleName.LLA : ModuleName.LLB;
+                if(IsLoadReadyForTM(loadlock))
+                {
+                    // switch wafer
+                    ExchangeLLWafersWithPMs(loadlock);
+                }
             }
-            else
+            else // DInDOut or mix pattern
             {
-                if(pmSlotStaus.Processed >= pmSlotStaus.Empty)
-                {
-                    if (PushPmWafers())
-                        return;
+                int llaOutNumber = Math.Min(Math.Min(pmSlotStaus.Processed, 2), llaSlotStatus.empty);
+                int llaInNumber = Math.Min(Math.Min(llaSlotStatus.unprocessed, 2), pmSlotStaus.Empty + llaOutNumber);
+                int llaExchangeNumber = llaOutNumber + llaInNumber;
 
-                    if (PushLoadlockWafers())
-                        return;
+                int llbOutNumber = Math.Min(Math.Min(pmSlotStaus.Processed, 2), llbSlotStatus.empty);
+                int llbInNumber = Math.Min(Math.Min(llbSlotStatus.unprocessed, 2), pmSlotStaus.Empty + llbOutNumber);
+                int llbExchangeNumber = llbOutNumber + llbInNumber;
+
+                if (IsLoadReadyForTM(ModuleName.LLA) && ((!_vacSchedulers[ModuleName.LLB].IsVac && llaExchangeNumber == llbExchangeNumber) || 
+                                                                        (llaExchangeNumber > llbExchangeNumber) || 
+                                                                        (!IsLoadReadyForTM(ModuleName.LLB) && llaExchangeNumber > 0)))
+                {
+                    ExchangeLLWafersWithPMs(ModuleName.LLA);
                 }
-                else
+                else if(IsLoadReadyForTM(ModuleName.LLB) && llaExchangeNumber > 0)
                 {
-                    if (PushLoadlockWafers())
-                        return;
-
-                    if (PushPmWafers())
-                        return;
+                    ExchangeLLWafersWithPMs(ModuleName.LLB);
                 }
             }
         }
 
         private void RuningTMRobotTask()
         {
-            if (_tmRobot.IsAvailable)
+            if (_tmRobot.IsAvailable && _movingItems.Count > 0)
             {
                 if (_tmRobot.PostMoveItems(_movingItems.ToArray()))
                 {
@@ -1399,43 +1524,32 @@ namespace Venus_RT.Modules
 
         private void PumpingEFEMRobotTask()
         {
-            foreach (var scheduler in _atmSchedulers)
+            var aligners = _atmSchedulers.Select(x => x).Where(x => ModuleHelper.IsAligner(x.Key) && x.Value.IsAvailable).ToDictionary(k => k.Key, v => v.Value);
+            foreach (var aligner in aligners)
             {
-                if (!scheduler.Value.IsAvailable)
-                    continue;
-
-                if (ModuleHelper.IsAligner(scheduler.Key))
-                {
-                    if (_atmModules[scheduler.Key].MovingStatus != MovingStatus.Idle)
-                    {
-                        ProcessAlignerTask();
-                        if (_atmModules[scheduler.Key].MovingStatus != MovingStatus.Idle)
-                            return;
-                    }
-
-                    if (ProcessAlignerEFEMRobotTask(scheduler.Key))
-                        return;
-                }
-                else if (ModuleHelper.IsLoadLock(scheduler.Key))
-                {
-                    if (ProcessLLEFEMRobotTask(scheduler.Key))
-                        return;
-                }
-                else if (ModuleHelper.IsCooling(scheduler.Key))
+                if (_atmModules[aligner.Key].MovingStatus != MovingStatus.Idle)
                 {
-                    if (ProcessCoolingEFEMRobotTask(scheduler.Key))
+                    ProcessAlignerTask();
+                    if (_atmModules[aligner.Key].MovingStatus != MovingStatus.Idle)
                         return;
                 }
-                else if (ModuleHelper.IsLoadPort(scheduler.Key))
-                {
-                    if (ProcessLPEFEMRobotTask(scheduler.Key))
-                        return;
-                }
-                else
-                {
-                    // should not go here
-                    LOG.Write(eEvent.ERR_ROUTER, $"Wrong Module: {scheduler.Key} in ATM System");
-                }
+
+                if (ProcessAlignerEFEMRobotTask(aligner.Key))
+                    return;
+            }
+
+            var lls = _atmSchedulers.Select(x => x).Where(x => ModuleHelper.IsLoadLock(x.Key) && x.Value.IsAvailable).ToDictionary(k => k.Key, v => v.Value);
+            foreach(var ll in lls)
+            {
+                if (ProcessLLEFEMRobotTask(ll.Key))
+                    return;
+            }
+
+            var lps = _atmSchedulers.Select(x => x).Where(x => ModuleHelper.IsLoadPort(x.Key) && x.Value.IsAvailable).ToDictionary(k => k.Key, v => v.Value);
+            foreach(var lp in lps)
+            {
+                if (ProcessLPEFEMRobotTask(lp.Key))
+                    return;
             }
         }
 
@@ -1451,10 +1565,10 @@ namespace Venus_RT.Modules
                 if (wafer.IsEmpty)
                     continue;
 
-                if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
+                if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null || wafer.NextSequenceStep == wafer.ProcessJob.Sequence.Steps.Count)
                     continue;
 
-                if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
+                if (wafer.NextSequenceStep > wafer.ProcessJob.Sequence.Steps.Count)
                 {
                     // should not go here
                     LOG.Write(eEvent.ERR_ROUTER, ModuleName.System, $"Wafer:{wafer.WaferOrigin} NextSequenceStep {wafer.NextSequenceStep} exceeds {wafer.ProcessJob.Sequence.Name} max steps number");
@@ -1488,7 +1602,7 @@ namespace Venus_RT.Modules
             else if (wafer.NextSequenceStep > wafer.ProcessJob.Sequence.Steps.Count)
             {
                 // should not go here
-                LOG.Write(eEvent.ERR_ROUTER, ModuleName.System, $"Wafer:{wafer.WaferOrigin} NextSequenceStep {wafer.NextSequenceStep} exceeds {wafer.ProcessJob.Sequence.Name} max steps number");
+                LOG.Write(eEvent.ERR_ROUTER, ModuleName.System, $"Wafer:{wafer.WaferOrigin} NextSequenceStep {wafer.NextSequenceStep} exceeds {wafer.ProcessJob.Sequence.Name} max steps number in IsAtmWaferReadyOut()");
                 return false;
             }
 
@@ -1582,7 +1696,7 @@ namespace Venus_RT.Modules
             int Empty = 0;
             foreach (var module in _vacModules)
             {
-                if (ModuleHelper.IsPm(module.Key) && _vacSchedulers[module.Key].IsAvailable)
+                if (ModuleHelper.IsPm(module.Key) && _vacSchedulers[module.Key].IsAvailable && _vacModules[module.Key].MovingStatus == MovingStatus.Idle)
                 {
                     var wafer = WaferManager.Instance.GetWafer(module.Key, 0);
                     if(wafer.IsEmpty)
@@ -1641,6 +1755,11 @@ namespace Venus_RT.Modules
             return unfinished.Contains(ll);
         }
 
+        private bool IsLoadReadyForTM(ModuleName ll)
+        {
+            return _vacSchedulers[ll].IsAvailable && _vacModules[ll].MovingStatus == MovingStatus.Idle && !IsLoadLockReservedByEFEM(ll);
+        }
+
         private bool IsPMKeepEmpty(ModuleName pm)
         {
             return WaferManager.Instance.CheckNoWafer(pm, 0) && _movingItems.FindIndex(item => item.DestinationModule == pm) == -1;
@@ -1691,10 +1810,11 @@ namespace Venus_RT.Modules
             return false;
         }
 
-        private Tuple<int, int> GetLLProcessStatusCount(ModuleName ll)
+        private (int processed, int unprocessed, int empty) GetLLProcessStatusCount(ModuleName ll)
         {
             int processedCount = 0;
             int unprocessCount = 0;
+            int empty = 0;
             int slotCount = ll == ModuleName.LLA ? _LLASlotNumber : _LLBSlotNumber;
             if (ModuleHelper.IsLoadLock(ll))
             {
@@ -1710,7 +1830,7 @@ namespace Venus_RT.Modules
                 }
             }
 
-            return new Tuple<int, int>(processedCount, unprocessCount);
+            return (processedCount, unprocessCount, slotCount - processedCount - unprocessCount);
         }
 
 
@@ -1737,34 +1857,50 @@ namespace Venus_RT.Modules
 
             if (_LLInOutPath == SequenceLLInOutPath.AInBOut)
             {
-                return llbWaferStatus.Item1 == _LLBSlotNumber ? 0 :
-                    _LLASlotNumber + pmWaferStatus.empty - llaWaferStatus.Item1 - llaWaferStatus.Item2
+                if (_atmSchedulers[ModuleName.LLB].IsAtm && llbWaferStatus.processed >= 2)
+                    return 0;
+
+                int canPushIn = llbWaferStatus.processed == _LLBSlotNumber ? 0 :
+                    pmWaferStatus.empty + llaWaferStatus.empty
                     - GetTMRobotWaferCount() - GetAtmInerWaferCount() - GetEfemRoborWaferCount();
+
+                // 修正 单手臂占用影响Throughput的问题
+                if (canPushIn == 1/* && llbWaferStatus.processed >= 2*/)
+                    return 0;
+
+                return canPushIn;
             }
             else if (_LLInOutPath == SequenceLLInOutPath.BInAOut)
             {
-                return llaWaferStatus.Item1 == _LLASlotNumber ? 0 :
-                    _LLBSlotNumber + pmWaferStatus.empty - llbWaferStatus.Item1 - llbWaferStatus.Item2
+                if (_atmSchedulers[ModuleName.LLA].IsAtm && llaWaferStatus.processed >= 2)
+                    return 0;
+
+                int canPushIn = llaWaferStatus.processed == _LLASlotNumber ? 0 :
+                    pmWaferStatus.empty + llbWaferStatus.empty
                     - GetTMRobotWaferCount() - GetAtmInerWaferCount() - GetEfemRoborWaferCount();
+
+                if (canPushIn == 1 && llaWaferStatus.processed >= 2)
+                    return 0;
+
+                return canPushIn;
             }
             else if (_LLInOutPath == SequenceLLInOutPath.AInAOut || (_LLInOutPath == SequenceLLInOutPath.DInDOut && _vacSchedulers[ModuleName.LLA].IsOnline && !_vacSchedulers[ModuleName.LLB].IsOnline))
             {
-                return llaWaferStatus.Item1 > 0 ? 0 :
-                    _LLASlotNumber / 2 + pmWaferStatus.empty - llaWaferStatus.Item2
+                return llaWaferStatus.processed > 0 ? 0 :
+                    _LLASlotNumber / 2 + pmWaferStatus.empty - llaWaferStatus.unprocessed
                     - GetTMRobotWaferCount() - GetEfemRoborWaferCount() - GetAtmInerWaferCount();
 
             }
             else if (_LLInOutPath == SequenceLLInOutPath.BInBOut || (_LLInOutPath == SequenceLLInOutPath.DInDOut && !_vacSchedulers[ModuleName.LLA].IsOnline && _vacSchedulers[ModuleName.LLB].IsOnline))
             {
-                return llbWaferStatus.Item1 > 0 ? 0 :
-                    _LLBSlotNumber / 2 + pmWaferStatus.empty - llbWaferStatus.Item2
+                return llbWaferStatus.processed > 0 ? 0 :
+                    _LLBSlotNumber / 2 + pmWaferStatus.empty - llbWaferStatus.unprocessed
                         - GetTMRobotWaferCount() - GetEfemRoborWaferCount() - GetAtmInerWaferCount();
             }
             else if (_LLInOutPath == SequenceLLInOutPath.DInDOut && _vacSchedulers[ModuleName.LLA].IsOnline && _vacSchedulers[ModuleName.LLB].IsOnline)
             {
-                return llaWaferStatus.Item1 + llbWaferStatus.Item1 > 1 ? 0 :
-                    (_LLASlotNumber + _LLBSlotNumber) / 2 + pmWaferStatus.empty
-                    - llaWaferStatus.Item1 - llaWaferStatus.Item2 - llbWaferStatus.Item1 - llbWaferStatus.Item2
+                return llaWaferStatus.processed + llbWaferStatus.processed > 1 ? 0 :
+                    (llaWaferStatus.empty + llbWaferStatus.empty) / 2 + pmWaferStatus.empty
                     - GetTMRobotWaferCount() - GetEfemRoborWaferCount() - GetAtmInerWaferCount();
             }
             else
@@ -2124,22 +2260,20 @@ namespace Venus_RT.Modules
             {
                 foreach (var stepModule in wafer.ProcessJob.Sequence.Steps[i].StepModules)
                 {
-                    if (!ModuleHelper.IsPm(stepModule))
-                        break;
-
                     if (!_vacSchedulers.Keys.Contains(stepModule))
                         continue;
 
                     if (!_vacSchedulers[stepModule].IsOnline)
                         continue;
-                }
-
-                if (processIn == ModuleName.System)
-                    return true;
 
-                if (wafer.ProcessJob.Sequence.Steps[i].StepModules
-                    .Contains(processIn))
-                    return true;
+                    if (ModuleHelper.IsPm(stepModule))
+                    {
+                        if (stepModule == processIn || processIn == ModuleName.System)
+                            return true;
+                    }
+                    else
+                        break;
+                }
             }
 
             return false;

+ 13 - 7
Venus/Venus_RT/Modules/EFEM/EfemSwapRoutine.cs

@@ -43,6 +43,9 @@ namespace Venus_RT.Modules.EFEM
         private int _autoPumpOptInWafer = 4;
         private int _autoPumpOptOutWafer = 0;
 
+        private SequenceLLInOutPath _sequencePattern = SequenceLLInOutPath.DInDOut;
+        private bool _bAutoMode = true;
+
         public EfemSwapRoutine(EfemBase efem) : base(ModuleName.EfemRobot)
         {
             _efem = efem;
@@ -93,6 +96,9 @@ namespace Venus_RT.Modules.EFEM
             _autoPumpOptInWafer = SC.GetValue<int>("EFEM.LLAutoPumpInWaferOpt");
             _autoPumpOptOutWafer = SC.GetValue<int>("EFEM.LLAutoPumpOutWaferOpt");
 
+            _sequencePattern = Singleton<RouteManager>.Instance.LLInOutPath;
+            _bAutoMode = Singleton<RouteManager>.Instance.IsAutoMode;
+
             _actionCount = _actionList.Count;
             return Runner.Start(Module, $"EFEM Swap with {_targetModule}");
         }
@@ -216,21 +222,21 @@ namespace Venus_RT.Modules.EFEM
             var waferStatus = _llModule.GetWaferProcessStatus();
 
             bool bAutoPump = false;
-            if (Singleton<RouteManager>.Instance.IsAutoMode)
+            if (_bAutoMode)
             {
-                if (((Singleton<RouteManager>.Instance.LLInOutPath == SequenceLLInOutPath.AInBOut && _targetModule == ModuleName.LLA) ||
-                     (Singleton<RouteManager>.Instance.LLInOutPath == SequenceLLInOutPath.BInAOut && _targetModule == ModuleName.LLB)) &&
+                if (((_sequencePattern == SequenceLLInOutPath.AInBOut && _targetModule == ModuleName.LLA) ||
+                     (_sequencePattern == SequenceLLInOutPath.BInAOut && _targetModule == ModuleName.LLB)) &&
                       waferStatus.unprocessed >= _autoPumpOptInWafer)
                 {
                     bAutoPump = true;
                 }
-                else if (((Singleton<RouteManager>.Instance.LLInOutPath == SequenceLLInOutPath.AInBOut && _targetModule == ModuleName.LLB) ||
-                          (Singleton<RouteManager>.Instance.LLInOutPath == SequenceLLInOutPath.BInAOut && _targetModule == ModuleName.LLA)) &&
+                else if (((_sequencePattern == SequenceLLInOutPath.AInBOut && _targetModule == ModuleName.LLB) ||
+                          (_sequencePattern == SequenceLLInOutPath.BInAOut && _targetModule == ModuleName.LLA)) &&
                            waferStatus.processed <= _autoPumpOptOutWafer)
                 {
                     bAutoPump = true;
                 }
-                else if (Singleton<RouteManager>.Instance.LLInOutPath == SequenceLLInOutPath.DInDOut &&
+                else if (_sequencePattern == SequenceLLInOutPath.DInDOut &&
                     waferStatus.processed   >= _autoPumpOptOutWafer &&
                     waferStatus.unprocessed <= _autoPumpOptInWafer)
                 {
@@ -238,7 +244,7 @@ namespace Venus_RT.Modules.EFEM
                 }
             }
 
-            LOG.Write(eEvent.EV_EFEM_ROBOT, Module, $"NotifyLLDone() => {_targetModule}, Sequence Pattern{Singleton<RouteManager>.Instance.LLInOutPath}, unprocessed wafer:{waferStatus.unprocessed}, processed wafer: {waferStatus.processed},bAutoPump  = {bAutoPump}, Config Option:{_autoPumpOptInWafer},{_autoPumpOptOutWafer}");
+            LOG.Write(eEvent.EV_EFEM_ROBOT, Module, $"NotifyLLDone() => {_targetModule}, Sequence Pattern{_sequencePattern}, unprocessed wafer:{waferStatus.unprocessed}, processed wafer: {waferStatus.processed},bAutoPump  = {bAutoPump}, Config Option:{_autoPumpOptInWafer},{_autoPumpOptOutWafer}");
             _llModule.PostMsg(bAutoPump ? LLEntity.MSG.AutoPump : LLEntity.MSG.EFEM_Exchange_Ready);
             
             return true;

+ 0 - 3
Venus/Venus_RT/Modules/RouteManager.cs

@@ -198,8 +198,6 @@ namespace Venus_RT.Modules
             {
                 seTM = new SETMEntity();
             }
-
-
                 
 
             fsm = new StateMachine<RouteManager>(Name, (int)RtState.Init, 200);
@@ -608,7 +606,6 @@ namespace Venus_RT.Modules
        
         private void BuildTransitionTable()
         {
-            fsm = new StateMachine<RouteManager>(ModuleName.System.ToString(), (int)RtState.Init, 50);
             //Init sequence
             Transition(RtState.Init,            MSG.HOME,               FsmStartHome,               RtState.Initializing);
             Transition(RtState.Idle,            MSG.HOME,               FsmStartHome,               RtState.Initializing);

+ 5 - 0
Venus/Venus_RT/Modules/Schedulers/SchedulerLoadLock.cs

@@ -51,5 +51,10 @@ namespace Venus_RT.Modules.Schedulers
         {
             return true;
         }
+
+        public List<int> GetOrderedOutSlot()
+        {
+            return  WaferArriveTicks.OrderBy(item => item.Value).ToDictionary(k => k.Key, v => v.Value).Keys.ToList();
+        }
     }
 }

+ 29 - 0
Venus/Venus_RT/Modules/Schedulers/SchedulerTMRobot.cs

@@ -319,6 +319,7 @@ namespace Venus_RT.Modules.Schedulers
                 }
             }
 
+            PrepareLLPressure(items);
             RunSchedulers();
             return true;
         }
@@ -368,5 +369,33 @@ namespace Venus_RT.Modules.Schedulers
             _schedulerList.Clear();
 
         }
+
+        private void PrepareLLPressure(MoveItem[] items)
+        {
+            if (items.Length == 0)
+                return;
+
+            ModuleName firstModule = items[0].SourceModule;
+            List<ModuleName> lls = new List<ModuleName>();
+            for (int i = 0; i < items.Length; i++)
+            {
+                if(ModuleHelper.IsLoadLock(items[i].SourceModule) && Singleton<RouteManager>.Instance.GetLL(items[i].SourceModule).IsATM)
+                {
+                    if (!lls.Contains(items[i].SourceModule) && items[i].SourceModule != firstModule)
+                        lls.Add(items[i].SourceModule);
+                }
+
+                if (ModuleHelper.IsLoadLock(items[i].DestinationModule) && Singleton<RouteManager>.Instance.GetLL(items[i].DestinationModule).IsATM)
+                {
+                    if (!lls.Contains(items[i].DestinationModule) && items[i].DestinationModule != firstModule)
+                        lls.Add(items[i].DestinationModule);
+                }
+            }
+
+            foreach( var ll in lls)
+            {
+                Singleton<RouteManager>.Instance.GetLL(ll).CheckToPostMessage((int)LLEntity.MSG.Pump);
+            }
+        }
     }
 }

+ 14 - 8
Venus/Venus_RT/Modules/TM/MFSwapRoutine.cs

@@ -40,6 +40,9 @@ namespace Venus_RT.Modules.TM
         private int _autoVentOptInWafer = 0;
         private int _autoVentOptOutWafer = 4;
 
+        private SequenceLLInOutPath _sequencePattern = SequenceLLInOutPath.DInDOut;
+        private bool _bAutoMode = true;
+
 
         Queue<MoveItem> _actionList = new Queue<MoveItem>();
         MoveItem _currentAction;
@@ -88,6 +91,9 @@ namespace Venus_RT.Modules.TM
             _autoVentOptInWafer = SC.GetValue<int>("TM.LLAutoVentInWaferOpt");
             _autoVentOptOutWafer = SC.GetValue<int>("TM.LLAutoVentOutWaferOpt");
 
+            _sequencePattern = Singleton<RouteManager>.Instance.LLInOutPath;
+            _bAutoMode = Singleton<RouteManager>.Instance.IsAutoMode;
+
             return Runner.Start(Module, $"Swap with {_targetModule}");
         }
 
@@ -244,23 +250,23 @@ namespace Venus_RT.Modules.TM
 
         private bool NotifyLLDone()
         {
-            var waferStatus = _llModule.GetWaferProcessStatus();
             bool bAutoVent = false;
-            if(Singleton<RouteManager>.Instance.IsAutoMode)
+            var waferStatus = _llModule.GetWaferProcessStatus();
+            if(_bAutoMode)
             {
-                if (((Singleton<RouteManager>.Instance.LLInOutPath == SequenceLLInOutPath.AInBOut && _targetModule == ModuleName.LLA) || 
-                     (Singleton<RouteManager>.Instance.LLInOutPath == SequenceLLInOutPath.BInAOut && _targetModule == ModuleName.LLB)) &&
+                if (((_sequencePattern == SequenceLLInOutPath.AInBOut && _targetModule == ModuleName.LLA) || 
+                     (_sequencePattern == SequenceLLInOutPath.BInAOut && _targetModule == ModuleName.LLB)) &&
                       waferStatus.unprocessed <= _autoVentOptInWafer)
                 {
                     bAutoVent = true;
                 }
-                else if (((Singleton<RouteManager>.Instance.LLInOutPath == SequenceLLInOutPath.AInBOut && _targetModule == ModuleName.LLB) ||
-                          (Singleton<RouteManager>.Instance.LLInOutPath == SequenceLLInOutPath.BInAOut && _targetModule == ModuleName.LLA)) &&
+                else if (((_sequencePattern == SequenceLLInOutPath.AInBOut && _targetModule == ModuleName.LLB) ||
+                          (_sequencePattern == SequenceLLInOutPath.BInAOut && _targetModule == ModuleName.LLA)) &&
                            waferStatus.processed >= _autoVentOptOutWafer)
                 {
                     bAutoVent = true;
                 }
-                else if(Singleton<RouteManager>.Instance.LLInOutPath == SequenceLLInOutPath.DInDOut && 
+                else if(_sequencePattern == SequenceLLInOutPath.DInDOut && 
                     waferStatus.processed   >= _autoVentOptOutWafer && 
                     waferStatus.unprocessed <= _autoVentOptInWafer)
                 {
@@ -268,7 +274,7 @@ namespace Venus_RT.Modules.TM
                 }
             }
 
-            LOG.Write(eEvent.INFO_TM, Module, $"NotifyLLDone() => {_targetModule}, Sequence Pattern{Singleton<RouteManager>.Instance.LLInOutPath}, unprocessed wafer:{waferStatus.unprocessed}, processed wafer: {waferStatus.processed},bAutoVent  = {bAutoVent}, Config Option:{_autoVentOptInWafer},{_autoVentOptOutWafer}");
+            LOG.Write(eEvent.INFO_TM, Module, $"NotifyLLDone() => {_targetModule}, Sequence Pattern{_sequencePattern}, unprocessed wafer:{waferStatus.unprocessed}, processed wafer: {waferStatus.processed},bAutoVent  = {bAutoVent}, Config Option:{_autoVentOptInWafer},{_autoVentOptOutWafer}");
             _llModule.PostMsg(bAutoVent ? LLEntity.MSG.AutoVent : LLEntity.MSG.TM_Exchange_Ready);
             return true;
         }