123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using Aitex.Core.Common;
- using Aitex.Core.RT.Log;
- using Aitex.Core.RT.Routine;
- using EFEM.RT.Routines;
- using Aitex.Sorter.Common;
- using Aitex.Sorter.RT.Module;
- using MECF.Framework.Common.Equipment;
- using MECF.Framework.Common.SubstrateTrackings;
- using Aitex.Core.RT.Device;
- namespace EFEM.RT.Modules
- {
- public class DualArmMoveManager : IMoveManager
- {
- public event Action<MoveErrorArgument> 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 Queue<MoveTask> tasks = new Queue<MoveTask>();
- private Queue<MoveTask> curtasks = new Queue<MoveTask>();
- private Queue<IRoutine> steps = new Queue<IRoutine>();
- private IRoutine curStep = null;
- private readonly bool _isInterferencePrevent =
- DeviceDefineManager.Instance.GetValue<bool>("InterferencePrevent") ?? false;
- private IEfemPickRoutine pickRoutine1 = null;
- private IEfemPlaceRoutine placeRoutine1 = null;
- private IEfemPickRoutine pickRoutine2 = null;
- private IEfemPlaceRoutine placeRoutine2 = null;
- private SwapRoutine swaproutine1 = null;
- private int lastTaskCount = 0;
- private int handChangeCount = 0;
- private bool _pause;
- public DualArmMoveManager()
- {
- pickRoutine1 = new PickRoutine("System", "Pick");
- pickRoutine1.Initalize();
- placeRoutine1 = new PlaceRoutine("System", "Place");
- placeRoutine1.Initalize();
- pickRoutine2 = new PickRoutine("System", "Pick");
- pickRoutine2.Initalize();
- placeRoutine2 = new PlaceRoutine("System", "Place");
- placeRoutine2.Initalize();
- swaproutine1 = new SwapRoutine("System", "Swap");
- swaproutine1.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();
- _pause = false;
- return true;
- }
- public bool Start(List<MoveTask> tasks)
- {
- _pause = false;
- //tasks = tasks.OrderBy(item =>item.SourceStaion).ThenBy(item => item.SourceSlot).ToList<MoveTask>();
- foreach (MoveTask task in tasks)
- {
- WaferManager.Instance.UpdateWaferProcessStatus(task.SourceStaion, task.SourceSlot, EnumWaferProcessStatus.Wait);//(task.WaferID, EnumWaferProcessStatus.Wait);
- task.WaferID = WaferManager.Instance.GetWaferID(task.SourceStaion, task.SourceSlot);
- }
- this.tasks.Clear();
- for (int i = 0; i < tasks.Count; i++)
- {
- this.tasks.Enqueue(tasks[i]);
- }
- if (!newTask())
- {
- return false;
- }
- if (steps.Count > 0)
- {
- curStep = steps.Dequeue();
- }
- if (curStep != null)
- {
- Result ret = curStep.Start();
- if (ret == Result.FAIL)
- {
- return false;
- }
- }
- lastTaskCount = tasks.Count;
- return true;
- }
- private bool newTask()
- {
- MoveTask[] nextTasks = new MoveTask[] { null, null };
- steps.Clear();
- curStep = null;
- if (tasks.Count == 0)
- {
- return true; //completed
- }
- for (int i = 0; i < nextTasks.Length && i < tasks.Count; i++)
- {
- nextTasks[i] = tasks.ElementAt(i);
- }
- if(nextTasks[1] != null && IsNeighbors(nextTasks[0], nextTasks[1], true) && IsNeighbors(nextTasks[0], nextTasks[1], false))//dual arm
- {
- ////double pick double place
- DPDP(nextTasks[0], nextTasks[1]);
- WaferManager.Instance.UpdateWaferProcessStatus(nextTasks[0].SourceStaion, nextTasks[0].SourceSlot, EnumWaferProcessStatus.Wait);//(nextTasks[0].WaferID, EnumWaferProcessStatus.InProcess);
- WaferManager.Instance.UpdateWaferProcessStatus(nextTasks[1].SourceStaion, nextTasks[1].SourceSlot, EnumWaferProcessStatus.Wait);//(nextTasks[1].WaferID, EnumWaferProcessStatus.InProcess);
- tasks.Dequeue();
- tasks.Dequeue();
- LOG.Info(string.Format("Dual transfer step 1, wafer move from {0}{1:D2} to {2}{3:D2}.",
- nextTasks[0].SourceStaion.ToString(), nextTasks[0].SourceSlot + 1, nextTasks[0].DestStaion.ToString(), nextTasks[0].DestSlot + 1));
- LOG.Info(string.Format("Dual transfer step 2, wafer move from {0}{1:D2} to {2}{3:D2}.",
- nextTasks[1].SourceStaion.ToString(), nextTasks[1].SourceSlot + 1, nextTasks[1].DestStaion.ToString(), nextTasks[1].DestSlot + 1));
- }
- else
- {
- Hand hand;
- if (handChangeCount % 2 == 0)
- {
- hand = WaferManager.Instance.CheckNoWafer(ModuleName.Robot, 0) ? Hand.Blade1 : Hand.Blade2;
- }
- else
- {
- hand = WaferManager.Instance.CheckNoWafer(ModuleName.Robot, 1) ? Hand.Blade2 : Hand.Blade1;
- }
- handChangeCount++;
- if (handChangeCount == int.MaxValue)
- handChangeCount = 0;
- if (!WaferManager.Instance.CheckNoWafer(ModuleName.Robot, (int)hand))
- {
- return false;
- }
- Move(nextTasks[0], hand);
- WaferManager.Instance.UpdateWaferProcessStatus(nextTasks[0].SourceStaion, nextTasks[0].SourceSlot, EnumWaferProcessStatus.Wait);//(nextTasks[0].WaferID, EnumWaferProcessStatus.InProcess);
- tasks.Dequeue();
- LOG.Info(string.Format("Single transfer wafer move from {0}{1:D2} to {2}{3:D2}.",
- nextTasks[0].SourceStaion.ToString(), nextTasks[0].SourceSlot, nextTasks[0].DestStaion.ToString(), nextTasks[0].DestSlot));
- }
- return true;
- }
- private bool IsSwap(MoveTask task)
- {
- if (task == null)
- return false;
- if ((task.DestStaion == task.SourceStaion) && (task.DestSlot == task.SourceSlot))
- return false;
- return WaferManager.Instance.CheckHasWafer(task.DestStaion, task.DestSlot);
- }
- private bool IsNeighbors(MoveTask task1, MoveTask task2, bool pick)
- {
- if (pick)
- {
- return (task1.SourceStaion == task2.SourceStaion) && (task1.SourceSlot + 1 == task2.SourceSlot);
- }
- return (task1.DestStaion == task2.DestStaion) && (task1.DestSlot + 1 == task2.DestSlot);
- }
- private void Move(MoveTask task, Hand hand)
- {
- if (task.SourceStaion != ModuleName.Robot)
- {
- pickRoutine1.Source = task.SourceStaion;
- pickRoutine1.Slot = task.SourceSlot;
- pickRoutine1.Blade = hand;
- steps.Enqueue(pickRoutine1);
- }
- if (task.DestStaion != ModuleName.Robot)
- {
- placeRoutine1.Station = task.DestStaion;
- placeRoutine1.Slot = task.DestSlot;
- placeRoutine1.Blade = hand;
- steps.Enqueue(placeRoutine1);
- }
- }
- private void DPDP(MoveTask task1, MoveTask task2)
- {
- if (task1.SourceStaion != ModuleName.Robot)
- {
- pickRoutine1.Source = task1.SourceStaion;
- pickRoutine1.Slot = task1.SourceSlot;
- pickRoutine1.Blade = Hand.Blade1;
- steps.Enqueue(pickRoutine1);
- }
- if (task2.SourceStaion != ModuleName.Robot)
- {
- pickRoutine2.Source = task2.SourceStaion;
- pickRoutine2.Slot = task2.SourceSlot;
- pickRoutine2.Blade = Hand.Blade2;
- steps.Enqueue(pickRoutine2);
- }
- if (task1.DestStaion != ModuleName.Robot)
- {
- placeRoutine1.Station = task1.DestStaion;
- placeRoutine1.Slot = task1.DestSlot;
- placeRoutine1.Blade = Hand.Blade1;
- steps.Enqueue(placeRoutine1);
- }
- if (task2.DestStaion != ModuleName.Robot)
- {
- placeRoutine2.Station = task2.DestStaion;
- placeRoutine2.Slot = task2.DestSlot;
- placeRoutine2.Blade = Hand.Blade2;
- steps.Enqueue(placeRoutine2);
- }
- }
- private void DPSP(MoveTask task1, MoveTask task2)
- {
- if (task1.SourceStaion != ModuleName.Robot)
- {
- pickRoutine1.Source = task1.SourceStaion;
- pickRoutine1.Slot = task1.SourceSlot;
- pickRoutine1.Blade = Hand.Blade1;
- steps.Enqueue(pickRoutine1);
- }
- if (task2.SourceStaion != ModuleName.Robot)
- {
- pickRoutine2.Source = task2.SourceStaion;
- pickRoutine2.Slot = task2.SourceSlot;
- pickRoutine2.Blade = Hand.Blade2;
- steps.Enqueue(pickRoutine2);
- }
- if (task1.DestStaion != ModuleName.Robot)
- {
- placeRoutine1.Station = task1.DestStaion;
- placeRoutine1.Slot = task1.DestSlot;
- placeRoutine1.Blade = Hand.Both;
- steps.Enqueue(placeRoutine1);
- }
- }
- private void SPDP(MoveTask task1, MoveTask task2)
- {
- if (task1.SourceStaion != ModuleName.Robot)
- {
- pickRoutine1.Source = task1.SourceStaion;
- pickRoutine1.Slot = task1.SourceSlot;
- pickRoutine1.Blade = Hand.Both;
- steps.Enqueue(pickRoutine1);
- }
- if (task1.DestStaion != ModuleName.Robot)
- {
- placeRoutine1.Station = task1.DestStaion;
- placeRoutine1.Slot = task1.DestSlot;
- placeRoutine1.Blade = Hand.Blade1;
- steps.Enqueue(placeRoutine1);
- }
- if (task2.DestStaion != ModuleName.Robot)
- {
- placeRoutine2.Station = task2.DestStaion;
- placeRoutine2.Slot = task2.DestSlot;
- placeRoutine2.Blade = Hand.Blade2;
- steps.Enqueue(placeRoutine2);
- }
- }
- private void SPSP(MoveTask task)
- {
- if (task.SourceStaion != ModuleName.Robot)
- {
- pickRoutine1.Source = task.SourceStaion;
- pickRoutine1.Slot = task.SourceSlot;
- pickRoutine1.Blade = Hand.Both;
- steps.Enqueue(pickRoutine1);
- }
- if (task.DestStaion != ModuleName.Robot)
- {
- placeRoutine1.Station = task.DestStaion;
- placeRoutine1.Slot = task.DestSlot;
- placeRoutine1.Blade = Hand.Both;
- steps.Enqueue(placeRoutine1);
- }
- }
- ///
- private bool CanUsedBlade2(MoveTask task1, MoveTask task2, MoveTask task3, MoveTask task4, out int handledTask)
- {
- handledTask = 0;
- if (task1 == null || task1.SourceSlot + 3 > 24)
- {
- return false;
- }
- if (task1 != null && task2 != null && task3 != null && task4 != null)
- {
- if ((task2.SourceSlot == task1.SourceSlot + 1) && (task2.DestSlot == task1.DestSlot + 1)
- && (task3.SourceSlot == task2.SourceSlot + 1) && (task3.DestSlot == task2.DestSlot + 1)
- && (task4.SourceSlot == task3.SourceSlot + 1) && (task4.DestSlot == task3.DestSlot + 1)
- )
- {
- if (CheckEmptySlot(task1))
- {
- handledTask = 4;
- return true;
- }
- }
- }
- return false;
- }
- private bool _CanUsedBlade2(MoveTask task1, out int handledTask)
- {
- handledTask = 0;
- bool[] bExists = new bool[] { true, false, false, false };
- if (task1.SourceSlot + 3 > 24)
- {
- return false;
- }
- if (CheckEmptySlot(task1, bExists))
- {
- handledTask = 1;
- return true;
- }
- return false;
- }
- private bool _CanUsedBlade2(MoveTask task1, MoveTask task2, out int handledTask)
- {
- handledTask = 0;
- bool[] bExists = new bool[] { true, false, false, false };
- int offset = task2.SourceSlot - task1.SourceSlot;
- if (offset > 3)
- {
- return _CanUsedBlade2(task1, out handledTask);
- }
- if (task2.SourceSlot - task1.SourceSlot == task2.DestSlot - task1.DestSlot)
- {
- bExists[task2.SourceSlot - task1.SourceSlot] = true;
- if (CheckEmptySlot(task1, bExists))
- {
- handledTask = 2;
- return true;
- }
- }
- return false;
- }
- private bool _CanUsedBlade2(MoveTask task1, MoveTask task2, MoveTask task3, out int handledTask)
- {
- handledTask = 0;
- bool[] bExists = new bool[] { true, false, false, false };
- int offset = task3.SourceSlot - task1.SourceSlot;
- if (offset > 3)
- {
- return _CanUsedBlade2(task1, task2, out handledTask);
- }
- if (task2.SourceSlot - task1.SourceSlot == task2.DestSlot - task1.DestSlot
- && task3.SourceSlot - task1.SourceSlot == task3.DestSlot - task1.DestSlot)
- {
- bExists[task2.SourceSlot - task1.SourceSlot] = true;
- bExists[task3.SourceSlot - task1.SourceSlot] = true;
- if (CheckEmptySlot(task1, bExists))
- {
- handledTask = 3;
- return true;
- }
- }
- return false;
- }
- private bool _CanUsedBlade2(MoveTask task1, MoveTask task2, MoveTask task3, MoveTask task4, out int handledTask)
- {
- handledTask = 0;
- bool[] bExists = new bool[] { true, false, false, false };
- int offset = task4.SourceSlot - task1.SourceSlot;
- if (offset > 3)
- {
- return _CanUsedBlade2(task1, task2, task3, out handledTask);
- }
- if (task2.SourceSlot - task1.SourceSlot == task2.DestSlot - task1.DestSlot
- && task3.SourceSlot - task1.SourceSlot == task3.DestSlot - task1.DestSlot
- && task4.SourceSlot - task1.SourceSlot == task4.DestSlot - task1.DestSlot)
- {
- bExists[task2.SourceSlot - task1.SourceSlot] = true;
- bExists[task3.SourceSlot - task1.SourceSlot] = true;
- bExists[task4.SourceSlot - task1.SourceSlot] = true;
- if (CheckEmptySlot(task1, bExists))
- {
- handledTask = 4;
- return true;
- }
- }
- return false;
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="objs"></param>
- /// <returns>如果任务全部完成,或者任务失败,返回true</returns>
- public bool Monitor(object[] objs)
- {
- Result ret = Result.RUN;
- if (tasks.Count == 0 && steps.Count == 0 && curStep == null)
- {
- return true; //completed
- }
- if (curStep != null)
- {
- ret = curStep.Monitor();
- }
- if (ret == Result.DONE || curStep == null)
- {
- if (_pause)
- {
- return false; //pause
- }
- if (steps.Count > 0)
- {
- curStep = steps.Dequeue();
- }
- else
- {
- newTask();
- if (steps.Count > 0)
- {
- curStep = steps.Dequeue();
- }
- else
- curStep = null;
- }
- if (curStep != null)
- {
- ret = curStep.Start();
- if (ret == Result.FAIL)
- {
- WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 0, EnumWaferProcessStatus.Failed);
- WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 1, EnumWaferProcessStatus.Failed);
- WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 2, EnumWaferProcessStatus.Failed);
- WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 3, EnumWaferProcessStatus.Failed);
- WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 4, EnumWaferProcessStatus.Failed);
- NotifyError("Robot", "Robot Error");
- return true; //transition
- }
- }
- else
- {
- return true; //transition
- }
- return false;
- }
- else if (ret == Result.FAIL)
- {
- WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 0, EnumWaferProcessStatus.Failed);
- WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 1, EnumWaferProcessStatus.Failed);
- WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 2, EnumWaferProcessStatus.Failed);
- WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 3, EnumWaferProcessStatus.Failed);
- WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 4, EnumWaferProcessStatus.Failed);
- NotifyError("Robot", "Robot Error");
- return true; //transition
- }
- return false;
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="objs"></param>
- /// <returns>如果任务全部完成,或者任务失败,返回true</returns>
- public Result Monitor()
- {
- Result ret = Result.RUN;
- if (tasks.Count == 0 && steps.Count == 0 && curStep == null)
- {
- return Result.DONE; //completed
- }
- if (curStep != null)
- {
- ret = curStep.Monitor();
- }
- if (ret == Result.DONE || curStep == null)
- {
- if (_pause)
- {
- return Result.RUN; //pause
- }
- if (steps.Count > 0)
- {
- curStep = steps.Dequeue();
- }
- else
- {
- newTask();
- if (steps.Count > 0)
- {
- curStep = steps.Dequeue();
- }
- else
- curStep = null;
- }
- if (curStep != null)
- {
- ret = curStep.Start();
- if (ret == Result.FAIL)
- {
- WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 0, EnumWaferProcessStatus.Failed);
- WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 1, EnumWaferProcessStatus.Failed);
- WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 2, EnumWaferProcessStatus.Failed);
- WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 3, EnumWaferProcessStatus.Failed);
- WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 4, EnumWaferProcessStatus.Failed);
- NotifyError("Robot", "Robot Error");
- return Result.FAIL; //transition
- }
- }
- else
- {
- return Result.DONE; //transition
- }
- return Result.RUN;
- }
- else if (ret == Result.FAIL)
- {
- WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 0, EnumWaferProcessStatus.Failed);
- WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 1, EnumWaferProcessStatus.Failed);
- WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 2, EnumWaferProcessStatus.Failed);
- WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 3, EnumWaferProcessStatus.Failed);
- WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 4, EnumWaferProcessStatus.Failed);
- NotifyError("Robot", "Robot Error");
- return Result.FAIL; //transition
- }
- return Result.RUN;
- }
- private bool CheckEmptySlot(MoveTask task)
- {
- for (int i = 0; i < 4; i++)
- {
- if (!WaferManager.Instance.CheckWafer(task.SourceStaion, task.SourceSlot + i, WaferStatus.Normal))
- return false;
- if (!WaferManager.Instance.CheckNoWafer(task.DestStaion, task.DestSlot + i))
- return false;
- }
- return true;
- }
- private bool CheckEmptySlot(MoveTask task, bool[] exist)
- {
- for (int i = 0; i < 4; i++)
- {
- if (!exist[i])
- {
- if (!WaferManager.Instance.CheckNoWafer(task.SourceStaion, task.SourceSlot + i))
- return false;
- }
- if (!WaferManager.Instance.CheckNoWafer(task.DestStaion, task.DestSlot + i))
- return false;
- }
- return true;
- }
- private void NotifyError(string module, string message)
- {
- if (OnMoveError != null)
- {
- OnMoveError(new MoveErrorArgument(module, message));
- }
- }
- }
- }
|