2023-05-05 16:09:03 +08:00
|
|
|
|
using System.Linq;
|
2023-05-08 09:42:15 +08:00
|
|
|
|
using Aitex.Core.RT.Event;
|
2023-03-03 15:42:13 +08:00
|
|
|
|
using Aitex.Core.Util;
|
|
|
|
|
using MECF.Framework.Common.Equipment;
|
|
|
|
|
using MECF.Framework.Common.SubstrateTrackings;
|
2023-04-13 15:35:13 +08:00
|
|
|
|
using SicModules.Cassettes;
|
2023-05-05 16:09:03 +08:00
|
|
|
|
using SicModules.PMs;
|
2023-03-03 15:42:13 +08:00
|
|
|
|
using SicRT.Equipments.Systems;
|
|
|
|
|
|
|
|
|
|
namespace SicRT.Modules.Schedulers
|
|
|
|
|
{
|
|
|
|
|
public class SchedulerCassette : SchedulerModule
|
|
|
|
|
{
|
2023-05-05 16:09:03 +08:00
|
|
|
|
#region Variables
|
2023-03-03 15:42:13 +08:00
|
|
|
|
|
2023-05-05 16:09:03 +08:00
|
|
|
|
private readonly CassetteModule _cass;
|
2023-03-03 15:42:13 +08:00
|
|
|
|
|
2023-05-05 16:09:03 +08:00
|
|
|
|
private readonly PMModule _pm1, _pm2;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 最后一次传盘动作是Pick还是Place。
|
|
|
|
|
/// </summary>
|
|
|
|
|
private TaskType _lastTransferAction;
|
2023-03-03 15:42:13 +08:00
|
|
|
|
|
2023-05-05 16:09:03 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// 最后一次传盘的槽位。
|
|
|
|
|
/// </summary>
|
|
|
|
|
private int _lastTransferSlot;
|
2023-03-03 15:42:13 +08:00
|
|
|
|
|
2023-05-05 16:09:03 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Constructors
|
2023-03-03 15:42:13 +08:00
|
|
|
|
|
|
|
|
|
public SchedulerCassette(ModuleName module) : base(module.ToString())
|
|
|
|
|
{
|
|
|
|
|
_module = module.ToString();
|
|
|
|
|
_cass = Singleton<EquipmentManager>.Instance.Modules[module] as CassetteModule;
|
2023-05-05 16:09:03 +08:00
|
|
|
|
_pm1 = Singleton<EquipmentManager>.Instance.Modules[ModuleName.PM1] as PMModule;
|
|
|
|
|
_pm2 = Singleton<EquipmentManager>.Instance.Modules[ModuleName.PM2] as PMModule;
|
2023-03-03 15:42:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-05 16:09:03 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Properties
|
|
|
|
|
|
|
|
|
|
public override bool IsAvailable => IsOnline && _cass.IsIdle && CheckTaskDone();
|
|
|
|
|
|
|
|
|
|
public override bool IsOnline => _cass.IsOnline;
|
|
|
|
|
|
|
|
|
|
public override bool IsError => _cass.IsError;
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Methods
|
|
|
|
|
|
2023-03-03 15:42:13 +08:00
|
|
|
|
public bool Monitor()
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override bool IsReadyForPlace(ModuleName robot, int slot)
|
|
|
|
|
{
|
|
|
|
|
return WaferManager.Instance.CheckNoWafer(_cass.Module, slot) && WaferManager.Instance.CheckNoTray(ModuleHelper.Converter(_cass.Module), slot);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override bool IsReadyForPick(ModuleName robot, int slot)
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-05 16:09:03 +08:00
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
// 传盘结束后,如果上个动作是Place,Wafer回到Cassette,则响蜂鸣器进行提示。
|
|
|
|
|
if (_lastTransferAction == TaskType.Place)
|
|
|
|
|
{
|
|
|
|
|
// PM1一定存在,PM2不一定;如果PM2不存在,则默认使用PM1的三色灯
|
|
|
|
|
var pmOfSt = _pm1;
|
|
|
|
|
|
|
|
|
|
// 判断最后一次放的Wafer在哪个PM做的工艺,则点亮对应PM的蜂鸣器
|
|
|
|
|
var wi = GetWaferInfo(_lastTransferSlot);
|
|
|
|
|
var whichPmName = wi.SubstHists.FirstOrDefault(x => x.locationID.Contains("PM"));
|
|
|
|
|
if (whichPmName != null)
|
|
|
|
|
{
|
|
|
|
|
if (whichPmName.locationID.ToUpper() == "PM2" && _pm2 != null)
|
|
|
|
|
pmOfSt = _pm2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 触发蜂鸣器
|
2023-05-08 09:42:15 +08:00
|
|
|
|
if (pmOfSt?.CreateProcessDoneSignal(out var reason) == false)
|
|
|
|
|
EV.PostWarningLog(Module.ToString(), reason);
|
2023-05-05 16:09:03 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void ResetTask()
|
|
|
|
|
{
|
|
|
|
|
base.ResetTask();
|
|
|
|
|
_lastTransferAction = TaskType.None;
|
|
|
|
|
_lastTransferSlot = -1;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-03 15:42:13 +08:00
|
|
|
|
public bool CheckTaskDone()
|
|
|
|
|
{
|
|
|
|
|
var taskSucceed = false;
|
|
|
|
|
switch (_task)
|
|
|
|
|
{
|
|
|
|
|
case TaskType.None:
|
|
|
|
|
taskSucceed = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return SuperCheckTaskDone(taskSucceed, _cass.IsIdle | _cass.IsError);
|
|
|
|
|
}
|
2023-05-05 16:09:03 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2023-03-03 15:42:13 +08:00
|
|
|
|
}
|
|
|
|
|
}
|