using Aitex.Core.Common; using Aitex.Core.RT.Log; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.Sorter.Common; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.ModuleLibrary.EfemModules; using MECF.Framework.RT.ModuleLibrary.SystemModules; using MECF.Framework.RT.ModuleLibrary.TMModules; using System; using System.Linq; namespace EfemDualSchedulerLib.Schedulers { public class SchedulerTM : SchedulerModule { public override bool IsAvailable { get { return _tm.IsReady && _tm.IsOnline && CheckTaskDone(); } } public override bool IsOnline { get { return _tm.IsOnline; } } public override bool IsError { get { return _tm.IsError; } } public bool Blade1Enable { get => SC.GetValueOrDefault($"TM.TMRobot.LowerBladeEnable"); } public bool Blade2Enable { get => SC.GetValueOrDefault($"TM.TMRobot.UpperBladeEnable"); } private TMModuleBase _tm = null; private Hand _hand; private Hand _taskSwapPickHand; private Hand _taskSwapPlaceHand; private int[] _taskSwapPickSlot; private int[] _taskSwapPlaceSlot; private int[] _slots; private Pan _pan; private Pan _placePan; public ModuleName PreviousTarget { get; set; } public SchedulerTM(TMModuleBase moduleDevice) : base(ModuleName.TM.ToString()) { _tm = moduleDevice; PreviousTarget = ModuleName.System; } public override void ResetTask() { base.ResetTask(); PreviousTarget = ModuleName.System; } public override WaferInfo GetWaferInfo(int slot) { return WaferManager.Instance.GetWafer(ModuleName.TMRobot, slot); } public override bool HasWafer(int slot) { return WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, slot); } public override bool NoWafer(int slot) { return Converter.MapBladeToSlots(Converter.MapSlotToHand(slot)).All(p=> WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, p)); } public override 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(ModuleName.TMRobot)) return false; return true; } public override 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(ModuleName.TMRobot)) return false; if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter["SlotSelection"].ToString().Contains(thisSlot.ToString())) return false; return true; } public bool IsReadyForPick(Hand blade) { return Converter.MapBladeToSlots(blade).All(p=> WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, p)); } public bool IsReadyForPlace(Hand blade) { return Converter.MapBladeToSlots(blade).Any(p=> WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, p)); } public bool Pick(ModuleName source, int[] slot, Hand hand, Pan pan, double temp1, double temp2, bool enableCheckTemp) { _task = TaskType.Pick; _hand = hand; _slots = slot; _pan = pan; if (!_tm.Pick(source, hand, pan, slot, temp1, temp2, enableCheckTemp, out string reason)) { LOG.Write(reason); } PreviousTarget = source; Array.ForEach(slot, p => LogTaskStart(_task, $"{source}.{p + 1}=>{Module}.{hand}")); return true; } public bool Place(ModuleName destination, int[] slot, Hand hand, Pan pan, double temp1, double temp2, bool enableCheckTemp) { _task = TaskType.Place; _hand = hand; _slots = slot; _pan = pan; if (!_tm.Place(destination, hand, pan, slot, temp1, temp2, enableCheckTemp, out string reason)) { LOG.Write(reason); } PreviousTarget = destination; Array.ForEach(slot,p=> LogTaskStart(_task, $"{Module}.{hand}=>{destination}.{p + 1}")); return true; } public bool Map(ModuleName destination) { _task = TaskType.Map; if (!_tm.Map(destination, out string reason)) { LOG.Write(reason); } PreviousTarget = destination; LogTaskStart(_task, $"mapping {Module}"); return true; } public bool PickAndPlace(ModuleName target, Hand pickHand, Pan pickPan, int[] pickSlot, Hand placeHand, Pan placePan, int[] placeSlot,double targetTemp1, double targetTemp2) { PreviousTarget = target; _task = TaskType.PickAndPlace; _taskSwapPickHand = pickHand; _pan = pickPan; _taskSwapPickSlot = pickSlot; _taskSwapPlaceHand = placeHand; _placePan = placePan; _taskSwapPlaceSlot = placeSlot; LogTaskStart(_task, $" {target}.[{string.Join(",", pickSlot.Select(p => p + 1).ToArray())}]=>{Module}.{pickHand}.{pickPan} && {Module}.{placeHand}.{placePan}=>{target}.[{string.Join(",", placeSlot.Select(p => p + 1).ToArray())}]"); return _tm.PickAndPlace(target, pickHand, pickPan, pickSlot, target, placeHand, placePan, placeSlot, targetTemp1, targetTemp2, out _); } public bool Goto(ModuleName target, int[] slot, Hand pickHand, Pan pickPan) { PreviousTarget = target; _task = TaskType.Goto; _hand = pickHand; _slots = slot; _pan = pickPan; if (!_tm.Goto(target, pickHand, slot, out string reason,_pan)) { LOG.Write(reason); } Array.ForEach(slot, p => LogTaskStart(_task, $"robot {pickHand} goto {target}")); return true; } private bool CheckPickDone(Hand hand, Pan pan) { var res = Converter.MapBladeAndPanToSlot(hand, pan)?.All(p => WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, p)); return res == null ? false : res.Value; } private bool CheckPlaceDone(Hand hand,Pan pan) { var res = Converter.MapBladeAndPanToSlot(hand, pan)?.All(p => WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, p)); return res == null ? false : res.Value; } public bool CheckTaskDone() { bool ret = false; switch (_task) { case TaskType.None: ret = true; break; case TaskType.Pick: ret = CheckPickDone(_hand, _pan); break; case TaskType.Place: ret = CheckPlaceDone(_hand, _pan); break; case TaskType.Map: ret = _tm.IsReady; break; case TaskType.Goto: ret = _tm.IsReady; break; case TaskType.PickAndPlace: ret = CheckPickDone(_taskSwapPickHand, _pan) && CheckPlaceDone(_taskSwapPlaceHand, _placePan); break; } if (ret && _task != TaskType.None) { LogTaskDone(_task, ""); _task = TaskType.None; } return ret; } } }