using Aitex.Core.Common.DeviceData; using Aitex.Core.RT.Fsm; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.Sorter.Common; using athosRT.FSM; using athosRT.Modules.EFEMs; using athosRT.tool; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; using static athosRT.Modules.SchedulerEfemRobot; namespace athosRT.Modules { public enum EnumMoveType { Place, Pick, Move, } class SchedulerItem { public RouteManager1.MSG MoveType { get; set; } public ModuleName target { get; set; } public Queue moveList { get; set; } public RState Status { get; set; } } public class SchedulerEfemRobot : SchedulerModule { public override bool IsAvailable { get { return _entity.IsIdle && true && CheckTaskDone() && RunSchedulers(); } } public override bool IsOnline { //get { return _entity.IsOnline; } get { return true; } } public override bool IsError { get { return _entity.IsError; } } public override bool IsIdle { get { return _entity.IsIdle; } } public RState RobotStatus { get { switch (_entity.Robot.RobotState) { case RobotStateEnum.Error: return RState.Failed; case RobotStateEnum.Idle: return RState.End; case RobotStateEnum.Init: return RState.Init; default: return RState.Running; } } } private RouteManager1 _entity = null; private SchedulerItem _currentScheduler = null; private int _entityTaskToken = (int)FSM_MSG.NONE; public ModuleName PreviousTarget { get; set; } public SchedulerEfemRobot() : base(ModuleName.EfemRobot.ToString()) { _entity = Singleton.Instance.GetRT(); PreviousTarget = ModuleName.System; } //public bool Goto(ModuleName target, int slot) //{ // _entityTaskToken = _entity.InvokeGoto(target, slot); // PreviousTarget = target; // // LogTaskStart(_task, $"Robot goto {target}.{slot + 1}"); // // return true; //} //public bool Map(ModuleName destination) //{ // _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 (_entityTaskToken) { case (int)FSM_MSG.NONE: ret = true; break; case (int)RouteManager1.MSG.Pick: case (int)RouteManager1.MSG.Place: //case (int)RouteManager1.MSG.Swap: ret = IsAllWafersArrived(); break; case (int)RouteManager1.MSG.MapWafer: ret = _entity.CheckAcked(_entityTaskToken) && _entity.IsIdle; break; //case (int)RouteManager1.MSG.Goto: // ret = _entity.CheckAcked(_entityTaskToken) && _entity.IsIdle; // break; case (int)RouteManager1.MSG.Align: ret = _entity.CheckAcked(_entityTaskToken) && _entity.IsIdle; break; } if (ret && _task != TaskType.None) { LogTaskDone(_task, ""); _task = TaskType.None; } return ret; } public bool PostMoveItems(MoveItem[] items) { if (items.Length > 0) { _currentScheduler = new SchedulerItem(); _currentScheduler.moveList = new Queue(); _currentScheduler.Status = RState.Init; foreach (var item in items) { LogObject.Info(ModuleName.EfemRobot.ToString(), $"Post Moving Item: {item.SourceModule} Slot {item.SourceSlot + 1} => {item.DestinationModule} Slot {item.DestinationSlot + 1}"); _currentScheduler.MoveType = items.First().TransferType == EnumMoveType.Pick ? RouteManager1.MSG.Pick : RouteManager1.MSG.Place; _currentScheduler.target = item.Module; _currentScheduler.moveList.Enqueue(item); } } RunSchedulers(); return true; } bool RunSchedulers() { if (_currentScheduler == null) return true; if (_entity.IsIdle) { if (_currentScheduler.Status == RState.Init) { foreach (var item in _currentScheduler.moveList) { LogObject.Info(ModuleName.EfemRobot.ToString(), $"EFEM Robot Moving Items: {item.SourceModule} Slot {item.SourceSlot + 1} => {item.DestinationModule} Slot {item.DestinationSlot + 1}"); } if (_entity.CheckToPostMessage((int)_currentScheduler.MoveType, _currentScheduler.moveList)) { _currentScheduler.Status = RState.Running; _entityTaskToken = (int)_currentScheduler.MoveType; } else _entityTaskToken = (int)FSM_MSG.NONE; } else if (_currentScheduler.Status == RState.Running) { if (IsAllWafersArrived()) { if (_entityTaskToken == (int)RouteManager1.MSG.Pick ||_entityTaskToken == (int)RouteManager1.MSG.Place //||_entityTaskToken == (int)RouteManager1.MSG.Swap ) { _entityTaskToken = (int)FSM_MSG.NONE; } _currentScheduler.Status = RState.End; } } } return _currentScheduler.Status == RState.End; } private bool IsAllWafersArrived() { foreach (var item in _currentScheduler.moveList) { if (WaferManager.Instance.CheckNoWafer(item.DestinationModule, item.DestinationSlot)) return false; } return true; } public override void ResetTask() { base.ResetTask(); _entityTaskToken = (int)FSM_MSG.NONE; if (_currentScheduler != null) { _currentScheduler.moveList.Clear(); _currentScheduler.Status = RState.End; } } //public override bool Align(float angle) //{ // _task = TaskType.Align; // // LogTaskStart(_task, $"Aligning"); // // _increasingAngle = SC.GetValue($"EFEM.Aligner.IncreasingAngle"); // if (_increasingAngle == 0) // { // // enable change align angle only with increasing function disable to avoid logic confuse // _alignAngle = SC.GetValue($"EFEM.Aligner.AlignAngle"); // } // // _alignAngle = (_alignAngle + _increasingAngle) % 360; // _entityTaskToken = _entity.InvokeAlign(ModuleName.Aligner1.ToString(), 0, _alignAngle); // // return _entityTaskToken == (int)RouteManager1.MSG.Align; //} [DataContract] [Serializable] //helper class public class MoveItem : IDeviceData { [DataMember] public ModuleName SourceModule { get; set; } [DataMember] public int SourceSlot { get; set; } [DataMember] public ModuleName DestinationModule { get; set; } [DataMember] public int DestinationSlot { get; set; } [DataMember] public Hand RobotHand { get; set; } public ModuleName Module { get { return ModuleHelper.IsTMRobot(SourceModule) || ModuleHelper.IsEfemRobot(SourceModule) ? DestinationModule : SourceModule; } } public EnumMoveType TransferType { get { if (ModuleHelper.IsTMRobot(SourceModule) || ModuleHelper.IsEfemRobot(SourceModule)) return EnumMoveType.Place; else if (ModuleHelper.IsTMRobot(DestinationModule) || ModuleHelper.IsEfemRobot(DestinationModule)) return EnumMoveType.Pick; else return EnumMoveType.Move; } } public MoveItem(ModuleName sourceModule, int sourceSlot, ModuleName destinationModule, int destinationSlot, Hand robotHand) { this.SourceModule = sourceModule; this.SourceSlot = sourceSlot; this.DestinationModule = destinationModule; this.DestinationSlot = destinationSlot; this.RobotHand = robotHand; } public void Update(IDeviceData data) { throw new NotImplementedException(); } } } }