using Aitex.Core.Common.DeviceData; using Aitex.Core.Util; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using Aitex.Sorter.Common; using VirgoRT.Modules; using MECF.Framework.Common.Schedulers; using VirgoRT.Devices; using Aitex.Core.Common; namespace VirgoRT.Scheduler { public class SchedulerModule { public enum TaskType { None, PrepareTransfer, Pick, Place, PickAndPlace, PostTransfer, Preprocess, Process, PostProcess, IdlePurgeProcess, IdleCleanProcess, PreJobProcess, CompleteJobProcess, OpenCover, CloseCover, Load, Unload, Align, TransferTarget, Cooling, Heating, Map, Goto, } public ModuleName Module { get { return ModuleHelper.Converter(_module); } } public virtual bool IsAvailable { get; } public virtual bool IsOnline { get; } public virtual bool IsError { get; } private R_TRIG[] firstDetectWaferArriveTrigs = new R_TRIG[25]; private R_TRIG[] firstDetectWaferLeaveTrigs = new R_TRIG[25]; public int InTransferSlot { get { return _inTransferSlot; } } protected string _module; protected TaskType _task = TaskType.None; protected EnumTransferType _inTransferType; protected int _inTransferSlot; protected ModuleName _inProcessRobot; public Dictionary WaferArriveTicks { get; set; } public SchedulerModule(string module) { _module = module; WaferArriveTicks = new Dictionary(); WaferArriveTicks[0] = DateTime.Now.Ticks; WaferArriveTicks[1] = WaferArriveTicks[0]; for (int i = 0; i < firstDetectWaferArriveTrigs.Length; i++) { firstDetectWaferArriveTrigs[i] = new R_TRIG(); } for (int i = 0; i < firstDetectWaferLeaveTrigs.Length; i++) { firstDetectWaferLeaveTrigs[i] = new R_TRIG(); } } protected void LogTaskStart(TaskType cmd, string message) { EV.PostInfoLog("Scheduler", $"Task start:{_module}, {cmd}, {message}"); } protected void LogTaskDone(TaskType cmd, string message) { EV.PostInfoLog("Scheduler", $"Task done:{_module}, {cmd}, {message}"); } public void ResetTask() { _task = TaskType.None; } public bool WaitTransfer(ModuleName robot, EnumTransferType transferType, int slot) { _task = TaskType.TransferTarget; _inProcessRobot = robot; _inTransferType = transferType; _inTransferSlot = slot; LogTaskStart(_task, $"Note {robot} in transfer"); return true; } public bool IsWaitTransfer(ModuleName robot) { return _task == TaskType.TransferTarget && _inProcessRobot == robot; } public bool IsWaitTransfer(ModuleName robot, EnumTransferType transferType) { return _task == TaskType.TransferTarget && _inProcessRobot == robot && _inTransferType == transferType; } public virtual bool StopWaitTransfer(ModuleName robot) { LogTaskDone(_task, $"Note {robot} transfer complete"); _inProcessRobot = ModuleName.System; _task = TaskType.None; WaferArriveTicks[_inTransferSlot] = DateTime.Now.Ticks; return true; } public WaferInfo GetWaferInfo(int slot) { return WaferManager.Instance.GetWafer(ModuleHelper.Converter(_module), slot); } public bool HasWafer(int slot) { return WaferManager.Instance.CheckHasWafer(ModuleHelper.Converter(_module), slot); } public bool NoWafer(int slot) { return WaferManager.Instance.CheckNoWafer(ModuleHelper.Converter(_module), slot); } public bool FirstDetectWaferArrive(int slot) { firstDetectWaferArriveTrigs[slot].CLK = HasWafer(slot); return firstDetectWaferArriveTrigs[slot].Q; } public bool FirstDetectWaferLeave(int slot) { firstDetectWaferLeaveTrigs[slot].CLK = NoWafer(slot); return firstDetectWaferLeaveTrigs[slot].Q; } /// /// 检查参数代表的wafer下一站是否是本模块 /// /// 已有wafer的Module /// 已有wafer的Slot /// public virtual bool CheckWaferNextStepIsThisModule(ModuleName module, int slot) { if (!WaferManager.Instance.CheckHasWafer(module, slot)) return false; WaferInfo wafer = WaferManager.Instance.GetWafer(module, slot); if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null) return false; if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count) return false; if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(Module)) return false; return true; } /// /// 检查参数代表的wafer下一站是否是本模块thisSlot /// /// 已有wafer的Module /// 已有wafer的Slot /// 本模块slot位置 /// public virtual bool CheckWaferNextStepIsThisModuleSlot(ModuleName module, int slot, int thisSlot) { if (!WaferManager.Instance.CheckHasWafer(module, slot)) return false; WaferInfo wafer = WaferManager.Instance.GetWafer(module, slot); if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null) return false; if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count) return false; if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(Module)) return false; if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter["SlotSelection"].ToString().Contains(thisSlot.ToString())) return false; return true; } public virtual bool CheckWaferNextStepIsThisModuleSlotInSwap(ModuleName module, int slot, int thisSlot) { if (!WaferManager.Instance.CheckHasWafer(module, slot)) return false; WaferInfo wafer = WaferManager.Instance.GetWafer(module, slot); if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null) return false; if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count) return false; if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(Module)) return true; if (wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter.ContainsKey("SlotSelection") && wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter["SlotSelection"].ToString().Contains(thisSlot.ToString())) return true; return false; } /// /// 判断下一步的模块是否有Wafer /// /// /// 是否忽略机械手 /// public virtual bool CheckWaferNextStepModuleNoWafer(int slot, bool needIgnoreRobot = true) { if (!WaferManager.Instance.CheckHasWafer(Module, slot)) return false; WaferInfo wafer = WaferManager.Instance.GetWafer(Module, slot); if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null) return false; var step = wafer.NextSequenceStep; if (step >= wafer.ProcessJob.Sequence.Steps.Count) return false; List lstModuleName = wafer.ProcessJob.Sequence.Steps[step].StepModules; if (needIgnoreRobot && lstModuleName.Any(x => x == ModuleName.EfemRobot)) { step += 1; if (step >= wafer.ProcessJob.Sequence.Steps.Count) return false; lstModuleName = wafer.ProcessJob.Sequence.Steps[step].StepModules; } if (lstModuleName.Count > 0) { for (int i = 0; i < lstModuleName.Count; i++) { if (WaferManager.Instance.CheckNoWafer(lstModuleName[i], 0)) { return true; } } } return false; } public virtual bool CheckWaferNextStepModule(int slot, ModuleName targetModule) { if (!WaferManager.Instance.CheckHasWafer(Module, slot)) return false; WaferInfo wafer = WaferManager.Instance.GetWafer(Module, slot); if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null) return false; var step = wafer.NextSequenceStep; if (step >= wafer.ProcessJob.Sequence.Steps.Count) return false; List lstModuleName = wafer.ProcessJob.Sequence.Steps[step].StepModules; if (lstModuleName.Any(x => x == ModuleName.EfemRobot)) { step += 1; if (step >= wafer.ProcessJob.Sequence.Steps.Count) return false; lstModuleName = wafer.ProcessJob.Sequence.Steps[step].StepModules; } if (lstModuleName.Any(x => x == targetModule)) { return true; } return false; } public virtual bool IsReadyForPick(ModuleName robot, int slot, Hand blade) { return true; } public virtual bool IsReadyForPlace(ModuleName robot, int slot, Hand blade) { return true; } public virtual bool PrepareTransfer(ModuleName robot, EnumTransferType type, int slot) { return true; } public virtual bool PostTransfer(ModuleName robot, EnumTransferType type, int slot) { StopWaitTransfer(robot); return true; } public virtual bool PostTransfer(ModuleName robot) { StopWaitTransfer(robot); return true; } public virtual bool Process(string recipeName, bool isCleanRecipe, bool withDummyWafer, WaferInfo wafer) { return true; } public virtual bool Cooling(int coolingTime) { return true; } public virtual bool Preheating(float temperature) { return true; } } }