using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Aitex.Core.RT.Fsm; using Aitex.Core.RT.Log; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.Sorter.Common; using VirgoRT.Modules; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; namespace VirgoRT.Scheduler { public class SchedulerEfemRobot : SchedulerModule { public override bool IsAvailable { get { return _entity.IsIdle && /*_entity.IsOnline && */CheckTaskDone(); } } public override bool IsOnline { get { return _entity.IsOnline; } } public bool LiftDone { get { return _entity.LiftDone; } } public override bool IsError { get { return _entity.IsError; } } public bool Blade1Enable { get { if (SC.ContainsItem($"EFEM.EfemRobot.LowerBladeEnable")) { return SC.GetValue($"EFEM.EfemRobot.LowerBladeEnable"); } return true; } set { if (SC.ContainsItem($"EFEM.EfemRobot.LowerBladeEnable")) { SC.SetItemValue($"EFEM.EfemRobot.LowerBladeEnable", value); } } } public bool Blade2Enable { get { if (SC.ContainsItem($"EFEM.EfemRobot.UpperBladeEnable")) { return SC.GetValue($"EFEM.EfemRobot.UpperBladeEnable"); } return true; } set { if (SC.ContainsItem($"EFEM.EfemRobot.UpperBladeEnable")) { SC.SetItemValue($"EFEM.EfemRobot.UpperBladeEnable", value); } } } private EfemEntity _entity = null; private Hand _hand; private int _entityTaskToken = (int)FSM_MSG.NONE; private Hand _taskSwapPickHand; private Hand _taskSwapPlaceHand; private int _taskSwapPickSlot; private int _taskSwapPlaceSlot; public ModuleName PreviousTarget { get; set; } public SchedulerEfemRobot() : base(ModuleName.EfemRobot.ToString()) { _entity = Singleton.Instance.EFEM; PreviousTarget = ModuleName.System; } public bool IsReadyForPick(Hand blade) { return WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, (int)blade); } public bool IsReadyForPlace(Hand blade) { return WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, (int)blade); } public bool Pick(ModuleName source, int slot, Hand hand) { _task = TaskType.Pick; _hand = hand; _entityTaskToken = _entity.InvokePick(source, slot, hand, WaferManager.Instance.GetWafer(source, slot).Size); PreviousTarget = source; LogTaskStart(_task, $"{source}.{slot + 1}=>{Module}.{hand}"); return true; } public bool Place(ModuleName destination, int slot, Hand hand) { _task = TaskType.Place; _hand = hand; _entityTaskToken = _entity.InvokePlace(destination, slot, hand, WaferManager.Instance.GetWafer(ModuleName.EfemRobot, hand==Hand.Blade1 ? 0:1).Size); PreviousTarget = destination; LogTaskStart(_task, $"{Module}.{hand}=>{destination}.{slot + 1}"); return true; } public bool PickAndPlace(ModuleName target, int pickSlot, int placeSlot, Hand pickHand, Hand placeHand) { PreviousTarget = target; _task = TaskType.PickAndPlace; _taskSwapPickHand = pickHand; _taskSwapPlaceHand = placeHand; _taskSwapPickSlot = pickSlot; _taskSwapPlaceSlot = placeSlot; _entityTaskToken = _entity.InvokePickAndPlace(target, pickHand, pickSlot, placeHand, placeSlot, WaferManager.Instance.GetWafer(target, pickSlot).Size); LogTaskStart(_task, $" {target}.{pickSlot + 1}=>{Module}.{pickHand} && {Module}.{placeHand}=>{target}.{placeSlot + 1}"); return true; } public bool Goto(ModuleName target, int slot ) { _task = TaskType.Goto; _entityTaskToken = _entity.InvokeGoto(target, slot ); PreviousTarget = target; LogTaskStart(_task, $"Robot goto {target}.{slot + 1}"); return true; } public bool Map(ModuleName destination ) { _task = TaskType.Map; _entityTaskToken = _entity.InvokeMap(destination.ToString()); LogTaskStart(_task, $"{Module} mapping"); PreviousTarget = destination; return true; } public bool Monitor() { return true; } public bool CheckTaskDone() { bool ret = false; switch (_task) { case TaskType.None: ret = true; break; case TaskType.Pick: ret = WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, (int)_hand); if (ret) { WaferArriveTicks[(int) _hand] = DateTime.Now.Ticks; } break; case TaskType.Place: ret = WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, (int)_hand); break; case TaskType.Map: ret = _entity.CheckAcked(_entityTaskToken) && _entity.IsIdle; break; case TaskType.Goto: ret = _entity.CheckAcked(_entityTaskToken) && _entity.IsIdle; break; case TaskType.PickAndPlace: ret = WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, (int)_taskSwapPickHand) && WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, (int)_taskSwapPlaceHand); if (ret) { WaferArriveTicks[(int)_taskSwapPickHand] = DateTime.Now.Ticks; } break; } if (ret && _task != TaskType.None) { LogTaskDone(_task, ""); _task = TaskType.None; } return ret; } } }