|
@@ -113,6 +113,7 @@ namespace Venus_RT.Modules
|
|
|
int _LLBSlotNumber = 4;
|
|
|
int _efemRobotSingleArmOption = 0;
|
|
|
SequenceLLInOutPath _LLInOutPath = SequenceLLInOutPath.DInDOut;
|
|
|
+ public SequenceLLInOutPath LLInOutPath { get { return _LLInOutPath; } }
|
|
|
|
|
|
List<MoveItem> _movingItems = new List<MoveItem>();
|
|
|
List<MoveItem> _efemMovingItems = new List<MoveItem>();
|
|
@@ -630,7 +631,8 @@ namespace Venus_RT.Modules
|
|
|
private void driveVacSystem()
|
|
|
{
|
|
|
PumpingTMRobotTask();
|
|
|
- ProcessTMRobotTask();
|
|
|
+ //ProcessTMRobotTask();
|
|
|
+ RoutingInnerPart();
|
|
|
RuningTMRobotTask();
|
|
|
}
|
|
|
|
|
@@ -704,7 +706,7 @@ namespace Venus_RT.Modules
|
|
|
|
|
|
foreach (var inItem in _vacReadyInSlots)
|
|
|
{
|
|
|
- if (inItem.Key.Module == next_module && inItem.Key.Slot == nSlot && _vacModules[next_module].MovingStatus != MovingStatus.Moving)
|
|
|
+ if (inItem.Key.Module == next_module && inItem.Key.Slot == nSlot && _vacModules[next_module].MovingStatus == MovingStatus.Idle && _vacSchedulers[next_module].IsAvailable)
|
|
|
{
|
|
|
destSlot.Module = next_module;
|
|
|
destSlot.Slot = nSlot;
|
|
@@ -758,7 +760,6 @@ namespace Venus_RT.Modules
|
|
|
validSlot.Add(slot);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
else if (ModuleHelper.IsPm(mod))
|
|
|
{
|
|
@@ -769,7 +770,6 @@ namespace Venus_RT.Modules
|
|
|
validSlot.Add(0);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
return validSlot.Distinct().ToList();
|
|
|
}
|
|
|
|
|
@@ -985,6 +985,199 @@ namespace Venus_RT.Modules
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ bool PushTMRobotWafers()
|
|
|
+ {
|
|
|
+ if (_tmRobot.IsAvailable && _tmRobot.RobotStatus != RState.Running)
|
|
|
+ {
|
|
|
+ for (int i = 0; i < 2; i++)
|
|
|
+ {
|
|
|
+ if (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, i))
|
|
|
+ {
|
|
|
+ if (SearchWaferDestination(new SlotItem(ModuleName.TMRobot, i), out SlotItem destSlot))
|
|
|
+ {
|
|
|
+ _movingItems.Add(new MoveItem(ModuleName.TMRobot, i, destSlot.Module, destSlot.Slot, (Hand)i));
|
|
|
+ UpdateModuleMovingStatus(destSlot.Module);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return _movingItems.Count > 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ bool PushPmWafers()
|
|
|
+ {
|
|
|
+ if (_tmRobot.IsAvailable && _tmRobot.RobotStatus != RState.Running)
|
|
|
+ {
|
|
|
+ foreach (var slot in _vacReadyOutSlots)
|
|
|
+ {
|
|
|
+ if (_vacModules[slot.Key.Module].MovingStatus != MovingStatus.Idle)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ if (ModuleHelper.IsPm(slot.Key.Module))
|
|
|
+ {
|
|
|
+ if (SearchWaferDestination(slot.Key, out SlotItem destSlot))
|
|
|
+ {
|
|
|
+ _movingItems.Add(new MoveItem(slot.Key.Module, slot.Key.Slot, destSlot.Module, destSlot.Slot, Hand.None));
|
|
|
+ UpdateModuleMovingStatus(slot.Key.Module);
|
|
|
+ UpdateModuleMovingStatus(destSlot.Module);
|
|
|
+
|
|
|
+
|
|
|
+ // check whether match double move pattern
|
|
|
+ int inCount = 0;
|
|
|
+ var same_dest = SearchWaitInSlots(destSlot.Module);
|
|
|
+ foreach (var in_slot in same_dest)
|
|
|
+ {
|
|
|
+ if (_vacModules[in_slot.SourceModule].MovingStatus == MovingStatus.Idle && inCount < 1)
|
|
|
+ {
|
|
|
+ _movingItems.Add(in_slot);
|
|
|
+ UpdateItemMovingStatus(in_slot);
|
|
|
+ inCount++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // check whether match swap pattern
|
|
|
+ if (inCount == 0 && !IsPMNeedWTWClean(slot.Key.Module))
|
|
|
+ {
|
|
|
+ int swapCount = 0;
|
|
|
+ var in_slots = SearchWaitInSlots(slot.Key.Module);
|
|
|
+ foreach (var swap_slot in in_slots)
|
|
|
+ {
|
|
|
+ if (_vacModules[swap_slot.SourceModule].MovingStatus == MovingStatus.Idle && swapCount < 1)
|
|
|
+ {
|
|
|
+ _movingItems.Add(swap_slot);
|
|
|
+ UpdateItemMovingStatus(swap_slot);
|
|
|
+ swapCount++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return _movingItems.Count > 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ private bool PushLoadlockWafers()
|
|
|
+ {
|
|
|
+ if (_tmRobot.IsAvailable && _tmRobot.RobotStatus != RState.Running)
|
|
|
+ {
|
|
|
+ foreach (var slot in _vacReadyOutSlots)
|
|
|
+ {
|
|
|
+ if (_vacModules[slot.Key.Module].MovingStatus != MovingStatus.Idle)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ if (ModuleHelper.IsLoadLock(slot.Key.Module))
|
|
|
+ {
|
|
|
+ if (IsLoadLockReservedByEFEM(slot.Key.Module))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ var llStatus = GetLLProcessStatusCount(slot.Key.Module);
|
|
|
+ if (SearchWaferDestination(slot.Key, out SlotItem destSlot))
|
|
|
+ {
|
|
|
+ _movingItems.Add(new MoveItem(slot.Key.Module, slot.Key.Slot, destSlot.Module, destSlot.Slot, Hand.None));
|
|
|
+ UpdateModuleMovingStatus(slot.Key.Module);
|
|
|
+ UpdateModuleMovingStatus(destSlot.Module);
|
|
|
+
|
|
|
+ if (llStatus.Item2 > 1)
|
|
|
+ {
|
|
|
+ // check whether match double pick pattern
|
|
|
+ foreach (var item in _vacReadyOutSlots)
|
|
|
+ {
|
|
|
+ if (item.Key.Module == slot.Key.Module && item.Key.Slot != slot.Key.Slot)
|
|
|
+ {
|
|
|
+ if (SearchWaferDestination(item.Key, out SlotItem destSlot_2))
|
|
|
+ {
|
|
|
+ _movingItems.Add(new MoveItem(item.Key.Module, item.Key.Slot, destSlot_2.Module, destSlot_2.Slot, Hand.None));
|
|
|
+ UpdateModuleMovingStatus(destSlot_2.Module);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (_movingItems.Count == 1)
|
|
|
+ {
|
|
|
+ foreach (var item in _vacReadyOutSlots)
|
|
|
+ {
|
|
|
+ if (item.Key.Module == slot.Key.Module && item.Key.Slot != slot.Key.Slot)
|
|
|
+ {
|
|
|
+ if (SearchCanReplaceSlot(item.Key, out SlotItem replaceSlot, out SlotItem destSlot_2))
|
|
|
+ {
|
|
|
+ _movingItems.Add(new MoveItem(item.Key.Module, item.Key.Slot, replaceSlot.Module, replaceSlot.Slot, Hand.None));
|
|
|
+ _movingItems.Add(new MoveItem(replaceSlot.Module, replaceSlot.Slot, destSlot_2.Module, destSlot_2.Slot, Hand.None));
|
|
|
+ UpdateModuleMovingStatus(replaceSlot.Module);
|
|
|
+ UpdateModuleMovingStatus(destSlot.Module);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // check whether match swap pattern
|
|
|
+ int inCount = 0;
|
|
|
+ var in_slots = SearchWaitInSlots(slot.Key.Module);
|
|
|
+ foreach (var in_slot in in_slots)
|
|
|
+ {
|
|
|
+ if (_vacModules[in_slot.DestinationModule].MovingStatus == MovingStatus.Idle && inCount < 2)
|
|
|
+ {
|
|
|
+ _movingItems.Add(in_slot);
|
|
|
+ UpdateItemMovingStatus(in_slot);
|
|
|
+ inCount++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return _movingItems.Count > 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void RoutingInnerPart()
|
|
|
+ {
|
|
|
+ if (PushTMRobotWafers())
|
|
|
+ return;
|
|
|
+
|
|
|
+ var pmSlotStaus = GetPMValidSlotsStatus();
|
|
|
+ if (pmSlotStaus.Processed + pmSlotStaus.Empty == 0)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if(pmSlotStaus.Empty == 0)
|
|
|
+ {
|
|
|
+ if (PushPmWafers())
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ else if(pmSlotStaus.Processed == 0)
|
|
|
+ {
|
|
|
+ if (PushLoadlockWafers())
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if(pmSlotStaus.Processed >= pmSlotStaus.Empty)
|
|
|
+ {
|
|
|
+ if (PushPmWafers())
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (PushLoadlockWafers())
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (PushLoadlockWafers())
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (PushPmWafers())
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private void RuningTMRobotTask()
|
|
|
{
|
|
|
if (_tmRobot.IsAvailable)
|
|
@@ -1197,8 +1390,11 @@ namespace Venus_RT.Modules
|
|
|
#region Atm System
|
|
|
private void driveAtmSystem()
|
|
|
{
|
|
|
- PumpingEFEMRobotTask();
|
|
|
- RuningEFEMRobotTask();
|
|
|
+ if(_efemMovingItems.Count == 0)
|
|
|
+ {
|
|
|
+ PumpingEFEMRobotTask();
|
|
|
+ RuningEFEMRobotTask();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private void PumpingEFEMRobotTask()
|
|
@@ -1382,6 +1578,29 @@ namespace Venus_RT.Modules
|
|
|
return new Tuple<int, int>(exist, empty);
|
|
|
}
|
|
|
|
|
|
+ private (int Processed, int Empty) GetPMValidSlotsStatus()
|
|
|
+ {
|
|
|
+ int Processed = 0;
|
|
|
+ int Empty = 0;
|
|
|
+ foreach (var module in _vacModules)
|
|
|
+ {
|
|
|
+ if (ModuleHelper.IsPm(module.Key) && _vacSchedulers[module.Key].IsAvailable)
|
|
|
+ {
|
|
|
+ var wafer = WaferManager.Instance.GetWafer(module.Key, 0);
|
|
|
+ if(wafer.IsEmpty)
|
|
|
+ {
|
|
|
+ Empty++;
|
|
|
+ }
|
|
|
+ else if(wafer.ProcessState == EnumWaferProcessStatus.Completed)
|
|
|
+ {
|
|
|
+ Processed++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return (Processed, Empty);
|
|
|
+ }
|
|
|
+
|
|
|
private int GetTMRobotWaferCount()
|
|
|
{
|
|
|
return (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0) ? 1 : 0) + (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 1) ? 1 : 0);
|