using System.Collections.Generic; using Aitex.Core.Common; using Aitex.Core.RT.Routine; using Aitex.Core.Util; using Aitex.Core.RT.Event; using MECF.Framework.Common.Equipment; using VirgoRT.Scheduler; using Aitex.Sorter.Common; using MECF.Framework.Common.Schedulers; using MECF.Framework.Common.SubstrateTrackings; using VirgoRT.Modules.PMs; using VirgoRT.Modules.Schedulers; using Aitex.Core.RT.SCCore; namespace VirgoRT.Modules { internal interface IManualTransferRoutine : IRoutine { } public class MoveItemEx : MoveItem { public int CoolingTime { get; set; } public MoveItemEx(ModuleName sourceModule, int sourceSlot, ModuleName destinationModule, int destinationSlot, int coolingTime, Hand blade) : base(sourceModule, sourceSlot, destinationModule, destinationSlot, blade) { CoolingTime = coolingTime; } } public class ManualTransfer : TransferModule { private Queue _moveTaskQueue = new Queue(); private IRoutine _activeTask; public Result Start(object[] objs) { _moveTaskQueue.Clear(); ModuleName source = (ModuleName)objs[0]; int ss = (int)objs[1]; ModuleName target = (ModuleName)objs[2]; int ds = (int)objs[3]; bool autoAlign = (bool)objs[4]; int alignAngle = (int)objs[5]; bool autoCooling = (bool)objs[6]; int coolingTime = (int)objs[7]; if (!WaferManager.Instance.CheckWafer(source, ss, WaferStatus.Normal)) { EV.PostWarningLog("System", $"source {source} slot {ss + 1} no normal wafer"); return Result.FAIL; } if (!WaferManager.Instance.CheckNoWafer(target, ds)) { EV.PostWarningLog("System", "destination has wafer"); return Result.FAIL; } if (source != ModuleName.EfemRobot && WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 0) && WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 1)) { EV.PostWarningLog("System", "robot has wafer"); return Result.FAIL; } Hand blade = WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 0) ? Hand.Blade1 : Hand.Blade2; if (source == ModuleName.EfemRobot) blade = ss == 0 ? Hand.Blade1 : Hand.Blade2; else if (target == ModuleName.EfemRobot) blade = ds == 0 ? Hand.Blade1 : Hand.Blade2; if (autoAlign && !ModuleHelper.IsAligner(source) && !ModuleHelper.IsAligner(target)) { if (WaferManager.Instance.CheckHasWafer(ModuleName.Aligner1, 0) && WaferManager.Instance.CheckHasWafer(ModuleName.Aligner2, 0)) { EV.PostWarningLog("System", "Can not transfer, aligner has wafer, can not auto align"); return Result.FAIL; } ModuleName aligner = WaferManager.Instance.CheckHasWafer(ModuleName.Aligner1, 0) ? ModuleName.Aligner2 : ModuleName.Aligner1; _moveTaskQueue.Enqueue(new EfemRobotMover(new MoveItemEx(source, ss, aligner, 0, 1, blade))); _moveTaskQueue.Enqueue(new AlignRoutine(aligner.ToString())); _moveTaskQueue.Enqueue(new EfemRobotMover(new MoveItemEx(aligner, 0, target, ds, 0, blade))); } else if (autoCooling && !ModuleHelper.IsCooling(source) && !ModuleHelper.IsCooling(target)) { if (WaferManager.Instance.CheckHasWafer(ModuleName.Cooling1, 0) && WaferManager.Instance.CheckHasWafer(ModuleName.Cooling2, 0)) { EV.PostWarningLog("System", "Can not transfer, cooling has wafer, can not auto cooling"); return Result.FAIL; } ModuleName cooling = WaferManager.Instance.CheckHasWafer(ModuleName.Cooling1, 0) ? ModuleName.Cooling2 : ModuleName.Cooling1; _moveTaskQueue.Enqueue(new EfemRobotMover(new MoveItemEx(source, ss, cooling, 0, coolingTime, blade))); _moveTaskQueue.Enqueue(new CoolingRoutine(cooling.ToString(), coolingTime)); _moveTaskQueue.Enqueue(new EfemRobotMover(new MoveItemEx(cooling, 0, target, ds, 0, blade))); } else { _moveTaskQueue.Enqueue(new EfemRobotMover(new MoveItemEx(source, ss, target, ds, coolingTime, blade))); if (ModuleHelper.IsAligner(target) || ModuleHelper.IsCooling(target)) { _moveTaskQueue.Enqueue(new AlignRoutine(target.ToString())); } } _activeTask = _moveTaskQueue.Dequeue(); return _activeTask.Start(); } public Result Monitor(object[] objs) { System.Diagnostics.Debug.Assert(_activeTask != null, "mover should not be null, call start first"); Result ret = _activeTask.Monitor(); if (ret == Result.FAIL) return ret; if (ret == Result.DONE) { if (_moveTaskQueue.Count > 0) { _activeTask = _moveTaskQueue.Dequeue(); return _activeTask.Start(); } return Result.DONE; } return Result.RUN; } public void Clear() { _moveTaskQueue.Clear(); _activeTask = null; } } public class EfemRobotMover : TransferModule, IRoutine { private MoveItemEx _moveTask; private SchedulerModule _source; private SchedulerModule _destination; public EfemRobotMover(MoveItemEx moveTask) { _moveTask = moveTask; } public Result Start() { _source = GetModule(_moveTask.SourceModule.ToString()); _destination = GetModule(_moveTask.DestinationModule.ToString()); System.Diagnostics.Debug.Assert(_source != null, $"{_moveTask.SourceModule} not valid"); System.Diagnostics.Debug.Assert(_destination != null, $"{_moveTask.DestinationModule} not valid"); if (!WaferManager.Instance.CheckHasWafer(_moveTask.SourceModule, _moveTask.SourceSlot)) { EV.PostWarningLog("System", $"Failed transfer, source {_moveTask.SourceModule} slot {_moveTask.SourceSlot + 1} has not wafer"); return Result.FAIL; } if (WaferManager.Instance.CheckHasWafer(_moveTask.DestinationModule, _moveTask.DestinationSlot)) { EV.PostWarningLog("System", $"Failed transfer, destination {_moveTask.DestinationModule} slot {_moveTask.DestinationSlot + 1} has wafer"); return Result.FAIL; } if (!_source.IsAvailable) { EV.PostWarningLog("System", $"Failed transfer, source {_moveTask.SourceModule} not ready"); return Result.FAIL; } if (ModuleHelper.IsLoadPort(_source.Module)) { if (!(_source as SchedulerLoadPort).CheckReadyTransfer()) { EV.PostWarningLog("System", $"Failed transfer, source {_moveTask.SourceModule} not ready"); return Result.FAIL; } } if (!_destination.IsAvailable) { EV.PostWarningLog("System", $"Failed transfer, Destination {_moveTask.DestinationModule} not ready"); return Result.FAIL; } if (ModuleHelper.IsLoadPort(_destination.Module)) { if (!(_destination as SchedulerLoadPort).CheckReadyTransfer()) { EV.PostWarningLog("System", $"Failed transfer, source {_moveTask.DestinationModule} not ready"); return Result.FAIL; } } if (!_efemRobot.IsAvailable) { EV.PostWarningLog("System", $"Failed transfer, EFEM Robot not ready"); return Result.FAIL; } //if (ModuleHelper.IsAligner(_source.Module) || ModuleHelper.IsCooling(_source.Module)) // _source.Cooling(_moveTask.CoolingTime); //if (ModuleHelper.IsAligner(_destination.Module) || ModuleHelper.IsCooling(_destination.Module)) // _destination.Cooling(_moveTask.CoolingTime); //&& !SC.GetValue("EFEM.EfemRobot.UpperBladeEnable") if (_moveTask.SourceModule == ModuleName.EfemRobot || _moveTask.DestinationModule == ModuleName.EfemRobot) { if (_moveTask.SourceModule == ModuleName.EfemRobot) { if (_moveTask.SourceSlot == 0 && SC.GetValue("EFEM.EfemRobot.LowerBladeEnable")) { _moveTask.RobotHand = (Hand)_moveTask.SourceSlot; } else if (_moveTask.SourceSlot == 1 && SC.GetValue("EFEM.EfemRobot.UpperBladeEnable")) { _moveTask.RobotHand = (Hand)_moveTask.SourceSlot; } else { EV.PostWarningLog("System", $"手臂已被禁用"); return Result.FAIL; } } else if (_moveTask.DestinationModule == ModuleName.EfemRobot) { if (_moveTask.DestinationSlot == 0 && SC.GetValue("EFEM.EfemRobot.LowerBladeEnable")) { _moveTask.RobotHand = (Hand)_moveTask.DestinationSlot; } else if (_moveTask.DestinationSlot == 1 && SC.GetValue("EFEM.EfemRobot.UpperBladeEnable")) { _moveTask.RobotHand = (Hand)_moveTask.DestinationSlot; } else { EV.PostWarningLog("System", $"手臂已被禁用"); return Result.FAIL; } //_moveTask.RobotHand = (Hand)_moveTask.DestinationSlot; } } else { if (SC.GetValue("EFEM.EfemRobot.LowerBladeEnable") && !WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 0)) { _moveTask.RobotHand = (Hand)0; } else if (SC.GetValue("EFEM.EfemRobot.UpperBladeEnable") && !WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 1)) { _moveTask.RobotHand = (Hand)1; } else { EV.PostWarningLog("System", $"手臂已被禁用"); return Result.FAIL; } } return Result.RUN; } public Result Start(params object[] objs) { return this.Start(); } public Result Monitor() { if (_source.IsError || _destination.IsError || _efemRobot.IsError) return Result.FAIL; if (!WaferManager.Instance.CheckHasWafer(_moveTask.SourceModule, _moveTask.SourceSlot) && WaferManager.Instance.CheckHasWafer(_moveTask.DestinationModule, _moveTask.DestinationSlot) && _efemRobot.IsAvailable) { if (_source.IsWaitTransfer(ModuleName.EfemRobot)) { _source.PostTransfer(ModuleName.EfemRobot, EnumTransferType.Pick, 0); //_source.StopWaitTransfer(ModuleName.EfemRobot); } if (_destination.IsWaitTransfer(ModuleName.EfemRobot)) { _destination.PostTransfer(ModuleName.EfemRobot, EnumTransferType.Place, 0); //_destination.StopWaitTransfer(ModuleName.EfemRobot); } if (_source.IsAvailable && _destination.IsAvailable) { if (_moveTask.CoolingTime > 0 && ModuleHelper.IsCooling(_moveTask.DestinationModule)) { _destination.Cooling(_moveTask.CoolingTime); _moveTask.CoolingTime = 0; return Result.RUN; } return Result.DONE; } return Result.RUN; } if (!_efemRobot.IsAvailable) return Result.RUN; //pick if (_moveTask.SourceModule != ModuleName.EfemRobot) { if (WaferManager.Instance.CheckHasWafer(_moveTask.SourceModule, _moveTask.SourceSlot)) { if (!_source.IsAvailable) return Result.RUN; if (!_source.IsReadyForPick(ModuleName.EfemRobot, _moveTask.SourceSlot, _moveTask.RobotHand)) { if (!_source.PrepareTransfer(ModuleName.EfemRobot, EnumTransferType.Pick, _moveTask.SourceSlot)) return Result.FAIL; } if (!_source.IsAvailable) return Result.RUN; if (!WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, (int)_moveTask.RobotHand)) { if (!_efemRobot.Pick(_moveTask.SourceModule, _moveTask.SourceSlot, _moveTask.RobotHand)) { return Result.FAIL; } _source.WaitTransfer(ModuleName.EfemRobot, EnumTransferType.Pick, 0); } if (!_efemRobot.IsAvailable) return Result.RUN; } else { if (!_efemRobot.IsAvailable) return Result.RUN; if (_source.IsWaitTransfer(ModuleName.EfemRobot)) { _source.PostTransfer(ModuleName.EfemRobot, EnumTransferType.Pick, 0); } } } //place if (_moveTask.DestinationModule != ModuleName.EfemRobot) { if (!_destination.IsAvailable) return Result.RUN; if (!WaferManager.Instance.CheckHasWafer(_moveTask.DestinationModule, _moveTask.DestinationSlot)) { if (!_destination.IsReadyForPlace(ModuleName.EfemRobot, _moveTask.DestinationSlot, _moveTask.RobotHand)) { if (!_destination.PrepareTransfer(ModuleName.EfemRobot, EnumTransferType.Place, _moveTask.DestinationSlot)) return Result.FAIL; } if (!_destination.IsAvailable) return Result.RUN; if (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, (int)_moveTask.RobotHand)) { if (!_efemRobot.Place(_moveTask.DestinationModule, _moveTask.DestinationSlot, _moveTask.RobotHand)) return Result.FAIL; _destination.WaitTransfer(ModuleName.EfemRobot, EnumTransferType.Place, 0); } if (!_efemRobot.IsAvailable) return Result.RUN; } else { if (!_efemRobot.IsAvailable) return Result.RUN; if (_destination.IsWaitTransfer(ModuleName.EfemRobot)) { _destination.PostTransfer(ModuleName.EfemRobot, EnumTransferType.Place, 0); //_destination.StopWaitTransfer(ModuleName.EfemRobot); } } } return Result.RUN; } public void Abort() { Clear(); } public void Clear() { _efemRobot.ResetTask(); _source?.ResetTask(); _destination?.ResetTask(); } } public class AlignRoutine : TransferModule, IRoutine { private SchedulerAligner _aligner; public AlignRoutine(string module) { _aligner = GetModule(module) as SchedulerAligner; } public Result Start(params object[] objs) { _aligner.Align(0); return Result.RUN; } public Result Monitor() { if (_aligner.IsAvailable) return Result.DONE; return Result.RUN; } public void Abort() { } } public class CoolingRoutine : TransferModule, IRoutine { private SchedulerAligner _cooling; private int _coolingTimeS; public CoolingRoutine(string module, int coolingTimeS) { _cooling = GetModule(module) as SchedulerAligner; _coolingTimeS = coolingTimeS; } public Result Start(params object[] objs) { _cooling.Cooling(_coolingTimeS); return Result.RUN; } public Result Monitor() { if (_cooling.IsAvailable) return Result.DONE; return Result.RUN; } public void Abort() { } } }