using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using Aitex.Core.Common; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Log; using Aitex.Sorter.Common; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts; namespace Aitex.Sorter.RT.Module.Recipe { /// /// 排序 /// class RecipeParserOrder : IRecipeParser { public SorterRecipeXml XmlRecipe { get; set; } public bool Init(SorterRecipeXml xmlRecipe, out string reason) { reason = string.Empty; if (xmlRecipe.RecipeType != SorterRecipeType.Order) { LOG.Write("xml recipe type not valid, " + xmlRecipe.RecipeType); reason = "Recipe xml file not valid"; return false; } XmlRecipe = xmlRecipe; return true; } public List Parse(out string reason) { List result = new List(); reason = string.Empty; string paramName = string.Empty; LoadPort lp = DEVICE.GetDevice(XmlRecipe.Source[0].ToString()); if (!lp.IsEnableTransferWafer(out reason)) { reason = "Source is not valid for transfer."; return result; } switch (XmlRecipe.Source[0]) { case ModuleName.LP1: paramName = ParamName.WaferInfoFoupA; break; case ModuleName.LP2: paramName = ParamName.WaferInfoFoupB; break; case ModuleName.LP3: paramName = ParamName.WaferInfoFoupC; break; case ModuleName.LP4: paramName = ParamName.WaferInfoFoupD; break; case ModuleName.LP5: paramName = ParamName.WaferInfoFoupE; break; case ModuleName.LP6: paramName = ParamName.WaferInfoFoupF; break; case ModuleName.LP7: paramName = ParamName.WaferInfoFoupG; break; case ModuleName.LP8: paramName = ParamName.WaferInfoFoupH; break; case ModuleName.LP9: paramName = ParamName.WaferInfoFoupI; break; case ModuleName.LP10: paramName = ParamName.WaferInfoFoupJ; break; default: reason = string.Format("recipe source {0} not valid", XmlRecipe.Source); return result; } //WaferInfo[] foupInfos = (WaferInfo[])DATA.Poll(ChamberSetString.System, paramName); WaferInfo[] foupInfos = WaferManager.Instance.GetWafers(XmlRecipe.Source[0]); //Array.Reverse(foupInfos); Dictionary waferIdSlot = new Dictionary(); Dictionary waferIdWaferInfo = new Dictionary(); List waferInfos = new List(); for (int i = 0; i < foupInfos.Length; i++) { if (foupInfos[i].IsEmpty) continue; waferInfos.Add(foupInfos[i]); waferIdSlot[foupInfos[i].WaferID] = i; } //string[] ids = waferIdSlot.Keys.ToArray(); int[] slots = waferIdSlot.Values.ToArray(); //Array.Sort(ids); //Array.Sort(slots); if (XmlRecipe.OrderBy == OrderByMode.LaserMarker) { waferInfos.Sort((x, y) => string.Compare(x.LaserMarker, y.LaserMarker)); } else if (XmlRecipe.OrderBy == OrderByMode.T7Code) { waferInfos.Sort((x, y) => string.Compare(x.T7Code, y.T7Code)); } string[] sortedWaferId = new string[waferInfos.Count]; //int[] sortedSlot = new int[waferInfos.Count]; for (int i = 0; i < waferInfos.Count; i++) { sortedWaferId[i] = waferInfos[i].WaferID; } switch (XmlRecipe.PlaceModeOrder) { case SorterRecipePlaceModeOrder.Forward: Forward(sortedWaferId, slots, waferIdSlot, foupInfos, ref result, out reason); break; case SorterRecipePlaceModeOrder.ForwardPack: ForwardPack(sortedWaferId, slots, waferIdSlot, foupInfos, ref result, out reason); break; case SorterRecipePlaceModeOrder.Reverse: Reverse(sortedWaferId, slots, waferIdSlot, foupInfos, ref result, out reason); break; case SorterRecipePlaceModeOrder.ReversePack: ReversePack(sortedWaferId, slots, waferIdSlot, foupInfos, ref result, out reason); break; default: reason = string.Format("recipe PlaceModeOrder {0} not valid", XmlRecipe.PlaceModeOrder); return result; } //if (result.Count == 0) // reason = "Recipe has no vaild transfer task."; return result; } /// /// 最小的值放在下面,依次放在原来有wafer的地方 /// /// /// /// bool Forward(string[] sortedWaferId, int[] sortedSlot, Dictionary waferIdSlot, WaferInfo[] foupWafers, ref List lst, out string reason) { reason = string.Empty; for (int i = 0; i < sortedWaferId.Length && i < sortedSlot.Length; i++) { lst.Add(new TransferInfo() { Angle = XmlRecipe.AlignAngle, //Option = (XmlRecipe.IsAlign ? MoveOption.Align : MoveOption.None) // | (XmlRecipe.IsReadLaserMarker ? MoveOption.ReadID : MoveOption.None) // | (XmlRecipe.IsReadT7Code ? MoveOption.ReadID2 : MoveOption.None), Slot = sortedSlot[i], Source = XmlRecipe.Source[0], Station = XmlRecipe.Source[0], WaferID = sortedWaferId[i], }); } return true; } /// /// 最小的值放在下面,集中从下往上放 /// /// /// /// bool ForwardPack(string[] sortedWaferId, int[] sortedSlot, Dictionary waferIdSlot, WaferInfo[] foupWafers, ref List lst, out string reason) { reason = string.Empty; int to = 0; for (int i = 0; i < sortedWaferId.Length; i++) { lst.Add(new TransferInfo() { Angle = XmlRecipe.AlignAngle, Option = (XmlRecipe.IsAlign ? MoveOption.Align : MoveOption.None) | (XmlRecipe.IsReadLaserMarker ? MoveOption.ReadID : MoveOption.None) | (XmlRecipe.IsReadT7Code ? MoveOption.ReadID2 : MoveOption.None) | (XmlRecipe.WaferReaderIndex == 1 ? MoveOption.Reader1 : MoveOption.None) | (XmlRecipe.WaferReaderIndex == 2 ? MoveOption.Reader2 : MoveOption.None), Slot = to++, Source = XmlRecipe.Source[0], Station = XmlRecipe.Source[0], WaferID = sortedWaferId[i], }); } return true; } /// /// 最小的值放在上面,依次放在原来有wafer的地方 /// /// /// /// bool Reverse(string[] sortedWaferId, int[] sortedSlot, Dictionary waferIdSlot, WaferInfo[] foupWafers, ref List lst, out string reason) { reason = string.Empty; int to = sortedSlot.Length - 1; for (int i = sortedWaferId.Length - 1; i >= 0; i--) { lst.Add(new TransferInfo() { Angle = XmlRecipe.AlignAngle, Option = (XmlRecipe.IsAlign ? MoveOption.Align : MoveOption.None) | (XmlRecipe.IsReadLaserMarker ? MoveOption.ReadID : MoveOption.None) | (XmlRecipe.IsReadT7Code ? MoveOption.ReadID2 : MoveOption.None) | (XmlRecipe.WaferReaderIndex == 1 ? MoveOption.Reader1 : MoveOption.None) | (XmlRecipe.WaferReaderIndex == 2 ? MoveOption.Reader2 : MoveOption.None), Slot = sortedSlot[to--], Source = XmlRecipe.Source[0], Station = XmlRecipe.Source[0], WaferID = sortedWaferId[i], }); } return true; } /// /// 最小的值放在上面,从上往下顺序放 /// /// /// /// bool ReversePack(string[] sortedWaferId, int[] sortedSlot, Dictionary waferIdSlot, WaferInfo[] foupWafers, ref List lst, out string reason) { reason = string.Empty; int to = 0; for (int i = sortedWaferId.Length - 1; i >= 0; i--) { lst.Add(new TransferInfo() { Angle = XmlRecipe.AlignAngle, Option = (XmlRecipe.IsAlign ? MoveOption.Align : MoveOption.None) | (XmlRecipe.IsReadLaserMarker ? MoveOption.ReadID : MoveOption.None) | (XmlRecipe.IsReadT7Code ? MoveOption.ReadID2 : MoveOption.None), Slot = to++, Source = XmlRecipe.Source[0], Station = XmlRecipe.Source[0], WaferID = sortedWaferId[i], }); } return true; } } }