123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523 |
- using Aitex.Core.Common;
- using Aitex.Core.Util;
- using Aitex.Sorter.Common;
- using MECF.Framework.Common.DBCore;
- using MECF.Framework.Common.Jobs;
- using MECF.Framework.Common.Routine;
- using MECF.Framework.Common.SubstrateTrackings;
- using CyberX8_Core;
- using CyberX8_RT.Modules;
- using CyberX8_RT.Schedulers;
- using SecsGem.Core.ItemModel;
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using Aitex.Core.RT.Log;
- namespace CyberX8_RT.Dispatch
- {
- public class JobDispatcher : ICycle
- {
- #region 内部变量
- /// <summary>
- /// 状态
- /// </summary>
- private RState _cycleState = RState.Init;
- /// <summary>
- /// Cycle计时器
- /// </summary>
- private Stopwatch _cycleWatch = new Stopwatch();
- #endregion
- /// <summary>
- /// 是否存在Job
- /// </summary>
- public bool HasJobRunning => JobProcesser.Instance.ControlJobInfos.Count > 0;
- /// <summary>
- /// 状态
- /// </summary>
- public RState CycleState => _cycleState;
- /// <summary>
- /// 构造函数
- /// </summary>
- public JobDispatcher()
- {
- SchedulerManager.Instance.Initialize();
- CycleManager.Instance.Initialize();
- }
- public void Abort()
- {
- }
- #region Job
- /// <summary>
- /// 创建任务
- /// </summary>
- /// <param name="param"></param>
- /// <param name="reason"></param>
- /// <returns></returns>
- public bool CreateJob(Dictionary<string, object> param, out string reason)
- {
- return JobProcesser.Instance.CreateJob(param, out reason);
- }
- /// <summary>
- /// 暂停所有任务
- /// </summary>
- /// <returns></returns>
- public bool PauseAllJobs()
- {
- foreach(var job in JobProcesser.Instance.ControlJobInfos)
- {
- bool result = JobProcesser.Instance.PauseJob(job.Name,out string reason);
- if(!result)
- {
- return false;
- }
- }
- _cycleState = RState.Paused;
- WaferHolderTaskManager.Instance.PauseAllTask();
- WaferTaskManager.Instance.PauseAllTask();
- return true;
- }
- /// <summary>
- /// 暂停Job
- /// </summary>
- /// <param name="jobName"></param>
- /// <param name="reason"></param>
- /// <returns></returns>
- public bool PauseJob(string jobName, out string reason)
- {
- bool result = JobProcesser.Instance.PauseJob(jobName, out reason);
- if(result)
- {
- if (!JobProcesser.Instance.ControlJobInfos.Exists(job => job.State == EnumControlJobState.Executing))
- _cycleState = RState.Paused;
-
- }
- return result;
- }
- /// <summary>
- /// 恢复所有任务
- /// </summary>
- /// <returns></returns>
- public bool ResumeAllJobs()
- {
- foreach (var job in JobProcesser.Instance.ControlJobInfos)
- {
- bool result = JobProcesser.Instance.ResumeJob(job.Name, out string reason);
- if (!result)
- {
- return false;
- }
- }
- WaferHolderTaskManager.Instance.ResumeAllTask();
- WaferTaskManager.Instance.ResumeAllTask();
- _cycleState = RState.Running;
- return true;
- }
- /// <summary>
- /// 恢复Job
- /// </summary>
- /// <param name="jobName"></param>
- /// <param name="reason"></param>
- /// <returns></returns>
- public bool ResumeJob(string jobName, out string reason)
- {
- bool result=JobProcesser.Instance.ResumeJob(jobName, out reason);
- if(result)
- {
- _cycleState = RState.Running;
- }
- return result;
- }
- /// <summary>
- /// 启动任务
- /// </summary>
- /// <param name="jobName"></param>
- /// <param name="reason"></param>
- /// <returns></returns>
- /// <exception cref="NotImplementedException"></exception>
- public bool StartJob(string jobName, out string reason)
- {
- bool result = JobProcesser.Instance.StartJob(jobName, out reason);
- if(result)
- {
- ControlJobInfo cj = JobProcesser.Instance.ControlJobInfos.Find(x => x.Name == jobName);
- if (!_cycleWatch.IsRunning)
- {
- _cycleWatch.Restart();
- }
- _cycleState = RState.Running;
- }
- return result;
- }
- /// <summary>
- /// 停止任务
- /// </summary>
- /// <param name="jobName"></param>
- /// <param name="reason"></param>
- /// <returns></returns>
- public bool StopJob(string jobName, out string reason)
- {
- return JobProcesser.Instance.StopJob(jobName, out reason);
- }
- /// <summary>
- /// System Abort
- /// </summary>
- /// <returns></returns>
- public bool SystemAbort()
- {
- JobProcesser.Instance.SystemAbort();
- return true;
- }
- /// <summary>
- /// 删除所有job
- /// </summary>
- /// <returns></returns>
- public bool RemoveAllJob()
- {
- JobProcesser.Instance.RemoveAllJob();
- return true;
- }
- #endregion
- /// <summary>
- /// 检验是否所有任务完成
- /// </summary>
- /// <returns></returns>
- public bool CheckAllJobDone()
- {
- foreach (var cj in JobProcesser.Instance.ControlJobInfos)
- {
- if (cj.State != EnumControlJobState.Completed)
- return false;
- }
- return true;
- }
- /// <summary>
- /// 检验是否存在已经完成的任务
- /// </summary>
- /// <param name="sJobName"></param>
- /// <returns></returns>
- public bool CheckJobJustDone(out string sJobName)
- {
- foreach (var cj in JobProcesser.Instance.ControlJobInfos)
- {
- if (cj.State == EnumControlJobState.Completed && !cj.BeenPosted)
- {
- sJobName = $"{cj.Module};{cj.JobWaferSize};{cj.LotName};{cj.LotWafers.Count};{cj.StartTime:T};{cj.EndTime:T}";
- cj.BeenPosted = true;
- return true;
- }
- }
- sJobName = "NULL";
- return false;
- }
- public RState CheckManualReturnWafer()
- {
- return RState.End;
- }
- public void Clear()
- {
- }
-
- public bool ManualReturnWafer(object[] objs)
- {
- return true;
- }
- /// <summary>
- /// 监控
- /// </summary>
- /// <returns></returns>
- public RState Monitor()
- {
- UpdateProcessJobStatus();
- UpdateControlJobStatus();
- CreateWaferHolderTask();
- RunWaferHolderTask();
- RunWaferTask();
- return _cycleState;
- }
- public RState ReturnAllWafers()
- {
- return RState.Init;
- }
- /// <summary>
- /// 启动
- /// </summary>
- /// <param name="objs"></param>
- /// <returns></returns>
- public RState Start(params object[] objs)
- {
- _cycleWatch.Stop();
- SchedulerManager.Instance.ResetSchedulerModule();
- CycleManager.Instance.InitializeAllLoadPortData();
- return RState.Running;
- }
- /// <summary>
- /// 更新ProcessJob状态
- /// </summary>
- private void UpdateProcessJobStatus()
- {
- foreach (var pj in JobProcesser.Instance.ProcessJobInfos)
- {
- if (CheckAllWaferReturned(pj, pj.State != EnumProcessJobState.Stopping))
- {
- pj.SetState(EnumProcessJobState.ProcessingComplete);
- JobDataRecorder.EndPJ(pj.InnerId.ToString(), 0, 0);
- }
- }
- List<ProcessJobInfo> list = JobProcesser.Instance.GetRecipeStateProcessJobs(EnumProcessJobState.Queued);
- foreach(var item in list)
- {
- if(SchedulerSequenceRecipeManager.Instance.ExistAvaibleProcessCell(item.SequenceRecipe, false))
- {
- ActiveProcessJob(item);
- }
- else
- {
- UpdateProcessJobCanceled(item);
- }
- }
- }
- /// <summary>
- /// ProcessJob状态修改为canceled
- /// </summary>
- /// <param name="pj"></param>
- private void UpdateProcessJobCanceled (ProcessJobInfo pj)
- {
- foreach (var slot in pj.SlotWafers)
- {
- var wafer = WaferManager.Instance.GetWafer(slot.Item1, slot.Item2);
- if (!wafer.IsEmpty&&wafer.ProcessState==EnumWaferProcessStatus.Idle)
- {
- wafer.ProcessState = EnumWaferProcessStatus.Canceled;
- LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"wafer {slot.Item1} slot {slot.Item2} state changed to canceled");
- }
- }
- pj.SetState(EnumProcessJobState.Canceled);
- JobDataRecorder.EndPJ(pj.InnerId.ToString(), 0, 0);
- LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"Processjob sequence {pj.SequenceRecipe.Ppid} not avaible cell,state changed to canceled");
- }
- /// <summary>
- /// 检验ProcessJob是否所有Wafer已经回到了LoadPort
- /// </summary>
- /// <param name="pj"></param>
- /// <param name="checkAllProcessed"></param>
- /// <returns></returns>
- private bool CheckAllWaferReturned(ProcessJobInfo pj, bool checkAllProcessed)
- {
- bool allWaferReturn = true;
- foreach (var slot in pj.SlotWafers)
- {
- var wafer = WaferManager.Instance.GetWafer(slot.Item1, slot.Item2);
- if (wafer.IsEmpty || (wafer.ProcessState != EnumWaferProcessStatus.Completed && checkAllProcessed))
- {
- allWaferReturn = false;
- break;
- }
- }
- return allWaferReturn;
- }
- /// <summary>
- /// 更新ControlJob状态
- /// </summary>
- private void UpdateControlJobStatus()
- {
- if(JobProcesser.Instance.ControlJobInfos==null||JobProcesser.Instance.ControlJobInfos.Count==0)
- {
- return;
- }
- List<ControlJobInfo> runningJobs=JobProcesser.Instance.getRunningControlJobs();
- foreach (ControlJobInfo controlJobInfo in runningJobs)
- {
- if (IsAllProcessJobComplete(controlJobInfo))
- {
- CycleManager.Instance.UpdateCycleCount(controlJobInfo.Module);
- if (CycleManager.Instance.GetLoadportCycleCount(controlJobInfo.Module) >= controlJobInfo.CycleNumber)
- {
- JobProcesser.Instance.CompleteControlJob(controlJobInfo);
- FaJobManager.Instance.Complete(controlJobInfo.Name);
- LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{controlJobInfo.Name} complete");
- }
- else
- {
- JobProcesser.Instance.RestartControlJob(controlJobInfo);
- }
- }
- }
- if(CheckAllJobDone())
- {
- _cycleState = RState.End;
- }
- }
- /// <summary>
- /// 是否所有ProcessJob已经完成
- /// </summary>
- /// <param name="cj"></param>
- /// <returns></returns>
- private bool IsAllProcessJobComplete(ControlJobInfo cj)
- {
- foreach (var pj in JobProcesser.Instance.ProcessJobInfos)
- {
- if (pj.ControlJobName == cj.Name)
- {
- if (pj.State == EnumProcessJobState.Canceled)
- {
- if (!CheckAllWaferReturned(pj, false))
- {
- return false;
- }
- }
- else if (pj.State != EnumProcessJobState.ProcessingComplete)
- {
- return false;
- }
- }
-
- for (int i = 0; i < pj.SlotWafers.Count; i++)
- {
- var item = pj.SlotWafers[i];
- if (WaferManager.Instance.CheckHasWafer(item.Item1, item.Item2))
- {
- WaferInfo waferInfo = WaferManager.Instance.GetWafer(item.Item1, item.Item2);
- if(WaferTaskManager.Instance.Contains(waferInfo.WaferID))
- {
- return false;
- }
- }
- }
- }
- return true;
- }
- /// <summary>
- /// 启动ProcessJob
- /// </summary>
- /// <param name="pj"></param>
- /// <returns></returns>
- private bool ActiveProcessJob(ProcessJobInfo pj)
- {
- if (pj.State == EnumProcessJobState.Queued)
- {
- ControlJobInfo cj = JobProcesser.Instance.ControlJobInfos.Find(O => O.Name == pj.ControlJobName);
- if (cj == null)
- {
- return false;
- }
- foreach (var pjSlotWafer in pj.SlotWafers)
- {
- WaferInfo wafer = WaferManager.Instance.GetWafer(pjSlotWafer.Item1, pjSlotWafer.Item2);
- wafer.ProcessJob = pj;
- wafer.NextSequenceStep = 0;
- WaferDataRecorder.SetPjInfo(wafer.InnerId.ToString(), pj.InnerId.ToString());
- }
- CarrierInfo carrier = CarrierManager.Instance.GetCarrier(cj.Module);
- JobDataRecorder.StartPJ(pj.InnerId.ToString(), carrier.InnerId.ToString(), cj.InnerId.ToString(), pj.Name, cj.Module, cj.Module, pj.SlotWafers.Count);
- pj.SetState(EnumProcessJobState.Processing);
- }
- return true;
- }
- /// <summary>
- /// 创建WaferHolder任务
- /// </summary>
- private void CreateWaferHolderTask()
- {
- if (JobProcesser.Instance.ProcessJobInfos.Count == 0) { return; }
- //查看Loader之前是否有Wafer(出现场景LoaderTransporter取WaferHolder出现Id不匹配,Loader前面就已经存在了Wafer)
- WaferInfo waferInfo = WaferHolderTaskManager.Instance.GetPreLoaderHasWafer();
- List<ProcessJobInfo> tmpProcessJobs = new List<ProcessJobInfo>();
- if (waferInfo == null)
- {
- var runningProcessJobs = JobProcesser.Instance.GetRecipeStateProcessJobs(EnumProcessJobState.Processing);
- foreach (var job in runningProcessJobs)
- {
- if (!SchedulerSequenceRecipeManager.Instance.ExistAvaibleProcessCell(job.SequenceRecipe, false))
- {
- UpdateProcessJobCanceled(job);
- continue;
- }
- if (!CheckProcessJobHasUncompleteWafer(job))
- {
- continue;
- }
- tmpProcessJobs.Add(job);
- }
- }
- else
- {
- if (waferInfo.ProcessJob != null)
- {
- tmpProcessJobs.Add(waferInfo.ProcessJob);
- }
- }
- if (tmpProcessJobs.Count != 0)
- {
- WaferHolderTaskManager.Instance.CreateWaferHolderTask(tmpProcessJobs);
- }
- else
- {
- WaferHolderTaskManager.Instance.CreateDummyWaferHolderTask();
- }
- }
- /// <summary>
- /// 检验ProcessJob是否存在未加工的Wafer
- /// </summary>
- /// <param name="pj"></param>
- /// <returns></returns>
- private bool CheckProcessJobHasUncompleteWafer(ProcessJobInfo pj)
- {
- for (int i = 0; i < pj.SlotWafers.Count; i++)
- {
- var item = pj.SlotWafers[i];
- if (WaferManager.Instance.CheckHasWafer(item.Item1, item.Item2))
- {
- WaferInfo waferInfo = WaferManager.Instance.GetWafer(item.Item1, item.Item2);
- if (waferInfo != null && waferInfo.ProcessState == EnumWaferProcessStatus.Idle)
- {
- if (!WaferTaskManager.Instance.Contains(waferInfo.WaferID))
- {
- return true;
- }
- }
- }
- }
- return false;
- }
- /// <summary>
- /// 运行WaferHolder任务
- /// </summary>
- private void RunWaferHolderTask()
- {
- WaferHolderTaskDispatcher.Instance.Analyse();
- }
- /// <summary>
- /// 运行Wafer任务
- /// </summary>
- private void RunWaferTask()
- {
- List<WaferTask> waferTasks = WaferTaskManager.Instance.LoadWaferTaskList();
- foreach(var item in waferTasks)
- {
- item.Run();
- }
- }
- }
- }
|