Browse Source

throughput enhancement.

sangwq 11 months ago
parent
commit
0af5bc1e75

+ 1 - 2
Venus/Venus_RT/Config/System_Kepler2200.sccfg

@@ -25,8 +25,7 @@
 		<config default="Kepler" name="Name" nameView="Name" description="Name" tag="" unit="" type="String" />
 		<config default="0" name="LoadlockSlotInOutOption"  nameView="Loadlock Slot In Out Option" description="0, All slots in All slot Out; 1, Upper slots in lower slots out; 2, Lower slots in Upper slot out " max="2" min="0" paramter="" tag="" unit="" type="Integer"/>
 		<config default="false" name="EnableDeviceLog" nameView="" description="" max="" min="" paramter="" tag="" unit="" type="Bool" />
-
-
+		<config default="0" name ="SpecialRoutingPattern" nameView="Secail system routing pattern" description="0, disable, 1, long time recipe mode;" max="99" min="0" parameter="" tag="" unit="" type="Integer" visible="false"/>
 
 		<!--<configs name="FDC" nameView="FDC">
 			<config default="Fdc" name="DataGroupName"  nameView="FDC Data group" description="FDC data group, defined in DataGroup.xml" max="" min="" paramter="" tag="" visible="false" unit="" type="String" />

+ 1 - 0
Venus/Venus_RT/Config/System_Kepler2300.sccfg

@@ -22,6 +22,7 @@
 		<config default="10"  name="CheckResourceInterval" nameView="CheckResourceInterval" description="进程资源监视间隔,单位为分钟,0为不监视" max="60" min="0" paramter="" tag="" unit="min" type="Integer"/>
 		<config default="1000"  name="DataCollectionInterval" nameView="DataCollectionInterval" description="插入数据时间间隔" max="2000" min="200" paramter="" tag="" unit="ms" type="Integer"/>
 		<config default="false" name="IsEnableEthercat" nameView="Is Enable Ethercat" description="是否开启凌华Ethercat" max="" min="" paramter="" tag="" unit="" type="Bool" visible="false"/>
+		<config default="0" name ="SpecialRoutingPattern" nameView="Secail system routing pattern" description="0, disable, 1, long time recipe mode;" max="99" min="0" parameter="" tag="" unit="" type="Integer" visible="false"/>
 		<config default="Kepler" name="Name" nameView="Name" description="Name" tag="" unit="" type="String" />
 		<config default="0" name="LoadlockSlotInOutOption"  nameView="Loadlock Slot In Out Option" description="0, All slots in All slots Out; 1, Upper slots in lower slots out; 2, Lower slots in Upper slot out " max="2" min="0" paramter="" tag="" unit="" type="Integer"/>
 		<configs name="SetUp" nameView="Set Up" visible="false">

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

@@ -325,7 +325,6 @@ namespace Venus_RT.Modules.Schedulers
                 }
             }
 
-            PrepareLLPressure(items);
             RunSchedulers();
             return true;
         }

+ 102 - 8
Venus/Venus_RT/Modules/SystemDispatcher.cs

@@ -848,6 +848,12 @@ namespace Venus_RT.Modules
         LowerInUpperOut,
     }
 
+    enum SpecialRoutingPattern
+    {
+        Disable,
+        LongTimeRecipe,
+    }
+
     class SystemDispatcher : ICycle
     {
         private List<ControlJobInfo> _lstControlJobs = new List<ControlJobInfo>();
@@ -882,9 +888,12 @@ namespace Venus_RT.Modules
         private Dictionary<ModuleName, int> _lpCycleCount = new Dictionary<ModuleName, int> { { ModuleName.LP1, 0 }, { ModuleName.LP2, 0 }, { ModuleName.LP3, 0 } };
         private Dictionary<ModuleName, int> _lpCycleSP = new Dictionary<ModuleName, int> { { ModuleName.LP1, 1 }, { ModuleName.LP2, 1 }, { ModuleName.LP3, 1 } };
         private Dictionary<ModuleName, float> _lpThroughput = new Dictionary<ModuleName, float>{ {ModuleName.LP1, 0}, { ModuleName.LP2, 0}, { ModuleName.LP3, 0} };
+        private Dictionary<ModuleName, Stopwatch> _lpCycleWatch = new Dictionary<ModuleName, Stopwatch> { { ModuleName.LP1, new Stopwatch() }, { ModuleName.LP2, new Stopwatch()}, { ModuleName.LP3, new Stopwatch()} }; 
+
         private Stopwatch _cycleWatch = new Stopwatch();
 
         private SequenceLLInOutPath _LLInOutPath = SequenceLLInOutPath.DInDOut;
+        private SpecialRoutingPattern _specialRoutingPattern = SpecialRoutingPattern.Disable;
 
         public SequenceLLInOutPath LLInOutPath => _LLInOutPath; 
 
@@ -953,6 +962,7 @@ namespace Venus_RT.Modules
             _efemRobotSingleArmOption   = SC.GetValue<int>("EFEM.SingleArmOption");
             _tmRobotSingleArmOption     = SC.GetValue<int>("TM.SingleArmOption");
             _LLSlotInOutOption          = (LLSlotInOutOpt)SC.GetValue<int>("System.LoadlockSlotInOutOption");
+            _specialRoutingPattern      = (SpecialRoutingPattern)SC.GetValue<int>("System.SpecialRoutingPattern");
 
             // rounding TM robot single arm option
             if(_tmRobotSingleArmOption > 2 && _LLSlotInOutOption == LLSlotInOutOpt.AllInAllOut)
@@ -968,6 +978,7 @@ namespace Venus_RT.Modules
             _lpCycleCount = new Dictionary<ModuleName, int> { { ModuleName.LP1, 0 }, { ModuleName.LP2, 0 }, { ModuleName.LP3, 0 } };
             _lpCycleSP = new Dictionary<ModuleName, int> { { ModuleName.LP1, 1 }, { ModuleName.LP2, 1 }, { ModuleName.LP3, 1 } };
             _lpThroughput = new Dictionary<ModuleName, float> { { ModuleName.LP1, 0 }, { ModuleName.LP2, 0 }, { ModuleName.LP3, 0 } };
+            _lpCycleWatch = new Dictionary<ModuleName, Stopwatch> { { ModuleName.LP1, new Stopwatch() }, { ModuleName.LP2, new Stopwatch() }, { ModuleName.LP3, new Stopwatch() } };
 
             return RState.Running;
         }
@@ -1004,7 +1015,7 @@ namespace Venus_RT.Modules
             {
                 jobId = "CJ_Local_" + module;
             }
-          
+
             foreach (var item in _loadportControlJobDic.Values)
             {
                 if (item?.Name == jobId)
@@ -1016,7 +1027,7 @@ namespace Venus_RT.Modules
             }
             string lotId = (string)param["LotId"];
             if (string.IsNullOrEmpty(lotId))
-            { 
+            {
                 lotId = "CJ_Local_" + module;
             }
 
@@ -1172,7 +1183,6 @@ namespace Venus_RT.Modules
             //AssociatedPMWithLP(cj);
             _loadportControlJobDic[cj.Module] = cj;
 
-
             _faCallback.JobCreated(cj, GetFirstProcessJob(cj));
             return true;
         }
@@ -1966,7 +1976,7 @@ namespace Venus_RT.Modules
                     var lp = ModuleHelper.Converter(cj.Module);
                     if (_lpCycleCount[lp] > 0)
                     {
-                        _lpThroughput[lp] = (float)(_lpCycleWafer[lp] / (DateTime.Now - cj.StartTime).TotalHours);
+                        _lpThroughput[lp] = (float)((_lpCycleWafer[lp] - 2) / _lpCycleWatch[lp].Elapsed.TotalHours);
                     }
                 }
             }
@@ -2099,6 +2109,12 @@ namespace Venus_RT.Modules
                     _faCallback.JobWaferEnd(currentControlJob, item.SourceSlot);
                 }
             }
+
+            if(ModuleHelper.IsLoadPort(item.DestinationModule))
+            {
+                if (!_lpCycleWatch[wafer.sourceMod].IsRunning)
+                    _lpCycleWatch[wafer.sourceMod].Start();
+            }
             //--2024-03-21 增加了PortJobWaferEnd 上报事件 end--
         }
 
@@ -2209,6 +2225,9 @@ namespace Venus_RT.Modules
                 }
             }
 
+            if (_tmRobotStatus == RState.Running)
+                return;
+
             // keep two raw atm wafer, try match a double place to LL
             var atmWaferCount = _lstWaferTasks.Count(wt => ModuleHelper.IsPm(wt.destMod) && (ModuleHelper.IsLoadPort(wt.currentMod) || ModuleHelper.IsAligner(wt.currentMod) || ModuleHelper.IsEFEMRobot(wt.currentMod) || ModuleHelper.IsLoadLock(wt.currentMod)));
             if (atmWaferCount < 2)
@@ -2217,6 +2236,22 @@ namespace Venus_RT.Modules
                 if (busyPMs.Count() == 0)
                     return;
 
+                ModuleName nextPM = busyPMs.First().Key;
+                if (_lpCycleWafer.Sum(kv => kv.Value) == 0)
+                {
+                    if (busyPMs.ToList().Exists(kv => _dictModuleTask[kv.Key].TimeToReady > 36000) && busyPMs.ToList().Exists(pv => _dictModuleTask[pv.Key].TimeToReady < 3600))
+                    {
+                        foreach (var pm in busyPMs)
+                        {
+                            if (_dictModuleTask[pm.Key].TimeToReady > 36000)
+                            {
+                                nextPM = pm.Key;
+                                break;
+                            }
+                        }
+                    }
+                }
+
                 foreach (var runningJob in runningJobs)
                 {
                     if (_qePollingJobs.Contains(runningJob) && _qePollingJobs.First() != runningJob)
@@ -2227,9 +2262,9 @@ namespace Venus_RT.Modules
                         if (wafer.IsEmpty || wafer.ProcessJob == null)
                             continue;
 
-                        if (wafer.ProcessJob.Sequence.PMs.Contains(busyPMs.First().Key) && wafer.NextSequenceStep == 0 && !_lstWaferTasks.Exists(task => task.sourceMod == (ModuleName)wafer.OriginStation && task.sourceSlot == wafer.OriginSlot))
+                        if (wafer.ProcessJob.Sequence.PMs.Contains(nextPM) && wafer.NextSequenceStep == 0 && !_lstWaferTasks.Exists(task => task.sourceMod == (ModuleName)wafer.OriginStation && task.sourceSlot == wafer.OriginSlot))
                         {
-                            CreateWaferTasks(wafer, busyPMs.First().Key);
+                            CreateWaferTasks(wafer, nextPM);
                             return;
                         }
                     }
@@ -3282,7 +3317,44 @@ namespace Venus_RT.Modules
                 
                 if(robotWafers.Count == 0)
                 {
-                    if(_dictModuleTask.Count(mod => ModuleHelper.IsPm(mod.Key) && mod.Value.HasWafer && mod.Value.TimeToReady < 5) > 0 && outLLModule.ReayForTMInTime(30) && outLLWaferStatus.emptySlot.Count > 0)
+                    #region special routing pattern
+                    if (_specialRoutingPattern != SpecialRoutingPattern.Disable)
+                    {
+                        if(_specialRoutingPattern == SpecialRoutingPattern.LongTimeRecipe && freeHands.Count == 2)
+                        {
+                             if(_dictModuleTask.Where(mod => ModuleHelper.IsPm(mod.Key) && !mod.Value.HasWafer).Count() == 0)
+                            {
+                                var readyOutPMs = _dictModuleTask.Where(mod => ModuleHelper.IsPm(mod.Key) && mod.Value.HasWafer && mod.Value.TimeToReady < 25).OrderBy(mod => mod.Value.TimeToReady).ToList();
+                                if(readyOutPMs.Count > 0 && inLLModule.ReayForTMInTime(5) && _lstWaferTasks.Exists(wt => wt.currentMod == inLL && readyOutPMs.Exists(kv => kv.Key == wt.destMod)))
+                                {
+                                    var llWafer = _lstWaferTasks.Find(wt => wt.currentMod == inLL && wt.destMod == readyOutPMs.First().Key);
+                                    if(llWafer != null)
+                                    {
+                                        _tmSchdActions.Enqueue(new List<MoveItem> { new MoveItem(inLL, llWafer.currentSlot, ModuleName.TMRobot, (int)freeHands[0], freeHands[0]) });
+
+                                        var pmSwap = new List<MoveItem>
+                                        {   new MoveItem(readyOutPMs.First().Key, 0, ModuleName.TMRobot, (int)freeHands[1], freeHands[1]),
+                                            new MoveItem(ModuleName.TMRobot, (int)freeHands[0], readyOutPMs.First().Key, 0, freeHands[0])
+                                        };
+
+                                        _tmSchdActions.Enqueue(pmSwap);
+
+                                        if(outLLModule.ReayForTMInTime(25) && outLLWaferStatus.emptySlot.Count > 0)
+                                        {
+                                            _tmSchdActions.Enqueue(new List<MoveItem> { new MoveItem(ModuleName.TMRobot, (int)freeHands[1], outLL, outLLWaferStatus.emptySlot[0], freeHands[1]) });
+                                        }
+                                    }
+                                }
+
+                                return;
+                            }
+                        }
+                    }
+
+                    #endregion
+
+
+                    if (_dictModuleTask.Count(mod => ModuleHelper.IsPm(mod.Key) && mod.Value.HasWafer && mod.Value.TimeToReady < 5) > 0 && outLLModule.ReayForTMInTime(30) && outLLWaferStatus.emptySlot.Count > 0)
                     {
                         var readyOutPMs = _dictModuleTask.Where(mod => ModuleHelper.IsPm(mod.Key) && mod.Value.HasWafer && mod.Value.TimeToReady < 25).OrderBy(mod => mod.Value.TimeToReady).ToList();
                         var placeActions = new List<MoveItem>();
@@ -3330,7 +3402,29 @@ namespace Venus_RT.Modules
                 }
                 else
                 {
-                    foreach(var robotWafer in robotWafers)
+                    #region special routing pattern
+                    if (_specialRoutingPattern != SpecialRoutingPattern.Disable)
+                    {
+                        if (_specialRoutingPattern == SpecialRoutingPattern.LongTimeRecipe && _tmRobotSingleArmOption == 0)
+                        {
+                            if(_dictModuleTask.Where(mod => ModuleHelper.IsPm(mod.Key) && !mod.Value.HasWafer).Count() == 0)
+                            {
+                                if (ModuleHelper.IsLoadPort(robotWafers[0].destMod))
+                                {
+                                    if (outLLModule.ReayForTMInTime(10) && outLLWaferStatus.emptySlot.Count > 0)
+                                    {
+                                        _tmSchdActions.Enqueue(new List<MoveItem> { new MoveItem(ModuleName.TMRobot, robotWafers[0].currentSlot, outLL, outLLWaferStatus.emptySlot[0], (Hand)(robotWafers[0].currentSlot)) });
+                                    }
+                                }
+
+                                return;
+                            }
+                        }
+                    }
+
+                    #endregion
+
+                    foreach (var robotWafer in robotWafers)
                     {
                         if (ModuleHelper.IsPm(robotWafer.destMod))
                         {

+ 3 - 3
Venus/Venus_RT/Modules/TM/MFPMPickRoutine.cs

@@ -162,11 +162,11 @@ namespace Venus_RT.Modules.TM
                .Wait(PickStepWithHeater.WaitPressreStable,     TMPMPressureIsOK,   _delay_60s)
                .Run(PickStepWithHeater.OpenPMSlitDoor,         OpenPMSlitDoor,     OpenPMSlitDoorIsOK)
                .Run(PickStepWithHeater.Picking,                Picking,            WaitPickDone)
-               .Run(PickStepWithHeater.QueryAWC,               QueryAWC,           WaitRobotQueryDone)
-               .Run(PickStepWithHeater.SavePickeData,          RecordAWCData,      NullFun)
+               .RunIf(PickStepWithHeater.QueryAWC,             _queryAwc,          QueryAWC,            WaitRobotQueryDone)
+               .RunIf(PickStepWithHeater.SavePickeData,        _queryAwc,          RecordAWCData,       NullFun)
                .Wait(PickStepWithHeater.WaitPLCReady,          PLCIsReadyOK)
                .Run(PickStepWithHeater.ClosePMSlitDoor,        ClosePMSlitDoor,    ClosePMSlitDoorIsOK)
-               .Run(PickStepWithHeater.CheckAWC,               CheckAwc                               )
+               .RunIf(PickStepWithHeater.CheckAWC,             _queryAwc,          CheckAwc)
                .End(PickStepWithHeater.NotifyDone,             NotifyPMDone,       _delay_1s);
                 break;
             }

+ 3 - 3
Venus/Venus_RT/Modules/TM/MFPMPlaceRoutine.cs

@@ -159,11 +159,11 @@ namespace Venus_RT.Modules.TM
               .Wait(PlaceWithHeaterStep.WaitPressreStable,          TMPMPressureIsOK, _delay_60s)
               .Run(PlaceWithHeaterStep.OpenPMSlitDoor,              OpenPMSlitDoor,                                      OpenPMSlitDoorIsOK)
               .Run(PlaceWithHeaterStep.Placing,                     Placing,                                             WaitPlaceDone)
-              .Run(PlaceWithHeaterStep.QueryAWC,                    QueryAWC,                                            WaitRobotQueryDone, _delay_1s)
-              .Run(PlaceWithHeaterStep.SavePlaceData,               RecordAWCData,                                       NullFun)
+              .RunIf(PlaceWithHeaterStep.QueryAWC,                  _queryAwc,                                           QueryAWC,                                            WaitRobotQueryDone, _delay_1s)
+              .RunIf(PlaceWithHeaterStep.SavePlaceData,             _queryAwc,                                           RecordAWCData,                                       NullFun)
               .Wait(PlaceWithHeaterStep.WaitPLCReady,               PLCIsReadyOK)
               .Run(PlaceWithHeaterStep.ClosePMSlitDoor,             ClosePMSlitDoor,                                     ClosePMSlitDoorIsOK)
-              .Run(PlaceWithHeaterStep.CheckAwc,                    CheckAwc)
+              .RunIf(PlaceWithHeaterStep.CheckAwc,                  _queryAwc,                                           CheckAwc)
 
               .End(PlaceWithHeaterStep.NotifyDone,                  NotifyPMDone,                                        _delay_50ms);
               break;

+ 10 - 10
Venus/Venus_RT/Modules/TM/MFPickRoutine.cs

@@ -125,16 +125,16 @@ namespace Venus_RT.Modules.TM
 
         public RState Monitor()
         {
-            Runner.Wait(PickStep.WaitModuleReady,     () => _llModule.IsIdle,     _delay_60s)
-                .Run(PickStep.ModulePrepare,          ModulePrepare,              IsModulePrepareReady)
-                .Wait(PickStep.WaitPressreStable,     TMLLPressureIsOK,           _delay_60s)
-                .Run(PickStep.OpenSlitDoor,           OpenSlitDoor,               IsSlitDoorOpen, _delay_30s)
-                .Run(PickStep.Picking,                Picking,                    WaitPickDone, _delay_30s)
-                .Run(PickStep.QueryAwc,               QueryAwc,                   WaitQueryDoneAndRecord, _delay_30s)
-                .Run(PickStep.CloseSlitDoor,          CloseSlitDoor,              IsSlitDoorClosed, _delay_30s)
-                .Run(PickStep.CheckAwc,               CheckAwc                                    )
-
-                .End(PickStep.NotifyDone,             NotifyLLDone,               _delay_50ms);         
+            Runner.Wait(PickStep.WaitModuleReady,     () => _llModule.IsIdle,       _delay_60s)
+                .Run(PickStep.ModulePrepare,          ModulePrepare,                IsModulePrepareReady)
+                .Wait(PickStep.WaitPressreStable,     TMLLPressureIsOK,             _delay_60s)
+                .Run(PickStep.OpenSlitDoor,           OpenSlitDoor,                 IsSlitDoorOpen,         _delay_30s)
+                .Run(PickStep.Picking,                Picking,                      WaitPickDone,           _delay_30s)
+                .RunIf(PickStep.QueryAwc,             _queryAwc,                    QueryAwc,               WaitQueryDoneAndRecord,     _delay_30s)
+                .Run(PickStep.CloseSlitDoor,          CloseSlitDoor,                IsSlitDoorClosed,       _delay_30s)
+                .RunIf(PickStep.CheckAwc,             _queryAwc,                    CheckAwc)
+
+                .End(PickStep.NotifyDone,             NotifyLLDone,                 _delay_50ms);         
 
             return Runner.Status;
         }

+ 6 - 6
Venus/Venus_RT/Modules/TM/MFPlaceRoutine.cs

@@ -124,12 +124,12 @@ namespace Venus_RT.Modules.TM
           Runner.Wait(PlaceStep.WaitModuleReady,      () => _llModule.IsIdle,      _delay_3m)
                 .RunIf(PlaceStep.PreRotation,          _JetTM.PreRotateModules.ContainsKey(_targetModule),      RotateArm,      WaitRotateDone, _delay_30s)
                 .Run(PlaceStep.ModulePrepare,          ModulePrepare,               IsModulePrepareReady)
-                .Wait(PlaceStep.WaitPressreStable,     TMLLPressureIsOK,                                   _delay_60s)
-                .Run(PlaceStep.OpenSlitDoor,           OpenSlitDoor,                IsSlitDoorOpen, _delay_30s)
-                .Run(PlaceStep.Placing,                Placing,                     WaitPlaceDone, _delay_30s)
-                .Run(PlaceStep.QueryAwc,               QueryAwc,                    WaitQueryDoneAndRecord, _delay_30s)
-                .Run(PlaceStep.CloseSlitDoor,          CloseSlitDoor,               IsSlitDoorClosed, _delay_30s)
-                .Run(PlaceStep.CheckAwc,               CheckAwc)
+                .Wait(PlaceStep.WaitPressreStable,     TMLLPressureIsOK,                                        _delay_60s)
+                .Run(PlaceStep.OpenSlitDoor,           OpenSlitDoor,                IsSlitDoorOpen,             _delay_30s)
+                .Run(PlaceStep.Placing,                Placing,                     WaitPlaceDone,              _delay_30s)
+                .RunIf(PlaceStep.QueryAwc,             _queryAwc,                   QueryAwc,                    WaitQueryDoneAndRecord, _delay_30s)
+                .Run(PlaceStep.CloseSlitDoor,          CloseSlitDoor,               IsSlitDoorClosed,           _delay_30s)
+                .Run_If(PlaceStep.CheckAwc,            _queryAwc,                   CheckAwc)
 
                 .End(PlaceStep.NotifyDone,             NotifyLLDone,                                         _delay_50ms);          
             return Runner.Status;