using System; using System.Collections.Generic; using System.Diagnostics.Eventing.Reader; using Aitex.Core.Common; using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.Sorter.Common; using Aitex.Sorter.RT.Module; using Aitex.Sorter.RT.SorterCommonFrame.Routines; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts; //using SorterRT.Routines; namespace Aitex.Sorter.RT.SorterCommonFrame.Modules { public class DualMoveManager : IMoveManager { public event Action OnMoveError; public int TaskCount { get { return tasks.Count; } } public bool IsPaused { get { return !_pause; } } public int WaferCompleted { get { int count = tasks.Count; int completed = lastTaskCount - count; lastTaskCount = count; return completed; } } private PickRoutine pickRoutine = null; private PlaceRoutine placeRoutine = null; private AlignRoutine alignRoutine = null; private SwapRoutine swapRoutine = null; private List tasks = new List(); private IRoutine _robotRoutine = null; private AlignRoutine _alignerRoutine = null; private MoveTask task1 = null; private MoveTask task2 = null; private MoveTask task3 = null; private bool _verifyFail = false; private int lastTaskCount = 0; private bool _pause; public DualMoveManager() { pickRoutine = new PickRoutine("System", "PickRoutine"); pickRoutine.Initalize(); swapRoutine = new SwapRoutine("System", "SwapRoutine"); swapRoutine.Initalize(); placeRoutine = new PlaceRoutine("System", "PlaceRoutine"); placeRoutine.Initalize(); alignRoutine = new AlignRoutine("System", "AlignRoutine"); alignRoutine.Initalize(); } public bool Initialize() { return true; } public bool Pause() { _pause = true; return true; } public bool Resume() { _pause = false; return true; } public bool Stop() { tasks.Clear(); if (task1 != null) tasks.Add(task1); if (task2 != null) tasks.Add(task2); _pause = false; return true; } public bool Start(List tasks) { _robotRoutine = null; _alignerRoutine = null; _pause = false; this.tasks = tasks; foreach (MoveTask task in tasks) { WaferManager.Instance.UpdateWaferProcessStatus(task.WaferID, ProcessStatus.Wait); task.WaferID = WaferManager.Instance.GetWaferID(task.SourceStaion, task.SourceSlot); } newTask(); if (task1 == null) { return true; } _robotRoutine = null; _alignerRoutine = null; lastTaskCount = tasks.Count; return true; } private void newTask() { if (tasks.Count > 0) task1 = tasks[0]; if (task1 != null) { WaferManager.Instance.UpdateWaferProcessStatus(task1.WaferID, ProcessStatus.Busy); task1.swap = IsSwap(task1); LOG.Info(string.Format(" next task1, Wafer Moved from {0}{1:D2} to {2}{3:D2}.option is {4}, swasp is {5}", task1.SourceStaion.ToString(), task1.SourceSlot, task1.DestStaion.ToString(), task1.DestSlot, task1.option, task1.swap)); task2 = FindSecondTask(task1.DestStaion, task1.DestSlot, task1.option, task1.swap); if (task2 != null) { WaferManager.Instance.UpdateWaferProcessStatus(task2.WaferID, ProcessStatus.Busy); task3 = FindThirdTask(task2.DestStaion, task2.DestSlot, task2.option, task2.swap); if (task3 != null) { WaferManager.Instance.UpdateWaferProcessStatus(task3.WaferID, ProcessStatus.Busy); } } } } private bool IsSwap(MoveTask task) { if ((task.DestStaion == task.SourceStaion) && (task.DestSlot == task.SourceSlot)) return false; return WaferManager.Instance.CheckHasWafer(task.DestStaion, task.DestSlot); } /// /// /// /// /// 如果任务全部完成,或者任务失败,返回true public bool Monitor(object[] objs) { Result ret = Result.RUN; if (tasks.Count == 0 && task1 == null && task2 == null) { return true; //completed } if (ret == Result.DONE || task1 ==null) { if (_pause) { return false; //pause } } if (task1 == null) { if (!_pause) newTask(); } if (_alignerRoutine != null) { ret = _alignerRoutine.Monitor(); if (ret == Result.DONE) { _alignerRoutine = null; AlignCompleted(); return false; } else if (ret == Result.FAIL) { WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 0, ProcessStatus.Failed); WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 1, ProcessStatus.Failed); WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Aligner, 0, ProcessStatus.Failed); NotifyError("Aligner", "Aligner Error"); return true; //failed } } if (_robotRoutine != null) { ret = _robotRoutine.Monitor(); if (ret == Result.DONE) { _robotRoutine = null; return false; } else if (ret == Result.FAIL) { WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 0, ProcessStatus.Failed); WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 1, ProcessStatus.Failed); WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Aligner, 0, ProcessStatus.Failed); NotifyError("Robot", "Robot Error"); return true; //failed } } else { if (!_pause) { IRoutine rountine = NextRoutine(); if (rountine != null) { rountine.Start(); _robotRoutine = rountine; } } } return false; } public Result Monitor() { Result ret = Result.RUN; if (tasks.Count == 0 && task1 == null && task2 == null) { return Result.DONE; //completed } if (ret == Result.DONE || task1 ==null) { if (_pause) { return Result.RUN; //pause } } if (task1 == null) { if (!_pause) newTask(); } if (_alignerRoutine != null) { ret = _alignerRoutine.Monitor(); if (ret == Result.DONE) { _alignerRoutine = null; AlignCompleted(); return Result.RUN; } else if (ret == Result.FAIL) { WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 0, ProcessStatus.Failed); WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 1, ProcessStatus.Failed); WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Aligner, 0, ProcessStatus.Failed); NotifyError("Aligner", "Aligner Error"); return Result.FAIL; //failed } if (ret == Result.VERIFYFAIL) { //_alignerRoutine = null; if (SC.ContainsItem(SorterCommon.ScPathName.Process_LMMismatchHandle)) switch (SC.GetValue(SorterCommon.ScPathName.Process_LMMismatchHandle)) { case 2: task1.DestStaion = task1.SourceStaion; task1.DestSlot = task1.SourceSlot; WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Aligner, 0, ProcessStatus.Failed); _verifyFail = true; break; case 3: ModuleName handleLp; if (SC.ContainsItem(SorterCommon.ScPathName.Process_MismatchCollectPort)) { handleLp = ModuleHelper.Converter(SC.GetStringValue(SorterCommon.ScPathName.Process_MismatchCollectPort)); if (!ModuleHelper.IsLoadPort(handleLp)) break; //handleLp = ModuleName.LP1; } else break; task1.DestStaion = handleLp; int startSlot = SC.ContainsItem("LoadPort." + handleLp.ToString() + "StartSlot") ? SC.GetValue("LoadPort." + handleLp.ToString() + "StartSlot") : 1; if (startSlot > 25 || startSlot < 1) startSlot = 1; int endSlot = SC.ContainsItem("LoadPort." + handleLp.ToString() + "EndSlot") ? SC.GetValue("LoadPort." + handleLp.ToString() + "EndSlot") : 25; if (endSlot > 25 || endSlot < 1) endSlot = 25; WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Aligner, 0, ProcessStatus.Failed); _verifyFail = true; var emptySlot = DEVICE.GetDevice(handleLp.ToString()).GetEmptySlot(); foreach (int slot in emptySlot) { if (slot < startSlot || slot > endSlot) emptySlot.Remove(slot); } if (emptySlot.Count != 0) { if (SC.ContainsItem("Process.PlaceFromTopOnHostLPMode") && SC.GetValue("Process.PlaceFromTopOnHostLPMode")) { task1.DestSlot = emptySlot[emptySlot.Count - 1]; } else { task1.DestSlot = emptySlot[0]; } break; } else { Singleton.Instance.PostMsg(RouteManagerSorter.MSG.PauseRecipe); EV.PostWarningLog(handleLp.ToString(), $"{handleLp} is full."); break; } default: break; } _alignerRoutine.PostAlignValue = SC.ContainsItem("Aligner." + task1.DestStaion + "PostAlignAngle") ? SC.GetValue("Aligner." + task1.DestStaion + "PostAlignAngle") : 0; //AlignCompleted(); return Result.RUN; } } if (_robotRoutine != null) { ret = _robotRoutine.Monitor(); if (ret == Result.DONE) { _robotRoutine = null; return Result.RUN; } else if (ret == Result.FAIL) { WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 0, ProcessStatus.Failed); WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 1, ProcessStatus.Failed); WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Aligner, 0, ProcessStatus.Failed); NotifyError("Robot", "Robot Error"); return Result.FAIL; //failed } } else { if (!_pause) { IRoutine rountine = NextRoutine(); if (rountine != null) { rountine.Start(); _robotRoutine = rountine; } } } return Result.RUN; } private void AlignCompleted() { if (task1 != null) { if (task1.Step == MoveStep.WaitAligner) { task1.Step = MoveStep.PickFromAligner; } } if (task2 != null) { if (task2.Step == MoveStep.WaitAligner) { task2.Step = MoveStep.PickFromAligner; } } if (task3 != null) { if (task3.Step == MoveStep.WaitAligner) { task3.Step = MoveStep.PickFromAligner; } } } private IRoutine NextRoutine() { IRoutine routine = null; if (task2 != null && task2.Step == MoveStep.Aligning) { alignRoutine.Option = task2.option; alignRoutine.Notch = task2.Notch; alignRoutine.IsVerifyAny = task2.VerifyAny; alignRoutine.IsVerifyLM1 = task2.VerifyLaserMaker; alignRoutine.StrLaserMark1 = task2.LaserMaker; alignRoutine.IsReadLM2 = task2.VerifyT7Code; alignRoutine.StrLaserMark2 = task2.T7Code; alignRoutine.PostAlignValue = SC.ContainsItem("Aligner." + task2.DestStaion.ToString() + "PostAlignAngle") ? SC.GetValue("Aligner." + task2.DestStaion.ToString() + "PostAlignAngle") : 0; _alignerRoutine = alignRoutine; _alignerRoutine.Start(); task2.Step = MoveStep.WaitAligner; } if (task3 != null && task3.Step == MoveStep.Aligning) { alignRoutine.Option = task3.option; alignRoutine.Notch = task3.Notch; alignRoutine.IsVerifyAny = task3.VerifyAny; alignRoutine.IsVerifyLM1 = task3.VerifyLaserMaker; alignRoutine.StrLaserMark1 = task3.LaserMaker; alignRoutine.IsReadLM2 = task3.VerifyT7Code; alignRoutine.StrLaserMark2 = task3.T7Code; alignRoutine.PostAlignValue = SC.ContainsItem("Aligner." + task3.DestStaion + "PostAlignAngle") ? SC.GetValue("Aligner." + task3.DestStaion + "PostAlignAngle") : 0; _alignerRoutine = alignRoutine; _alignerRoutine.Start(); task3.Step = MoveStep.WaitAligner; } //pass aligner and turnover station if (task1 != null && PassTurnOver(task1.option) && PassAligner(task1.option)) { switch (task1.Step) { case MoveStep.PickFromSource: { pickRoutine.Source = task1.SourceStaion; pickRoutine.Slot = task1.SourceSlot; pickRoutine.Blade = GetEmptyHand(); task1.Blade = pickRoutine.Blade; routine = pickRoutine; task1.Step = MoveStep.PlaceToAligner; break; } case MoveStep.PlaceToAligner: { placeRoutine.Station = ModuleName.Aligner; placeRoutine.Slot = 0; placeRoutine.Blade = task1.Blade; task1.Step = MoveStep.Aligning; routine = placeRoutine; break; } case MoveStep.PlaceToTurnOver: { placeRoutine.Station = ModuleName.TurnOverStation; placeRoutine.Slot = 0; placeRoutine.Blade = task1.Blade; task1.Step = MoveStep.PickFromTurnOver; routine = placeRoutine; break; } case MoveStep.Aligning: { alignRoutine.Option = task1.option; alignRoutine.Notch = task1.Notch; alignRoutine.IsVerifyAny = task1.VerifyAny; alignRoutine.IsVerifyLM1 = task1.VerifyLaserMaker; alignRoutine.StrLaserMark1 = task1.LaserMaker; alignRoutine.IsVerifyLM2 = task1.VerifyT7Code; alignRoutine.StrLaserMark1 = task1.T7Code; alignRoutine.PostAlignValue = SC.ContainsItem("Aligner." + task1.DestStaion + "PostAlignAngle") ? SC.GetValue("Aligner." + task1.DestStaion + "PostAlignAngle") : 0; _alignerRoutine = alignRoutine; _alignerRoutine.Start(); task1.Step = MoveStep.WaitAligner; if (task2 != null) { if (task2.Step == MoveStep.PickFromSource) { pickRoutine.Source = task2.SourceStaion; pickRoutine.Slot = task2.SourceSlot; pickRoutine.Blade = GetEmptyHand(); task2.Blade = pickRoutine.Blade; routine = pickRoutine; task2.Step = MoveStep.PlaceToAligner; } } break; } case MoveStep.PickFromTurnOver: { if (task2 != null) { switch (task2.Step) { case MoveStep.PlaceToTurnOver: swapRoutine.Source = ModuleName.TurnOverStation; swapRoutine.Slot = 0; swapRoutine.PlaceBlade = task2.Blade; task1.Blade = SwapHand(swapRoutine.PlaceBlade); task1.Step = MoveStep.PlaceToDest; task2.Step = MoveStep.PickFromTurnOver; routine = swapRoutine; break; case MoveStep.PlaceToAligner: placeRoutine.Station = ModuleName.Aligner; placeRoutine.Slot = 0; placeRoutine.Blade = task2.Blade; task2.Step = MoveStep.Aligning; routine = placeRoutine; break; case MoveStep.PickFromAligner: if (task3!=null) { switch (task3.Step) { case MoveStep.PickFromSource: pickRoutine.Source = task3.SourceStaion; pickRoutine.Slot = task3.SourceSlot; pickRoutine.Blade = GetEmptyHand(); task3.Blade = pickRoutine.Blade; routine = pickRoutine; task3.Step = MoveStep.PlaceToAligner; break; case MoveStep.PlaceToAligner: swapRoutine.Source = ModuleName.Aligner; swapRoutine.Slot = 0; swapRoutine.PlaceBlade = task3.Blade; task2.Blade = SwapHand(swapRoutine.PlaceBlade); task2.Step = MoveStep.PlaceToTurnOver; task3.Step = MoveStep.Aligning; routine = swapRoutine; break; } } else { pickRoutine.Source = ModuleName.Aligner; pickRoutine.Slot = 0; pickRoutine.Blade = task2.Blade; task2.Step = MoveStep.PlaceToTurnOver; routine = pickRoutine; } break; } } else { pickRoutine.Source = ModuleName.TurnOverStation; pickRoutine.Slot = 0; pickRoutine.Blade = task1.Blade; task1.Step = MoveStep.PlaceToDest; routine = pickRoutine; } break; } case MoveStep.PickFromAligner: { if (_alignerRoutine == null) //aligning completed { if (task2 != null && task3 != null && task2.Step != MoveStep.PlaceToAligner) { switch (task3.Step) { case MoveStep.PickFromSource: pickRoutine.Source = task3.SourceStaion; pickRoutine.Slot = task3.SourceSlot; pickRoutine.Blade = GetEmptyHand(); task3.Blade = pickRoutine.Blade; routine = pickRoutine; task3.Step = MoveStep.PlaceToAligner; break; case MoveStep.PlaceToAligner: swapRoutine.Source = ModuleName.Aligner; swapRoutine.Slot = 0; swapRoutine.PlaceBlade = task3.Blade; task2.Blade = SwapHand(swapRoutine.PlaceBlade); task2.Step = MoveStep.PlaceToTurnOver; task3.Step = MoveStep.Aligning; routine = swapRoutine; break; } } else if (task2 != null) { switch (task2.Step) { case MoveStep.PickFromTurnOver: pickRoutine.Source = ModuleName.TurnOverStation; pickRoutine.Slot = 0; pickRoutine.Blade = task2.Blade; task2.Step = MoveStep.PlaceToAligner; routine = pickRoutine; break; case MoveStep.PlaceToTurnOver: placeRoutine.Station = ModuleName.TurnOverStation; placeRoutine.Slot = 0; placeRoutine.Blade = task2.Blade; task2.Step = MoveStep.PickFromTurnOver; routine = placeRoutine; break; case MoveStep.PlaceToAligner: swapRoutine.Source = ModuleName.Aligner; swapRoutine.Slot = 0; swapRoutine.PlaceBlade = task2.Blade; task1.Blade = SwapHand(swapRoutine.PlaceBlade); task1.Step = MoveStep.PlaceToTurnOver; task2.Step = MoveStep.Aligning; routine = swapRoutine; break; } } else { //从aligner移动至Turnover station pickRoutine.Source = ModuleName.Aligner; pickRoutine.Slot = 0; pickRoutine.Blade = task1.Blade; task1.Step = MoveStep.PlaceToTurnOver; routine = pickRoutine; } } break; } case MoveStep.PlaceToDest: { if (task2 != null) { if (WaferManager.Instance.CheckNoWafer(task1.DestStaion, task1.DestSlot)) { if (task2.Step == MoveStep.PickFromSource && !task2.swap) { pickRoutine.Source = task2.SourceStaion; pickRoutine.Slot = task2.SourceSlot; pickRoutine.Blade = GetEmptyHand(); task2.Blade = pickRoutine.Blade; task2.Step = MoveStep.PlaceToDest; routine = pickRoutine; } else { placeRoutine.Station = task1.DestStaion; placeRoutine.Slot = task1.DestSlot; placeRoutine.Blade = task1.Blade; task1.swap = false; task1.Step = MoveStep.Completed; routine = placeRoutine; } } else { task1.Step = MoveStep.Completed; _robotRoutine = placeRoutine; swapRoutine.Source = task1.DestStaion; swapRoutine.Slot = task1.DestSlot; swapRoutine.PlaceBlade = task1.Blade; task1.Blade = SwapHand(swapRoutine.PlaceBlade); task1.swap = true; task1.Step = MoveStep.Completed; routine = swapRoutine; } } else { if (WaferManager.Instance.CheckNoWafer(task1.DestStaion, task1.DestSlot)) { placeRoutine.Station = task1.DestStaion; placeRoutine.Slot = task1.DestSlot; placeRoutine.Blade = task1.Blade; task1.swap = false; task1.Step = MoveStep.Completed; routine = placeRoutine; } else { task1.Step = MoveStep.Completed; _robotRoutine = placeRoutine; swapRoutine.Source = task1.DestStaion; swapRoutine.Slot = task1.DestSlot; swapRoutine.PlaceBlade = task1.Blade; task1.Blade = SwapHand(swapRoutine.PlaceBlade); task1.swap = true; task1.Step = MoveStep.Completed; routine = swapRoutine; } } break; } case MoveStep.Completed: { if (_verifyFail) { WaferManager.Instance.UpdateWaferProcessStatus(task1.DestStaion, task1.DestSlot, ProcessStatus.Failed); _verifyFail = false; } else WaferManager.Instance.UpdateWaferProcessStatus(task1.DestStaion, task1.DestSlot, ProcessStatus.Completed); tasks.Remove(task1); if (task3 != null && task2 != null) { if (task2.Step == MoveStep.PlaceToDest) { task1 = task2; task2 = null; } else { if (task1.swap) { MoveTask task = GetNextTask(); task1 = task2; task2 = task; } else { task1 = task2; task2 = task3; task3 = FindThirdTask(task2.DestStaion, task2.DestSlot, task2.option, task2.swap); } } } else if (task2 != null) { if (task2.Step == MoveStep.PlaceToDest) { task1 = task2; task2 = null; } else { if (task1.swap) { MoveTask task = GetNextTask(); task1 = task2; task2 = task; } else { task1 = task2; task2 = FindSecondTask(task1.DestStaion, task1.DestSlot, task1.option, task1.swap); } } } else { if (task1.swap) task1 = GetNextTask(); else task1 = null; } break; } } if (task2 != null) { if (routine == null) { if (task2.Step == MoveStep.PickFromSource) { pickRoutine.Source = task2.SourceStaion; pickRoutine.Slot = task2.SourceSlot; pickRoutine.Blade = GetEmptyHand(); task2.Blade = pickRoutine.Blade; routine = pickRoutine; task2.Step = MoveStep.PlaceToAligner; } else if (task2.Step == MoveStep.PlaceToDest) { if (WaferManager.Instance.CheckNoWafer(task2.DestStaion, task2.DestSlot)) { placeRoutine.Station = task2.DestStaion; placeRoutine.Slot = task2.DestSlot; placeRoutine.Blade = task2.Blade; task2.swap = false; task2.Step = MoveStep.Completed; routine = placeRoutine; } else { task2.Step = MoveStep.Completed; _robotRoutine = placeRoutine; swapRoutine.Source = task2.DestStaion; swapRoutine.Slot = task2.DestSlot; swapRoutine.PlaceBlade = task2.Blade; task2.Blade = SwapHand(swapRoutine.PlaceBlade); task2.swap = true; task2.Step = MoveStep.Completed; routine = swapRoutine; } } else if (task2.Step == MoveStep.Completed) { WaferManager.Instance.UpdateWaferProcessStatus(task2.DestStaion, task2.DestSlot, Aitex.Core.Common.ProcessStatus.Completed); tasks.Remove(task2); return routine; } } } } else { if (task1.Step == MoveStep.PickFromSource) { if (IsDoublePick()) { pickRoutine.Source = task1.SourceStaion; if (task1.SourceSlot < task2.SourceSlot) pickRoutine.Slot = task1.SourceSlot; else pickRoutine.Slot = task2.SourceSlot; pickRoutine.Blade = Hand.Both; task1.Blade = Hand.Both; routine = pickRoutine; task1.Step = MoveStep.PlaceToDest; task2.Step = MoveStep.PlaceToDest; } else { pickRoutine.Source = task1.SourceStaion; pickRoutine.Slot = task1.SourceSlot; pickRoutine.Blade = GetEmptyHand(); task1.Blade = pickRoutine.Blade; routine = pickRoutine; if (PassAligner(task1.option) && PassTurnOver(task1.option)) { task1.Step = MoveStep.PlaceToAligner; } else if (PassAligner(task1.option)) { task1.Step = MoveStep.PlaceToAligner; } else if (PassTurnOver(task1.option)) { task1.Step = MoveStep.PlaceToTurnOver; } else { task1.Step = MoveStep.PlaceToDest; } } } else if (task1.Step == MoveStep.PlaceToAligner) { placeRoutine.Station = ModuleName.Aligner; placeRoutine.Slot = 0; placeRoutine.Blade = task1.Blade; task1.Step = MoveStep.Aligning; routine = placeRoutine; } else if (task1.Step == MoveStep.PlaceToTurnOver) { placeRoutine.Station = ModuleName.TurnOverStation; placeRoutine.Slot = 0; placeRoutine.Blade = task1.Blade; task1.Step = MoveStep.Turning; routine = placeRoutine; } else if (task1.Step == MoveStep.Turning) { if (task2 != null) { if (PassTurnOver(task2.option)) { if (task2.Step == MoveStep.PickFromSource) { pickRoutine.Source = task2.SourceStaion; pickRoutine.Slot = task2.SourceSlot; pickRoutine.Blade = GetEmptyHand(); task2.Blade = pickRoutine.Blade; routine = pickRoutine; if(PassAligner(task2.option)) task2.Step = MoveStep.PlaceToAligner; else task2.Step = MoveStep.PlaceToTurnOver; } else if (task2.Step == MoveStep.PickFromAligner) { pickRoutine.Source = ModuleName.Aligner; pickRoutine.Slot = 0; pickRoutine.Blade = GetEmptyHand(); task2.Blade = pickRoutine.Blade; routine = pickRoutine; task2.Step = MoveStep.PlaceToTurnOver; } } task1.Step = MoveStep.PickFromTurnOver; } else { pickRoutine.Source = ModuleName.TurnOverStation; pickRoutine.Slot = 0; pickRoutine.Blade = task1.Blade; task1.Step = MoveStep.PickFromTurnOver; routine = pickRoutine; } } else if (task1.Step == MoveStep.Aligning) { alignRoutine.Option = task1.option; alignRoutine.Notch = task1.Notch; alignRoutine.IsVerifyAny = task1.VerifyAny; alignRoutine.IsVerifyLM1 = task1.VerifyLaserMaker; alignRoutine.StrLaserMark1 = task1.LaserMaker; alignRoutine.IsVerifyLM2 = task1.VerifyT7Code; alignRoutine.StrLaserMark2 = task1.T7Code; alignRoutine.PostAlignValue = SC.ContainsItem("Aligner." + task1.DestStaion.ToString() + "PostAlignAngle") ? SC.GetValue("Aligner." + task1.DestStaion.ToString() + "PostAlignAngle") : 0; _alignerRoutine = alignRoutine; _alignerRoutine.Start(); task1.Step = MoveStep.WaitAligner; if (task2 != null) { if (PassAligner(task2.option)) { if (task2.Step == MoveStep.PickFromSource) { pickRoutine.Source = task2.SourceStaion; pickRoutine.Slot = task2.SourceSlot; pickRoutine.Blade = GetEmptyHand(); task2.Blade = pickRoutine.Blade; routine = pickRoutine; task2.Step = MoveStep.PlaceToAligner; } } } } else if (task1.Step == MoveStep.PickFromTurnOver) { if (task2 != null) { if (task2.Step == MoveStep.PlaceToTurnOver) { swapRoutine.Source = ModuleName.TurnOverStation; swapRoutine.Slot = 0; swapRoutine.PlaceBlade = task2.Blade; task1.Blade = SwapHand(swapRoutine.PlaceBlade); task1.Step = MoveStep.PlaceToDest; task2.Step = MoveStep.PickFromTurnOver; routine = swapRoutine; } else if (task2.Step == MoveStep.PlaceToAligner) { placeRoutine.Station = ModuleName.Aligner; placeRoutine.Slot = 0; placeRoutine.Blade = task2.Blade; task2.Step = MoveStep.Aligning; routine = placeRoutine; } else if (task2.Step == MoveStep.PickFromAligner) { pickRoutine.Source = ModuleName.Aligner; pickRoutine.Slot = 0; pickRoutine.Blade = task2.Blade; task2.Step = MoveStep.PlaceToTurnOver; routine = pickRoutine; } } else { pickRoutine.Source = ModuleName.TurnOverStation; pickRoutine.Slot = 0; pickRoutine.Blade = task1.Blade; task1.Step = MoveStep.PlaceToDest; routine = pickRoutine; } } else if (task1.Step == MoveStep.PickFromAligner) { if (_alignerRoutine == null) //aligning completed { if (task2 != null) { if (task2.Step == MoveStep.PickFromTurnOver) { pickRoutine.Source = ModuleName.TurnOverStation; pickRoutine.Slot = 0; pickRoutine.Blade = task2.Blade; task2.Step = MoveStep.PlaceToAligner; routine = pickRoutine; } else if (task2.Step == MoveStep.PlaceToTurnOver) { placeRoutine.Station = ModuleName.TurnOverStation; placeRoutine.Slot = 0; placeRoutine.Blade = task2.Blade; task2.Step = MoveStep.PickFromTurnOver; routine = placeRoutine; } else if (task2.Step == MoveStep.PlaceToAligner) { if (PassTurnOver(task1.option)) { swapRoutine.Source = ModuleName.Aligner; swapRoutine.Slot = 0; swapRoutine.PlaceBlade = task2.Blade; task1.Blade = SwapHand(swapRoutine.PlaceBlade); task1.Step = MoveStep.PlaceToTurnOver; task2.Step = MoveStep.Aligning; routine = swapRoutine; } else { swapRoutine.Source = ModuleName.Aligner; swapRoutine.Slot = 0; swapRoutine.PlaceBlade = task2.Blade; task1.Blade = SwapHand(swapRoutine.PlaceBlade); task1.Step = MoveStep.PlaceToDest; task2.Step = MoveStep.Aligning; routine = swapRoutine; } } } else { if (PassTurnOver(task1.option)) { pickRoutine.Source = ModuleName.Aligner; pickRoutine.Slot = 0; pickRoutine.Blade = task1.Blade; task1.Step = MoveStep.PlaceToTurnOver; routine = pickRoutine; } else { pickRoutine.Source = ModuleName.Aligner; pickRoutine.Slot = 0; pickRoutine.Blade = task1.Blade; task1.Step = MoveStep.PlaceToDest; routine = pickRoutine; } } } else { //waiting } } else if (task1.Step == MoveStep.PlaceToDest) { if (task2 != null && task2.Step == MoveStep.PlaceToDest && IsDoublePlace()) { placeRoutine.Station = task1.DestStaion; //placeRoutine.Slot = task1.DestSlot; if (task1.DestSlot < task2.DestSlot) placeRoutine.Slot = task1.DestSlot; else placeRoutine.Slot = task2.DestSlot; placeRoutine.Blade = Hand.Both; task1.Step = MoveStep.Completed; task2.Step = MoveStep.Completed; routine = placeRoutine; } else { if (task2 != null) { if (WaferManager.Instance.CheckNoWafer(task1.DestStaion, task1.DestSlot)) { if (task2.Step == MoveStep.PickFromSource && !PassAligner(task2.option) && !PassTurnOver(task2.option) && !task2.swap) { pickRoutine.Source = task2.SourceStaion; pickRoutine.Slot = task2.SourceSlot; pickRoutine.Blade = GetEmptyHand(); task2.Blade = pickRoutine.Blade; task2.Step = MoveStep.PlaceToDest; routine = pickRoutine; } else { placeRoutine.Station = task1.DestStaion; placeRoutine.Slot = task1.DestSlot; placeRoutine.Blade = task1.Blade; task1.swap = false; task1.Step = MoveStep.Completed; routine = placeRoutine; } } else { task1.Step = MoveStep.Completed; _robotRoutine = placeRoutine; swapRoutine.Source = task1.DestStaion; swapRoutine.Slot = task1.DestSlot; swapRoutine.PlaceBlade = task1.Blade; task1.Blade = SwapHand(swapRoutine.PlaceBlade); task1.swap = true; task1.Step = MoveStep.Completed; routine = swapRoutine; } } else { if (WaferManager.Instance.CheckNoWafer(task1.DestStaion, task1.DestSlot)) { placeRoutine.Station = task1.DestStaion; placeRoutine.Slot = task1.DestSlot; placeRoutine.Blade = task1.Blade; task1.swap = false; task1.Step = MoveStep.Completed; routine = placeRoutine; } else { task1.Step = MoveStep.Completed; _robotRoutine = placeRoutine; swapRoutine.Source = task1.DestStaion; swapRoutine.Slot = task1.DestSlot; swapRoutine.PlaceBlade = task1.Blade; task1.Blade = SwapHand(swapRoutine.PlaceBlade); task1.swap = true; task1.Step = MoveStep.Completed; routine = swapRoutine; } } } } else if (task1.Step == MoveStep.Completed) { if (_verifyFail) { WaferManager.Instance.UpdateWaferProcessStatus(task1.DestStaion, task1.DestSlot, Aitex.Core.Common.ProcessStatus.Failed); _verifyFail = false; } else WaferManager.Instance.UpdateWaferProcessStatus(task1.DestStaion, task1.DestSlot, Aitex.Core.Common.ProcessStatus.Completed); tasks.Remove(task1); if (task2 != null && task2.Step == MoveStep.Completed) { WaferManager.Instance.UpdateWaferProcessStatus(task2.DestStaion, task2.DestSlot, Aitex.Core.Common.ProcessStatus.Completed); tasks.Remove(task2); task2 = null; } if (task2 != null) { if (task2.Step == MoveStep.PlaceToDest) { task1 = task2; task2 = null; } else { if (task1.swap) { MoveTask task = GetNextTask(); task1 = task2; task2 = task; } else { task1 = task2; task2 = FindSecondTask(task1.DestStaion, task1.DestSlot, task1.option, task1.swap); } } } else { if (task1.swap) task1 = GetNextTask(); else task1 = null; } } if (task2 != null) { if (routine == null) { if (task2.Step == MoveStep.PickFromSource) { pickRoutine.Source = task2.SourceStaion; pickRoutine.Slot = task2.SourceSlot; pickRoutine.Blade = GetEmptyHand(); task2.Blade = pickRoutine.Blade; routine = pickRoutine; if (PassAligner(task2.option) && PassTurnOver(task2.option)) { task2.Step = MoveStep.PlaceToAligner; } else if (PassTurnOver(task2.option)) { task2.Step = MoveStep.PlaceToTurnOver; } else if (PassAligner(task2.option)) { task2.Step = MoveStep.PlaceToAligner; } else { task2.Step = MoveStep.PlaceToDest; } } else if (task2.Step == MoveStep.PlaceToDest) { if (WaferManager.Instance.CheckNoWafer(task2.DestStaion, task2.DestSlot)) { placeRoutine.Station = task2.DestStaion; placeRoutine.Slot = task2.DestSlot; placeRoutine.Blade = task2.Blade; task2.swap = false; task2.Step = MoveStep.Completed; routine = placeRoutine; } else { task2.Step = MoveStep.Completed; _robotRoutine = placeRoutine; swapRoutine.Source = task2.DestStaion; swapRoutine.Slot = task2.DestSlot; swapRoutine.PlaceBlade = task2.Blade; task2.Blade = SwapHand(swapRoutine.PlaceBlade); task2.swap = true; task2.Step = MoveStep.Completed; routine = swapRoutine; } } else if (task2.Step == MoveStep.Completed) { WaferManager.Instance.UpdateWaferProcessStatus(task2.DestStaion, task2.DestSlot, Aitex.Core.Common.ProcessStatus.Completed); tasks.Remove(task2); return routine; } } } } return routine; } private bool IsDoublePick() { if (!SC.GetValue(SorterCommon.ScPathName.Robot_DualBlade1TransferEnable)) return false; if (task2 == null) return false; if (task1.option != task2.option) return false; if (PassAligner(task1.option)) return false; if (PassTurnOver(task1.option)) return false; if (task1.swap || task2.swap) return false; if (task1.SourceStaion != task2.SourceStaion) return false; if (Math.Abs(task1.DestSlot - task2.DestSlot) != 1) return false; if (Math.Abs(task1.SourceSlot - task2.SourceSlot) != 1) return false; return true; } private bool IsDoublePlace() { if(!SC.GetValue(SorterCommon.ScPathName.Robot_DualBlade1TransferEnable)) return false; if (task2 == null) return false; if (task1.option != task2.option) return false; if (PassAligner(task1.option)) return false; if (task1.swap || task2.swap) return false; if (task1.DestStaion != task2.DestStaion) return false; if (Math.Abs(task1.DestSlot - task2.DestSlot) != 1) return false; return true; } private bool PassAligner(MoveOption option) { //return false; return (((option & MoveOption.Align) == MoveOption.Align) || ((option & MoveOption.ReadID) == MoveOption.ReadID) || ((option & MoveOption.ReadID2) == MoveOption.ReadID2) ); } private bool PassTurnOver(MoveOption option) { //return false; return (((option & MoveOption.Turnover) == MoveOption.Turnover)); } private Hand GetEmptyHand() { if (!WaferManager.Instance.CheckWafer(ModuleName.Robot, 0, WaferStatus.Normal)) { return Hand.Blade1; } if (!WaferManager.Instance.CheckWafer(ModuleName.Robot, 1, WaferStatus.Normal)) { return Hand.Blade2; } return Hand.Blade1; } private bool RobotHaveWafer() { if (WaferManager.Instance.CheckHasWafer(ModuleName.Robot, 0)) { return true; } if (WaferManager.Instance.CheckHasWafer(ModuleName.Robot, 1)) { return true; } return false; } private Hand SwapHand(Hand blade) { if (blade == Hand.Blade1) { return Hand.Blade2; } return Hand.Blade1; } private MoveTask GetNextTask() { MoveTask newTask = null; if (task1.swap) { newTask = FindSwapNextTask(task1.DestStaion, task1.DestSlot); if (newTask == null) { LOG.Error("有未定义目标位置的传片任务"); return newTask; } if (PassAligner(newTask.option)) newTask.Step = MoveStep.PlaceToAligner; else newTask.Step = MoveStep.PlaceToDest; newTask.Blade = task1.Blade; } if (newTask != null) { if (!newTask.swap) WaferManager.Instance.UpdateWaferProcessStatus(newTask.WaferID, ProcessStatus.Busy); } return newTask; } private MoveTask FindSwapNextTask(ModuleName chamber, int slot) { foreach (MoveTask task in tasks) { if (task.SourceStaion == chamber && task.SourceSlot == slot) { task.swap = IsSwap(task); LOG.Info(string.Format("Get Swap next task, Wafer Moved from {0}{1:D2} to {2}{3:D2}.option is {4}, swasp is {5}", task.SourceStaion.ToString(), task.SourceSlot, task.DestStaion.ToString(), task.DestSlot,task.option,task.swap)); return task; } } return null; } private MoveTask FindSecondTask(ModuleName chamber, int slot, MoveOption option, bool swap) { bool bPassAligner = PassAligner(option); if (!bPassAligner && swap) //task1 swap and no pass aligner, onr task excute { LOG.Info(string.Format("Get second task, no task")); return null; } // foreach (MoveTask task in tasks) if (tasks.Count >1) { MoveTask task = tasks[1]; task.swap = IsSwap(task); if (task == task1) { LOG.Info(string.Format("Get second task, no task")); return null; } if (task.SourceStaion == chamber && task.SourceSlot == slot) //task source is task1 target, can't run together { LOG.Info(string.Format("Get second task, no task")); return null; } bool bTaskPassAligner = PassAligner(task.option); //path should be same if (bTaskPassAligner != bPassAligner) { LOG.Info(string.Format("Get second task, no task")); return null; } if (task.swap != swap) { LOG.Info(string.Format("Get second task, no task")); return null; } if (swap) { if (task.DestStaion == chamber && task.DestSlot == slot) { LOG.Info(string.Format("Get second task, no task")); return null; ; } } LOG.Info(string.Format("Get second task, Wafer Moved from {0}{1:D2} to {2}{3:D2}.option is {4}, swap is {5}", task.SourceStaion.ToString(), task.SourceSlot, task.DestStaion.ToString(), task.DestSlot, task.option, task.swap)); if (task != null) { if (!task.swap) WaferManager.Instance.UpdateWaferProcessStatus(task.WaferID, ProcessStatus.Busy); } return task; } LOG.Info(string.Format("Get second task, no task")); return null; } private MoveTask FindThirdTask(ModuleName chamber, int slot, MoveOption option, bool swap) { bool bPassAligner = PassAligner(option); if (!bPassAligner && swap) //task1 swap and no pass aligner, onr task execute { LOG.Info("Get third task, no task"); return null; } if (tasks.Count >2) { MoveTask task = tasks[2]; task.swap = IsSwap(task); if (task == task2) { LOG.Info(string.Format("Get third task, no task")); return null; } if (task.SourceStaion == chamber && task.SourceSlot == slot) //task source is task1 target, can't run together { LOG.Info(string.Format("Get third task, no task")); return null; } bool bTaskPassAligner = PassAligner(task.option); //path should be same if (bTaskPassAligner != bPassAligner) { LOG.Info(string.Format("Get third task, no task")); return null; } if (task.swap != swap) { LOG.Info(string.Format("Get third task, no task")); return null; } if (swap) { if (task.DestStaion == chamber && task.DestSlot == slot) { LOG.Info(string.Format("Get third task, no task")); return null; ; } } LOG.Info(string.Format("Get third task, Wafer Moved from {0}{1:D2} to {2}{3:D2}.option is {4}, swap is {5}", task.SourceStaion.ToString(), task.SourceSlot, task.DestStaion.ToString(), task.DestSlot, task.option, task.swap)); if (task != null) { if (!task.swap) WaferManager.Instance.UpdateWaferProcessStatus(task.WaferID, ProcessStatus.Busy); } return task; } LOG.Info(string.Format("Get third task, no task")); return null; } //private void PostMsg(RouteManager.MSG msg, params object[] objs) //{ // Singleton.Instance.PostMsg(msg, objs); //} private void NotifyError(string module, string message) { if (OnMoveError != null) { OnMoveError(new MoveErrorArgument(module, message)); } } } }