using Aitex.Common.Util; using Aitex.Core.Common; using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.Sorter.Common; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using FurnaceRT.Equipments.CarrierRobots; using FurnaceRT.Equipments.PMs.RecipeExecutions; using FurnaceRT.Equipments.Schedulers; using FurnaceRT.Equipments.Systems; using FurnaceRT.Equipments.WaferRobots; using MECF.Framework.Common.Jobs; using FurnaceRT.Equipments.LPs; using FurnaceRT.Equipments.Stockers; using Aitex.Core.RT.Log; using FurnaceRT.Equipments.FIMSs; using Aitex.Core.RT.DataCenter; using FurnaceRT.Devices; namespace FurnaceRT.Equipments.Jobs { public class TransferJob : SchedulerModuleFactory { private List _lstTransferJobs = new List(); private SchedulerFACallback _faCallback; private SchedulerDBCallback _dbCallback; private const string LogSource = "System"; private LoadPortModule _lp1Module; private LoadPortModule _lp2Module; public bool HasJobRunning { get { return _lstTransferJobs.Count > 0; } } public TransferJob() { _faCallback = new SchedulerFACallback(); _dbCallback = new SchedulerDBCallback(); InitModule(); _lp1Module = Singleton.Instance.Modules.ContainsKey(ModuleName.LP1) ? Singleton.Instance.Modules[ModuleName.LP1] as LoadPortModule : null; _lp2Module = Singleton.Instance.Modules.ContainsKey(ModuleName.LP2) ? Singleton.Instance.Modules[ModuleName.LP2] as LoadPortModule : null; DATA.Subscribe($"Scheduler.TransferJobList", () => { return _lstTransferJobs; }); DATA.Subscribe($"Scheduler.CurrentTransferJob", () => { var pj = _lstTransferJobs.Find(x => x.State == EnumTransferJobState.Active); return pj; }); DATA.Subscribe($"Scheduler.OccupyStockers", () => { return GetOccupyStockers(); }); } public void ResetTask(ModuleName module) { if (module == _waferRobot.Module) _waferRobot.ResetTask(); if (module == _carrierRobot.Module) _carrierRobot.ResetTask(); } public void Clear() { _carrierRobot.ResetTask(); _waferRobot.ResetTask(); foreach (var lp in _lstLPs) { lp.ResetTask(); } foreach (var fims in _lstFIMSs) { fims.ResetTask(); } _lstTransferJobs.Clear(); } #region Job Management public Result CreateJob(params object[] objs) { if (objs == null || objs.Length == 0) { Singleton.Instance.TransferJobStartFailedWarning.Set("Parameter not valid"); return Result.FAIL; } var param = (Dictionary)objs[0]; if (param == null) { Singleton.Instance.TransferJobStartFailedWarning.Set("Parameter not valid"); return Result.FAIL; } var content = ""; foreach (var key in param.Keys) { content += $"{key}-{param[key]}#"; } LOG.Write($"Transfer Job: {content}"); var waferTypeString = param.ContainsKey("WaferType") ? (string)param["WaferType"] : ""; var transferTypeString = (string)param["TransferType"]; TransferJobInfo tj = new TransferJobInfo(); tj.CreateTime = DateTime.Now; tj.BatchName = param.ContainsKey("Batch") ? (string)param["Batch"] : ""; tj.CarrierType = (CarrierType)Enum.Parse(typeof(CarrierType), waferTypeString); tj.Type = (EnumTransferJobType)Enum.Parse(typeof(EnumTransferJobType), transferTypeString); tj.State = EnumTransferJobState.Created; tj.CarrierParas = new List(); List carrierIdLst = new List(); List moduleLst = new List(); foreach (var module in Singleton.Instance.Modules.Keys) { if ((Singleton.Instance.Modules[module] is StockerModule) || (Singleton.Instance.Modules[module] is FIMSModule)) { if (CarrierManager.Instance.HasCarrier(module.ToString())) { var carrier = CarrierManager.Instance.GetCarrier(module.ToString()); carrierIdLst.Add(carrier.CarrierId); moduleLst.Add(carrier.InternalModuleName); } } } if (param.ContainsKey("CarrierPara")) { if (tj.Type == EnumTransferJobType.Loading) { //Stocker1,P_00000036,25,Exist,1111111111111111111111111,LP1;Stocker2,P_00000037,25,Exist,1111111111111111111111111,LP2 var paras = param["CarrierPara"].ToString().Split(';'); if (paras != null && paras.Length > 0) { foreach (var item in paras) { var arry = item.Split(','); if (arry != null && arry.Length == 6) { CarrierPara carrierPara = new CarrierPara() { Stocker = ModuleHelper.Converter(arry[0]), CarrierID = arry[1], //WaferCount = int.Parse(arry[2]), IsCompareWithSlotMap = arry[3].ToLower() == "exist", SlotMap = arry[4], TargetPort = ModuleHelper.Converter(arry[5]), CarrierType = tj.CarrierType, }; if (carrierIdLst.Any(x => x == carrierPara.CarrierID) || moduleLst.Any(x => x == carrierPara.Stocker)) { Singleton.Instance.LoadCassetteJobStartFailedWarning.Set($"Carrier ID ={carrierPara.CarrierID} of {carrierPara.Stocker} is already exist"); return Result.FAIL; } if (CarrierManager.Instance.HasCarrier($"{carrierPara.Stocker}")) { Singleton.Instance.LoadCassetteJobStartFailedWarning.Set($"Carrier of {carrierPara.Stocker} is already exist in stocker"); return Result.FAIL; } if (!SC.GetValue("System.IsSimulatorMode")) { var stockerModule = Singleton.Instance.Modules[carrierPara.Stocker] as StockerModule; if (stockerModule != null && stockerModule.IsFoupPresent) { Singleton.Instance.LoadCassetteJobStartFailedWarning.Set($"Cassette of {carrierPara.Stocker} is already exist in stocker"); return Result.FAIL; } } tj.CarrierParas.Add(carrierPara); carrierIdLst.Add(arry[1]); moduleLst.Add(carrierPara.Stocker); } } } } else { //Stocker1,LP1;Stocker2,LP2 var paras = param["CarrierPara"].ToString().Split(';'); if (paras != null && paras.Length > 0) { foreach (var item in paras) { var arry = item.Split(','); CarrierPara carrierPara = null; if (arry != null && arry.Length >= 2) { //两个参数是Unload,6个参数是Load Process Unload carrierPara = new CarrierPara() { Stocker = ModuleHelper.Converter(arry[0]), TargetPort = arry.Length == 6 ? ModuleHelper.Converter(arry[5]) : ModuleHelper.Converter(arry[1]), }; if (arry.Length != 6) { if (!CarrierManager.Instance.HasCarrier($"{carrierPara.Stocker}")) { Singleton.Instance.UnloadCassetteJobStartFailedWarning.Set($"Carrier of {carrierPara.Stocker} is not exist in stocker"); return Result.FAIL; } if (CarrierManager.Instance.GetCarrier($"{carrierPara.Stocker}", 0).InternalModuleName != carrierPara.Stocker) { Singleton.Instance.UnloadCassetteJobStartFailedWarning.Set($"Carrier of {carrierPara.Stocker} is not match stocker module name {CarrierManager.Instance.GetCarrier($"{carrierPara.Stocker}", 0).InternalModuleName}"); return Result.FAIL; } if (!SC.GetValue("System.IsSimulatorMode")) { var stockerModule = Singleton.Instance.Modules[carrierPara.Stocker] as StockerModule; if (stockerModule != null && !stockerModule.IsFoupPresent) { Singleton.Instance.LoadCassetteJobStartFailedWarning.Set($"Cassette of {carrierPara.Stocker} is not exist in stocker"); return Result.FAIL; } } } } if (carrierPara != null) { carrierPara.CarrierID = CarrierManager.Instance.GetCarrier($"{carrierPara.Stocker}").CarrierId; tj.CarrierParas.Add(carrierPara); } } } } } _lstTransferJobs.Add(tj); return Result.RUN; } internal void AbortJob(string jobName) { var tj = _lstTransferJobs.Find(x => x.Name == jobName); if (tj == null) { EV.PostWarningLog(LogSource, $"stop job rejected, not found job with id {jobName}"); return; } tj.State = EnumTransferJobState.Aborting; } internal void CancelUnloadingJob(string port, string CarrierId) { var tj = _lstTransferJobs.Find(x => x.State == EnumTransferJobState.Active); if (tj == null) { EV.PostWarningLog(LogSource, $"cancel unloading job rejected, not found job with CarrierId {CarrierId}"); return; } var carrierPara = tj.CarrierParas.Find(x => x.TargetPort.ToString() == port && x.CarrierID == CarrierId); if (carrierPara != null) tj.CarrierParas.Remove(carrierPara); } internal bool StartJob(string jobName) { return true; } #endregion Job Management public Result Monitor() { TransferJobInfo tjActive = _lstTransferJobs.Find(x => x.State == EnumTransferJobState.Active); if (tjActive != null) { MonitorModuleTasks(); } MonitorJobTasks(); UpdateLoadPortLotIDList(); return Result.RUN; } public bool CheckAllJobDone() { foreach (var tj in _lstTransferJobs) { if (tj.State == EnumTransferJobState.Created || tj.State == EnumTransferJobState.Active) return false; } return true; } private void UpdateLoadPortLotIDList() { TransferJobInfo tjActive = _lstTransferJobs.Find(x => x.State == EnumTransferJobState.Active); if (tjActive != null && tjActive.CarrierParas != null) { if (_lp1Module != null) { _lp1Module.CurrentLotId = ""; } if (_lp2Module != null) { _lp2Module.CurrentLotId = ""; } List lp1WaitLotId = new List(); List lp2WaitLotId = new List(); foreach (var item in tjActive.CarrierParas) { if ((tjActive.Type == EnumTransferJobType.Loading && !item.IsLoaded) || (tjActive.Type == EnumTransferJobType.Unloading && !item.IsUnloaded)) { var lpModule = Singleton.Instance.Modules[item.TargetPort] as LoadPortModule; if (lpModule != null && item.TargetPort == ModuleName.LP1 && string.IsNullOrEmpty(lpModule.CurrentLotId)) { _lp1Module.CurrentLotId = item.CarrierID; } if (lpModule != null && item.TargetPort == ModuleName.LP2 && string.IsNullOrEmpty(lpModule.CurrentLotId)) { _lp2Module.CurrentLotId = item.CarrierID; } if (item.TargetPort == ModuleName.LP1) { lp1WaitLotId.Add(item.CarrierID); } if (item.TargetPort == ModuleName.LP2) { lp2WaitLotId.Add(item.CarrierID); } } } if (_lp1Module != null) { _lp1Module.WaitLotId = lp1WaitLotId; } if (_lp2Module != null) { _lp2Module.WaitLotId = lp2WaitLotId; } } else { if (_lp1Module != null) { _lp1Module.CurrentLotId = ""; if (_lp1Module.WaitLotId == null || _lp1Module.WaitLotId.Any()) _lp1Module.WaitLotId = new List(); } if (_lp2Module != null) { _lp2Module.CurrentLotId = ""; if (_lp2Module.WaitLotId == null || _lp2Module.WaitLotId.Any()) _lp2Module.WaitLotId = new List(); } } } #region Module task public Result MonitorModuleTasks() { MonitorLPClampInLoadingTask(); MonitorCarrierRobotTask(); MonitorWaferRobotTask(); MonitorLPTask(); MonitorFIMSTask(); return Result.RUN; } private void MonitorLPClampInLoadingTask() { if (!_lstTransferJobs.Any()) return; var tj = _lstTransferJobs.Find(x => x.State == EnumTransferJobState.Active); if (tj == null || tj.CarrierParas == null) return; if (tj.Type == EnumTransferJobType.Loading) { foreach (var lp in _lstLPs) { if (!lp.IsAvailable) continue; if (!tj.CarrierParas.Any(x => x.TargetPort == lp.Module && !x.IsLoaded)) continue; var lpModule = Singleton.Instance.Modules[lp.Module] as LoadPortModule; if (lpModule.LPDevice.IsFoupPresent) { //FOUP放上去之后,先上锁 if (!lpModule.IsClamp && lpModule.LPDevice.Clamp(out _)) { return; } } } } } private void MonitorLPTask() { if (!_lstTransferJobs.Any()) return; var tj = _lstTransferJobs.Find(x => x.State == EnumTransferJobState.Active); if (tj == null || tj.CarrierParas == null) return; if (tj.Type == EnumTransferJobType.Loading) { foreach (var lp in _lstLPs) { if (!lp.IsAvailable) continue; if (!tj.CarrierParas.Any(x => x.TargetPort == lp.Module && !x.IsLoaded)) continue; var lpModule = Singleton.Instance.Modules[lp.Module] as LoadPortModule; if (lpModule.LPDevice.IsFoupPresent) { //FOUP放上去之后,先上锁 if (!lpModule.IsClamp && lpModule.LPDevice.Clamp(out _)) { return; } } else { //空的,先松开锁 if (!lpModule.IsReleased && lpModule.LPDevice.Unclamp(out _)) { return; } } } } else if (tj.Type == EnumTransferJobType.Unloading) { foreach (var lp in _lstLPs) { if (!lp.IsAvailable) continue; if (!tj.CarrierParas.Any(x => x.TargetPort == lp.Module && !x.IsLoaded)) continue; var lpModule = Singleton.Instance.Modules[lp.Module] as LoadPortModule; if (lpModule.LPDevice.IsFoupPresent) { if (!lpModule.IsReleased && lpModule.LPDevice.Unclamp(out _)) { return; } } else { //空的,先松开锁 if (!lpModule.IsReleased && lpModule.LPDevice.Unclamp(out _)) { return; } } } } } private void MonitorFIMSTask() { if (!_lstTransferJobs.Any() || SC.GetValue("WaferRobot.BypassFIMSMap")) return; var tj = _lstTransferJobs.Find(x => x.State == EnumTransferJobState.Active); if (tj == null || tj.CarrierParas == null) return; if (tj.Type == EnumTransferJobType.Loading) { var hasNotMappedCarrier = false; var robotCarrier = CarrierManager.Instance.GetCarrier(ModuleName.CarrierRobot, 0); if (robotCarrier != null && !robotCarrier.IsEmpty && !robotCarrier.IsMapped) { if (tj.CarrierParas.Any(x => x.Stocker == robotCarrier.InternalModuleName && x.IsLoaded)) { hasNotMappedCarrier = true; } } foreach (var item in tj.CarrierParas) { var carrier = CarrierManager.Instance.GetCarrier(item.Stocker, 0); if (carrier == null || carrier.IsEmpty || carrier.IsMapped) continue; if (item.IsLoaded) { hasNotMappedCarrier = true; break; } } bool haveLoadingFims = false; foreach (var fims in _lstFIMSs) { if ((Singleton.Instance.Modules[fims.Module] as FIMSModule).IsLoading) { haveLoadingFims = true; break; } } foreach (var fims in _lstFIMSs) { if (!fims.IsAvailable) continue; var fimsDevice = DEVICE.GetDevice($"PM1.{fims.Module}"); if (CarrierManager.Instance.CheckNoCarrier(fims.Module, 0)) { if (hasNotMappedCarrier && fimsDevice.IsWaferRobotEX1AxisHomePosition && fimsDevice.IsWaferRobotEX2AxisHomePosition && !fimsDevice.IsUnloadCompleted && fims.Unload()) { return; } } else { var carrier = CarrierManager.Instance.GetCarrier(fims.Module, 0); if (carrier == null || carrier.IsEmpty) continue; if (tj.CarrierParas.Any(x => x.Stocker == carrier.InternalModuleName && x.IsLoaded)) { if (carrier.IsMapped && fimsDevice.IsWaferRobotEX1AxisHomePosition && fimsDevice.IsWaferRobotEX2AxisHomePosition && !fimsDevice.IsUnloadCompleted && fims.Unload()) { return; } if (!haveLoadingFims && !carrier.IsMapped && !fimsDevice.IsLoadCompleted && fims.Load()) { return; } } } } } else if (tj.Type == EnumTransferJobType.Unloading) { //do nothing } } private void MonitorWaferRobotTask() { if (!_waferRobot.IsAvailable) return; //wafer robot is idle, release all the target foreach (var fims in _lstFIMSs) { if (fims.IsWaitTransfer(ModuleName.WaferRobot)) { fims.StopWaitTransfer(ModuleName.WaferRobot); } } MonitorWaferRobotFIMSTask(); } private void MonitorWaferRobotFIMSTask() { if (!_waferRobot.IsAvailable || !_lstTransferJobs.Any()) return; var tj = _lstTransferJobs.Find(x => x.State == EnumTransferJobState.Active); if (tj == null || tj.CarrierParas == null) return; foreach (var fims in _lstFIMSs) { if (!fims.IsAvailable) continue; if (!CarrierManager.Instance.CheckHasCarrier(fims.Module, 0)) continue; var fimsDevice = DEVICE.GetDevice($"PM1.{fims.Module}"); if (!fimsDevice.IsLoadCompleted) continue; var carrier = CarrierManager.Instance.GetCarrier(fims.Module, 0); if (carrier == null || carrier.IsEmpty || carrier.IsMapped || SC.GetValue("WaferRobot.BypassFIMSMap")) continue; if (tj.CarrierParas.Any(x => x.Stocker == carrier.InternalModuleName)) { var carrierPara = tj.CarrierParas.FirstOrDefault(x => x.Stocker == carrier.InternalModuleName); if (carrierPara != null && _waferRobot.Map(fims.Module, carrierPara.WaferCount, carrierPara.SlotMap, carrierPara.IsCompareWithSlotMap, true, Hand.Blade1)) { fims.WaitTransfer(ModuleName.WaferRobot); } } } } private void MonitorCarrierRobotTask() { if (!_carrierRobot.IsAvailable) return; //carrier robot is idle, release all the target foreach (var stocker in _lstTotlaStockers) { if (stocker.IsWaitTransfer(ModuleName.CarrierRobot)) { stocker.StopWaitTransfer(ModuleName.CarrierRobot); } } foreach (var fims in _lstFIMSs) { if (fims.IsWaitTransfer(ModuleName.CarrierRobot)) { fims.StopWaitTransfer(ModuleName.CarrierRobot); } } foreach (var lp in _lstLPs) { if (lp.IsWaitTransfer(ModuleName.CarrierRobot)) { lp.StopWaitTransfer(ModuleName.CarrierRobot); } } MonitorCarrierRobotFIMSTask(); if (!_carrierRobot.IsAvailable) return; MonitorCarrierRobotStockerTask(); if (!_carrierRobot.IsAvailable) return; MonitorCarrierRobotLPTask(); if (!_carrierRobot.IsAvailable) return; //MonitorCarrierGotoTask(); } private void MonitorCarrierGotoTask() { if (!_carrierRobot.IsAvailable || !_lstTransferJobs.Any()) return; var tj = _lstTransferJobs.Find(x => x.State == EnumTransferJobState.Active); if (tj == null || tj.CarrierParas == null) return; if (tj.Type == EnumTransferJobType.Loading) { if (CarrierManager.Instance.CheckNoCarrier(ModuleName.CarrierRobot, 0)) { foreach (var lp in _lstLPs) { if (!tj.CarrierParas.Any(x => x.TargetPort == lp.Module && !x.IsLoaded)) continue; var lpDevice = DEVICE.GetDevice($"PM1.{lp.Module}"); if (lpDevice.IsFoupPresent) { if (!lpDevice.IsLoadCompleted && _carrierRobot.PreviousTarget != lp.Module && _carrierRobot.Goto(lp.Module, 0, Hand.Blade1, true)) { return; } } } if (!SC.GetValue("WaferRobot.BypassFIMSMap")) { foreach (var fims in _lstFIMSs) { if (CarrierManager.Instance.CheckHasCarrier(fims.Module, 0)) { var carrier1 = CarrierManager.Instance.GetCarrier(fims.Module, 0); if (carrier1 != null && !carrier1.IsMapped) { if (tj.CarrierParas.Any(x => x.Stocker == carrier1.InternalModuleName) && _carrierRobot.PreviousTarget != fims.Module && _carrierRobot.Goto(fims.Module, 0, Hand.Blade1, true)) { return; } } } } } } else { //goto fims 放 if (!SC.GetValue("WaferRobot.BypassFIMSMap")) { foreach (var fims in _lstFIMSs) { if (!fims.IsAvailable) continue; if (CarrierManager.Instance.CheckNoCarrier(fims.Module, 0)) { var robotCarrier = CarrierManager.Instance.GetCarrier(ModuleName.CarrierRobot, 0); if (robotCarrier != null && !robotCarrier.IsMapped && tj.CarrierParas.Any(x => x.Stocker == robotCarrier.InternalModuleName)) { if (_carrierRobot.PreviousTarget != fims.Module && _carrierRobot.Goto(fims.Module, 0, Hand.Blade1, false)) { return; } } } } } } } else if (tj.Type == EnumTransferJobType.Unloading) { if (CarrierManager.Instance.CheckHasCarrier(ModuleName.CarrierRobot, 0)) { foreach (var lp in _lstLPs) { if (!CarrierManager.Instance.CheckHasCarrier(lp.Module, 0)) continue; var robotCarrier = CarrierManager.Instance.GetCarrier(ModuleName.CarrierRobot, 0); var para = tj.CarrierParas.FirstOrDefault(x => x.Stocker == robotCarrier.InternalModuleName); if (para == null || para.TargetPort != lp.Module) continue; var lpDevice = DEVICE.GetDevice($"PM1.{lp.Module}"); if (!lpDevice.IsFoupPresent) { if (!lpDevice.IsLoadCompleted && _carrierRobot.PreviousTarget != lp.Module && _carrierRobot.Goto(lp.Module, 0, Hand.Blade1, false)) { lp.WaitTransfer(ModuleName.CarrierRobot); return; } } } } } } private void MonitorCarrierRobotStockerTask() { if (!_carrierRobot.IsAvailable || !_lstTransferJobs.Any()) return; var tj = _lstTransferJobs.Find(x => x.State == EnumTransferJobState.Active); if (tj == null || tj.CarrierParas == null) return; //pick var carrier = CarrierManager.Instance.GetCarrier(ModuleName.CarrierRobot, 0); if (carrier != null && carrier.IsEmpty) { SchedulerStocker stocker = null; foreach (var st in _lstTotlaStockers) { if (!st.IsAvailable || !st.IsReadyForPick(ModuleName.CarrierRobot, 0)) continue; if (CarrierManager.Instance.CheckHasCarrier(st.Module, 0)) { carrier = CarrierManager.Instance.GetCarrier(st.Module, 0); if (tj.Type == EnumTransferJobType.Loading) { //没有map,FIMS具备map条件时 if (carrier != null && !carrier.IsMapped && _lstFIMSs.Any(x => x.IsAvailable && x.IsReadyForPlace(ModuleName.CarrierRobot, 0)) && !SC.GetValue("WaferRobot.BypassFIMSMap")) { if (tj.CarrierParas.Any(x => x.Stocker == carrier.InternalModuleName)) { stocker = st; break; } } } else { if (tj.CarrierParas.Any(x => x.Stocker == carrier.InternalModuleName)) { stocker = st; break; } } } } if (stocker != null && _waferRobot.IsAvailable) { if (_carrierRobot.Pick(stocker.Module, 0, Hand.Blade1)) { stocker.WaitTransfer(ModuleName.CarrierRobot); return; } } } if (!_carrierRobot.IsAvailable || tj.Type != EnumTransferJobType.Loading) return; //place carrier = CarrierManager.Instance.GetCarrier(ModuleName.CarrierRobot, 0); if (carrier != null && !carrier.IsEmpty && tj.CarrierParas.Any(x => x.Stocker == carrier.InternalModuleName)) { var carrierPara = tj.CarrierParas.FirstOrDefault(x => x.Stocker == carrier.InternalModuleName); SchedulerStocker stocker = null; foreach (var st in _lstTotlaStockers) { if (!st.IsAvailable || !st.IsReadyForPlace(ModuleName.CarrierRobot, 0)) continue; if (st.Module != carrier.InternalModuleName) continue; if (CarrierManager.Instance.CheckNoCarrier(st.Module, 0)) { stocker = st; break; } } //map正常完成或者FIMS不具备map条件 if (stocker != null && ((carrier.IsMapped && carrier.IsMapOK) || SC.GetValue("WaferRobot.BypassFIMSMap") || !_lstFIMSs.Any(x => x.IsOnline && CarrierManager.Instance.CheckNoCarrier(x.Module, 0)))) { if (_carrierRobot.Place(stocker.Module, 0, Hand.Blade1)) { stocker.WaitTransfer(ModuleName.CarrierRobot); return; } } } } private void MonitorCarrierRobotLPTask() { if (!_carrierRobot.IsAvailable || !_lstTransferJobs.Any()) return; var tj = _lstTransferJobs.Find(x => x.State == EnumTransferJobState.Active); if (tj == null || tj.CarrierParas == null) return; if (tj.Type == EnumTransferJobType.Loading) { if (CarrierManager.Instance.CheckNoCarrier(ModuleName.CarrierRobot, 0)) { foreach (var lp in _lstLPs) { if (!lp.IsAvailable) continue; if (!tj.CarrierParas.Any(x => x.TargetPort == lp.Module && !x.IsLoaded)) continue; var lpDevice = DEVICE.GetDevice($"PM1.{lp.Module}"); if (lp.IsReadyForPick(_carrierRobot.Module, 0) && lpDevice.IsLoadCompleted) { var carrierPara = tj.CarrierParas.First(x => x.TargetPort == lp.Module && !x.IsLoaded); if (carrierPara != null && _carrierRobot.Load(lp.Module, 0, Hand.Blade1, carrierPara.Stocker, carrierPara.CarrierType, carrierPara.CarrierID, carrierPara)) { lp.WaitTransfer(ModuleName.CarrierRobot); return; } } } } } else { var carrier = CarrierManager.Instance.GetCarrier(ModuleName.CarrierRobot, 0); if (carrier != null && !carrier.IsEmpty) { foreach (var lp in _lstLPs) { if (!lp.IsAvailable || !CarrierManager.Instance.CheckNoCarrier(lp.Module, 0)) continue; var para = tj.CarrierParas.FirstOrDefault(x => x.Stocker == carrier.InternalModuleName); if (para == null || para.TargetPort != lp.Module) continue; var lpDevice = DEVICE.GetDevice($"PM1.{lp.Module}"); if (lp.IsReadyForPlace(_carrierRobot.Module, 0) && lpDevice.IsLoadCompleted) { if (_carrierRobot.Unload(lp.Module, 0, Hand.Blade1, para)) { lp.WaitTransfer(ModuleName.CarrierRobot); return; } } } } } } private void MonitorCarrierRobotFIMSTask() { if (!_carrierRobot.IsAvailable) return; var tj = _lstTransferJobs.Find(x => x.State == EnumTransferJobState.Active); if (tj == null || tj.CarrierParas == null || tj.Type != EnumTransferJobType.Loading) return; //pick var carrier = CarrierManager.Instance.GetCarrier(ModuleName.CarrierRobot, 0); if (carrier != null && carrier.IsEmpty) { SchedulerFIMS fims = null; foreach (var st in _lstFIMSs) { if (!st.IsAvailable || !st.IsReadyForPick(ModuleName.CarrierRobot, 0)) continue; if (CarrierManager.Instance.CheckHasCarrier(st.Module, 0)) { carrier = CarrierManager.Instance.GetCarrier(st.Module, 0); var fimsDevice = DEVICE.GetDevice($"PM1.{st.Module}"); if (carrier != null && carrier.IsMapped && carrier.IsMapOK && fimsDevice.IsUnloadCompleted && !SC.GetValue("WaferRobot.BypassFIMSMap")) { if (tj.CarrierParas.Any(x => x.Stocker == carrier.InternalModuleName)) { fims = st; break; } } } } if (fims != null) { if (_carrierRobot.Pick(fims.Module, 0, Hand.Blade1)) { fims.WaitTransfer(ModuleName.CarrierRobot); return; } } } if (!_carrierRobot.IsAvailable) return; //place carrier = CarrierManager.Instance.GetCarrier(ModuleName.CarrierRobot, 0); if (carrier != null && !carrier.IsEmpty && !carrier.IsMapped && tj.CarrierParas.Any(x => x.Stocker == carrier.InternalModuleName) && !SC.GetValue("WaferRobot.BypassFIMSMap")) { SchedulerFIMS fims = null; foreach (var st in _lstFIMSs) { if (!st.IsAvailable || !st.IsReadyForPlace(ModuleName.CarrierRobot, 0)) continue; var fimsDevice = DEVICE.GetDevice($"PM1.{st.Module}"); if (CarrierManager.Instance.CheckNoCarrier(st.Module, 0) && fimsDevice.IsUnloadCompleted) { fims = st; break; } } if (fims != null) { if (_carrierRobot.Place(fims.Module, 0, Hand.Blade1)) { fims.WaitTransfer(ModuleName.CarrierRobot); return; } } } } public List GetTransferJobStockers() { if (!_lstTransferJobs.Any()) return null; var tj = _lstTransferJobs.Find(x => x.State == EnumTransferJobState.Active); if (tj == null || tj.CarrierParas == null) return null; return tj.CarrierParas; } #endregion #region Job task public Result MonitorJobTasks() { UpdateTransferJobStatus(); StartNewJob(); return Result.RUN; } private void UpdateTransferJobStatus() { if (!_lstTransferJobs.Any()) return; if (!_carrierRobot.IsAvailable) return; List removeJobLst = new List(); foreach (var tj in _lstTransferJobs) { if (tj == null || tj.CarrierParas == null) continue; bool isComplete = true; if (tj.Type == EnumTransferJobType.Loading) { foreach (var item in tj.CarrierParas) { if (!CarrierManager.Instance.CheckHasCarrier(item.Stocker, 0)) { isComplete = false; continue; } var carrier = CarrierManager.Instance.GetCarrier(item.Stocker, 0); if (carrier != null && (carrier.IsEmpty || (!carrier.IsMapped && !SC.GetValue("WaferRobot.BypassFIMSMap")) || !item.IsLoaded)) { isComplete = false; continue; } } } else { foreach (var lp in _lstLPs) { if (tj.CarrierParas.Any(x => x.TargetPort == lp.Module)) { if (CarrierManager.Instance.CheckHasCarrier(lp.Module, 0)) { isComplete = false; continue; } } } if (tj.CarrierParas.Any(x => !x.IsUnloaded)) { isComplete = false; continue; } } if (isComplete) { tj.State = EnumTransferJobState.Complete; removeJobLst.Add(tj); string stocker = ""; tj.CarrierParas.ForEach(x => stocker += $"{x.Stocker}-"); LOG.Write($"Scheduler:{stocker} {tj.Type} change to complete"); if (tj.Type == EnumTransferJobType.Loading) { List unloadLPs = new List(); foreach (var item in tj.CarrierParas) { if (!unloadLPs.Contains(item.TargetPort) && !_lstTransferJobs.Any(x => (x.State == EnumTransferJobState.Created || x.State == EnumTransferJobState.Active) && x.CarrierParas.Any(ca => ca.TargetPort == item.TargetPort))) unloadLPs.Add(item.TargetPort); } //foreach (var lp in unloadLPs) //{ // (Singleton.Instance.Modules[lp] as LoadPortModule).InvokeUnload(); // LOG.Write($"Scheduler:{lp} start unload"); //} } } } foreach (var item in removeJobLst) { _lstTransferJobs.Remove(item); } } private void StartNewJob() { if (!_lstTransferJobs.Any() || !_carrierRobot.IsAvailable) return; //没有在process的stocker时,以时间先后为准 var processingStockers = Singleton.Instance.GetProcessingStockers(); if (processingStockers != null) { //有在process的stocker时,以时间先后和所有stokcer都不在process为准 foreach (var tj in _lstTransferJobs) { if (tj == null || tj.CarrierParas == null) continue; bool hasStokcerInProcessing = false; foreach (var item in tj.CarrierParas) { if (processingStockers.Any(x => x.Item1 == item.Stocker.ToString())) { hasStokcerInProcessing = true; break; } } if (!hasStokcerInProcessing) { break; } } } var tjActives = GetFirstCreatedTransferJob(EnumTransferJobType.Loading); if (tjActives.Any()) { foreach (var tjActive in tjActives) { if (tjActive != null && tjActive.State == EnumTransferJobState.Created && tjActive.Type == EnumTransferJobType.Loading) { bool isStockerReady = true; foreach (var stocker in _lstTotlaStockers) { if (CarrierManager.Instance.CheckHasCarrier(stocker.Module, 0)) { var carrier = CarrierManager.Instance.GetCarrier(stocker.Module, 0); if (carrier != null && tjActive.CarrierParas.Any(x => x.Stocker == carrier.InternalModuleName)) isStockerReady = false; } } if (CarrierManager.Instance.CheckHasCarrier(_carrierRobot.Module, 0)) { var carrier = CarrierManager.Instance.GetCarrier(_carrierRobot.Module, 0); if (carrier != null && tjActive.CarrierParas.Any(x => x.Stocker == carrier.InternalModuleName)) isStockerReady = false; } foreach (var fims in _lstFIMSs) { if (CarrierManager.Instance.CheckHasCarrier(fims.Module, 0)) { var carrier = CarrierManager.Instance.GetCarrier(fims.Module, 0); if (carrier != null && tjActive.CarrierParas.Any(x => x.Stocker == carrier.InternalModuleName)) isStockerReady = false; } } if (isStockerReady) { //transfer job开始 tjActive.State = EnumTransferJobState.Active; } if (tjActive.State == EnumTransferJobState.Active) { foreach (var lp in _lstLPs) { if (!lp.IsAvailable) continue; if (!tjActive.CarrierParas.Any(x => x.TargetPort == lp.Module)) continue; var lpDevice = DEVICE.GetDevice($"PM1.{lp.Module}"); } } } } } tjActives = GetFirstCreatedTransferJob(EnumTransferJobType.Unloading); if (tjActives.Any()) { foreach (var tjActive in tjActives) { if (tjActive != null && tjActive.State == EnumTransferJobState.Created && tjActive.Type == EnumTransferJobType.Unloading) { bool isStockerReady = true; var allPJStockers = Singleton.Instance.GetAllPJStockers(); foreach (var item in tjActive.CarrierParas) { if (CarrierManager.Instance.CheckNoCarrier(item.Stocker, 0)) { isStockerReady = false; continue; } if (allPJStockers != null && allPJStockers.Any(x => x.Item1 == item.Stocker.ToString())) { isStockerReady = false; continue; } var carrier = CarrierManager.Instance.GetCarrier(item.Stocker, 0); if (carrier != null && item.Stocker != carrier.InternalModuleName) isStockerReady = false; } if (isStockerReady) { //transfer job开始 tjActive.State = EnumTransferJobState.Active; } if (tjActive.State == EnumTransferJobState.Active) { foreach (var lp in _lstLPs) { if (!lp.IsAvailable) continue; if (!tjActive.CarrierParas.Any(x => x.TargetPort == lp.Module)) continue; } } } } } } internal List GetFirstCreatedTransferJob(EnumTransferJobType type) { DateTime dtMin = DateTime.MaxValue; List currentTj = new List(); var lpNumber = 2; List occupyLPs = new List(); foreach (var tj in _lstTransferJobs) { if (tj == null || tj.State == EnumTransferJobState.Active || tj.State == EnumTransferJobState.Complete || tj.Type != type) { continue; } if (occupyLPs.Count == lpNumber) break; currentTj.Add(tj); foreach (var para in tj.CarrierParas) { if (type == EnumTransferJobType.Loading && !para.IsLoaded && !occupyLPs.Any(x => x == para.TargetPort)) occupyLPs.Add(para.TargetPort); if (type == EnumTransferJobType.Unloading && !para.IsUnloaded && !occupyLPs.Any(x => x == para.TargetPort)) occupyLPs.Add(para.TargetPort); } } return currentTj; } public List GetOccupyStockers() { var occupyStockers = new List(); var checkModuleLst = new List(); checkModuleLst.Add(ModuleName.CarrierRobot); foreach (var fims in _lstFIMSs) { if (fims == null) continue; checkModuleLst.Add(fims.Module); } foreach (var stocker in _lstTotlaStockers) { if (stocker == null) continue; checkModuleLst.Add(stocker.Module); } foreach (var module in checkModuleLst) { var carrier = CarrierManager.Instance.GetCarrier(module, 0); if (carrier == null || carrier.IsEmpty) continue; occupyStockers.Add(carrier.InternalModuleName.ToString()); } var loadCarrierParas = new List(); if (_lstTransferJobs.Any()) { foreach (var tj in _lstTransferJobs) { if (tj == null || tj.Type != EnumTransferJobType.Loading) continue; loadCarrierParas.AddRange(tj.CarrierParas); } } if (loadCarrierParas != null && loadCarrierParas.Any()) { foreach (var para in loadCarrierParas) { occupyStockers.Add(para.Stocker.ToString()); } } return occupyStockers; } #endregion } }