using Aitex.Common.Util; 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 FurnaceRT.Devices; using FurnaceRT.Equipments.Boats; using FurnaceRT.Equipments.CarrierRobots; using FurnaceRT.Equipments.FIMSs; using FurnaceRT.Equipments.PMs; using FurnaceRT.Equipments.Schedulers; using FurnaceRT.Equipments.Systems; using FurnaceRT.Equipments.WaferRobots; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Schedulers; using MECF.Framework.Common.SubstrateTrackings; using System; using System.Collections.Generic; namespace FurnaceRT.Equipments.Jobs { public class ReturnAllWafer : SchedulerModuleFactory, IRoutine { private const string LogSource = "System"; private Dictionary _boatSlotWafers = new Dictionary(); private List _sideDummySlots = new List(); private List _extraDummySlots = new List(); private List _productSlots = new List(); private List _monitor1Slots = new List(); private List _monitor2Slots = new List(); private PMModule _pmModule; public ReturnAllWafer() { InitModule(); } public Result Start(params object[] objs) { Clear(); //if (!(Singleton.Instance.Modules[ModuleName.CarrierRobot] as CarrierRobotModule).CheckCassetteRobotRetractPosition()) //{ // Singleton.Instance.ReturnAllWaferJobStartFailedWarning.Description = "Cassette Robot not at home position"; // Singleton.Instance.ReturnAllWaferJobStartFailedWarning.Set(); // return Result.FAIL; //} //if (!(Singleton.Instance.Modules[ModuleName.WaferRobot] as WaferRobotModule).WaferRobotDevice.IsRetract) //{ // Singleton.Instance.ReturnAllWaferJobStartFailedWarning.Description = "Wafer Robot not at home position"; // Singleton.Instance.ReturnAllWaferJobStartFailedWarning.Set(); // return Result.FAIL; //} if (!(Singleton.Instance.Modules[ModuleName.Boat] as BoatModule).IsBoatElevatorAtHomePosition) { Singleton.Instance.ReturnAllWaferJobStartFailedWarning.Set("Boat Z Axis not at home position"); return Result.FAIL; } if (!(Singleton.Instance.Modules[ModuleName.Boat] as BoatModule).IsBoatRotationAtHomePosition) { Singleton.Instance.ReturnAllWaferJobStartFailedWarning.Set("Boat R Axis not at home position"); return Result.FAIL; } var waferRobotWafers = WaferManager.Instance.GetWafers(_waferRobot.Module); foreach (var wafer in waferRobotWafers) { if (wafer == null || wafer.IsEmpty) continue; //wafer robot上的wafer必须全部能够return if (!CheckWaferCouldBeReturn(wafer)) { Singleton.Instance.ReturnAllWaferJobStartFailedWarning.Set($"Wafer {(ModuleName)wafer.Station}.{wafer.Slot + 1} can not return, origin {(ModuleName)wafer.OriginStation}.{wafer.OriginSlot + 1} is not available"); return Result.FAIL; } } var pmWafers = WaferManager.Instance.GetWafers(_pm1.Module); foreach (var wafer in pmWafers) { if (wafer == null || wafer.IsEmpty) continue; //boat上的wafer可以有不能return if (!CheckWaferCouldBeReturn(wafer)) { Singleton.Instance.ReturnAllWaferJobStartFailedWarning.Set($"Wafer {(ModuleName)wafer.Station}.{wafer.Slot + 1} can not return, origin {(ModuleName)wafer.OriginStation}.{wafer.OriginSlot + 1} is not available"); } } Init(); return Result.RUN; } public void ResetTask(ModuleName module) { if (module == _waferRobot.Module) _waferRobot.ResetTask(); if (module == _carrierRobot.Module) _carrierRobot.ResetTask(); } private void Clear() { _carrierRobot.ResetTask(); _waferRobot.ResetTask(); } private void Init() { _boatSlotWafers.Clear(); _sideDummySlots.Clear(); _extraDummySlots.Clear(); _productSlots.Clear(); _monitor1Slots.Clear(); _monitor2Slots.Clear(); //M-->P-->ED-->SD for (int i = 0; i < SC.GetValue($"Boat.SlotCount"); i++) { if (!WaferManager.Instance.CheckHasWafer(_pm1.Module, i)) continue; var wafer = WaferManager.Instance.GetWafer(_pm1.Module, i); if (wafer == null || wafer.IsEmpty) continue; if (!CheckWaferCouldBeReturn(wafer)) continue; switch (wafer.WaferType) { case WaferType.SD: _sideDummySlots.Add(i); break; case WaferType.ED: _extraDummySlots.Add(i); break; case WaferType.P: _productSlots.Add(i); break; case WaferType.M1: _monitor1Slots.Add(i); break; case WaferType.M2: _monitor2Slots.Add(i); break; } } if (SC.GetStringValue("System.ChargingOrderToBoat") == "FromTopToBottom") { //升序,return wafer和charge顺序相反 } else { _productSlots.Sort((x, y) => -x.CompareTo(y));//降序 _monitor1Slots.Sort((x, y) => -x.CompareTo(y));//降序 _monitor2Slots.Sort((x, y) => -x.CompareTo(y));//降序 _extraDummySlots.Sort((x, y) => -x.CompareTo(y));//降序 _sideDummySlots.Sort((x, y) => -x.CompareTo(y));//降序 } } public Result Monitor() { MonitorCassetteRobotTask(); MonitorWaferRobotTask(); MonitorFIMSTask(); if (MonitorTaskDone()) { return Result.DONE; } return Result.RUN; } public bool MonitorTaskDone() { if (!_carrierRobot.IsAvailable) return false; if (!_waferRobot.IsAvailable) return false; if (CarrierManager.Instance.CheckHasCarrier(_carrierRobot.Module, 0)) { return false; } var waferRobotWafers = WaferManager.Instance.GetWafers(_waferRobot.Module); foreach (var wafer in waferRobotWafers) { if (!wafer.IsEmpty) return false; } var pmWafers = WaferManager.Instance.GetWafers(_pm1.Module); foreach (var wafer in pmWafers) { if (!wafer.IsEmpty) { if (CheckWaferCouldBeReturn(wafer)) { return false; } } } foreach (var st in _lstFIMSs) { if (!st.IsOnline) continue; if (CarrierManager.Instance.CheckHasCarrier(st.Module, 0)) { return false; } } return true; } private bool CheckWaferCouldBeReturn(WaferInfo wafer) { if (wafer != null && !wafer.IsEmpty) { return ModuleHelper.IsStocker((ModuleName)wafer.OriginStation) && SC.ContainsItem($"System.SetUp.Is{(ModuleName)wafer.OriginStation}Installed") && SC.GetValue($"System.SetUp.Is{(ModuleName)wafer.OriginStation}Installed") && WaferManager.Instance.CheckNoWafer((ModuleName)wafer.OriginStation, wafer.OriginSlot); } return false; } private void MonitorFIMSTask() { //load bool haveLoadingFims = false; foreach (var st in _lstFIMSs) { if ((Singleton.Instance.Modules[st.Module] as FIMSModule).IsLoading) { haveLoadingFims = true; break; } } //load foreach (var st in _lstFIMSs) { if (!st.IsAvailable || haveLoadingFims || !CarrierManager.Instance.CheckHasCarrier(st.Module, 0)) continue; var fimsDevice = DEVICE.GetDevice($"PM1.{st.Module}"); var carrier = CarrierManager.Instance.GetCarrier(st.Module, 0); if (carrier != null) { if (!CheckCarrierCanPickFromFIMSInDischarge(carrier.InternalModuleName) && !fimsDevice.IsLoadCompleted && st.Load()) { return; } } } //unload //先判断满片的情况,满片的先unload foreach (var st in _lstFIMSs) { if (!st.IsAvailable || !CarrierManager.Instance.CheckHasCarrier(st.Module, 0)) continue; var fimsDevice = DEVICE.GetDevice($"PM1.{st.Module}"); var carrier = CarrierManager.Instance.GetCarrier(st.Module, 0); if (carrier != null) { if (!CheckCarrierHasEmptySlot(st.Module) && !fimsDevice.IsUnloadCompleted && st.Unload()) { return; } } } if (!_waferRobot.IsAvailable) return; foreach (var st in _lstFIMSs) { if (!st.IsAvailable || !CarrierManager.Instance.CheckHasCarrier(st.Module, 0)) continue; var fimsDevice = DEVICE.GetDevice($"PM1.{st.Module}"); var carrier = CarrierManager.Instance.GetCarrier(st.Module, 0); if (carrier != null) { if (CheckCarrierCanPickFromFIMSInDischarge(carrier.InternalModuleName) && !fimsDevice.IsUnloadCompleted && st.Unload()) { return; } } } } private void MonitorCassetteRobotTask() { if (!_carrierRobot.IsAvailable) return; //cassette robot is idle, release all the target foreach (var stocker in _lstTotlaStockers) { if (stocker.IsWaitTransfer(ModuleName.CarrierRobot)) { stocker.StopWaitTransfer(ModuleName.CarrierRobot); } } foreach (var stage in _lstFIMSs) { if (stage.IsWaitTransfer(ModuleName.CarrierRobot)) { stage.StopWaitTransfer(ModuleName.CarrierRobot); } } DischargingOrderBySort(SC.GetStringValue("System.ChargingOrderBySort")); if (!_carrierRobot.IsAvailable) return; MonitorCassetteRobotStageTask(); } private void DischargingOrderBySort(string order) { switch (order) { case "ED,P,M": MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.M1, _monitor1Slots); MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.M2, _monitor2Slots); if (!_carrierRobot.IsAvailable) return; MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.P, _productSlots); if (!_carrierRobot.IsAvailable) return; MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.ED, _extraDummySlots); break; case "ED,M,P": MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.P, _productSlots); if (!_carrierRobot.IsAvailable) return; MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.M1, _monitor1Slots); MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.M2, _monitor2Slots); if (!_carrierRobot.IsAvailable) return; MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.ED, _extraDummySlots); break; case "P,ED,M": MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.M1, _monitor1Slots); MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.M2, _monitor2Slots); if (!_carrierRobot.IsAvailable) return; MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.ED, _extraDummySlots); if (!_carrierRobot.IsAvailable) return; MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.P, _productSlots); break; case "P,M,ED": MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.ED, _extraDummySlots); if (!_carrierRobot.IsAvailable) return; MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.M1, _monitor1Slots); MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.M2, _monitor2Slots); if (!_carrierRobot.IsAvailable) return; MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.P, _productSlots); break; case "M,P,ED": MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.ED, _extraDummySlots); if (!_carrierRobot.IsAvailable) return; MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.P, _productSlots); if (!_carrierRobot.IsAvailable) return; MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.M1, _monitor1Slots); MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.M2, _monitor2Slots); break; case "M,ED,P": MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.P, _productSlots); if (!_carrierRobot.IsAvailable) return; MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.ED, _extraDummySlots); if (!_carrierRobot.IsAvailable) return; MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.M1, _monitor1Slots); MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.M2, _monitor2Slots); break; default: MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.M1, _monitor1Slots); MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.M2, _monitor2Slots); if (!_carrierRobot.IsAvailable) return; MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.P, _productSlots); if (!_carrierRobot.IsAvailable) return; MonitorCassetteRobotStockerTaskInDischarge(_lstTotlaStockers, WaferType.ED, _extraDummySlots); break; } if (!_carrierRobot.IsAvailable) return; MonitorCassetteRobotStockerTaskInDischarge(_lstSideDummyStocker, WaferType.SD, _sideDummySlots); } private void MonitorCassetteRobotStockerTaskInDischarge(List targetStockers, WaferType targetWaferType, List waferSlots) { if (!_carrierRobot.IsAvailable) return; var targetCarrierType = (CarrierType)(Enum.Parse(typeof(CarrierType), targetWaferType.ToString())); //pick if (CarrierManager.Instance.CheckNoCarrier(ModuleName.CarrierRobot, 0) && waferSlots.Count > 0) { bool needPickSdCassette = false; int sdWaferCount = GetWaferCountRelatedToWaferRobot(targetWaferType, true); needPickSdCassette = sdWaferCount > 0; var sdStockerModule = GetModuleNameForNextWafer(targetWaferType); if (needPickSdCassette && sdStockerModule != ModuleName.System) { SchedulerStocker sdStocker = null; foreach (var sd in targetStockers) { if (!CarrierManager.Instance.CheckHasCarrier(sd.Module, 0) || CarrierManager.Instance.GetCarrier(sd.Module, 0).CarrierType != targetCarrierType) continue; if (sd.Module == sdStockerModule && CheckCarrierHasEmptySlot(sd.Module)) { sdStocker = sd; break; } } SchedulerFIMS fims = null; foreach (var st in _lstFIMSs) { if (!st.IsAvailable) continue; if (CarrierManager.Instance.CheckNoCarrier(st.Module, 0)) { fims = st; break; } } if (sdStocker != null && fims != null) { if (_carrierRobot.Pick(sdStocker.Module, 0, Hand.Blade1)) { sdStocker.WaitTransfer(ModuleName.CarrierRobot); return; } } } } if (!_carrierRobot.IsAvailable) return; if (!_waferRobot.IsAvailable) return; //place var carrier = CarrierManager.Instance.GetCarrier(ModuleName.CarrierRobot, 0); if (carrier != null && !carrier.IsEmpty && carrier.CarrierType == targetCarrierType) { if (!CheckModuleHasWaferInWaferRobotAndPM(carrier.InternalModuleName) || !CheckCarrierHasEmptySlot(ModuleName.CarrierRobot)) { SchedulerStocker sdStocker = null; foreach (var sd in targetStockers) { if (CarrierManager.Instance.CheckNoCarrier(sd.Module, 0) && sd.Module == carrier.InternalModuleName) { sdStocker = sd; break; } } if (sdStocker != null) { if (_carrierRobot.Place(sdStocker.Module, 0, Hand.Blade1)) { sdStocker.WaitTransfer(ModuleName.CarrierRobot); return; } } } } } private ModuleName GetModuleNameForNextWafer(WaferType waferType) { ModuleName module = ModuleName.System; bool hasEmptyFims = false; foreach (var fims in _lstFIMSs) { if (CarrierManager.Instance.CheckNoCarrier(fims.Module, 0)) { hasEmptyFims = true; break; } } if (!hasEmptyFims) return module; if (WaferManager.Instance.CheckHasWafer(ModuleName.WaferRobot, 0)) { module = (ModuleName)WaferManager.Instance.GetWafer(ModuleName.WaferRobot, 0).OriginStation; } else if (WaferManager.Instance.CheckHasWafer(ModuleName.WaferRobot, 1)) { module = (ModuleName)WaferManager.Instance.GetWafer(ModuleName.WaferRobot, 1).OriginStation; } else if (WaferManager.Instance.CheckHasWafer(ModuleName.WaferRobot, 2)) { module = (ModuleName)WaferManager.Instance.GetWafer(ModuleName.WaferRobot, 2).OriginStation; } else if (WaferManager.Instance.CheckHasWafer(ModuleName.WaferRobot, 3)) { module = (ModuleName)WaferManager.Instance.GetWafer(ModuleName.WaferRobot, 3).OriginStation; } else if (WaferManager.Instance.CheckHasWafer(ModuleName.WaferRobot, 4)) { module = (ModuleName)WaferManager.Instance.GetWafer(ModuleName.WaferRobot, 4).OriginStation; } else { if (SC.GetStringValue("System.ChargingOrderToBoat") == "FromTopToBottom") { for (int i = 0; i < SC.GetValue($"Boat.SlotCount"); i++) { if (!WaferManager.Instance.CheckHasWafer(_pm1.Module, i)) continue; var wafer = WaferManager.Instance.GetWafer(_pm1.Module, i); if (wafer == null || wafer.IsEmpty) continue; if (wafer.WaferType == waferType) { module = (ModuleName)WaferManager.Instance.GetWafer(_pm1.Module, i).OriginStation; break; } } } else { for (int i = SC.GetValue($"Boat.SlotCount") - 1; i >= 0; i--) { if (!WaferManager.Instance.CheckHasWafer(_pm1.Module, i)) continue; var wafer = WaferManager.Instance.GetWafer(_pm1.Module, i); if (wafer == null || wafer.IsEmpty) continue; if (wafer.WaferType == waferType) { module = (ModuleName)WaferManager.Instance.GetWafer(_pm1.Module, i).OriginStation; break; } } } } //下一片要放回的cassette已经在fims上 bool isCarrierAlreadyPicked = false; foreach (var fims in _lstFIMSs) { if (!CarrierManager.Instance.CheckHasCarrier(fims.Module, 0)) continue; var carrier = CarrierManager.Instance.GetCarrier(fims.Module); if (carrier != null && carrier.InternalModuleName == module) { isCarrierAlreadyPicked = true; } } if (CarrierManager.Instance.CheckHasCarrier(ModuleName.CarrierRobot, 0)) { var carrier = CarrierManager.Instance.GetCarrier(ModuleName.CarrierRobot); if (carrier != null && carrier.InternalModuleName == module) { isCarrierAlreadyPicked = true; } } if (isCarrierAlreadyPicked) { if (SC.GetStringValue("System.ChargingOrderToBoat") == "FromTopToBottom") { for (int i = 0; i < SC.GetValue($"Boat.SlotCount"); i++) { if (!WaferManager.Instance.CheckHasWafer(_pm1.Module, i)) continue; var wafer = WaferManager.Instance.GetWafer(_pm1.Module, i); if (wafer == null || wafer.IsEmpty) continue; if (wafer.WaferType == waferType && (ModuleName)WaferManager.Instance.GetWafer(_pm1.Module, i).OriginStation != module) { module = (ModuleName)WaferManager.Instance.GetWafer(_pm1.Module, i).OriginStation; break; } } } else { for (int i = SC.GetValue($"Boat.SlotCount") - 1; i >= 0; i--) { if (!WaferManager.Instance.CheckHasWafer(_pm1.Module, i)) continue; var wafer = WaferManager.Instance.GetWafer(_pm1.Module, i); if (wafer == null || wafer.IsEmpty) continue; if (wafer.WaferType == waferType && (ModuleName)WaferManager.Instance.GetWafer(_pm1.Module, i).OriginStation != module) { module = (ModuleName)WaferManager.Instance.GetWafer(_pm1.Module, i).OriginStation; break; } } } } return module; } private void MonitorCassetteRobotStockerTask() { if (!_carrierRobot.IsAvailable) return; //pick if (CarrierManager.Instance.CheckNoCarrier(ModuleName.CarrierRobot, 0) && WaferManager.Instance.CheckHasWafer(ModuleName.WaferRobot, 2)) { var stockerModule = (ModuleName)WaferManager.Instance.GetWafer(ModuleName.WaferRobot, 2).OriginStation; if (stockerModule != ModuleName.System) { SchedulerStocker mStocker = null; foreach (var m in _lstTotlaStockers) { bool hasCarrier = CarrierManager.Instance.CheckHasCarrier(m.Module, 0); bool hasEmptySlot = CheckCarrierHasEmptySlot(m.Module); //if (CarrierManager.Instance.CheckHasCarrier(m.Module, 0) && m.Module == stockerModule && CheckCarrierHasEmptySlot(m.Module)) if (hasCarrier && m.Module == stockerModule && hasEmptySlot) { mStocker = m; break; } } SchedulerFIMS stage = null; foreach (var st in _lstFIMSs) { if (!st.IsAvailable) continue; if (CarrierManager.Instance.CheckNoCarrier(st.Module, 0)) { stage = st; break; } } if (mStocker != null && stage != null) { if (_carrierRobot.Pick(mStocker.Module, 0, Hand.Blade1)) { mStocker.WaitTransfer(ModuleName.CarrierRobot); } } } } if (!_carrierRobot.IsAvailable) return; //place var carrier = CarrierManager.Instance.GetCarrier(ModuleName.CarrierRobot, 0); if (carrier != null && !carrier.IsEmpty) { if (!CheckModuleHasWaferInWaferRobotAndPM(carrier.InternalModuleName) || !CheckCarrierHasEmptySlot(ModuleName.CarrierRobot)) { SchedulerStocker stocker = null; foreach (var m in _lstTotlaStockers) { if (CarrierManager.Instance.CheckNoCarrier(m.Module, 0) && m.Module == carrier.InternalModuleName) { stocker = m; break; } } if (stocker != null) { if (_carrierRobot.Place(stocker.Module, 0, Hand.Blade1)) { stocker.WaitTransfer(ModuleName.CarrierRobot); } } } } } private void MonitorCassetteRobotStageTask() { if (!_carrierRobot.IsAvailable) return; //pick var carrier = CarrierManager.Instance.GetCarrier(ModuleName.CarrierRobot, 0); if (carrier != null && carrier.IsEmpty) { SchedulerFIMS stage = null; foreach (var st in _lstFIMSs) { if (!st.IsAvailable) continue; if (!_waferRobot.IsAvailable) continue; if (CarrierManager.Instance.CheckHasCarrier(st.Module, 0)) { carrier = CarrierManager.Instance.GetCarrier(st.Module, 0); if (carrier != null) { if (!CheckCarrierHasEmptySlot(st.Module)) { stage = st; break; } //GetWaferSlotsAndWaferType(carrier, out List slots, out WaferType waferType); //if (slots != null && !CheckModuleHasWaferInWaferRobotAndPM(carrier.InternalModuleName)) if (!CheckModuleHasWaferInWaferRobotAndPM(carrier.InternalModuleName)) { stage = st; break; } } } } if (stage != null) { if (_carrierRobot.Pick(stage.Module, 0, Hand.Blade1)) { stage.WaitTransfer(ModuleName.CarrierRobot); } } } if (!_carrierRobot.IsAvailable) return; //place carrier = CarrierManager.Instance.GetCarrier(ModuleName.CarrierRobot, 0); if (carrier != null && !carrier.IsEmpty) { SchedulerFIMS stage = null; foreach (var st in _lstFIMSs) { if (!st.IsAvailable) continue; if (CarrierManager.Instance.CheckNoCarrier(st.Module, 0)) { GetWaferSlotsAndWaferType(carrier, out List slots, out WaferType waferType); if (slots != null && GetWaferCountRelatedToWaferRobot(waferType, false) > 0 && CheckModuleHasWaferInWaferRobotAndPM(carrier.InternalModuleName)) { stage = st; break; } } } if (stage != null) { if (_carrierRobot.Place(stage.Module, 0, Hand.Blade1)) { stage.WaitTransfer(ModuleName.CarrierRobot); } } } } private void MonitorWaferRobotTask() { if (!_waferRobot.IsAvailable) return; foreach (var stage in _lstFIMSs) { if (stage.IsWaitTransfer(ModuleName.WaferRobot)) { stage.StopWaitTransfer(ModuleName.WaferRobot); } } if (_pm1.IsWaitTransfer(ModuleName.WaferRobot)) { _pm1.StopWaitTransfer(ModuleName.WaferRobot); } MonitorWaferRobotFIMSTask(); if (!_waferRobot.IsAvailable) return; MonitorWaferRobotPMTask(); } private void MonitorWaferRobotFIMSTask() { if (!_waferRobot.IsAvailable) return; //place if (WaferManager.Instance.CheckHasWafer(ModuleName.WaferRobot, 2)) { SchedulerFIMS stage = null; var waferInRobot = WaferManager.Instance.GetWafer(ModuleName.WaferRobot, 2); foreach (var st in _lstFIMSs) { if (!st.IsAvailable) continue; if (!CarrierManager.Instance.CheckHasCarrier(st.Module, 0)) continue; var carrier = CarrierManager.Instance.GetCarrier(st.Module, 0); if (carrier == null || carrier.IsEmpty) continue; if ((ModuleName)waferInRobot.OriginStation != carrier.InternalModuleName) continue; // check FIMS var fimsDevice = DEVICE.GetDevice($"PM1.{st.Module}"); if (!fimsDevice.IsLoadCompleted) continue; bool hasEmptySlot = false; var wafers = WaferManager.Instance.GetWafers(st.Module); if (wafers != null) { foreach (var wafer in wafers) { if (wafer == null) continue; if (wafer.IsEmpty) { hasEmptySlot = true; break; } } } if (hasEmptySlot) { stage = st; break; } } if (stage != null) { Hand placeBlade = Hand.Blade1; int placeSlot = waferInRobot.OriginSlot; if (WaferManager.Instance.CheckHasWafer(ModuleName.WaferRobot, 0) && WaferManager.Instance.CheckHasWafer(ModuleName.WaferRobot, 1) && WaferManager.Instance.CheckHasWafer(ModuleName.WaferRobot, 3) && WaferManager.Instance.CheckHasWafer(ModuleName.WaferRobot, 4) && WaferManager.Instance.GetWafer(ModuleName.WaferRobot, 0).OriginStation == WaferManager.Instance.GetWafer(ModuleName.WaferRobot, 1).OriginStation && WaferManager.Instance.GetWafer(ModuleName.WaferRobot, 1).OriginStation == WaferManager.Instance.GetWafer(ModuleName.WaferRobot, 2).OriginStation && WaferManager.Instance.GetWafer(ModuleName.WaferRobot, 2).OriginStation == WaferManager.Instance.GetWafer(ModuleName.WaferRobot, 3).OriginStation && WaferManager.Instance.GetWafer(ModuleName.WaferRobot, 3).OriginStation == WaferManager.Instance.GetWafer(ModuleName.WaferRobot, 4).OriginStation) { var tempPlaceSlot = WaferManager.Instance.GetWafer(ModuleName.WaferRobot, 0).OriginSlot; if (tempPlaceSlot + 4 < SC.GetValue("System.CassetteSlotCount")) { if (WaferManager.Instance.CheckNoWafer(stage.Module, tempPlaceSlot + 1) && WaferManager.Instance.CheckNoWafer(stage.Module, tempPlaceSlot + 2) && WaferManager.Instance.CheckNoWafer(stage.Module, tempPlaceSlot + 3) && WaferManager.Instance.CheckNoWafer(stage.Module, tempPlaceSlot + 4)) { placeBlade = Hand.Both; placeSlot = tempPlaceSlot; } } } if (placeSlot != -1 && _waferRobot.Place(stage.Module, placeSlot, placeBlade)) { stage.WaitTransfer(ModuleName.WaferRobot); } } } } private void MonitorWaferRobotPMTask() { if (!_waferRobot.IsAvailable) return; var pmModule = Singleton.Instance.Modules[ModuleName.PM1] as PMModule; if (pmModule == null) return; var stageStockerModeleName = ModuleName.System; foreach (var st in _lstFIMSs) { if (!st.IsAvailable) continue; if (!CarrierManager.Instance.CheckHasCarrier(st.Module, 0)) continue; var carrier = CarrierManager.Instance.GetCarrier(st.Module, 0); if (carrier == null || carrier.IsEmpty) continue; bool hasEmptySlot = false; var wafers = WaferManager.Instance.GetWafers(st.Module); if (wafers != null) { foreach (var item in wafers) { if (item == null) continue; if (item.IsEmpty) { hasEmptySlot = true; break; } } } if (hasEmptySlot) { stageStockerModeleName = carrier.InternalModuleName; break; } } //pick var wafer = WaferManager.Instance.GetWafer(ModuleName.WaferRobot, 2); List targetWaferSlots = GetWaferSlots(); if (wafer != null && wafer.IsEmpty && targetWaferSlots != null) { Hand pickBlade = Hand.Blade1; int pickSlot = -1; for (int i = 0; i < targetWaferSlots.Count; i++) { var targetWafer = WaferManager.Instance.GetWafer(_pm1.Module, targetWaferSlots[i]); if (targetWafer == null || targetWafer.IsEmpty || !CheckWaferCouldBeReturn(targetWafer)) continue; //先取stage上有空slot的carrier对应的wafer if (stageStockerModeleName != ModuleName.System && (ModuleName)targetWafer.OriginStation != stageStockerModeleName) continue; pickSlot = targetWaferSlots[i]; if (i + 4 < targetWaferSlots.Count && Math.Abs(targetWaferSlots[i] - targetWaferSlots[i + 4]) == 4) { if (WaferManager.Instance.CheckHasWafer(_pm1.Module, targetWaferSlots[i + 1]) && WaferManager.Instance.CheckHasWafer(_pm1.Module, targetWaferSlots[i + 2]) && WaferManager.Instance.CheckHasWafer(_pm1.Module, targetWaferSlots[i + 3]) && WaferManager.Instance.CheckHasWafer(_pm1.Module, targetWaferSlots[i + 4]) && SC.GetValue($"{_waferRobot.Module}.IsSupport5Wafer")) { bool isFromTopToBottom = SC.GetStringValue("System.ChargingOrderToBoat") == "FromTopToBottom"; var wafer0 = WaferManager.Instance.GetWafer(_pm1.Module, targetWaferSlots[i + (isFromTopToBottom ? 4 : 0)]); var wafer1 = WaferManager.Instance.GetWafer(_pm1.Module, targetWaferSlots[i + (isFromTopToBottom ? 3 : 1)]); var wafer2 = WaferManager.Instance.GetWafer(_pm1.Module, targetWaferSlots[i + 2]); var wafer3 = WaferManager.Instance.GetWafer(_pm1.Module, targetWaferSlots[i + (isFromTopToBottom ? 1 : 3)]); var wafer4 = WaferManager.Instance.GetWafer(_pm1.Module, targetWaferSlots[i + (isFromTopToBottom ? 0 : 4)]); if (WaferManager.Instance.CheckNoWafer(ModuleName.WaferRobot, 0) && WaferManager.Instance.CheckNoWafer(ModuleName.WaferRobot, 1) && WaferManager.Instance.CheckNoWafer(ModuleName.WaferRobot, 3) && WaferManager.Instance.CheckNoWafer(ModuleName.WaferRobot, 4) && wafer0.OriginStation == wafer1.OriginStation && wafer0.OriginStation == wafer2.OriginStation && wafer0.OriginStation == wafer3.OriginStation && wafer0.OriginStation == wafer4.OriginStation && Math.Abs(wafer1.OriginSlot - wafer2.OriginSlot) == 1 && Math.Abs(wafer2.OriginSlot - wafer3.OriginSlot) == 1 && Math.Abs(wafer0.OriginSlot - wafer4.OriginSlot) == 4 && Math.Abs(wafer0.OriginSlot - wafer3.OriginSlot) == 3 && Math.Abs(wafer0.OriginSlot - wafer2.OriginSlot) == 2 && Math.Abs(wafer0.OriginSlot - wafer1.OriginSlot) == 1) { pickBlade = Hand.Both; pickSlot = wafer4.Slot; } } } break; } if (pmModule.CheckReadyForTransfer(_waferRobot.Module, pickBlade, pickSlot, EnumTransferType.Pick, out string reason) && pickSlot != -1 && _waferRobot.Pick(_pm1.Module, pickSlot, pickBlade)) { _pm1.WaitTransfer(ModuleName.WaferRobot); } } } private List GetWaferSlots() { List slots = null; switch (SC.GetStringValue("System.ChargingOrderBySort")) { case "ED,P,M": if (CheckWaferSlotsHasWafer(_monitor1Slots)) return _monitor1Slots; if (CheckWaferSlotsHasWafer(_monitor2Slots)) return _monitor2Slots; if (CheckWaferSlotsHasWafer(_productSlots)) return _productSlots; if (CheckWaferSlotsHasWafer(_extraDummySlots)) return _extraDummySlots; break; case "ED,M,P": if (CheckWaferSlotsHasWafer(_productSlots)) return _productSlots; if (CheckWaferSlotsHasWafer(_monitor1Slots)) return _monitor1Slots; if (CheckWaferSlotsHasWafer(_monitor2Slots)) return _monitor2Slots; if (CheckWaferSlotsHasWafer(_extraDummySlots)) return _extraDummySlots; break; case "P,ED,M": if (CheckWaferSlotsHasWafer(_monitor1Slots)) return _monitor1Slots; if (CheckWaferSlotsHasWafer(_monitor2Slots)) return _monitor2Slots; if (CheckWaferSlotsHasWafer(_extraDummySlots)) return _extraDummySlots; if (CheckWaferSlotsHasWafer(_productSlots)) return _productSlots; break; case "P,M,ED": if (CheckWaferSlotsHasWafer(_extraDummySlots)) return _extraDummySlots; if (CheckWaferSlotsHasWafer(_monitor1Slots)) return _monitor1Slots; if (CheckWaferSlotsHasWafer(_monitor2Slots)) return _monitor2Slots; if (CheckWaferSlotsHasWafer(_productSlots)) return _productSlots; break; case "M,P,ED": if (CheckWaferSlotsHasWafer(_extraDummySlots)) return _extraDummySlots; if (CheckWaferSlotsHasWafer(_productSlots)) return _productSlots; if (CheckWaferSlotsHasWafer(_monitor1Slots)) return _monitor1Slots; if (CheckWaferSlotsHasWafer(_monitor2Slots)) return _monitor2Slots; break; case "M,ED,P": if (CheckWaferSlotsHasWafer(_productSlots)) return _productSlots; if (CheckWaferSlotsHasWafer(_extraDummySlots)) return _extraDummySlots; if (CheckWaferSlotsHasWafer(_monitor1Slots)) return _monitor1Slots; if (CheckWaferSlotsHasWafer(_monitor2Slots)) return _monitor2Slots; break; default: if (CheckWaferSlotsHasWafer(_monitor1Slots)) return _monitor1Slots; if (CheckWaferSlotsHasWafer(_monitor2Slots)) return _monitor2Slots; if (CheckWaferSlotsHasWafer(_productSlots)) return _productSlots; if (CheckWaferSlotsHasWafer(_extraDummySlots)) return _extraDummySlots; break; } foreach (var slot in _sideDummySlots) { if (WaferManager.Instance.CheckHasWafer(_pm1.Module, slot)) { return _sideDummySlots; } } return slots; } private void GetWaferSlotsAndWaferType(CarrierInfo carrier, out List slots, out WaferType waferType) { slots = null; waferType = WaferType.None; if (carrier != null && !carrier.IsEmpty) { switch (carrier.CarrierType) { case CarrierType.SD: slots = _sideDummySlots; waferType = WaferType.SD; break; case CarrierType.ED: slots = _extraDummySlots; waferType = WaferType.ED; break; case CarrierType.M1: slots = _monitor1Slots; waferType = WaferType.M1; break; case CarrierType.M2: slots = _monitor2Slots; waferType = WaferType.M2; break; case CarrierType.P: slots = _productSlots; waferType = WaferType.P; break; } } } private bool CheckWaferSlotsHasWafer(List slots) { foreach (var slot in slots) { if (WaferManager.Instance.CheckHasWafer(_pm1.Module, slot)) { return true; } } return false; } private bool CheckModuleHasWaferInWaferRobotAndPM(ModuleName module) { bool isHaveWafer = false; for (int i = 0; i < SC.GetValue($"Boat.SlotCount"); i++) { if (!WaferManager.Instance.CheckHasWafer(_pm1.Module, i)) continue; var wafer = WaferManager.Instance.GetWafer(_pm1.Module, i); if (wafer == null || wafer.IsEmpty) continue; if (wafer.OriginStation == (int)module) { isHaveWafer = true; break; } } for (int i = 0; i < SC.GetValue("WaferRobot.SlotCount"); i++) { if (!WaferManager.Instance.CheckHasWafer(ModuleName.WaferRobot, i)) continue; var wafer = WaferManager.Instance.GetWafer(ModuleName.WaferRobot, i); if (wafer == null || wafer.IsEmpty) continue; if (wafer.OriginStation == (int)module) { isHaveWafer = true; break; } } return isHaveWafer; } private int GetWaferCountRelatedToWaferRobot(WaferType waferType, bool subtractionStage = true) { int count = 0; for (int i = 0; i < 5; i++) { var wafer = WaferManager.Instance.GetWafer(ModuleName.WaferRobot, i); if (!wafer.IsEmpty && wafer.WaferType == waferType) count++; } for (int i = 0; i < SC.GetValue($"Boat.SlotCount"); i++) { var wafer = WaferManager.Instance.GetWafer(_pm1.Module, i); if (!wafer.IsEmpty && wafer.WaferType == waferType) count++; } if (subtractionStage) { foreach (var stage in _lstFIMSs) { if (CarrierManager.Instance.CheckNoCarrier(stage.Module, 0)) continue; var wafers = WaferManager.Instance.GetWafers(stage.Module); foreach (var wafer in wafers) { if (!wafer.IsEmpty && wafer.WaferType == waferType) count--; } } } return count < 0 ? 0 : count; } private bool CheckCarrierHasEmptySlot(ModuleName module) { bool hasEmpty = false; var wafers = WaferManager.Instance.GetWafers(module); if (wafers != null) { foreach (var wafer in wafers) { if (wafer.IsEmpty) { hasEmpty = true; break; } } } return hasEmpty; } private bool CheckCarrierHasWaferInPM(ModuleName module) { bool isHaveWafer = false; for (int i = 0; i < SC.GetValue($"Boat.SlotCount"); i++) { if (!WaferManager.Instance.CheckHasWafer(_pm1.Module, i)) continue; var wafer = WaferManager.Instance.GetWafer(_pm1.Module, i); if (wafer == null || wafer.IsEmpty) continue; if (wafer.OriginStation == (int)module) { isHaveWafer = true; break; } } return isHaveWafer; } private bool CheckCarrierHasWaferInWaferRobot(ModuleName module) { bool isHaveWafer = false; for (int i = 0; i < 5; i++) { var wafer = WaferManager.Instance.GetWafer(ModuleName.WaferRobot, i); if (wafer.OriginStation == (int)module) { isHaveWafer = true; break; }; } return isHaveWafer; } private bool CheckCarrierNoHasEmptySlot(ModuleName module) { bool noHasEmpty = true; var wafers = WaferManager.Instance.GetWafers(module); if (wafers != null) { foreach (var wafer in wafers) { if (!wafer.IsEmpty) { noHasEmpty = false; break; } } } return noHasEmpty; } private bool CheckCarrierCanPickFromFIMSInDischarge(ModuleName fimsCarrierModule) { List robotModules = new List(); for (int i = 0; i < WaferManager.Instance.GetWafers(ModuleName.WaferRobot).Length; i++) { var wafer = WaferManager.Instance.GetWafer(ModuleName.WaferRobot, i); if (wafer == null || wafer.IsEmpty) continue; if (!robotModules.Contains((ModuleName)wafer.OriginStation)) robotModules.Add((ModuleName)wafer.OriginStation); } if (robotModules.Contains(fimsCarrierModule)) return false; List pmModules = new List(); for (int i = 0; i < WaferManager.Instance.GetWafers(_pm1.Module).Length; i++) { var wafer = WaferManager.Instance.GetWafer(_pm1.Module, i); if (wafer == null || wafer.IsEmpty) continue; if (!pmModules.Contains((ModuleName)wafer.OriginStation)) pmModules.Add((ModuleName)wafer.OriginStation); if (pmModules.Count == _lstFIMSs.Count) break; } if (pmModules.Contains(fimsCarrierModule)) return false; return true; } public void Abort() { } } }