using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.Routine; using Aitex.Core.Util; using Aitex.Sorter.Common; using athosRT.Devices; using athosRT.FSM; using athosRT.Modules.EFEMs.Routine; using athosRT.tool; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase; using System; using System.Collections.Generic; using System.Linq; using System.Reflection.Emit; using System.Text; using System.Threading.Tasks; using IRoutine = athosRT.FSM.IRoutine; using EV = athosRT.tool.EV; using athosRT.Modules; namespace athosRT.Modules.EFEMs { public class StaticTransfer { private Queue steps = null;//定义routine队列 private IRoutine curStep = null;//当前routine private PickRoutine[] pickRoutine = null; private PlaceRoutine[] placeRoutine = null; private AlignRoutine[] alignRoutine = null;//对齐 private ModuleName _sourceStation; private ModuleName _targetStation; public string Name = "Transfer"; public int Notch1 { get; set; } public ModuleName SourceStation => _sourceStation; public ModuleName TargetStation => _targetStation; private readonly RobotBaseDevice robot; public StaticTransfer() { robot = DEVICE.GetDevice("Robot"); int IndexNum = 5; steps = new Queue(); pickRoutine = new PickRoutine[IndexNum]; for (int index = 0; index < IndexNum; ++index) { //LogObject.Info(Name, $"第{index}个 PickRoutine开始实例化"); pickRoutine[index] = new PickRoutine(ModuleName.System); } placeRoutine = new PlaceRoutine[IndexNum]; for (int index = 0; index < IndexNum; ++index) { //LogObject.Info(Name, $"第{index}个 PickRoutine开始实例化"); placeRoutine[index] = new PlaceRoutine(ModuleName.System); } alignRoutine = new AlignRoutine[2]; for (int index = 0; index < 2; ++index) { alignRoutine[index] = new AlignRoutine(); } } public bool Start(object[] objs) { LogObject.Info(Name, "transfer start"); MoveType moveType; Enum.TryParse(objs[0].ToString(),out moveType);//mov类型 LogObject.Info(Name, "transfer MoveType"); MoveOption moveOption; Enum.TryParse(objs[1].ToString(), out moveOption);//mov选项 LogObject.Info(Name, "transfer MoveOption"); //bool flag = (moveOption & MoveOption.Align) == MoveOption.Align || (moveOption & MoveOption.ReadID) == MoveOption.ReadID || (moveOption & MoveOption.ReadID2) == MoveOption.ReadID2; bool flag = false; Hand hand; Enum.TryParse(objs[2].ToString(), out hand);//手臂 LogObject.Info(Name, "transfer Hand"); ModuleName moduleName1 = ModuleHelper.Converter(objs[3].ToString()); LogObject.Info(Name, "transfer Source"); _sourceStation = moduleName1; int num1 = Convert.ToInt32(objs[4]); LogObject.Info(Name, "transfer source slot"); ModuleName moduleName2= ModuleHelper.Converter(objs[5].ToString()); LogObject.Info(Name, "transfer destination"); _targetStation = moduleName2; int num2 = Convert.ToInt32(objs[6]); LogObject.Info(Name, "transfer destiation slot"); steps.Clear(); switch (moveType) { case MoveType.Move: //当目标不是robot的时候(也是就是ll lp等)装入pick队列 if (moduleName1 != ModuleName.Robot) { pickRoutine[0].Source = moduleName1; pickRoutine[0].Slot = num1; pickRoutine[0].Blade = hand; steps.Enqueue(pickRoutine[0]); } //robot 上wafer 移动到下个目标 else { placeRoutine[1].Station = moduleName2; placeRoutine[1].Slot = num2; placeRoutine[1].Blade = hand; steps.Enqueue(placeRoutine[1]); goto case MoveType.Swap; } //当目标是Aligner或ReadID1、2时 if (flag) { //place的初始点是aligner slot槽是0 blade是hand placeRoutine[0].Station = ModuleName.Aligner; placeRoutine[0].Slot = 0; placeRoutine[0].Blade = hand; steps.Enqueue(placeRoutine[0]); //align的选项是moveOption 缺口是motch alignRoutine[0].Option = moveOption; alignRoutine[0].Notch = Notch1; steps.Enqueue(alignRoutine[0]); switch (moduleName2) { //如果目标2是aligner case ModuleName.Aligner: goto label_32; //是robot 从aligner上获取 case ModuleName.Robot: pickRoutine[1].Source = ModuleName.Aligner; pickRoutine[1].Slot = 0; pickRoutine[1].Blade = (Hand)num2; steps.Enqueue(pickRoutine[1]); break; //默认的 default: pickRoutine[1].Source = ModuleName.Aligner; pickRoutine[1].Slot = 0; pickRoutine[1].Blade = hand; steps.Enqueue(pickRoutine[1]); placeRoutine[1].Station = moduleName2; placeRoutine[1].Slot = num2; placeRoutine[1].Blade = hand; steps.Enqueue(placeRoutine[1]); break; } goto case MoveType.Swap; } else { //如果modulename2不为robot if (moduleName2 != ModuleName.Robot) { //place1的目标是module placeRoutine[1].Station = moduleName2; placeRoutine[1].Slot = num2; placeRoutine[1].Blade = hand; steps.Enqueue(placeRoutine[1]); } goto case MoveType.Swap; } case MoveType.Swap: label_32: //没有入列 count为空 if (steps.Count == 0) { LogObject.Error(Name, "没有任务进入队列"); return false; } curStep = steps.Dequeue(); //开启当前步骤 if(curStep.Start(objs) != RState.Failed) { LogObject.Info(Name, "开始当前步骤"); return true; } LogObject.Error(Name,"Failed start transfer"); return false; default: ModuleName moduleName3 = (ModuleName)objs[7]; int num3 = (int)objs[8]; ModuleName moduleName4 = (ModuleName)objs[9]; int num4 = (int)objs[10]; //MoveType的数据类型 SPSP SPDP if (moveType == MoveType.SPSP || moveType == MoveType.SPDP) { //如果 起始点、终止点都不是robot if (moduleName1 != ModuleName.Robot && moduleName3 != ModuleName.Robot) { //从pick捡起modulename1 pickRoutine[0].Source = moduleName1; pickRoutine[0].Slot = num1; pickRoutine[0].Blade = Hand.Blade1; steps.Enqueue(pickRoutine[0]); //从pick捡起modulename3 pickRoutine[1].Source = moduleName3; pickRoutine[1].Slot = num3; pickRoutine[1].Blade = Hand.Blade2; steps.Enqueue(pickRoutine[1]); } else if (moduleName1 == ModuleName.Robot) { //如果是在robot上 源为m3 pickRoutine[1].Source = moduleName3; pickRoutine[1].Slot = num3; pickRoutine[1].Blade = num1 != 0 ? Hand.Blade1 : Hand.Blade2; steps.Enqueue(pickRoutine[1]); } else { //如果不是在robot上 则要先从1上取出来 pickRoutine[0].Source = moduleName1; pickRoutine[0].Slot = num1; pickRoutine[0].Blade = num3 != 0 ? Hand.Blade1 : Hand.Blade2; steps.Enqueue(pickRoutine[0]); } } else if (moduleName1 != ModuleName.Robot) { //双臂举起 pickRoutine[0].Source = moduleName1; pickRoutine[0].Slot = num1; pickRoutine[0].Blade = Hand.Both; steps.Enqueue(pickRoutine[0]); } if (moveType == MoveType.SPSP || moveType == MoveType.DPSP) { if (moduleName2 != ModuleName.Robot && moduleName2 != ModuleName.Robot) { placeRoutine[1].Station = moduleName2; placeRoutine[1].Slot = num2; placeRoutine[1].Blade = Hand.Blade1; steps.Enqueue(placeRoutine[1]); placeRoutine[2].Station = moduleName4; placeRoutine[2].Slot = num4; placeRoutine[2].Blade = Hand.Blade2; steps.Enqueue(placeRoutine[2]); } else if (moduleName2 == ModuleName.Robot) { placeRoutine[2].Station = moduleName4; placeRoutine[2].Slot = num4; placeRoutine[2].Blade = num3 != 0 ? Hand.Blade1 : Hand.Blade2; steps.Enqueue(placeRoutine[2]); } else { placeRoutine[1].Station = moduleName2; placeRoutine[1].Slot = num2; placeRoutine[1].Blade = num1 != 0 ? Hand.Blade1 : Hand.Blade2; steps.Enqueue(placeRoutine[1]); } } else if (moduleName2 != ModuleName.Robot) { placeRoutine[1].Station = moduleName2; placeRoutine[1].Slot = num2; placeRoutine[1].Blade = Hand.Both; steps.Enqueue(placeRoutine[1]); } goto case MoveType.Swap; } } /// /// monitor只管做队列的头部任务直到结束为止 /// /// /// 当前任务的执行结果 public bool Monitor(object[] objs) { RState result = RState.Failed; if(curStep!=null) result = curStep.Monitor(); switch(result) { case RState.End: curStep = steps.Count <= 0 ? null : steps.Dequeue();//出栈 //没有队列任务了 if (curStep == null) { LogObject.Info(Name, "所有Routine已经执行完毕"); return true; } //下一步任务start失败 if (curStep.Start() != RState.Failed) { //LogObject.Error(Name, "下一个Routine无法开始 请检查任务队列"); return false; } //不明确的发错误 可能是想把不包括的情况都认定为错误 PostMsg(RouteManager1.MSG.ERROR); return true; case RState.Failed: LogObject.Error(Name, "当前Routine执行失败 置错误"); PostMsg(RouteManager1.MSG.ERROR); return true; default: return false; } } public bool Return(object[] objs) { steps.Clear(); ModuleName lpModule = ModuleName.LP1; int slot = 0; if (Singleton.Instance.CheckHasWafer(ModuleName.Robot, 0)) { if (!FindEmptySlot(ref lpModule, ref slot)) { steps.Clear(); return false; } placeRoutine[0].Station = lpModule; placeRoutine[0].Slot = slot; placeRoutine[0].Blade = Hand.Blade1; steps.Enqueue(placeRoutine[0]); } if (Singleton.Instance.CheckHasWafer(ModuleName.Robot, 1) || Singleton.Instance.CheckHasWafer(ModuleName.Robot, 2) || Singleton.Instance.CheckHasWafer(ModuleName.Robot, 3)) { ++slot; if (!FindEmptySlotForMultiBlade(ref lpModule, ref slot)) { steps.Clear(); return false; } placeRoutine[1].Station = lpModule; placeRoutine[1].Slot = slot; placeRoutine[1].Blade = Hand.Blade2; steps.Enqueue(placeRoutine[1]); } if (Singleton.Instance.CheckHasWafer(ModuleName.Aligner, 0)) { ++slot; if (!FindEmptySlot(ref lpModule, ref slot)) { steps.Clear(); return false; } pickRoutine[0].Source = ModuleName.Aligner; pickRoutine[0].Slot = 0; pickRoutine[0].Blade = Hand.Blade1; steps.Enqueue(pickRoutine[0]); placeRoutine[2].Station = lpModule; placeRoutine[2].Slot = slot; placeRoutine[2].Blade = Hand.Blade1; steps.Enqueue(placeRoutine[2]); } if (steps.Count == 0) return false; curStep = steps.Dequeue(); if (curStep.Start(objs) != RState.Failed) return true; EV.PostWarningLog(ModuleName.System.ToString(), "Failed start return"); return false; } private bool FindEmptySlot(ref ModuleName lpModule, ref int slot) { LoadPortBaseDevice device = DEVICE.GetDevice(lpModule.ToString()); string reason; if (device.IsEnableTransferWafer(out reason)) { for (int slot1 = slot; slot1 < 25; ++slot1) { if (Singleton.Instance.CheckNoWafer(device.Name, slot1)) { slot = slot1; return true; } } } foreach (LoadPortBaseDevice allLoadPort in Singleton.Instance.GetAllLoadPorts()) { if (!(allLoadPort.Name == lpModule.ToString()) && allLoadPort.IsEnableTransferWafer(out reason)) { for (int slot2 = 0; slot2 < 25; ++slot2) { if (Singleton.Instance.CheckNoWafer(allLoadPort.Name, slot2)) { lpModule = (ModuleName)Enum.Parse(typeof(ModuleName), allLoadPort.Name); slot = slot2; return true; } } } } return false; } private bool FindEmptySlotForMultiBlade(ref ModuleName lpModule, ref int slot) { LoadPortBaseDevice device = DEVICE.GetDevice(lpModule.ToString()); string reason; if (device.IsEnableTransferWafer(out reason)) { for (int slot1 = slot; slot1 < 23; ++slot1) { if (Singleton.Instance.CheckNoWafer(device.Name, slot1) && Singleton.Instance.CheckNoWafer(device.Name, slot1 + 1) && Singleton.Instance.CheckNoWafer(device.Name, slot1 + 2)) { slot = slot1; return true; } } } foreach (LoadPortBaseDevice allLoadPort in Singleton.Instance.GetAllLoadPorts()) { if (!(allLoadPort.Name == lpModule.ToString()) && allLoadPort.IsEnableTransferWafer(out reason)) { for (int slot2 = 0; slot2 < 23; ++slot2) { if (Singleton.Instance.CheckNoWafer(allLoadPort.Name, slot2) && Singleton.Instance.CheckNoWafer(allLoadPort.Name, slot2 + 1) && Singleton.Instance.CheckNoWafer(allLoadPort.Name, slot2 + 2)) { lpModule = (ModuleName)Enum.Parse(typeof(ModuleName), allLoadPort.Name); slot = slot2; return true; } } } } return false; } public void Clear() { steps.Clear(); curStep = null; } private void PostMsg(RouteManager1.MSG msg, params object[] objs) => Singleton.Instance.PostMsg(msg, objs); } }