Sic04/SicRT/Equipments/ReturnAllWafer.cs

799 lines
27 KiB
C#
Raw Normal View History

2022-09-19 09:16:33 +08:00
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.Core.Util;
2022-09-19 09:16:33 +08:00
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 bool needAligner = false;
Dictionary<ModuleName, int> _checkPosition = new Dictionary<ModuleName, int>()
{
{ModuleName.PM1, 1},
{ModuleName.LoadLock, 1},
{ModuleName.UnLoad, 1},
{ModuleName.WaferRobot, 1},
{ModuleName.TrayRobot, 1},
{ModuleName.TMRobot, 1},
{ModuleName.Aligner, 1},
};
private readonly R_TRIG _trigLoadUnLoadAllPumpAlarm = new R_TRIG();
private readonly R_TRIG _trigWaferNoOriginWarn = new R_TRIG();
2022-09-19 09:16:33 +08:00
public ReturnAllWafer()
{
}
public Result Start()
{
if (!_tmRobot.IsAvailable)
{
EV.PostWarningLog("Scheduler", "can not return wafer, TmRobot is not available!");
2022-09-19 09:16:33 +08:00
return Result.FAIL;
}
if (!_trayRobot.IsAvailable)
{
EV.PostWarningLog("Scheduler", "can not return wafer, TrayRobot is not available!");
2022-09-19 09:16:33 +08:00
return Result.FAIL;
}
if (!_waferRobot.IsAvailable)
{
EV.PostWarningLog("Scheduler", "can not return wafer, WaferRobot is not available!");
2022-09-19 09:16:33 +08:00
return Result.FAIL;
}
if (!_load.IsAvailable)
{
EV.PostWarningLog("Scheduler", "can not return wafer, Load is not available!");
return Result.FAIL;
}
if (!_unload.IsAvailable)
{
EV.PostWarningLog("Scheduler", "can not return wafer, UnLoad is not available!");
return Result.FAIL;
}
if (!_buffer.IsAvailable)
{
EV.PostWarningLog("Scheduler", "can not return wafer, Buffer is not available!");
return Result.FAIL;
}
return Result.RUN;
}
public Result Monitor()
{
MonitorModuleTasks();
if (MonitorTaskDone())
{
return Result.DONE;
}
return Result.RUN;
}
public Result MonitorModuleTasks()
{
//Load和UnLoad不能同时抽气
//System.Diagnostics.Debug.Assert(!((_tmRobot.IsInPumping && _load.IsInPumping) || (_tmRobot.IsInPumping && _unload.IsInPumping) || (_unload.IsInPumping && _load.IsInPumping)), $"检测到 _load.IsInPumping :{_load.IsInPumping}, _unload.IsInPumping :{_unload.IsInPumping}, _tmRobot.IsInPumping :{_tmRobot.IsInPumping}");
_trigLoadUnLoadAllPumpAlarm.CLK = (_unload.IsInPumping && _load.IsInPumping);
if (_trigLoadUnLoadAllPumpAlarm.Q)
EV.PostAlarmLog("Scheduler", $"Detected that Load and UnLoad are pumping at the same timeLoad Task: {_load.GetTaskRunning()}, UnLoad Task: {_unload.GetTaskRunning()}");
2022-09-19 09:16:33 +08:00
MonitorPMTask();
MonitorLoadTask();
MonitorUnLoadTask();
MonitorBufferTask();
MonitorAlignerTask();
MonitorTmRobotTask();
MonitorWaferRobotTask();
MonitorTrayRobotTask();
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 (_buffer.HasWafer(0) || _buffer.HasWafer(1) || _buffer.HasWafer(2))
return false;
if (_buffer.HasTrayAndExceedProcessCount(0) || _buffer.HasTrayAndExceedProcessCount(1) || _buffer.HasTrayAndExceedProcessCount(2))
return false;
if (!_tmRobot.IsAvailable)
return false;
if (!_waferRobot.IsAvailable)
return false;
if (!_trayRobot.IsAvailable)
return false;
return true;
}
private void MonitorTmRobotTask()
{
if (!_tmRobot.IsAvailable)
return;
foreach (var pm in _lstPms)
{
if (pm.IsWaitTransfer(ModuleName.TMRobot))
pm.StopWaitTransfer(ModuleName.TMRobot);
}
if (_buffer.IsWaitTransfer(ModuleName.TMRobot))
_buffer.StopWaitTransfer(ModuleName.TMRobot);
if (_load.IsWaitTransfer(ModuleName.TMRobot))
_load.StopWaitTransfer(ModuleName.TMRobot);
if (_unload.IsWaitTransfer(ModuleName.TMRobot))
_unload.StopWaitTransfer(ModuleName.TMRobot);
MonitorTmRobotPMTask();
MonitorTmRobotBufferTask();
MonitorTmRobotLoadTask();
MonitorTmRobotUnLoadTask();
}
private void MonitorWaferRobotTask()
{
foreach (var cass in _lstCassettes)
{
if (cass.IsWaitTransfer(ModuleName.WaferRobot))
cass.StopWaitTransfer(ModuleName.WaferRobot);
}
if (_aligner.IsWaitTransfer(ModuleName.WaferRobot))
_aligner.StopWaitTransfer(ModuleName.WaferRobot);
if (_load.IsWaitTransfer(ModuleName.WaferRobot))
_load.StopWaitTransfer(ModuleName.WaferRobot);
if (_unload.IsWaitTransfer(ModuleName.WaferRobot))
_unload.StopWaitTransfer(ModuleName.WaferRobot);
MonitorWaferRobotCassetteTask();
MonitorWaferRobotAligerTask();
MonitorWaferRobotLoadTask();
MonitorWaferRobotUnLoadTask();
}
private void MonitorTrayRobotTask()
{
if (_cassetteBL.IsWaitTransfer(ModuleName.TrayRobot))
_cassetteBL.StopWaitTransfer(ModuleName.TrayRobot);
if (_load.IsWaitTransfer(ModuleName.TrayRobot))
_load.StopWaitTransfer(ModuleName.TrayRobot);
MonitorTrayRobotLoadTask();
MonitorTrayRobotCassetteTask();
}
private void MonitorTmRobotLoadTask()
{
if (!_load.IsAvailable)
return;
if (!_tmRobot.IsAvailable)
return;
//place Robot有次数耗尽的Tray无Wafer,Load无Tray
bool canPlace = _tmRobot.HasTrayAndExceedProcessCount(0) && _tmRobot.NoWafer(0) && _load.NoTray(0);
if (canPlace)
{
if (_load.IsReadyForPlace(ModuleName.TMRobot, 0))
{
if (_tmRobot.Place(_load.Module, 0, Hand.Blade1))
{
_load.WaitTransfer(ModuleName.TMRobot);
return;
}
}
}
}
private void MonitorTmRobotUnLoadTask()
{
if (!_unload.IsAvailable)
return;
if (!_tmRobot.IsAvailable)
return;
//UnLoad取盘只关心LoadLock是否有空位
//place Robot有Wafer,UnLoad无Tray无Wafer
bool canPlaceUnLoad = _tmRobot.HasWafer(0)
&& _unload.NoTray(0)
&& _unload.NoWafer(0);
if (canPlaceUnLoad)
{
if (_unload.IsReadyForPlace(ModuleName.TMRobot, 0))
{
if (_tmRobot.Place(_unload.Module, 0, Hand.Blade1))
{
_unload.WaitTransfer(ModuleName.TMRobot);
return;
}
}
}
if (!_unload.IsAvailable)
return;
if (!_tmRobot.IsAvailable)
return;
//pick UnLoad有Tray,TM无Tray,UnLoad分离完成
bool canPickUnLoad = _tmRobot.NoTray(0)
&& _unload.HasTray(0)
&& _unload.CheckWaferTraySeparated();
if (canPickUnLoad)
{
if (_unload.IsReadyForPick(ModuleName.TMRobot, 0) && !_load.IsInPumping)
{
if (_tmRobot.Pick(_unload.Module, 0, Hand.Blade1))
{
_unload.WaitTransfer(ModuleName.TMRobot);
return;
}
}
}
}
private void MonitorTmRobotBufferTask()
{
if (!_tmRobot.IsAvailable)
return;
if (!_buffer.IsAvailable)
return;
//place 次数未耗尽的Tray放入Buffer中
bool canPalce = _tmRobot.NoWafer(0) && _tmRobot.HasTrayAndNotExceedProcessCount(0);
if (canPalce)
{
SlotItem bufferEmptySlot = null;
for (int i = 0; i < 3; i++)
{
if (_buffer.NoTray(i) && _buffer.NoWafer(i))
{
bufferEmptySlot = new SlotItem(ModuleName.Buffer, i);
break;
}
}
if (bufferEmptySlot == null)
{
return;
}
if (_buffer.IsReadyForPlace(ModuleName.TMRobot, bufferEmptySlot.Slot))
{
if (_tmRobot.Place(_buffer.Module, bufferEmptySlot.Slot, Hand.Blade1))
{
_buffer.WaitTransfer(ModuleName.TMRobot);
return;
}
}
}
if (!_tmRobot.IsAvailable)
return;
if (!_buffer.IsAvailable)
return;
//pick 当前步(UnLoad没有Wafer),Buffer有Tray,机械手没有Tray
bool canPick = _tmRobot.NoTray(0) && _unload.NoTray(0) && _unload.NoWafer(0);
if (canPick)
{
for (int i = 0; i < 3; i++)
{
if (_buffer.HasTray(i) && _buffer.HasWafer(i))
{
if (_buffer.IsReadyForPick(ModuleName.TMRobot, i))
{
if (_tmRobot.Pick(_buffer.Module, i, Hand.Blade1))
{
_buffer.WaitTransfer(ModuleName.TMRobot);
return;
}
}
}
if (_buffer.HasTrayAndExceedProcessCount(i))
{
if (_buffer.IsReadyForPick(ModuleName.TMRobot, i))
{
if (_tmRobot.Pick(_buffer.Module, i, Hand.Blade1))
{
_buffer.WaitTransfer(ModuleName.TMRobot);
return;
}
}
}
}
}
}
private void MonitorTmRobotPMTask()
{
if (!_tmRobot.IsAvailable)
return;
//pick from pm
if (_tmRobot.NoWafer(0) && _tmRobot.NoTray(0) && _unload.NoWafer(0) && _unload.NoTray(0))
{
Hand pickBlade = Hand.Blade1;
ModuleName pickPm = ModuleName.System;
foreach (var schedulerPm in _lstPms)
{
//增加温度低于900才能Pick的限制
if (!schedulerPm.IsAvailable
|| GetModule(schedulerPm.Module).NoWafer(0)
|| _tmRobot.HasWafer((int)pickBlade)
|| !schedulerPm.CheckTempBelow900())
continue;
pickPm = schedulerPm.Module;
break;
}
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 MonitorWaferRobotLoadTask()
{
if (!_waferRobot.IsAvailable)
return;
if (!_load.IsAvailable)
return;
bool canPick = _waferRobot.NoWafer(0)
&& _load.HasWafer(0);
//&& _load.CheckWaferTraySeparated();
if (canPick)
{
if (_load.IsReadyForPick(ModuleName.WaferRobot, 0))
{
if (_waferRobot.Pick(_load.Module, 0, Hand.Blade1))
{
_load.WaitTransfer(ModuleName.WaferRobot);
return;
}
}
}
}
private void MonitorWaferRobotUnLoadTask()
{
if (!_waferRobot.IsAvailable)
return;
if (!_unload.IsAvailable)
return;
//pick UnLoad有Wafer没有Tray,Robot没有Wafer,步骤都完成了或者下一步的模块没有片子 (其它:UnLoad 夹爪夹住,顶针下降,SlitValve都关了,大气)
bool canPick = _waferRobot.NoWafer(0)
&& _unload.HasWafer(0)
&& _unload.NoTray(0);
if (canPick)
{
if (_unload.IsReadyForPick(ModuleName.WaferRobot, 0))
{
if (_waferRobot.Pick(_unload.Module, 0, Hand.Blade1))
{
_unload.WaitTransfer(ModuleName.WaferRobot);
return;
}
}
}
}
private void MonitorWaferRobotAligerTask()
{
if (_load.HasWafer(0) && _load.GetWaferInfo(0).NextStation != (int)ModuleName.Aligner)
_load.GetWaferInfo(0).NextStation = (int)ModuleName.Aligner;
if (_unload.HasWafer(0) && _unload.GetWaferInfo(0).NextStation != (int)ModuleName.Aligner)
_unload.GetWaferInfo(0).NextStation = (int)ModuleName.Aligner;
if (_waferRobot.HasWafer(0) && _waferRobot.GetWaferInfo(0).NextStation != (int)ModuleName.Aligner && _waferRobot.GetWaferInfo(0).NextStation != (int)ModuleName.System)
_waferRobot.GetWaferInfo(0).NextStation = (int)ModuleName.Aligner;
if (!_waferRobot.IsAvailable)
return;
if (!_aligner.IsAvailable)
return;
//place 任务还没完成,下一步是Aligner,Robot有片子,Aligner没片子
bool canPlaceAligner = _aligner.NoWafer(0)
&& _waferRobot.HasWafer(0)
&& _waferRobot.GetWaferInfo(0).NextStation == (int)ModuleName.Aligner;
if (canPlaceAligner)
{
if (_aligner.IsReadyForPlace(ModuleName.WaferRobot, 0))
{
if (_waferRobot.Place(_aligner.Module, 0, Hand.Blade1))
{
_aligner.WaitTransfer(ModuleName.WaferRobot);
return;
}
}
}
if (!_waferRobot.IsAvailable)
return;
if (!_aligner.IsAvailable)
return;
//pick Robot没片子,Aligner有片子
bool canPickAligner = _aligner.HasWafer(0)
&& _waferRobot.NoWafer(0);
if (canPickAligner)
{
if (_aligner.IsReadyForPick(ModuleName.WaferRobot, 0))
{
if (_waferRobot.Pick(_aligner.Module, 0, Hand.Blade1))
{
_aligner.WaitTransfer(ModuleName.WaferRobot);
return;
}
}
}
}
private void MonitorWaferRobotCassetteTask()
{
if (!_waferRobot.IsAvailable)
return;
//place
bool canPlaceCassette = _waferRobot.HasWafer(0)&& _waferRobot.GetWaferInfo(0).NextStation!=(int)ModuleName.Aligner;
if (canPlaceCassette)
{
WaferInfo wafer = _waferRobot.GetWaferInfo(0);
_trigWaferNoOriginWarn.CLK = (wafer.OriginStation != (int)ModuleName.CassAL &&
wafer.OriginStation != (int)ModuleName.CassAR);
// Wafer来源不明提示用户
if (_trigWaferNoOriginWarn.Q)
{
EV.PostWarningLog("ReturnAllWafer",
"Unknown origin station of wafer on Wafer Robot");
return;
}
2022-09-19 09:16:33 +08:00
if (wafer.OriginStation == (int)ModuleName.CassAL)
{
if (_cassetteAL.IsReadyForPlace(ModuleName.WaferRobot, wafer.OriginSlot) &&
WaferManager.Instance.CheckNoWafer(ModuleName.CassAL, wafer.OriginSlot))
2022-09-19 09:16:33 +08:00
{
if (_waferRobot.Place(_cassetteAL.Module, wafer.OriginSlot, Hand.Blade1))
{
_cassetteAL.WaitTransfer(ModuleName.WaferRobot);
return;
}
}
}
else if (wafer.OriginStation == (int)ModuleName.CassAR)
{
if (_cassetteAR.IsReadyForPlace(ModuleName.WaferRobot, wafer.OriginSlot) &&
WaferManager.Instance.CheckNoWafer(ModuleName.CassAR, wafer.OriginSlot))
2022-09-19 09:16:33 +08:00
{
if (_waferRobot.Place(_cassetteAR.Module, wafer.OriginSlot, Hand.Blade1))
{
_cassetteAR.WaitTransfer(ModuleName.WaferRobot);
return;
}
}
}
}
}
private void MonitorTrayRobotLoadTask()
{
if (!_trayRobot.IsAvailable)
return;
if (!_load.IsAvailable)
return;
//先取Wafer再取石墨盘
bool canPick = _load.HasTray(0) && _load.NoWafer(0);
if (canPick)
{
SlotItem emptyTraySlot = GetTrayOrignSlot(ModuleName.LoadLock, 0);
if (emptyTraySlot != null)
{
if (_load.IsReadyForPick(ModuleName.TrayRobot, 0))
{
if (_trayRobot.Pick(_load.Module, 0, Hand.Blade1))
{
_load.WaitTransfer(ModuleName.TrayRobot);
return;
}
}
}
}
}
private void MonitorTrayRobotCassetteTask()
{
if (!_trayRobot.IsAvailable)
return;
if (!_cassetteBL.IsAvailable)
return;
//place Robot有盘 其它逻辑跟Load的Pick一致
bool canPlace = _trayRobot.HasTray(0);
if (canPlace)
{
SlotItem slotItem = GetTrayOrignSlot(ModuleName.TrayRobot, 0); //GetEmptyTraySlot(13);
if (slotItem != null)
{
if (_cassetteBL.IsReadyForPlace(ModuleName.TrayRobot, slotItem.Slot))
{
if (_trayRobot.Place(slotItem.Module, slotItem.Slot, Hand.Blade1))
{
_cassetteBL.WaitTransfer(ModuleName.TrayRobot);
return;
}
}
}
}
}
private void MonitorBufferTask()
{
if (!_buffer.IsAvailable)
{
return;
}
if (!_buffer.IsReadyForPick(ModuleName.TMRobot, 0))
{
_buffer.PrepareTransfer(ModuleName.TMRobot, EnumTransferType.Place, 0);
}
}
private void MonitorAlignerTask()
{
if (!_aligner.IsAvailable)
{
return;
}
if (_aligner.HasWafer(0) && _aligner.GetWaferInfo(0).NextStation==(int)ModuleName.Aligner)
{
_aligner.Aligning();
_aligner.GetWaferInfo(0).NextStation = (int)ModuleName.System;
}
}
private void MonitorPMTask()
{
foreach (var pm in _lstPms)
{
if (!pm.IsAvailable)
continue;
if (pm.NoTray(0) && pm.NoWafer(0))
continue;
if (!pm.IsReadyForPick(ModuleName.TMRobot, 0))
{
pm.PrepareTransfer(ModuleName.TMRobot, EnumTransferType.Pick, 0);
}
}
}
private void MonitorLoadTask()
{
if (!_load.IsAvailable)
{
return;
}
if (_load.HasWafer(0))
{
if (/*_load.CheckWaferTraySeparated() &&*/ !_load.IsReadyForPick(ModuleName.WaferRobot, 0) && !_unload.IsInPumping && !_tmRobot.IsInPumping)
{
_load.PrepareTransfer(ModuleName.WaferRobot, EnumTransferType.Pick, 0);
return;
}
}
else if (_load.HasTray(0))
{
if (/*_load.CheckWaferTraySeparated() &&*/ !_load.IsReadyForPick(ModuleName.TrayRobot, 0) && !_unload.IsInPumping && !_tmRobot.IsInPumping)
{
_load.PrepareTransfer(ModuleName.TrayRobot, EnumTransferType.Pick, 0);
return;
}
}
else if (_tmRobot.HasTrayAndExceedProcessCount(0) && _tmRobot.NoWafer(0))
{
if (!_load.IsReadyForPlace(ModuleName.TMRobot, 0) && !_unload.IsInPumping && !_tmRobot.IsInPumping)
{
_load.PrepareTransfer(ModuleName.TMRobot, EnumTransferType.Place, 0);
return;
}
}
}
private void MonitorUnLoadTask()
{
if (!_unload.IsAvailable)
{
return;
}
// 如果有Wafer有Tray先检查是否分离
if (_unload.HasWafer(0) && _unload.HasTray(0))
2022-09-19 09:16:33 +08:00
{
if (!_unload.CheckWaferTraySeparated())
{
_unload.SeparateWaferTray();
return;
}
}
if (_unload.HasTray(0)) // UnLoad有Tray先让TMRobot取Tray
2022-09-19 09:16:33 +08:00
{
if (_unload.CheckWaferTraySeparated())
2022-09-19 09:16:33 +08:00
{
// 如果Sequence下一步是UnLoad,并且W&T已冷却和分离
if (!_unload.CheckPurgedBeforeTrayPicking()
&& !_load.IsInPumping)
{
var cycle = SC.GetValue<int>($"{ModuleName.UnLoad}.Purge.CyclePurgeCount");
var pumpDelay = SC.GetValue<int>($"{ModuleName.UnLoad}.Purge.PumpDelayTime");
_unload.PurgeBeforeTrayPicking(cycle, pumpDelay);
return;
}
if (_unload.CheckPurgedBeforeTrayPicking()
&& !_unload.IsReadyForPick(ModuleName.TMRobot, 0)
&& !_load.IsInPumping)
{
// UnLoad中有Tray则准备好让TMRobot来取
_unload.PrepareTransfer(ModuleName.TMRobot, EnumTransferType.Pick, 0);
return;
}
2022-09-19 09:16:33 +08:00
}
}
else if (_unload.HasWafer(0)) // 如果没TrayWaferRobot取Wafer
2022-09-19 09:16:33 +08:00
{
if (_unload.CheckWaferTraySeparated() )
2022-09-19 09:16:33 +08:00
{
// 如果取Wafer前还未Purge先Purge
if (!_unload.CheckPurgedBeforeWaferPicking()
&& !_load.IsInPumping)
{
var cycle = SC.GetValue<int>($"{ModuleName.UnLoad}.Purge.CyclePurgeCountBefWaferPicking");
var pumpDelay = SC.GetValue<int>($"{ModuleName.UnLoad}.Purge.PurgePumpDelayBefWaferPicking");
_unload.PurgeBeforeWaferPicking(cycle, pumpDelay);
return;
}
if (_unload.CheckPurgedBeforeWaferPicking()
&& !_unload.IsReadyForPick(ModuleName.WaferRobot, 0)
&& !_load.IsInPumping)
{
// 准备好让WaferRobot来取
_unload.PrepareTransfer(ModuleName.WaferRobot, EnumTransferType.Pick, 0);
}
2022-09-19 09:16:33 +08:00
}
return;
2022-09-19 09:16:33 +08:00
}
else // 如果UnLoad里啥也没有则准备好下次TMRobot喂 W&T
2022-09-19 09:16:33 +08:00
{
if (!_load.IsInPumping
&& !_unload.IsReadyForPlace(ModuleName.TMRobot, 0)
&& !_load.IsInPumping)
2022-09-19 09:16:33 +08:00
{
_unload.PrepareTransfer(ModuleName.TMRobot, EnumTransferType.Place, 0);
return;
}
}
}
private SlotItem GetEmptyTraySlot()
{
for (int i = 0; i < WaferManager.Instance.GetWafers(ModuleName.CassBL).Length; i++)
{
if (WaferManager.Instance.CheckNoTray(ModuleName.CassBL, i))
{
return new SlotItem(ModuleName.CassBL, i);
}
}
return null;
}
private SlotItem GetTrayOrignSlot(ModuleName module, int slot)
{
WaferInfo wafer = GetModule(module).GetWaferInfo(slot);
if (wafer != null && GetModule(module).HasTray(slot) && _cassetteBL.NoTray(wafer.TrayOriginSlot))
{
return new SlotItem(ModuleName.CassBL, wafer.TrayOriginSlot);
}
return null;
}
private bool CheckWaferCouldBeReturn(ModuleName module, int slot)
{
WaferInfo wafer = WaferManager.Instance.GetWafer(module, slot);
if (!wafer.IsEmpty)
{
return true;
}
else if (wafer.TrayState == WaferTrayStatus.Normal)
{
return true;
}
return false;
}
}
}