Browse Source

developing routing algorithm.

sangwq 1 year ago
parent
commit
3ee9634ad3

+ 241 - 21
Venus/Venus_RT/Modules/AutoCycle.cs

@@ -78,6 +78,8 @@ namespace Venus_RT.Modules
         List<int> _LLAOutSlot = new List<int> { 0, 1, 2, 3 };
         List<int> _LLBInSlot = new List<int> { 0, 1, 2, 3 };
         List<int> _LLBOutSlot = new List<int> { 0, 1, 2, 3 };
+        int _LLASlotNumber = 4;
+        int _LLBSlotNumber = 4;
 
         List<MoveItem> _movingItems = new List<MoveItem>();
         List<MoveItem> _efemMovingItems = new List<MoveItem>();
@@ -102,6 +104,9 @@ namespace Venus_RT.Modules
 
             InitModules();
 
+            _LLASlotNumber = SC.GetValue<int>("LLA.SlotNumber");
+            _LLBSlotNumber = SC.GetValue<int>("LLB.SlotNumber");
+
             DATA.Subscribe("Scheduler.CycledCount", () => _cycledCount);
             DATA.Subscribe("Scheduler.CycledWafer", () => _cycledWafer);
             DATA.Subscribe("Scheduler.CycleSetPoint", () => _cycleSetPoint);
@@ -568,6 +573,8 @@ namespace Venus_RT.Modules
                     }
                 }
             }
+
+            StartNewJob();
         }
 
         private void driveVacSystem()
@@ -584,7 +591,6 @@ namespace Venus_RT.Modules
             {
                 if (mod.Value.IsAvailable && _vacModules[mod.Key].MovingStatus == MovingStatus.Staying)
                 {
-
                     if(ModuleHelper.IsLoadLock(mod.Key))
                     {
                         var inSlots = mod.Key == ModuleName.LLA ? _LLAInSlot : _LLBInSlot;
@@ -859,11 +865,6 @@ namespace Venus_RT.Modules
                     if (ProcessLLEFEMRobotTask(scheduler.Key))
                         return;
                 }
-                else if(ModuleHelper.IsLoadPort(scheduler.Key))
-                {
-                    if (ProcessLPEFEMRobotTask(scheduler.Key))
-                        return;
-                }
                 else if(ModuleHelper.IsAligner(scheduler.Key))
                 {
                     if (ProcessAlignerEFEMRobotTask(scheduler.Key))
@@ -874,6 +875,11 @@ namespace Venus_RT.Modules
                     if (ProcessCoolingEFEMRobotTask(scheduler.Key))
                         return;
                 }
+                else if (ModuleHelper.IsLoadPort(scheduler.Key))
+                {
+                    if (ProcessLPEFEMRobotTask(scheduler.Key))
+                        return;
+                }
                 else
                 {
                     // should not go here
@@ -974,6 +980,83 @@ namespace Venus_RT.Modules
             return _efemMovingItems.Count > 0;
         }
 
+        private Tuple<int, int> GetPMWaferExistence()
+        {
+            int exist = 0;
+            int empty = 0;
+            foreach (var atmModule in _atmModules)
+            {
+                if (ModuleHelper.IsPm(atmModule.Key))
+                {
+                    if (WaferManager.Instance.CheckHasWafer(atmModule.Key, 0))
+                        exist++;
+                    else
+                        empty++;
+                }
+                    
+            }
+
+            return new Tuple<int, int>(exist, empty);
+        }
+
+        private int GetTMRobotWaferCount()
+        {
+            return (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0) ? 1 : 0) + (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 1) ? 1 : 0);
+        }
+
+        private int GetEfemRoborWaferCount()
+        {
+            return (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 0) ? 1 : 0) + (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 1) ? 1 : 0);
+        }
+
+        private Tuple<int, int>  GetLLProcessStatusCount(ModuleName ll)
+        {
+            int processedCount = 0;
+            int unprocessCount = 0;
+            int slotCount = ll == ModuleName.LLA ? _LLASlotNumber : _LLBSlotNumber;
+            if(ModuleHelper.IsLoadLock(ll))
+            {
+                for(int i = 0; i < slotCount;i++)
+                {
+                    if(WaferManager.Instance.CheckHasWafer(ll, i))
+                    {
+                        if(CheckWaferNeedProcessAndPMAvailable(ll, i))
+                            unprocessCount++;
+                        else
+                            processedCount++;
+                    }
+                }
+            }
+
+            return new Tuple<int, int>(processedCount, unprocessCount);
+        }
+
+
+        private int GetAtmInerWaferCount()
+        {
+            int nCount = 0;
+            foreach(var atmModule in _atmModules)
+            {
+                if (!ModuleHelper.IsEFEMRobot(atmModule.Key) && WaferManager.Instance.CheckHasWafer(atmModule.Key, 0))
+                    nCount++;
+            }
+
+            return nCount;
+        }
+        private bool IsReadyPushWaferIn()
+        {
+            var llaWaferStatus = GetLLProcessStatusCount(ModuleName.LLA);
+            var llbWaferStatus = GetLLProcessStatusCount(ModuleName.LLB);
+            var pmWaferStatus = GetPMWaferExistence();
+            if (pmWaferStatus.Item2 <= (llaWaferStatus.Item2 + llbWaferStatus.Item2))
+                return false;
+
+            if (GetEfemRoborWaferCount() >= 1 && GetAtmInerWaferCount() > 0)
+                return false;
+
+            return true;
+        }
+
         private bool ProcessLPEFEMRobotTask(ModuleName lp)
         {
             // check return
@@ -995,16 +1078,16 @@ namespace Venus_RT.Modules
                 }
             }
 
-            if (_efemMovingItems.Count > 0)
-                return true;
-
-            var outSlots = GetNextWaferInJobQueue(lp);
-            foreach(var slot in outSlots)
+            if(_efemMovingItems.Count == 0 && IsReadyPushWaferIn())
             {
-                var hand = GetEFEMRobotFreeHand();
-                if(hand != Hand.None)
+                var outSlots = GetNextWaferInJobQueue(lp);
+                foreach (var slot in outSlots)
                 {
-                    _efemMovingItems.Add(new MoveItem(lp, slot, ModuleName.EfemRobot, (int)hand, hand));
+                    var hand = GetEFEMRobotFreeHand();
+                    if (hand != Hand.None)
+                    {
+                        _efemMovingItems.Add(new MoveItem(lp, slot, ModuleName.EfemRobot, (int)hand, hand));
+                    }
                 }
             }
 
@@ -1015,10 +1098,6 @@ namespace Venus_RT.Modules
         {
             var inSlots = new List<int>();
 
-
-            //if (GetSystemInnerWaferCount() >= SystemInternalWaferCount || GetBufferWaferCount() > _maxBufferWaferCount)
-                //return new SlotItem(ModuleName.System, -1);
-
             foreach (var cj in _lstControlJobs)
             {
                 if (lp != ModuleName.System && (cj.Module != lp.ToString()))
@@ -1056,13 +1135,20 @@ namespace Venus_RT.Modules
                 {
                     _efemMovingItems.Add(new MoveItem(aligner, 0, ModuleName.EfemRobot, (int)hand, hand));
                 }
+
+                //// check with whether another robot arm wafer wait go to aligner
+                //var robotSlots = GetEfemRobotWaferReadyInHands(aligner);
+                //if (robotSlots.Count > 0)
+                //{
+                //    _efemMovingItems.Add(new MoveItem(ModuleName.EfemRobot, robotSlots.First(), aligner, 0, (Hand)robotSlots.First()));
+                //}
             }
-            else
+            else if(WaferManager.Instance.CheckNoWafer(aligner, 0))
             {
                 var robotSlots = GetEfemRobotWaferReadyInHands(aligner);
                 if(robotSlots.Count > 0)
                 {
-                    _efemMovingItems.Add(new MoveItem(aligner, 0, ModuleName.EfemRobot, robotSlots.First(), (Hand)robotSlots.First()));
+                    _efemMovingItems.Add(new MoveItem(ModuleName.EfemRobot, robotSlots.First(), aligner, 0, (Hand)robotSlots.First()));
                 }
             }
 
@@ -1093,7 +1179,7 @@ namespace Venus_RT.Modules
 
         private void RuningEFEMRobotTask()
         {
-            if (_efemRobot.IsAvailable)
+            if (_efemRobot.IsAvailable && _efemMovingItems.Count > 0)
             {
                 if (_efemRobot.PostMoveItems(_efemMovingItems.ToArray()))
                 {
@@ -1247,6 +1333,140 @@ namespace Venus_RT.Modules
             return false;
         }
 
+        private List<ModuleName> GetPmUsedInRunningPj()
+        {
+            var pmUsed = new List<ModuleName>();
+            foreach (var cj in _lstControlJobs)
+            {
+                if (cj.State != EnumControlJobState.Executing && cj.State != EnumControlJobState.Paused)
+                    continue;
+
+                foreach (var pj in _lstProcessJobs)
+                {
+                    if (pj.ControlJobName == cj.Name && (pj.State == EnumProcessJobState.Processing || pj.State == EnumProcessJobState.Paused))
+                    {
+                        for (int i = 0; i < pj.Sequence.Steps.Count; i++)
+                        {
+                            SequenceStepInfo stepInfo = pj.Sequence.Steps[i];
+                            foreach (var module in stepInfo.StepModules)
+                            {
+                                if (ModuleHelper.IsPm(module) && !pmUsed.Contains(module))
+                                    pmUsed.Add(module);
+                            }
+                        }
+                    }
+                }
+            }
+
+            return pmUsed;
+        }
+
+        private List<SchedulerPM> GetPmNeeded(ControlJobInfo cj)
+        {
+            List<SchedulerPM> result = new List<SchedulerPM>();
+
+            foreach (var pj in _lstProcessJobs)
+            {
+                if (pj.ControlJobName != cj.Name)
+                    continue;
+
+                var seq = pj.Sequence;
+                for (int i = 0; i < seq.Steps.Count; i++)
+                {
+                    SequenceStepInfo stepInfo = seq.Steps[i];
+                    foreach (var module in stepInfo.StepModules)
+                    {
+                        if (ModuleHelper.IsPm(module))
+                        {
+                            var pm = _vacSchedulers[module] as SchedulerPM;
+
+                            if (pm != null && !result.Contains(pm))
+                            {
+                                result.Add(pm);
+                            }
+                        }
+                    }
+                }
+            }
+
+
+            return result;
+        }
+        private void PreJobClean(ControlJobInfo cj)
+        {
+            if (cj.IsPreJobCleanDone)
+                return;
+
+            cj.IsPreJobCleanDone = true;
+
+            List<SchedulerPM> pms = GetPmNeeded(cj);
+            foreach (var pm in pms)
+            {
+                pm.PreJobClean();
+            }
+        }
+        private bool ActiveProcessJob(ProcessJobInfo pj)
+        {
+            foreach (var pjSlotWafer in pj.SlotWafers)
+            {
+                WaferInfo wafer = WaferManager.Instance.GetWafer(pjSlotWafer.Item1, pjSlotWafer.Item2);
+
+                wafer.ProcessJob = pj;
+                wafer.NextSequenceStep = 0;
+
+                WaferDataRecorder.SetPjInfo(wafer.InnerId.ToString(), pj.InnerId.ToString());
+            }
+
+            ControlJobInfo cj = _lstControlJobs.Find(x => x.Name == pj.ControlJobName);
+
+            CarrierInfo carrier = CarrierManager.Instance.GetCarrier(cj.Module);
+            JobDataRecorder.StartPJ(pj.InnerId.ToString(), carrier.InnerId.ToString(), cj.InnerId.ToString(), pj.Name, cj.Module, cj.Module, pj.SlotWafers.Count);
+
+            pj.SetState(EnumProcessJobState.Processing);
+
+            PreJobClean(cj);
+
+            return true;
+        }
+        private void StartNewJob()
+        {
+            ControlJobInfo cjActived = null;
+
+            List<ModuleName> pmOccupied = GetPmUsedInRunningPj();
+            foreach (var cj in _lstControlJobs)
+            {
+                if (cj.State != EnumControlJobState.Executing)
+                    continue;
+
+                cjActived = cj;
+
+                foreach (var pjName in cjActived.ProcessJobNameList)
+                {
+                    var pj = _lstProcessJobs.Find(x => x.Name == pjName);
+                    if (pj == null)
+                    {
+                        LOG.Write(eEvent.ERR_ROUTER, ModuleName.System, $"Not find pj named {pjName} in {cjActived.Name}");
+                        continue;
+                    }
+
+                    if (pj.State == EnumProcessJobState.Queued)
+                    {
+                        if (CheckSequencePmReady(pj.Sequence, pmOccupied, out var pmUsed, out string reason))
+                        {
+                            ActiveProcessJob(pj);
+
+                            foreach (var moduleName in pmUsed)
+                            {
+                                if (!pmOccupied.Contains(moduleName))
+                                    pmOccupied.Add(moduleName);
+                            }
+                        }
+                        break;
+                    }
+                }
+            }
+        }
+
         #endregion
     }
 }

+ 1 - 1
Venus/Venus_RT/Modules/EFEM/EfemPickRoutine.cs

@@ -79,7 +79,7 @@ namespace Venus_RT.Modules.EFEM
                     return RState.Failed;
                 }
 
-                _targetSlot2 = pickItem.ToArray()[1].DestinationSlot;
+                _targetSlot2 = pickItem.ToArray()[1].SourceSlot;
                 if (WaferManager.Instance.CheckNoWafer(_targetModule, _targetSlot2))
                 {
                     LOG.Write(eEvent.ERR_EFEM_ROBOT, Module, $"The target slot: {_targetModule}{_targetSlot2} has no wafer, cannot do the double pick action");

+ 5 - 1
Venus/Venus_RT/Modules/RouteManager.cs

@@ -691,7 +691,7 @@ namespace Venus_RT.Modules
                     return false;
             }
 
-            _isWaitUnload = (bool)DATA.Poll("LP1.NotifyJobDone") || (bool)DATA.Poll("LP2.NotifyJobDone");
+            //_isWaitUnload = (bool)DATA.Poll("LP1.NotifyJobDone") || (bool)DATA.Poll("LP2.NotifyJobDone");
 
             return ret ==  RState.End;
         }
@@ -814,6 +814,10 @@ namespace Venus_RT.Modules
 
                 OP.DoOperation("System.CreateJob", param);
             }
+            else if(flag == 5)
+            {
+                PostMsg(MSG.StartJob, "CJ_Local_LP1");
+            }
         }
     }
 }

+ 10 - 2
Venus/Venus_RT/Modules/Schedulers/SchedulerEfemRobot.cs

@@ -45,7 +45,7 @@ namespace Venus_RT.Scheduler
 
 
         private SchedulerItem _currentScheduler = null;
-        private int _entityTaskToken = (int)FSM_MSG.NONE;
+        private int _entityTaskToken = (int)TaskType.None;
 
 
         public ModuleName PreviousTarget { get; set; }
@@ -137,7 +137,10 @@ namespace Venus_RT.Scheduler
 
         bool RunSchedulers()
         {
-            if (_entity.IsIdle && CheckTaskDone())
+            if (_currentScheduler == null)
+                return true;
+
+            if (_entity.IsIdle)
             {
                 if(_currentScheduler.Status == RState.Init)
                 {
@@ -154,6 +157,11 @@ namespace Venus_RT.Scheduler
                     else
                         _entityTaskToken = (int)FSM_MSG.NONE;
                 }
+                else if(_currentScheduler.Status == RState.Running)
+                {
+                    if (IsAllWafersArrived())
+                        _currentScheduler.Status = RState.End;
+                }
             }
 
             return _currentScheduler.Status == RState.End;

+ 2 - 2
Venus/Venus_Simulator/Devices/EfemSimulator.cs

@@ -128,8 +128,8 @@ namespace Venus_Simulator.Devices
             EfemOperation op = EfemConstant.ToOperation(sBasic);
             ushort millionSec = this.SimuOperationTime(op);
 
-            // Sleep
-            await Task.Run(() => Thread.Sleep(millionSec));
+            // delay
+            await Task.Delay(millionSec);
 
             // build the INF string
             string strINF = string.Empty;