|
@@ -383,17 +383,6 @@ namespace EfemDualSchedulerLib
|
|
|
|
|
|
|
|
|
_cycleState = RState.Running;
|
|
|
- //foreach (var pj in _lstProcessJobs)
|
|
|
- //{
|
|
|
- // if (pj.ControlJobName == cj.Name)
|
|
|
- // {
|
|
|
- // pj.SetState(EnumProcessJobState.Processing);
|
|
|
- // }
|
|
|
- //}
|
|
|
- //if (cj.Module == ModuleName.VCEA.ToString())
|
|
|
- // _VCEAUnloadFlag = false;
|
|
|
- //if (cj.Module == ModuleName.VCEB.ToString())
|
|
|
- // _VCEAUnloadFlag = false;
|
|
|
}
|
|
|
|
|
|
if (!_lstControlJobs.Exists(x => x.State == EnumControlJobState.Executing))
|
|
@@ -981,9 +970,9 @@ namespace EfemDualSchedulerLib
|
|
|
|
|
|
//================2024-10-9 10:10:56 增加单边做完后unload功能===================
|
|
|
//逻辑说明:最后一个cycle中出现complete将其vcemodule controljob等从中间剥离
|
|
|
-
|
|
|
+
|
|
|
//未整体cycle 但是一边已经做完
|
|
|
- if (!_isCycleMode && CycleIndex == CycleNum && IsAutoUnLoad && _lstControlJobs.Exists(x=> x.State == EnumControlJobState.Completed))
|
|
|
+ if (!_isCycleMode && CycleIndex == CycleNum && IsAutoUnLoad && _lstControlJobs.Exists(x => x.State == EnumControlJobState.Completed))
|
|
|
{
|
|
|
_lstControlJobs.FindAll(x => x.State == EnumControlJobState.Completed).ForEach(ctrljob =>
|
|
|
{
|
|
@@ -1175,6 +1164,7 @@ namespace EfemDualSchedulerLib
|
|
|
{
|
|
|
if (_TMRobot.IsAvailable)
|
|
|
{
|
|
|
+ NotAllowStatusForRobot();
|
|
|
LetAlignWaferBackToRobot();//放开限制 埋点一层槽作为store缓存点 同时增加cooling swap策略
|
|
|
LetWaferGotoCooling();//cooling排除代码 可以优化空间当 保留一层的let in 作为中间存储层
|
|
|
PrepareWaferOnRBToPM();//手臂wafer到pm
|
|
@@ -1185,6 +1175,51 @@ namespace EfemDualSchedulerLib
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private void NotAllowStatusForRobot()
|
|
|
+ {
|
|
|
+ if (_lstPms.Exists(x => x.IsAvailable))
|
|
|
+ {
|
|
|
+ if ((WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0) || WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 2) &&
|
|
|
+ (WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 1) && WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 3))))
|
|
|
+ {
|
|
|
+ WaferInfo wafer = null;
|
|
|
+ if (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0))
|
|
|
+ wafer = WaferManager.Instance.GetWafer(ModuleName.TMRobot,0);
|
|
|
+ if (wafer == null && WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 2))
|
|
|
+ wafer = WaferManager.Instance.GetWafer(ModuleName.TMRobot,2);
|
|
|
+
|
|
|
+ if (wafer.ProcessState != EnumWaferProcessStatus.Completed)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (_VceModules[Wafer2Vce(wafer)][wafer.OriginSlot] == MovingStatus.Idle)
|
|
|
+ {
|
|
|
+ _moveQueue.Add(new MoveItem(ModuleName.TMRobot, 0,(ModuleName)wafer.OriginStation, wafer.OriginSlot,(Hand)0));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 1) || WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 3) &&
|
|
|
+ (WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0) && WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 2))))
|
|
|
+ {
|
|
|
+ WaferInfo wafer = null;
|
|
|
+ if (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 1))
|
|
|
+ wafer = WaferManager.Instance.GetWafer(ModuleName.TMRobot, 1);
|
|
|
+ if (wafer == null && WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 3))
|
|
|
+ wafer = WaferManager.Instance.GetWafer(ModuleName.TMRobot, 3);
|
|
|
+
|
|
|
+ if (wafer.ProcessState != EnumWaferProcessStatus.Completed)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (_VceModules[Wafer2Vce(wafer)][wafer.OriginSlot] == MovingStatus.Idle)
|
|
|
+ {
|
|
|
+ _moveQueue.Add(new MoveItem(ModuleName.TMRobot, 1, (ModuleName)wafer.OriginStation, wafer.OriginSlot, (Hand)1));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
//wafer在第一个cooling需求里 且状态是aligning的
|
|
|
private void LetAlignWaferBackToRobot()
|
|
|
{
|
|
@@ -1282,7 +1317,7 @@ namespace EfemDualSchedulerLib
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (wafer1!=null && RobotIsAllEmpty && wafer1.ProcessState == EnumWaferProcessStatus.Idle)
|
|
|
+ if (wafer1 != null && RobotIsAllEmpty && wafer1.ProcessState == EnumWaferProcessStatus.Idle)
|
|
|
{
|
|
|
_moveQueue.Add(new MoveItem(cooling.Module, 0, ModuleName.TMRobot, 0, 0));
|
|
|
_VceModules[ctrljob.Module][wafer1.OriginSlot] = MovingStatus.WaitProcess;
|
|
@@ -1344,9 +1379,9 @@ namespace EfemDualSchedulerLib
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- private bool RobotIsAllEmpty => WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0)&&
|
|
|
- WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 1) &&
|
|
|
- WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 2) &&
|
|
|
+ private bool RobotIsAllEmpty => WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0) &&
|
|
|
+ WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 1) &&
|
|
|
+ WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 2) &&
|
|
|
WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 3);
|
|
|
|
|
|
private void LetCoolWaferBackToVCE()
|
|
@@ -1364,7 +1399,7 @@ namespace EfemDualSchedulerLib
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
- else if(WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 2))
|
|
|
+ else if (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 2))
|
|
|
{
|
|
|
WaferInfo wafer = WaferManager.Instance.GetWafer(ModuleName.TMRobot, 2);
|
|
|
if (_VceModules[Wafer2Vce(wafer)][wafer.OriginSlot] == MovingStatus.Idle)
|
|
@@ -1409,6 +1444,17 @@ namespace EfemDualSchedulerLib
|
|
|
{
|
|
|
if (_TMRobot.IsAvailable)
|
|
|
{
|
|
|
+ /*
|
|
|
+ * 拦截策略
|
|
|
+ * 1.当PM有已经idle的 cooling上有没有做过的或者cooling上有
|
|
|
+ * 2.
|
|
|
+ */
|
|
|
+
|
|
|
+ //if ((PMHasAvailable() && CoolingHasNeedProcessWafer()) || CoolingHasNeedProcessWafer())
|
|
|
+ // return;
|
|
|
+ if ((PMHasAvailable() && CoolingHasNeedProcessWafer()) || CoolingHasNeedProcessWafer())
|
|
|
+ return;
|
|
|
+
|
|
|
foreach (SchedulerBuffer cooling in _lstCooling)
|
|
|
{
|
|
|
if (!cooling.IsAvailable)
|
|
@@ -1517,9 +1563,31 @@ namespace EfemDualSchedulerLib
|
|
|
wafer = ctrljob.LotWafers[i + (ctrljob.LotWafers.Count / 2)];
|
|
|
}
|
|
|
|
|
|
- if (wafer == null || (!SequenceNeedPMsAvailable(NeedPMs(wafer)) && !SequenceNeedCoolingAvailable(NeedAlignCoolings(wafer))) || wafer.ProcessState == EnumWaferProcessStatus.Completed)
|
|
|
+ if (wafer == null)
|
|
|
continue;
|
|
|
|
|
|
+ if (wafer.ProcessState == EnumWaferProcessStatus.Completed)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ //TAG : 首步 无Cooling下进入 PM占满 进入Cooling中缓存 cooling中未占满
|
|
|
+ if (!SequenceNeedPMsAvailable(NeedPMs(wafer)) && SequenceNoNeedCoolingFirst(wafer) && HasCoolingCanBeUse)
|
|
|
+ {
|
|
|
+ //寻找available且无wafer的cooling层
|
|
|
+ List<ModuleName> CanWorkCooling = new List<ModuleName>();
|
|
|
+ _lstCooling.ForEach(x => CanWorkCooling.Add(x.Module));
|
|
|
+ if (SearchEmptyCooling(CanWorkCooling, out ModuleName cooling, out int slot))
|
|
|
+ {
|
|
|
+ //nextslot.Add(wafer.OriginSlot, _destination);
|
|
|
+ _moveQueue.Add(new MoveItem((ModuleName)wafer.OriginStation, wafer.OriginSlot, cooling, slot, 0));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (!SequenceNeedPMsAvailable(NeedPMs(wafer)) && !SequenceNeedCoolingAvailable(NeedAlignCoolings(wafer)))
|
|
|
+ continue;
|
|
|
+
|
|
|
+
|
|
|
//如果是等待PM处理 找到可用的PM并装入任务 如果无可用的PM 就继续循环
|
|
|
if (!wafer.IsEmpty &&
|
|
|
SequenceNeedPMsAvailable(NeedPMs(wafer)) &&
|
|
@@ -1634,7 +1702,7 @@ namespace EfemDualSchedulerLib
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
|
|
|
// 判断是否切换到下一个VCE的标识是什么?
|
|
|
// 1. all wafer in cassette has run recipe
|
|
@@ -1755,13 +1823,13 @@ namespace EfemDualSchedulerLib
|
|
|
WaferInfo wafer = WaferManager.Instance.GetWafer(cooling, slot);
|
|
|
if (wafer.ProcessState == EnumWaferProcessStatus.Idle)
|
|
|
{
|
|
|
- _moveQueue.Add(new MoveItem(cooling, slot< 2 ? 0:1 , ModuleName.TMRobot, 0, Hand.Blade1));
|
|
|
+ _moveQueue.Add(new MoveItem(cooling, slot < 2 ? 0 : 1, ModuleName.TMRobot, 0, Hand.Blade1));
|
|
|
_VceModules[Wafer2Vce(wafer)][wafer.OriginSlot] = MovingStatus.WaitProcess;
|
|
|
RunTMRobotTask();
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
|
|
|
ControlJobInfo ctrljob = _lstControlJobs.Find(x => x.State == EnumControlJobState.Executing);
|
|
|
Dictionary<int, ModuleName> nextslot = new Dictionary<int, ModuleName>();
|
|
@@ -1891,7 +1959,7 @@ namespace EfemDualSchedulerLib
|
|
|
if (_tmwafer != null && _tmwafer.ProcessState == EnumWaferProcessStatus.Completed &&
|
|
|
!WaferCoolTaskIsFree(_tmwafer))
|
|
|
{
|
|
|
- EV.PostInfoLog("TM", $"手臂有做完工艺的wafer 但cooling不空 等着吧");
|
|
|
+ //EV.PostInfoLog("TM", $"手臂有做完工艺的wafer 但cooling不空 等着吧");
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -1959,7 +2027,7 @@ namespace EfemDualSchedulerLib
|
|
|
}
|
|
|
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
|
|
|
//空手下的wafer动作
|
|
|
private void HandPrepare()
|
|
@@ -2101,16 +2169,19 @@ namespace EfemDualSchedulerLib
|
|
|
if (_wafer != null && _wafer.ProcessState == EnumWaferProcessStatus.Completed && _VceModules[Wafer2Vce(_wafer)][_wafer.OriginSlot] != MovingStatus.Idle)
|
|
|
{
|
|
|
//2024-03-22 09:33:25 增加 没有Cooling的调度 此处是进cooling
|
|
|
- if (!CheckWaferNoCoolingTask(_wafer) && SequenceNeedCoolingsAvailable(_wafer).Count > 0)
|
|
|
+ if (!CheckWaferNoCoolingTask(_wafer))
|
|
|
{
|
|
|
- _VceModules[Wafer2Vce(_wafer)][_wafer.OriginSlot] = MovingStatus.StartCool;
|
|
|
- _moveQueue.Add(new MoveItem(ModuleName.TMRobot, 0, SequenceNeedCoolingsAvailable(_wafer)[0].Key, SequenceNeedCoolingsAvailable(_wafer)[0].Value, Hand.Blade1));
|
|
|
- RunTMRobotTask();
|
|
|
- return;
|
|
|
+ if (SequenceNeedCoolingsAvailable(_wafer).Count > 0)
|
|
|
+ {
|
|
|
+ _VceModules[Wafer2Vce(_wafer)][_wafer.OriginSlot] = MovingStatus.StartCool;
|
|
|
+ _moveQueue.Add(new MoveItem(ModuleName.TMRobot, 0, SequenceNeedCoolingsAvailable(_wafer)[0].Key, SequenceNeedCoolingsAvailable(_wafer)[0].Value, Hand.Blade1));
|
|
|
+ RunTMRobotTask();
|
|
|
+ return;
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
//此处是不进cooling的 判断sequence是否进入
|
|
|
- if (CheckWaferNoCoolingTask(_wafer))
|
|
|
+ else
|
|
|
{
|
|
|
_VceModules[Wafer2Vce(_wafer)][_wafer.OriginSlot] = MovingStatus.Idle;
|
|
|
_moveQueue.Add(new MoveItem(ModuleName.TMRobot, 0, (ModuleName)_wafer.OriginStation, _wafer.OriginSlot, Hand.Blade1));
|
|
@@ -2135,16 +2206,20 @@ namespace EfemDualSchedulerLib
|
|
|
|
|
|
if (_wafer != null && _wafer.ProcessState == EnumWaferProcessStatus.Completed && _VceModules[Wafer2Vce(_wafer)][_wafer.OriginSlot] != MovingStatus.Idle)
|
|
|
{
|
|
|
- if (!CheckWaferNoCoolingTask(_wafer) && SequenceNeedCoolingsAvailable(_wafer).Count > 0)
|
|
|
+ if (!CheckWaferNoCoolingTask(_wafer))
|
|
|
{
|
|
|
- _VceModules[Wafer2Vce(_wafer)][_wafer.OriginSlot] = MovingStatus.StartCool;
|
|
|
- _moveQueue.Add(new MoveItem(ModuleName.TMRobot, 1, SequenceNeedCoolingsAvailable(_wafer)[0].Key, SequenceNeedCoolingsAvailable(_wafer)[0].Value, Hand.Blade2));
|
|
|
- RunTMRobotTask();
|
|
|
- return;
|
|
|
+ if (SequenceNeedCoolingsAvailable(_wafer).Count > 0)
|
|
|
+ {
|
|
|
+ _VceModules[Wafer2Vce(_wafer)][_wafer.OriginSlot] = MovingStatus.StartCool;
|
|
|
+ _moveQueue.Add(new MoveItem(ModuleName.TMRobot, 1, SequenceNeedCoolingsAvailable(_wafer)[0].Key, SequenceNeedCoolingsAvailable(_wafer)[0].Value, Hand.Blade2));
|
|
|
+ RunTMRobotTask();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
|
|
|
//此处是不进cooling的 判断sequence是否进入
|
|
|
- if (CheckWaferNoCoolingTask(_wafer))
|
|
|
+ else
|
|
|
{
|
|
|
_VceModules[Wafer2Vce(_wafer)][_wafer.OriginSlot] = MovingStatus.Idle;
|
|
|
_moveQueue.Add(new MoveItem(ModuleName.TMRobot, 1, (ModuleName)_wafer.OriginStation, _wafer.OriginSlot, Hand.Blade2));
|
|
@@ -2159,8 +2234,34 @@ namespace EfemDualSchedulerLib
|
|
|
//没有cooling可以进
|
|
|
else
|
|
|
{
|
|
|
+
|
|
|
if (WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0) && WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 2))
|
|
|
{
|
|
|
+ if (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 1) || WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 3))
|
|
|
+ {
|
|
|
+ WaferInfo _wafer = null;
|
|
|
+ if (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 1))
|
|
|
+ {
|
|
|
+ _wafer = WaferManager.Instance.GetWafer(ModuleName.TMRobot, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (_wafer == null && WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 3))
|
|
|
+ {
|
|
|
+ _wafer = WaferManager.Instance.GetWafer(ModuleName.TMRobot, 3);
|
|
|
+ }
|
|
|
+ //2024-10-24 13:20:56 增加进cooling的swap调度
|
|
|
+ if (_wafer != null && _wafer.ProcessState == EnumWaferProcessStatus.Completed && ExsitCanSwapCooling(_wafer, out ModuleName cooling, out int slot))
|
|
|
+ {
|
|
|
+ _VceModules[Wafer2Vce(_wafer)][_wafer.OriginSlot] = MovingStatus.StartCool;
|
|
|
+ _moveQueue.Add(new MoveItem(cooling, slot, ModuleName.TMRobot, 0, Hand.Blade1));
|
|
|
+ _moveQueue.Add(new MoveItem(ModuleName.TMRobot, 1, cooling, slot, Hand.Blade2));
|
|
|
+ RunTMRobotTask();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((PMHasAvailable() && CoolingHasNeedProcessWafer()))
|
|
|
+ return;
|
|
|
|
|
|
//需要等待cooling 将其放回去
|
|
|
if (HasCoolingCanBeBack())
|
|
@@ -2182,38 +2283,61 @@ namespace EfemDualSchedulerLib
|
|
|
else
|
|
|
wafer = WaferManager.Instance.GetWafer(CanBackCooling.Key, 3);
|
|
|
}
|
|
|
- _moveQueue.Add(new MoveItem(CanBackCooling.Key, CanBackCooling.Value, (ModuleName)wafer.OriginStation, wafer.OriginSlot, Hand.Blade1));
|
|
|
- RunTMRobotTask();
|
|
|
- return;
|
|
|
+ if (wafer.ProcessState == EnumWaferProcessStatus.Completed)
|
|
|
+ {
|
|
|
+ _moveQueue.Add(new MoveItem(CanBackCooling.Key, CanBackCooling.Value, (ModuleName)wafer.OriginStation, wafer.OriginSlot, Hand.Blade1));
|
|
|
+ RunTMRobotTask();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 1) || WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 3))
|
|
|
+ {
|
|
|
+ WaferInfo waferonhand = new WaferInfo();
|
|
|
+ if (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 1))
|
|
|
+ waferonhand = WaferManager.Instance.GetWafer(ModuleName.TMRobot, 1);
|
|
|
+ if (waferonhand == null && WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 3))
|
|
|
+ waferonhand = WaferManager.Instance.GetWafer(ModuleName.TMRobot, 3);
|
|
|
+ if (waferonhand.ProcessState == EnumWaferProcessStatus.Completed)
|
|
|
+ {
|
|
|
+ _moveQueue.Add(new MoveItem(CanBackCooling.Key, CanBackCooling.Value, ModuleName.TMRobot, 0, Hand.Blade1));
|
|
|
+ RunTMRobotTask();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 1) && WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 3))
|
|
|
{
|
|
|
- //if (HasNoProcessCanSwap(out ModuleName canswapcooling, out int canswapslot))
|
|
|
- //{
|
|
|
- // if (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0) || WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 2))
|
|
|
- // {
|
|
|
- // WaferInfo _wafer = null;
|
|
|
- // if (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0))
|
|
|
- // {
|
|
|
- // _wafer = WaferManager.Instance.GetWafer(ModuleName.TMRobot, 0);
|
|
|
- // }
|
|
|
- //
|
|
|
- // if (_wafer == null && WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 2))
|
|
|
- // {
|
|
|
- // _wafer = WaferManager.Instance.GetWafer(ModuleName.TMRobot, 2);
|
|
|
- // }
|
|
|
- //
|
|
|
- // if (_wafer != null && _wafer.ProcessState == EnumWaferProcessStatus.Completed && _VceModules[Wafer2Vce(_wafer)][_wafer.OriginSlot] != MovingStatus.Idle)
|
|
|
- // {
|
|
|
- // _moveQueue.Add(new MoveItem(canswapcooling, canswapslot < 2 ? 0 : 1, ModuleName.TMRobot, 1, Hand.Blade2));
|
|
|
- // _moveQueue.Add(new MoveItem(ModuleName.TMRobot, 0, canswapcooling, canswapslot < 2 ? 0 : 1, Hand.Blade1));
|
|
|
- // RunTMRobotTask();
|
|
|
- // return;
|
|
|
- // }
|
|
|
- // }
|
|
|
- //}
|
|
|
+ if (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0) || WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 2))
|
|
|
+ {
|
|
|
+ WaferInfo _wafer = null;
|
|
|
+ if (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0))
|
|
|
+ {
|
|
|
+ _wafer = WaferManager.Instance.GetWafer(ModuleName.TMRobot, 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (_wafer == null && WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 2))
|
|
|
+ {
|
|
|
+ _wafer = WaferManager.Instance.GetWafer(ModuleName.TMRobot, 2);
|
|
|
+ }
|
|
|
+
|
|
|
+ //2024-10-24 13:20:56 增加进cooling的swap调度
|
|
|
+ if (_wafer != null && _wafer.ProcessState == EnumWaferProcessStatus.Completed && ExsitCanSwapCooling(_wafer, out ModuleName cooling, out int slot))
|
|
|
+ {
|
|
|
+ _VceModules[Wafer2Vce(_wafer)][_wafer.OriginSlot] = MovingStatus.StartCool;
|
|
|
+ _moveQueue.Add(new MoveItem(cooling, slot, ModuleName.TMRobot, 1, Hand.Blade2));
|
|
|
+ _moveQueue.Add(new MoveItem(ModuleName.TMRobot, 0, cooling, slot, Hand.Blade1));
|
|
|
+ RunTMRobotTask();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if ((PMHasAvailable() && CoolingHasNeedProcessWafer()))
|
|
|
+ return;
|
|
|
|
|
|
if (HasCoolingCanBeBack())
|
|
|
{
|
|
@@ -2234,9 +2358,29 @@ namespace EfemDualSchedulerLib
|
|
|
else
|
|
|
wafer = WaferManager.Instance.GetWafer(CanBackCooling.Key, 3);
|
|
|
}
|
|
|
- _moveQueue.Add(new MoveItem(CanBackCooling.Key, CanBackCooling.Value, (ModuleName)wafer.OriginStation, wafer.OriginSlot, Hand.Blade2));
|
|
|
- RunTMRobotTask();
|
|
|
- return;
|
|
|
+ if (wafer.ProcessState == EnumWaferProcessStatus.Completed)
|
|
|
+ {
|
|
|
+ _moveQueue.Add(new MoveItem(CanBackCooling.Key, CanBackCooling.Value, (ModuleName)wafer.OriginStation, wafer.OriginSlot, Hand.Blade2));
|
|
|
+ RunTMRobotTask();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0) || WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 2))
|
|
|
+ {
|
|
|
+ WaferInfo waferonhand = new WaferInfo();
|
|
|
+ if (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0))
|
|
|
+ waferonhand = WaferManager.Instance.GetWafer(ModuleName.TMRobot, 0);
|
|
|
+ if (waferonhand == null && WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 2))
|
|
|
+ waferonhand = WaferManager.Instance.GetWafer(ModuleName.TMRobot, 2);
|
|
|
+ if (waferonhand.ProcessState == EnumWaferProcessStatus.Completed)
|
|
|
+ {
|
|
|
+ _moveQueue.Add(new MoveItem(CanBackCooling.Key, CanBackCooling.Value, ModuleName.TMRobot, 1, Hand.Blade2));
|
|
|
+ RunTMRobotTask();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -2462,6 +2606,51 @@ namespace EfemDualSchedulerLib
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
+ private bool ExsitCanSwapCooling(WaferInfo wafer, out ModuleName cooling, out int slot)
|
|
|
+ {
|
|
|
+ cooling = ModuleName.System;
|
|
|
+ slot = -1;
|
|
|
+ foreach (ModuleName _cooling in _lstProcessJobs.Find(x => x.Sequence.Name == wafer.ProcessJob.Sequence.Name && x.Sequence.Steps.Count > 1).Sequence.Steps[wafer.NextSequenceStep].StepModules)
|
|
|
+ {
|
|
|
+ string md = _cooling.ToString();
|
|
|
+ if (ModuleHelper.IsCoolingBuffer(_cooling) && ModuleHelper.IsInstalled(_cooling))
|
|
|
+ {
|
|
|
+ if (WaferManager.Instance.CheckHasWafer(md, 0) && WaferManager.Instance.CheckHasWafer(md, 1))
|
|
|
+ {
|
|
|
+ WaferInfo _wafer = null;
|
|
|
+ if (WaferManager.Instance.CheckHasWafer(md, 0))
|
|
|
+ _wafer = WaferManager.Instance.GetWafer(_cooling, 0);
|
|
|
+ if (_wafer == null && WaferManager.Instance.CheckHasWafer(md, 1))
|
|
|
+ _wafer = WaferManager.Instance.GetWafer(_cooling, 1);
|
|
|
+
|
|
|
+ if (_wafer != null && _wafer.ProcessState != EnumWaferProcessStatus.Completed)
|
|
|
+ {
|
|
|
+ cooling = _cooling;
|
|
|
+ slot = 0;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (WaferManager.Instance.CheckHasWafer(md, 2) && WaferManager.Instance.CheckHasWafer(md, 3))
|
|
|
+ {
|
|
|
+ WaferInfo _wafer = null;
|
|
|
+ if (WaferManager.Instance.CheckHasWafer(md, 2))
|
|
|
+ _wafer = WaferManager.Instance.GetWafer(_cooling, 2);
|
|
|
+ if (_wafer == null && WaferManager.Instance.CheckHasWafer(md, 3))
|
|
|
+ _wafer = WaferManager.Instance.GetWafer(_cooling, 3);
|
|
|
+
|
|
|
+ if (_wafer != null && _wafer.ProcessState != EnumWaferProcessStatus.Completed)
|
|
|
+ {
|
|
|
+ cooling = _cooling;
|
|
|
+ slot = 1;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
private List<KeyValuePair<ModuleName, int>> SequenceNeedCoolingsAvailable(WaferInfo wafer)
|
|
|
{
|
|
|
List<KeyValuePair<ModuleName, int>> Coolings = new List<KeyValuePair<ModuleName, int>>();
|
|
@@ -2487,6 +2676,54 @@ namespace EfemDualSchedulerLib
|
|
|
return pj.Sequence.Steps.Count <= wafer.NextSequenceStep;
|
|
|
}
|
|
|
|
|
|
+ //no matter has wafer or not
|
|
|
+ private bool PMHasAvailable()
|
|
|
+ {
|
|
|
+ return _lstPms.Exists(x => x.IsAvailable);
|
|
|
+ }
|
|
|
+
|
|
|
+ private bool CoolingHasEmptySlot()
|
|
|
+ {
|
|
|
+ return _lstCooling.Exists(x => (WaferManager.Instance.CheckNoWafer(x.Module, 0) && WaferManager.Instance.CheckNoWafer(x.Module, 1)) ||
|
|
|
+ (WaferManager.Instance.CheckNoWafer(x.Module, 2) && WaferManager.Instance.CheckNoWafer(x.Module, 3)));
|
|
|
+ }
|
|
|
+
|
|
|
+ private bool CoolingHasNeedProcessWafer()
|
|
|
+ {
|
|
|
+ bool NeedProcessFlag = false;
|
|
|
+
|
|
|
+ _lstCooling.ForEach(x => {
|
|
|
+
|
|
|
+ if (!NeedProcessFlag)
|
|
|
+ {
|
|
|
+ if (WaferManager.Instance.CheckHasWafer(x.Module, 0) || WaferManager.Instance.CheckHasWafer(x.Module, 1))
|
|
|
+ {
|
|
|
+ WaferInfo wafer = new WaferInfo();
|
|
|
+ if (WaferManager.Instance.CheckHasWafer(x.Module, 0))
|
|
|
+ wafer = WaferManager.Instance.GetWafer(x.Module, 0);
|
|
|
+ if (wafer == null && WaferManager.Instance.CheckHasWafer(x.Module, 1))
|
|
|
+ wafer = WaferManager.Instance.GetWafer(x.Module, 1);
|
|
|
+ if (wafer != null && wafer.ProcessState != EnumWaferProcessStatus.Completed)
|
|
|
+ NeedProcessFlag = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (WaferManager.Instance.CheckHasWafer(x.Module, 2) || WaferManager.Instance.CheckHasWafer(x.Module, 3))
|
|
|
+ {
|
|
|
+ WaferInfo wafer = new WaferInfo();
|
|
|
+ if (WaferManager.Instance.CheckHasWafer(x.Module, 2))
|
|
|
+ wafer = WaferManager.Instance.GetWafer(x.Module, 2);
|
|
|
+ if (wafer == null && WaferManager.Instance.CheckHasWafer(x.Module, 3))
|
|
|
+ wafer = WaferManager.Instance.GetWafer(x.Module, 3);
|
|
|
+ if (wafer != null && wafer.ProcessState != EnumWaferProcessStatus.Completed)
|
|
|
+ NeedProcessFlag = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+ return NeedProcessFlag;
|
|
|
+ }
|
|
|
+
|
|
|
private bool WaferCoolTaskIsFree(WaferInfo wafer)
|
|
|
{
|
|
|
if (!_lstProcessJobs.Exists(x => x.Sequence.Name == wafer.ProcessJob.Sequence.Name && x.Sequence.Steps.Count > 1))
|
|
@@ -2520,6 +2757,43 @@ namespace EfemDualSchedulerLib
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ private bool SequenceNoNeedCoolingFirst(WaferInfo wafer)
|
|
|
+ {
|
|
|
+ if (_lstProcessJobs.Exists(x => x.Sequence.Name == wafer.ProcessJob.Sequence.Name && !ModuleHelper.IsCoolingBuffer(x.Sequence.Steps[0].StepModules[0])))
|
|
|
+ return true;
|
|
|
+ else
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private bool SearchEmptyCooling(List<ModuleName> needCoolings, out ModuleName cooling, out int slot)
|
|
|
+ {
|
|
|
+ cooling = ModuleName.System;
|
|
|
+ slot = -1;
|
|
|
+ foreach (var mod in needCoolings)
|
|
|
+ {
|
|
|
+ if (ModuleHelper.IsCoolingBuffer(mod) && ModuleHelper.IsInstalled(mod))
|
|
|
+ {
|
|
|
+ if (WaferManager.Instance.CheckNoWafer(mod, 0) && WaferManager.Instance.CheckNoWafer(mod, 1))
|
|
|
+ {
|
|
|
+ cooling = mod;
|
|
|
+ slot = 0;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (WaferManager.Instance.CheckNoWafer(mod, 2) && WaferManager.Instance.CheckNoWafer(mod, 3))
|
|
|
+ {
|
|
|
+ cooling = mod;
|
|
|
+ slot = 1;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
private bool SequenceNeedCoolingAvailable(List<ModuleName> needCoolings)
|
|
|
{
|
|
|
foreach (var module in needCoolings)
|
|
@@ -2685,6 +2959,7 @@ namespace EfemDualSchedulerLib
|
|
|
return ModuleName.TMRobot;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
private ModuleName SearchCooling(List<ModuleName> needCoolings, Dictionary<int,ModuleName> CoolingChoice)
|
|
|
{
|
|
|
foreach (var module in needCoolings)
|