using Aitex.Core.Common; using Aitex.Core.RT.Device.Unit; using Aitex.Core.RT.Log; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.Sorter.Common; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Schedulers; using MECF.Framework.Common.SubstrateTrackings; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Venus_Core; using Venus_RT.Modules.Schedulers; namespace Venus_RT.Modules { public class SEManualTransfer : IRoutine { SchedulerSETMRobot _tmrobot = (SchedulerSETMRobot)Singleton.Instance.GetScheduler(ModuleName.SETM); private List _moveQueue = new List(); private MovingStatus _moving_status = MovingStatus.Idle; private RState _transferstate = RState.Init; private int _tmRobotSingleArmOption = 0;//usable wafer private ModuleName source_station; private int source_slot; private ModuleName destination_station; private int destination_slot; private ModuleName original_station; private int original_slot; private float align_angle; public SEManualTransfer() { } public RState Start(params object[] objs) { _moveQueue.Clear(); // obj is enable && robot is usable if (objs.Length > 6) { _transferstate = RState.Running; //get where we from and where we go source_station = (ModuleName)Enum.Parse(typeof(ModuleName),objs[0].ToString()); source_slot = Convert.ToInt32(objs[1]); destination_station = (ModuleName)Enum.Parse(typeof(ModuleName), objs[2].ToString()); destination_slot = Convert.ToInt32(objs[3]); WaferInfo waferInfo = WaferManager.Instance.GetWafer(source_station,source_slot); original_station = (ModuleName)waferInfo.OriginStation; original_slot = waferInfo.OriginSlot; if ((bool)objs[4]) { align_angle = float.Parse(objs[5].ToString()); _moving_status = MovingStatus.WaitAlign; } else _moving_status = MovingStatus.Waiting; if (ModuleHelper.IsVCE(source_station) && _tmrobot.IsVCESlitDoorClosed) { LOG.Write(eEvent.ERR_TM, ModuleName.TMRobot, $"cannot transfer from {source_station} as VCE InnerDoor is close."); _transferstate = RState.Failed; } if (ModuleHelper.IsVCE(destination_station) && _tmrobot.IsVCESlitDoorClosed) { LOG.Write(eEvent.ERR_TM, ModuleName.TMRobot, $"cannot transfer to {destination_station} as VCE InnerDoor is close."); _transferstate = RState.Failed; } //from tm to tm if (source_station == destination_station && ModuleHelper.IsTMRobot(source_station)) { LOG.Write(eEvent.ERR_TM,ModuleName.TMRobot,"cannot transfer from TMRobot to TMRobot."); _transferstate = RState.Failed; } if(WaferManager.Instance.CheckNoWafer(source_station,source_slot)) { LOG.Write(eEvent.ERR_TM, ModuleName.TMRobot, "cannot transfer cause wafer has no wafer."); _transferstate = RState.Failed; } if (WaferManager.Instance.CheckHasWafer(destination_station, destination_slot)) { LOG.Write(eEvent.ERR_TM, ModuleName.TMRobot, "cannot transfer cause wafer has wafer."); _transferstate = RState.Failed; } } else { _transferstate = RState.Failed; } return _transferstate; } public RState Monitor() { //if tm is free if (_tmrobot.IsAvailable) { CheckTransferOver(); WaferNextGoto(); TMRobotTask(); } return _transferstate; } private void CheckTransferOver() { //when the transfer is over? //the wafer has arrived the targetModule and targetSlot if (WaferManager.Instance.CheckHasWafer(destination_station,destination_slot) && (ModuleName)WaferManager.Instance.GetWafer(destination_station, destination_slot).OriginStation == original_station && WaferManager.Instance.GetWafer(destination_station, destination_slot).OriginSlot == original_slot) { _moving_status = MovingStatus.Idle; _transferstate = RState.End; } } private void WaferNextGoto() { switch(_moving_status) { case MovingStatus.WaitAlign: _moveQueue.Add(new MoveItem(source_station, source_slot, ModuleName.VPA, 0, 0)); _moving_status = MovingStatus.StartAlign; break; case MovingStatus.StartAlign: _tmrobot.Align(align_angle); _moving_status = MovingStatus.Aligning; break; case MovingStatus.Aligning: _moveQueue.Add(new MoveItem(ModuleName.VPA, 0, destination_station, destination_slot, 0)); break; //goto slot need to go case MovingStatus.Waiting: _moveQueue.Add(new MoveItem(source_station, source_slot, destination_station, destination_slot, 0)); break; } } private void TMRobotTask() { if (_tmrobot.IsAvailable) { if (_moveQueue.Count > 0 && _tmrobot.PostMoveItems(_moveQueue.ToArray())) { foreach (var item in _moveQueue) { var wafer = WaferManager.Instance.GetWafer(item.SourceModule, item.SourceSlot); if (wafer.IsEmpty && _tmrobot.IsAvailable) { // post alarm _transferstate = RState.Failed; LOG.Write(eEvent.ERR_ROUTER, ModuleName.System, $"Cannot run TM moving task as Get {item.SourceModule}{item.SourceSlot} Wafer Info failed"); return; } } _moveQueue.Clear(); } } } public void Abort() { } } }