277 lines
8.5 KiB
C#
277 lines
8.5 KiB
C#
|
using System.Collections.Generic;
|
|||
|
using Aitex.Core.Common;
|
|||
|
using Aitex.Core.RT.Event;
|
|||
|
using Aitex.Core.RT.Routine;
|
|||
|
using Aitex.Core.RT.SCCore;
|
|||
|
using Aitex.Sorter.Common;
|
|||
|
using SicRT.Modules.Schedulers;
|
|||
|
using SicRT.Scheduler;
|
|||
|
using MECF.Framework.Common.Equipment;
|
|||
|
using MECF.Framework.Common.Schedulers;
|
|||
|
using MECF.Framework.Common.SubstrateTrackings;
|
|||
|
|
|||
|
namespace SicRT.Modules
|
|||
|
{
|
|||
|
public class ReturnAllWafer : SchedulerModuleFactory
|
|||
|
{
|
|||
|
private List<SchedulerPM> _lstPms = new List<SchedulerPM>();
|
|||
|
|
|||
|
Dictionary<ModuleName, int> _checkPosition = new Dictionary<ModuleName, int>()
|
|||
|
{
|
|||
|
{ModuleName.PM1, 1},
|
|||
|
{ModuleName.PM2, 1},
|
|||
|
//{ModuleName.PM3, 1},
|
|||
|
{ModuleName.TMRobot, 1},
|
|||
|
//{ModuleName.LLA, 2},
|
|||
|
//{ModuleName.LLB, 2},
|
|||
|
//{ModuleName.Aligner, 1},
|
|||
|
//{ModuleName.EfemRobot, 2},
|
|||
|
};
|
|||
|
|
|||
|
public ReturnAllWafer()
|
|||
|
{
|
|||
|
_lstPms.AddRange(new[] {_pm1, /*_pm2, _pm3*/});
|
|||
|
}
|
|||
|
|
|||
|
public Result Start( )
|
|||
|
{
|
|||
|
foreach (var positions in _checkPosition)
|
|||
|
{
|
|||
|
for (int i = 0; i < positions.Value; i++)
|
|||
|
{
|
|||
|
WaferInfo wafer = WaferManager.Instance.GetWafer(positions.Key, i);
|
|||
|
if (!wafer.IsEmpty)
|
|||
|
{
|
|||
|
if (!ModuleHelper.IsLoadPort((ModuleName)wafer.OriginStation))
|
|||
|
{
|
|||
|
EV.PostWarningLog("System", $"Wafer {positions.Key}.{i + 1} can not return, origin is not LP");
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
if (wafer.Status == WaferStatus.Dummy)
|
|||
|
{
|
|||
|
EV.PostWarningLog("System", $"Wafer {positions.Key}.{i + 1} can not return, wafer is dummy");
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
if (WaferManager.Instance.CheckNoWafer((ModuleName)wafer.OriginStation, wafer.OriginSlot))
|
|||
|
{
|
|||
|
EV.PostWarningLog("System", $"Wafer {positions.Key}.{i + 1} can not return, origin has wafer");
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
EV.PostInfoLog("System", $"Wafer return, {positions.Key}.{i + 1}=>{(ModuleName)wafer.OriginStation}.{wafer.OriginSlot + 1}");
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return Result.RUN;
|
|||
|
}
|
|||
|
|
|||
|
public Result Monitor( )
|
|||
|
{
|
|||
|
MonitorModuleTasks();
|
|||
|
|
|||
|
if (MonitorTaskDone())
|
|||
|
{
|
|||
|
return Result.DONE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
return Result.RUN;
|
|||
|
}
|
|||
|
|
|||
|
public void Clear()
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
public Result MonitorModuleTasks()
|
|||
|
{
|
|||
|
MonitorPMTask();
|
|||
|
|
|||
|
MonitorTmRobotTask();
|
|||
|
|
|||
|
MonitorLoadLockTask();
|
|||
|
|
|||
|
return Result.RUN;
|
|||
|
}
|
|||
|
|
|||
|
private bool MonitorTaskDone()
|
|||
|
{
|
|||
|
foreach (var positions in _checkPosition)
|
|||
|
{
|
|||
|
for (int i = 0; i < positions.Value; i++)
|
|||
|
{
|
|||
|
if (CheckWaferCouldBeReturn(positions.Key, i))
|
|||
|
{
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (!_tmRobot.IsAvailable)
|
|||
|
return false;
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
private void MonitorPMTask()
|
|||
|
{
|
|||
|
foreach (var pm in _lstPms)
|
|||
|
{
|
|||
|
if (!pm.IsAvailable)
|
|||
|
continue;
|
|||
|
|
|||
|
if (CheckWaferCouldBeReturn(pm.Module, 0))
|
|||
|
{
|
|||
|
if (!pm.IsReadyForPick(ModuleName.TMRobot, 0))
|
|||
|
{
|
|||
|
pm.PrepareTransfer(ModuleName.TMRobot, EnumTransferType.Pick, 0);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void MonitorTmRobotTask()
|
|||
|
{
|
|||
|
if (!_tmRobot.IsAvailable)
|
|||
|
return;
|
|||
|
|
|||
|
//TM robot is idle, release all the target
|
|||
|
|
|||
|
|
|||
|
foreach (var pm in _lstPms)
|
|||
|
{
|
|||
|
if (pm.IsWaitTransfer(ModuleName.TMRobot))
|
|||
|
pm.StopWaitTransfer(ModuleName.TMRobot);
|
|||
|
}
|
|||
|
|
|||
|
MonitorTmRobotLoadLockTask();
|
|||
|
if (!_tmRobot.IsAvailable)
|
|||
|
return;
|
|||
|
|
|||
|
MonitorTmRobotPMTask();
|
|||
|
if (!_tmRobot.IsAvailable)
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
private void MonitorTmRobotLoadLockTask()
|
|||
|
{
|
|||
|
if (!_tmRobot.IsAvailable)
|
|||
|
return;
|
|||
|
|
|||
|
//place to ll
|
|||
|
bool blade0HasWaferAndProcessed = CheckWaferCouldBeReturn(ModuleName.TMRobot, 0);
|
|||
|
bool blade1HasWaferAndProcessed = CheckWaferCouldBeReturn(ModuleName.TMRobot, 1);
|
|||
|
if (blade0HasWaferAndProcessed || blade1HasWaferAndProcessed)
|
|||
|
{
|
|||
|
Hand placeBlade = blade0HasWaferAndProcessed ? Hand.Blade1 : Hand.Blade2;
|
|||
|
if (blade0HasWaferAndProcessed && blade1HasWaferAndProcessed)
|
|||
|
{
|
|||
|
if (WaferManager.Instance.GetWafer(ModuleName.TMRobot, 1).OriginSlot <
|
|||
|
WaferManager.Instance.GetWafer(ModuleName.TMRobot, 0).OriginSlot)
|
|||
|
{
|
|||
|
placeBlade = Hand.Blade2;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
private void MonitorTmRobotPMTask()
|
|||
|
{
|
|||
|
if (!_tmRobot.IsAvailable)
|
|||
|
return;
|
|||
|
|
|||
|
//pick from pm
|
|||
|
if (WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0) || WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 1))
|
|||
|
{
|
|||
|
Hand pickBlade = WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0) ? Hand.Blade1 : Hand.Blade2;
|
|||
|
Hand otherBlade = pickBlade == Hand.Blade1 ? Hand.Blade2 : Hand.Blade1;
|
|||
|
|
|||
|
ModuleName pickPm = ModuleName.System;
|
|||
|
int waferOriginSlot = int.MaxValue;
|
|||
|
foreach (var schedulerPm in _lstPms)
|
|||
|
{
|
|||
|
if (!schedulerPm.IsAvailable
|
|||
|
|| !CheckWaferCouldBeReturn(schedulerPm.Module, 0))
|
|||
|
continue;
|
|||
|
|
|||
|
WaferInfo wafer = WaferManager.Instance.GetWafer(schedulerPm.Module, 0);
|
|||
|
|
|||
|
int slot = wafer.OriginSlot;
|
|||
|
if (slot < waferOriginSlot)
|
|||
|
{
|
|||
|
waferOriginSlot = slot;
|
|||
|
pickPm = schedulerPm.Module;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (pickPm != ModuleName.System)
|
|||
|
{
|
|||
|
SchedulerModule pm = GetModule(pickPm.ToString());
|
|||
|
if (pm.IsReadyForPick(ModuleName.TMRobot, 0))
|
|||
|
{
|
|||
|
if (_tmRobot.Pick(pm.Module, 0, pickBlade))
|
|||
|
{
|
|||
|
pm.WaitTransfer(ModuleName.TMRobot);
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private void MonitorLoadLockTask()
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
private bool CheckWaferCouldBeReturn(ModuleName module, int slot)
|
|||
|
{
|
|||
|
WaferInfo wafer = WaferManager.Instance.GetWafer(module, slot);
|
|||
|
if (!wafer.IsEmpty)
|
|||
|
{
|
|||
|
return ModuleHelper.IsLoadPort((ModuleName)wafer.OriginStation)
|
|||
|
&& wafer.Status != WaferStatus.Dummy
|
|||
|
&& WaferManager.Instance.CheckNoWafer((ModuleName)wafer.OriginStation, wafer.OriginSlot);
|
|||
|
}
|
|||
|
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
private int GetVacuumWafer()
|
|||
|
{
|
|||
|
int count = 0;
|
|||
|
|
|||
|
if (CheckWaferCouldBeReturn(ModuleName.TMRobot, 0))
|
|||
|
count++;
|
|||
|
if (CheckWaferCouldBeReturn(ModuleName.TMRobot, 1))
|
|||
|
count++;
|
|||
|
if (CheckWaferCouldBeReturn(ModuleName.PM1, 0))
|
|||
|
count++;
|
|||
|
if (CheckWaferCouldBeReturn(ModuleName.PM2, 0))
|
|||
|
count++;
|
|||
|
if (CheckWaferCouldBeReturn(ModuleName.PM3, 0))
|
|||
|
count++;
|
|||
|
|
|||
|
return count;
|
|||
|
}
|
|||
|
|
|||
|
private SlotItem GetWaferReturnLoadPort(ModuleName module, int slot)
|
|||
|
{
|
|||
|
WaferInfo wafer = WaferManager.Instance.GetWafer(module, slot);
|
|||
|
if (!wafer.IsEmpty)
|
|||
|
{
|
|||
|
return new SlotItem((ModuleName)wafer.OriginStation, wafer.OriginSlot);
|
|||
|
}
|
|||
|
|
|||
|
return null;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|