Sic10/SicRT/Equipments/Schedulers/SchedulerLoadLock.cs

378 lines
12 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Linq;
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 Aitex.Core.RT.Device.Devices;
using Aitex.Core.RT.Event;
using SicModules.LLs;
namespace SicRT.Scheduler
{
public class SchedulerLoadLock : SchedulerModule
{
#region Variables
/// <summary>
/// 最后一次传盘动作是Pick还是Place。
/// </summary>
private TaskType _lastTransferAction;
/// <summary>
/// 最后一次传盘的槽位。
/// </summary>
private int _lastTransferSlot;
#endregion
public override bool IsAvailable
{
get
{
return _ll.IsIdle && _ll.IsOnline && CheckTaskDone() && _ll.CheckSlitValveClosed();
}
}
public override bool IsOnline
{
get
{
return _ll.IsOnline;
}
}
public override bool IsError
{
get
{
return _ll.IsError;
}
}
private LoadLockModuleBase _ll = null;
private ModuleName _taskRobot;
private int _taskSlot;
private int _entityTaskToken = (int)FSM_MSG.NONE;
private bool _separated = false;
private bool _purged = false;
public bool IsInPumping { get => _task == TaskType.Pump || _task == TaskType.Purge || _task == TaskType.PrepareTransfer ; }
public SchedulerLoadLock(ModuleName module) : base(module.ToString())
{
_module = module.ToString();
_ll = Singleton<EquipmentManager>.Instance.Modules[module] as LoadLockModuleBase;
}
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 _ll.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.TMRobot)
{
return _ll.CheckReadyForTransfer(robot, Hand.Blade1, slot, EnumTransferType.Pick, out _);
}
return false;
}
public override bool IsReadyForPlace(ModuleName robot, int slot)
{
if (robot == ModuleName.TMRobot)
{
return _ll.CheckReadyForTransfer(robot, Hand.Blade1, slot, EnumTransferType.Place, out _);
}
return false;
}
public override bool IsReadyForTransfer(ModuleName robot, int slot)
{
if (robot == ModuleName.WaferRobot)
{
return _ll.CheckReadyForTransfer(robot, Hand.Blade1, slot, EnumTransferType.Place, out _);
}
else if (robot == ModuleName.TMRobot || robot == ModuleName.TrayRobot)
{
return _ll.CheckReadyForTransfer(robot, Hand.Blade1, slot, EnumTransferType.Place, out _)
&& WaferManager.Instance.CheckNoTray(ModuleHelper.Converter(_module), slot);
}
return false;
}
public bool Vent()
{
_task = TaskType.Vent;
_entityTaskToken = _ll.InvokeVent();
LogTaskStart(_task, $"{Module} vent to ATM");
return _entityTaskToken != (int)FSM_MSG.NONE;
}
public bool Pump()
{
_entityTaskToken = _ll.InvokePump();
if (_entityTaskToken != (int)FSM_MSG.NONE)
{
_task = TaskType.Pump;
LogTaskStart(_task, $"{Module} pump to Vaccum");
return true;
}
return false;
}
public bool Purge(params object[] objs)
{
_entityTaskToken = _ll.InvokePurge(objs);
if (_entityTaskToken != (int)FSM_MSG.NONE)
{
_task = TaskType.Purge;
LogTaskStart(_task, $"{Module} purge for new job");
_purged = true;
return true;
}
return false;
}
public bool GroupWaferTray()
{
_entityTaskToken = _ll.InvokeGroupWaferTray();
if (_entityTaskToken != (int)FSM_MSG.NONE)
{
_task = TaskType.Group;
LogTaskStart(_task, $"{Module} start group wafer and tray");
return true;
}
return false;
}
public bool SeparateWaferTray()
{
_entityTaskToken = _ll.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 int? GetWaferPurgeCount(int slot)
{
if (!WaferManager.Instance.CheckHasWafer(Module, slot))
return null;
var wafer = WaferManager.Instance.GetWafer(Module, slot);
if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
return null;
if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
return null;
if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Any(m => m == ModuleName.LoadLock || m == ModuleName.Load))
return null;
if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter.ContainsKey("PurgeCount"))
return null;
if (int.TryParse(wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter["PurgeCount"].ToString(), out int purgeCount))
{
return purgeCount;
}
return null;
}
public int? GetWaferPumpDelayTime(int slot)
{
if (!WaferManager.Instance.CheckHasWafer(Module, slot))
return null;
var wi = WaferManager.Instance.GetWafer(Module, slot);
if (wi.ProcessJob?.Sequence == null)
return null;
if (wi.NextSequenceStep >= wi.ProcessJob.Sequence.Steps.Count)
return null;
if (!wi.ProcessJob.Sequence.Steps[wi.NextSequenceStep].StepModules.Any(m => m == ModuleName.LoadLock || m == ModuleName.Load))
return null;
if (!wi.ProcessJob.Sequence.Steps[wi.NextSequenceStep].StepParameter.ContainsKey("PumpDelayTime"))
return null;
if (int.TryParse(wi.ProcessJob.Sequence.Steps[wi.NextSequenceStep].StepParameter["PumpDelayTime"].ToString(), out int pumpDelayTime))
{
return pumpDelayTime;
}
return null;
}
public override bool CheckWaferNextStepIsThis(ModuleName module, int slot)
{
if (!WaferManager.Instance.CheckHasWafer(module, slot))
return false;
var wi = WaferManager.Instance.GetWafer(module, slot);
if (wi.ProcessJob?.Sequence == null)
return false;
if (wi.NextSequenceStep >= wi.ProcessJob.Sequence.Steps.Count)
return false;
if (!wi.ProcessJob.Sequence.Steps[wi.NextSequenceStep].StepModules.Any(m => m == ModuleName.LoadLock || m == ModuleName.Load))
return false;
return true;
}
public override bool CheckWaferTrayGrouped()
{
return !_ll.CheckWaferClamped() && WaferManager.Instance.CheckHasWafer(Module, 0);
}
public override bool CheckWaferTraySeparated()
{
return _separated;
}
public override bool CheckSlitValveClosed()
{
return _ll.CheckSlitValveClosed();
}
public override bool CheckTrayPlaced()
{
return _ll.CheckTrayPlaced();
}
public bool WaitTransfer(ModuleName robot, bool isPick, int slot)
{
_lastTransferAction = isPick ? TaskType.Pick : TaskType.Place;
_lastTransferSlot = slot;
return base.WaitTransfer(robot);
}
/*public override bool StopWaitTransfer(ModuleName robot)
{
var ret = base.StopWaitTransfer(robot);
if (ret)
{
// 传盘结束后如果上个动作是PlaceWafer回到Cassette则响蜂鸣器进行提示。
if (_lastTransferAction == TaskType.Place
&& WaferManager.Instance.CheckHasWafer(ModuleName.LoadLock.ToString(), 0))
{
EV.PostMessage(Module.ToString(), EventEnum.PJ_DONE, "LoadLock", "0");
}
}
return ret;
}*/
public override void ResetTask()
{
base.ResetTask();
_lastTransferAction = TaskType.None;
_lastTransferSlot = -1;
}
public bool CheckTaskDone()
{
var taskSucceed = false;
switch (_task)
{
case TaskType.None:
taskSucceed = true;
break;
case TaskType.PrepareTransfer:
taskSucceed = _ll.CheckAcked(_entityTaskToken);
break;
case TaskType.Cooling:
taskSucceed = _ll.CheckAcked(_entityTaskToken);
break;
case TaskType.Vent:
taskSucceed = _ll.CheckAcked(_entityTaskToken);
break;
case TaskType.Pump:
taskSucceed = _ll.CheckAcked(_entityTaskToken);
break;
case TaskType.Purge:
taskSucceed = _ll.CheckAcked(_entityTaskToken);
break;
case TaskType.Group:
taskSucceed = _ll.CheckAcked(_entityTaskToken);
break;
case TaskType.Separate:
taskSucceed = _ll.CheckAcked(_entityTaskToken);
break;
}
return SuperCheckTaskDone(taskSucceed, _ll.IsIdle | _ll.IsError);
}
internal float GetTemperature()
{
IoTempMeter deviceLoadTemp = DEVICE.GetDevice<IoTempMeter>($"Buffer.BufferTemp");
return deviceLoadTemp.FeedBack;
}
public bool CheckPurged()
{
return _purged;
}
public void ResetPurged()
{
_purged = false;
}
}
}