400 lines
12 KiB
C#
400 lines
12 KiB
C#
using System.Linq;
|
||
using Aitex.Core.Common;
|
||
using Aitex.Core.RT.Device;
|
||
using Aitex.Core.RT.Fsm;
|
||
using Aitex.Core.Util;
|
||
using Aitex.Sorter.Common;
|
||
using MECF.Framework.Common.Equipment;
|
||
using MECF.Framework.Common.Schedulers;
|
||
using MECF.Framework.Common.SubstrateTrackings;
|
||
using SicRT.Equipments.Systems;
|
||
using SicRT.Modules.Schedulers;
|
||
using System.Diagnostics;
|
||
using Aitex.Core.RT.Event;
|
||
using SicModules.LLs;
|
||
using SicModules.UnLoads;
|
||
|
||
namespace SicRT.Scheduler
|
||
{
|
||
public class SchedulerUnLoad : SchedulerModule
|
||
{
|
||
public override bool IsAvailable
|
||
{
|
||
get
|
||
{
|
||
return _unL.IsIdle && _unL.IsOnline && CheckTaskDone() && _unL.CheckSlitValveClosed();
|
||
}
|
||
}
|
||
|
||
public override bool IsOnline
|
||
{
|
||
get
|
||
{
|
||
return _unL.IsOnline;
|
||
}
|
||
}
|
||
|
||
public override bool IsError
|
||
{
|
||
get
|
||
{
|
||
return _unL.IsError;
|
||
}
|
||
}
|
||
|
||
private UnLoadModuleBase _unL = null;
|
||
|
||
private ModuleName _taskRobot;
|
||
private int _taskSlot;
|
||
private int _entityTaskToken = (int)FSM_MSG.NONE;
|
||
private bool _separated = false;
|
||
private bool _purgedBefTrayPicking = false;
|
||
private bool _purgedBefWaferPicking = false;
|
||
private bool _purgedAfWaferPicked;
|
||
private bool _coolingCompleted = false;
|
||
|
||
public bool IsInPumping
|
||
{
|
||
get
|
||
{
|
||
return _task == TaskType.Pump || _task == TaskType.Purge || _task == TaskType.PrepareTransfer;
|
||
}
|
||
}
|
||
|
||
public SchedulerUnLoad(ModuleName module) : base(module.ToString())
|
||
{
|
||
_module = module.ToString();
|
||
_unL = Singleton<EquipmentManager>.Instance.Modules[module] as UnLoadModuleBase;
|
||
}
|
||
|
||
public override bool PrepareTransfer(ModuleName robot, EnumTransferType type, int slot)
|
||
{
|
||
_task = TaskType.PrepareTransfer;
|
||
_taskRobot = robot;
|
||
_taskSlot = slot;
|
||
|
||
LogTaskStart(_task, $"{robot} {type} slot {slot + 1}");
|
||
|
||
return _unL.PrepareTransfer(robot, Hand.Blade1, slot, type, out _);
|
||
}
|
||
|
||
internal bool CheckAtAtm()
|
||
{
|
||
SicLoadLock deviceLL = DEVICE.GetDevice<SicLoadLock>($"{_module}.{_module}");
|
||
|
||
return deviceLL.CheckAtm();
|
||
}
|
||
internal bool CheckAtVacuum()
|
||
{
|
||
SicLoadLock deviceLL = DEVICE.GetDevice<SicLoadLock>($"{_module}.{_module}");
|
||
|
||
return deviceLL.CheckVacuum();
|
||
}
|
||
internal void SetJobStatue()
|
||
{
|
||
SicLoadLock deviceLL = DEVICE.GetDevice<SicLoadLock>($"{_module}.{_module}");
|
||
//deviceLL.SetJobDoneStatus();
|
||
}
|
||
|
||
public override bool IsReadyForPick(ModuleName robot, int slot)
|
||
{
|
||
if (robot == ModuleName.WaferRobot)
|
||
{
|
||
return _unL.CheckReadyForTransfer(robot, Hand.Blade1, slot, EnumTransferType.Pick, out _)
|
||
&& WaferManager.Instance.CheckHasWafer(ModuleHelper.Converter(_module), slot);
|
||
}
|
||
else if (robot == ModuleName.TMRobot)
|
||
{
|
||
return _unL.CheckReadyForTransfer(robot, Hand.Blade1, slot, EnumTransferType.Pick, out _)
|
||
&& WaferManager.Instance.CheckHasTray(ModuleHelper.Converter(_module), slot);
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
public override bool IsReadyForPlace(ModuleName robot, int slot)
|
||
{
|
||
return _unL.CheckReadyForTransfer(robot, Hand.Blade1, slot, EnumTransferType.Place, out _)
|
||
&& WaferManager.Instance.CheckNoWafer(ModuleHelper.Converter(_module), slot)
|
||
&& WaferManager.Instance.CheckNoTray(ModuleHelper.Converter(_module), slot);
|
||
}
|
||
|
||
|
||
public bool Vent()
|
||
{
|
||
_task = TaskType.Vent;
|
||
|
||
_entityTaskToken = _unL.InvokeVent();
|
||
|
||
LogTaskStart(_task, $"{Module} vent to ATM");
|
||
|
||
return _entityTaskToken != (int)FSM_MSG.NONE;
|
||
}
|
||
|
||
public bool Pump()
|
||
{
|
||
_entityTaskToken = _unL.InvokePump();
|
||
if (_entityTaskToken != (int)FSM_MSG.NONE)
|
||
{
|
||
_task = TaskType.Pump;
|
||
LogTaskStart(_task, $"{Module} pump to Vaccum");
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
public override bool Cooling(bool coolingType, int coolingTime)
|
||
{
|
||
_entityTaskToken = _unL.InvokeCooling((int)coolingTime);
|
||
if (_entityTaskToken != (int)FSM_MSG.NONE)
|
||
{
|
||
_task = TaskType.Cooling;
|
||
LogTaskStart(_task, $"{Module} cooling {coolingTime} seconds");
|
||
}
|
||
|
||
_coolingCompleted = _entityTaskToken != (int)FSM_MSG.NONE;
|
||
return _coolingCompleted;
|
||
}
|
||
|
||
|
||
public bool PurgeBeforeTrayPicking(params object[] args)
|
||
{
|
||
// 如果循环次数为0,则跳过此步骤。
|
||
if (args is null || (args[0] is int cycle && cycle <= 0))
|
||
{
|
||
LogTaskStart(_task,
|
||
$" Purge before tray picking was ignored since the cycle is zero");
|
||
_purgedBefTrayPicking = true;
|
||
return true;
|
||
}
|
||
|
||
_entityTaskToken = _unL.InvokePurge(args);
|
||
if (_entityTaskToken != (int)FSM_MSG.NONE)
|
||
{
|
||
_task = TaskType.Purge;
|
||
LogTaskStart(_task, $" Purge before tray picking");
|
||
_purgedBefTrayPicking = true;
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
public bool PurgeBeforeWaferPicking(params object[] args)
|
||
{
|
||
// 如果循环次数为0,则跳过此步骤。
|
||
if (args is null || (args[0] is int cycle && cycle <= 0))
|
||
{
|
||
LogTaskStart(_task,
|
||
$"[{Module}] Purge before wafer picking was ignored since the cycle is zero");
|
||
_purgedBefWaferPicking = true;
|
||
return true;
|
||
}
|
||
|
||
_entityTaskToken = _unL.InvokePurge(args);
|
||
if (_entityTaskToken != (int)FSM_MSG.NONE)
|
||
{
|
||
_task = TaskType.Purge;
|
||
LogTaskStart(_task, $" Purge before wafer picking");
|
||
_purgedBefWaferPicking = true;
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
public bool PurgeAfterWaferPicked(params object[] args)
|
||
{
|
||
// 如果循环次数为0,则跳过此步骤。
|
||
if (args is null || (args[0] is int cycle && cycle <= 0))
|
||
{
|
||
LogTaskStart(_task,
|
||
$" Purge after wafer picked was ignored since the cycle is zero");
|
||
_purgedAfWaferPicked = true;
|
||
return true;
|
||
}
|
||
|
||
_entityTaskToken = _unL.InvokePurge(args);
|
||
if (_entityTaskToken != (int)FSM_MSG.NONE)
|
||
{
|
||
_task = TaskType.Purge;
|
||
LogTaskStart(_task, $" Purge after wafer picked");
|
||
_purgedAfWaferPicked = true;
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
public bool Monitor()
|
||
{
|
||
return true;
|
||
}
|
||
|
||
public bool GroupWaferTray()
|
||
{
|
||
_entityTaskToken = _unL.InvokeGroupWaferTray();
|
||
if (_entityTaskToken != (int)FSM_MSG.NONE)
|
||
{
|
||
|
||
_task = TaskType.Group;
|
||
LogTaskStart(_task, $"{Module} start group wafer and tray");
|
||
}
|
||
|
||
return _entityTaskToken != (int)FSM_MSG.NONE;
|
||
}
|
||
|
||
public bool SeparateWaferTray()
|
||
{
|
||
_entityTaskToken = _unL.InvokeSeparateWaferTray();
|
||
if (_entityTaskToken != (int)FSM_MSG.NONE)
|
||
{
|
||
_task = TaskType.Separate;
|
||
LogTaskStart(_task, $"{Module} start separate wafer and tray");
|
||
}
|
||
|
||
_separated = _entityTaskToken != (int)FSM_MSG.NONE;
|
||
return _entityTaskToken != (int)FSM_MSG.NONE;
|
||
}
|
||
|
||
public void ResetPurgedAndSeparatedStatus()
|
||
{
|
||
_coolingCompleted = false;
|
||
_separated = false;
|
||
_purgedBefTrayPicking = false;
|
||
_purgedBefWaferPicking = false;
|
||
_purgedAfWaferPicked = false;
|
||
|
||
EV.PostInfoLog(Module.ToString(), "Start to record cooling time");
|
||
}
|
||
|
||
public bool CheckCoolingCompleted()
|
||
{
|
||
return _coolingCompleted;
|
||
}
|
||
|
||
public override bool CheckWaferTraySeparated()
|
||
{
|
||
return _separated;
|
||
}
|
||
|
||
public bool CheckPurgedBeforeTrayPicking()
|
||
{
|
||
return _purgedBefTrayPicking;
|
||
}
|
||
|
||
public bool CheckPurgedBeforeWaferPicking()
|
||
{
|
||
return _purgedBefWaferPicking;
|
||
}
|
||
|
||
public bool CheckPurgedAfterWaferPicked()
|
||
{
|
||
return _purgedAfWaferPicked;
|
||
}
|
||
|
||
public override bool CheckSlitValveClosed()
|
||
{
|
||
return _unL.CheckSlitValveClosed();
|
||
}
|
||
|
||
public int GetWaferPurgeCount(int slot, string whichPurge = "PurgeCount")
|
||
{
|
||
if (!WaferManager.Instance.CheckHasWafer(Module, slot))
|
||
return 0;
|
||
|
||
var wafer = WaferManager.Instance.GetWafer(Module, slot);
|
||
|
||
if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
|
||
return 0;
|
||
|
||
if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
|
||
return 0;
|
||
|
||
if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(Module))
|
||
return 0;
|
||
|
||
if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter.ContainsKey(whichPurge))
|
||
return 0;
|
||
|
||
if (int.TryParse(
|
||
wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter[whichPurge].ToString(),
|
||
out int purgeCount))
|
||
{
|
||
return purgeCount;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
public int GetWaferPumpDelayTime(int slot, string whichPumpDelay = "PumpDelayTime")
|
||
{
|
||
if (!WaferManager.Instance.CheckHasWafer(Module, slot))
|
||
return 0;
|
||
|
||
var wafer = WaferManager.Instance.GetWafer(Module, slot);
|
||
|
||
if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
|
||
return 0;
|
||
|
||
if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
|
||
return 0;
|
||
|
||
if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(Module))
|
||
return 0;
|
||
|
||
if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter.ContainsKey(whichPumpDelay))
|
||
return 0;
|
||
|
||
if (int.TryParse(
|
||
wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter[whichPumpDelay]
|
||
.ToString(), out int pumpDelayTime))
|
||
{
|
||
return pumpDelayTime;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
public string GetTaskRunning()
|
||
{
|
||
return _task.ToString();
|
||
}
|
||
|
||
public bool CheckTaskDone()
|
||
{
|
||
var taskSucceed = false;
|
||
switch (_task)
|
||
{
|
||
case TaskType.None:
|
||
taskSucceed = true;
|
||
break;
|
||
case TaskType.PrepareTransfer:
|
||
taskSucceed = _unL.CheckAcked(_entityTaskToken);
|
||
break;
|
||
case TaskType.Cooling:
|
||
taskSucceed = _unL.CheckAcked(_entityTaskToken);
|
||
break;
|
||
case TaskType.Vent:
|
||
taskSucceed = _unL.CheckAcked(_entityTaskToken);
|
||
break;
|
||
case TaskType.Pump:
|
||
taskSucceed = _unL.CheckAcked(_entityTaskToken);
|
||
break;
|
||
case TaskType.Group:
|
||
taskSucceed = _unL.CheckAcked(_entityTaskToken);
|
||
break;
|
||
case TaskType.Purge:
|
||
taskSucceed = _unL.CheckAcked(_entityTaskToken);
|
||
break;
|
||
case TaskType.Separate:
|
||
taskSucceed = _unL.CheckAcked(_entityTaskToken);
|
||
break;
|
||
}
|
||
|
||
return SuperCheckTaskDone(taskSucceed, _unL.IsIdle | _unL.IsError);
|
||
}
|
||
}
|
||
}
|