WaferHolderTask.cs 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015
  1. using Aitex.Core.RT.Log;
  2. using Aitex.Core.Util;
  3. using MECF.Framework.Common.Equipment;
  4. using MECF.Framework.Common.SubstrateTrackings;
  5. using MECF.Framework.Common.WaferHolder;
  6. using CyberX8_Core;
  7. using CyberX8_RT.Modules.Loader;
  8. using CyberX8_RT.Modules.PUF;
  9. using CyberX8_RT.Modules;
  10. using CyberX8_RT.Schedulers;
  11. using System;
  12. using System.Collections.Generic;
  13. using System.ComponentModel;
  14. using System.Linq;
  15. using System.Text;
  16. using System.Threading.Tasks;
  17. using System.Windows.Documents;
  18. using Aitex.Core.Common;
  19. using MECF.Framework.Common.CommonData;
  20. using MECF.Framework.Common.Jobs;
  21. using Aitex.Core.RT.Fsm;
  22. using MECF.Framework.Common.RecipeCenter;
  23. using MECF.Framework.Common.ToolLayout;
  24. using Aitex.Core.RT.Routine;
  25. namespace CyberX8_RT.Dispatch
  26. {
  27. public enum WaferHolderTaskState
  28. {
  29. Created,
  30. Processing,
  31. End,
  32. Error,
  33. Canceled
  34. }
  35. /// <summary>
  36. /// WaferHolder
  37. /// </summary>
  38. /// <param name="info"></param>
  39. /// <param name="schedulerSequence"></param>
  40. public delegate void WaferHolderSchedulerComplete(WaferHolderInfo info, SchedulerSequence schedulerSequence);
  41. /// <summary>
  42. /// WaferHolderTask完成
  43. /// </summary>
  44. /// <param name="id"></param>
  45. public delegate void WaferHolderTaskComplete(string id);
  46. public class WaferHolderTask
  47. {
  48. #region 内部变量
  49. /// <summary>
  50. /// 调度步骤
  51. /// </summary>
  52. private List<SchedulerSequence> _schedulerSequences;
  53. /// <summary>
  54. /// 当前步骤索引
  55. /// </summary>
  56. private int _currentSequenceIndex = 0;
  57. /// <summary>
  58. /// PUF实例
  59. /// </summary>
  60. private PUFEntity _puf1Entity;
  61. /// <summary>
  62. /// PUF实例
  63. /// </summary>
  64. private PUFEntity _puf2Entity;
  65. /// <summary>
  66. /// 是否开始执行
  67. /// </summary>
  68. private bool _isStart = false;
  69. /// <summary>
  70. /// 暂停时的索引
  71. /// </summary>
  72. private int _pausedIndex = -1;
  73. /// <summary>
  74. /// 错误上升触发
  75. /// </summary>
  76. private R_TRIG _sequenceErrorTigger = new R_TRIG();
  77. /// <summary>
  78. /// Sequence类型
  79. /// </summary>
  80. private string _sequenceType = "";
  81. /// <summary>
  82. /// FA回复
  83. /// </summary>
  84. private SchedulerFACallback _schedulerFACallback = new SchedulerFACallback();
  85. #endregion
  86. #region 属性
  87. /// <summary>
  88. /// ID
  89. /// </summary>
  90. public string ID { get;private set; }
  91. /// <summary>
  92. /// WaferHolder属性
  93. /// </summary>
  94. public WaferHolderInfo WaferHolderInfo { get;private set; }
  95. /// <summary>
  96. /// Process Job信息
  97. /// </summary>
  98. public ProcessJobInfo ProcessJobInfo { get;private set; }
  99. /// <summary>
  100. /// 状态
  101. /// </summary>
  102. public WaferHolderTaskState State { get; private set; }
  103. /// <summary>
  104. /// 步骤完成事件
  105. /// </summary>
  106. public event WaferHolderSchedulerComplete OnSchedulerComplete;
  107. /// <summary>
  108. /// 任务完成事件
  109. /// </summary>
  110. public event WaferHolderTaskComplete OnTaskComplete;
  111. /// <summary>
  112. /// 调度集合
  113. /// </summary>
  114. public List<SchedulerSequence> SchedulerSequences { get { return _schedulerSequences; } }
  115. #endregion
  116. /// <summary>
  117. /// 构造函数
  118. /// </summary>
  119. /// <param name="waferHolderInfo"></param>
  120. /// <param name="schedulerSequences"></param>
  121. public WaferHolderTask(WaferHolderInfo waferHolderInfo,ProcessJobInfo processJobInfo)
  122. {
  123. ID=Guid.NewGuid().ToString();
  124. WaferHolderInfo=waferHolderInfo;
  125. WaferHolderInfo.Status = WaferHolderStatus.Normal;
  126. if (processJobInfo != null)
  127. {
  128. WaferHolderInfo.SequenceId = processJobInfo.SequenceRecipe.Ppid;
  129. WaferHolderInfo.SequenceRecipe = processJobInfo.SequenceRecipe;
  130. _sequenceType = processJobInfo.SequenceRecipe.SequenceType;
  131. WaferHolderInfo.CurrentControlJobId = processJobInfo.ControlJobName;
  132. WaferHolderInfo.LotId = processJobInfo.LotName;
  133. }
  134. else
  135. {
  136. AnalyseProductionProcessJobInfo();
  137. }
  138. ProcessJobInfo=processJobInfo;
  139. State = WaferHolderTaskState.Created;
  140. _puf1Entity = Singleton<RouteManager>.Instance.GetModule<PUFEntity>(ModuleName.PUF1.ToString());
  141. _puf2Entity = Singleton<RouteManager>.Instance.GetModule<PUFEntity>(ModuleName.PUF2.ToString());
  142. }
  143. /// <summary>
  144. /// 初始化调度步骤
  145. /// </summary>
  146. /// <param name="schedulers"></param>
  147. public void InitialSchedulers(List<SchedulerSequence> schedulers)
  148. {
  149. _schedulerSequences = schedulers;
  150. }
  151. /// <summary>
  152. /// 分析生产片的ProcessJob信息
  153. /// </summary>
  154. private void AnalyseProductionProcessJobInfo()
  155. {
  156. if (string.IsNullOrEmpty(WaferHolderInfo.WaferAId))
  157. {
  158. WaferInfo waferAInfo = WaferManager.Instance.GetWaferByWaferId(WaferHolderInfo.WaferAId);
  159. if (waferAInfo != null && waferAInfo.WaferType == WaferType.Production)
  160. {
  161. ProcessJobInfo = waferAInfo.ProcessJob;
  162. _sequenceType = ProcessJobInfo.SequenceRecipe.SequenceType;
  163. WaferHolderInfo.CurrentControlJobId = ProcessJobInfo.ControlJobName;
  164. WaferHolderInfo.LotId = ProcessJobInfo.LotName;
  165. return;
  166. }
  167. }
  168. if (string.IsNullOrEmpty(WaferHolderInfo.WaferBId))
  169. {
  170. WaferInfo waferBInfo = WaferManager.Instance.GetWaferByWaferId(WaferHolderInfo.WaferBId);
  171. if (waferBInfo != null && waferBInfo.WaferType == WaferType.Production)
  172. {
  173. ProcessJobInfo = waferBInfo.ProcessJob;
  174. _sequenceType = ProcessJobInfo.SequenceRecipe.SequenceType;
  175. WaferHolderInfo.CurrentControlJobId = ProcessJobInfo.ControlJobName;
  176. WaferHolderInfo.LotId = ProcessJobInfo.LotName;
  177. }
  178. }
  179. }
  180. /// <summary>
  181. /// 执行
  182. /// </summary>
  183. public void Run()
  184. {
  185. if(_currentSequenceIndex>=_schedulerSequences.Count)
  186. {
  187. State = WaferHolderTaskState.End;
  188. if(OnTaskComplete!=null)
  189. {
  190. OnTaskComplete(ID);
  191. }
  192. FaModuleNotifier.Instance.NotifyWaferShuttleJobEnd(WaferHolderInfo);
  193. LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"WaferHolder {WaferHolderInfo.Id} task complete");
  194. return;
  195. }
  196. if (!_isStart)
  197. {
  198. bool preCondition = CheckStartCondition();
  199. if (!preCondition)
  200. {
  201. return;
  202. }
  203. LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"{WaferHolderInfo.Id} prepare Start {_currentSequenceIndex + 1} sequence");
  204. _isStart = true;
  205. if (WaferHolderInfo.SchedulerModules == null)
  206. {
  207. WaferHolderInfo.SchedulerModules = new List<string>();
  208. }
  209. WaferHolderInfo.SchedulerModules.Clear();
  210. }
  211. SchedulerSequence sequence = _schedulerSequences[_currentSequenceIndex];
  212. //暂停中
  213. if (sequence.State == RState.Init && _currentSequenceIndex >= _pausedIndex && _pausedIndex != -1)
  214. {
  215. return;
  216. }
  217. if (_currentSequenceIndex == _schedulerSequences.Count - 1 && sequence.State == RState.End)
  218. {
  219. State=WaferHolderTaskState.End;
  220. if (OnTaskComplete != null)
  221. {
  222. OnTaskComplete(ID);
  223. }
  224. FaModuleNotifier.Instance.NotifyWaferShuttleJobEnd(WaferHolderInfo);
  225. LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"WaferHolder {WaferHolderInfo.Id} task complete");
  226. return;
  227. }
  228. if(_currentSequenceIndex<_schedulerSequences.Count)
  229. {
  230. if(sequence.State==RState.Init)
  231. {
  232. if(sequence.SchedulerModule==null)
  233. {
  234. return;
  235. }
  236. if(!BufferWaferHolderJudgeResource(sequence))
  237. {
  238. return;
  239. }
  240. string reason = "";
  241. bool sequeceCondition = sequence.SchedulerModule.CheckPrecondition(_schedulerSequences, _currentSequenceIndex, sequence.Parameters,WaferHolderInfo.Id,ref reason);
  242. if (sequeceCondition)
  243. {
  244. bool result = sequence.SchedulerModule.RunProcess(sequence.Recipe,sequence.Parameters, sequence.SynchronousModuleMessages);
  245. if (result)
  246. {
  247. if (State == WaferHolderTaskState.Created)
  248. {
  249. State = WaferHolderTaskState.Processing;
  250. FaModuleNotifier.Instance.NotifyWaferShuttleJobStart(WaferHolderInfo);
  251. }
  252. sequence.State = RState.Running;
  253. sequence.StartTime = DateTime.Now;
  254. LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"{WaferHolderInfo.Id} Start {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module}");
  255. }
  256. else
  257. {
  258. if (sequence.ModuleName == ModuleName.Transporter1&&sequence.NextModuleType==ModuleType.Metal)
  259. {
  260. if (!CheckAfterMetalAvaible())
  261. {
  262. LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"{WaferHolderInfo.Id} {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module} has no avaible metal");
  263. WaferHolderMoveItem waferHolderMoveItem = sequence.Parameters as WaferHolderMoveItem;
  264. waferHolderMoveItem.DestModuleType = ModuleType.Dryer;
  265. waferHolderMoveItem.DestModule = ModuleName.Unknown;
  266. LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"{WaferHolderInfo.Id} {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module} next sequence changed to dryer");
  267. }
  268. }
  269. }
  270. }
  271. else
  272. {
  273. _sequenceErrorTigger.CLK = !sequeceCondition;
  274. if (_sequenceErrorTigger.Q)
  275. {
  276. LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferHolderInfo.Id} Start {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module} failed,{reason}");
  277. }
  278. }
  279. }
  280. else if(sequence.State==RState.Running)
  281. {
  282. sequence.SchedulerModule.MonitorProcess(sequence,false);
  283. _sequenceErrorTigger.CLK = sequence.SchedulerModule.IsError;
  284. if (sequence.SchedulerModule.IsError)
  285. {
  286. //用于LoadTransporter取的WaferHolder Id不一致,则取消当前WaferHolderTask
  287. if (sequence.ModuleName == ModuleName.Transporter2)
  288. {
  289. LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"{WaferHolderInfo.Id} {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module} failed,task canceled");
  290. State = WaferHolderTaskState.Canceled;
  291. return;
  292. }
  293. if (_sequenceErrorTigger.Q)
  294. {
  295. AnalyseSchedulerErrorState(sequence);
  296. }
  297. }
  298. else if(sequence.SchedulerModule.IsIdle)
  299. {
  300. sequence.EndTime = DateTime.Now;
  301. sequence.State = RState.End;
  302. sequence.ProcessMilliSeconds=sequence.EndTime.Subtract(sequence.StartTime).TotalMilliseconds;
  303. if(sequence.IsProcessSequece)
  304. {
  305. UpdateWaferHolderProcessingStatus();
  306. }
  307. if(sequence.IsLastProcessSequence)
  308. {
  309. UpdateWaferHolderProcessComplete();
  310. }
  311. if (OnSchedulerComplete != null)
  312. {
  313. OnSchedulerComplete(WaferHolderInfo, sequence);
  314. }
  315. UpdateLoaderToBufferWaferHolderToloaderStatus(sequence);
  316. LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferHolderInfo.Id} {_currentSequenceIndex + 1} sequence {sequence.ModuleName} complete, time length {sequence.ProcessMilliSeconds}");
  317. _currentSequenceIndex++;
  318. AutoChangeLoaderTransporterScheduler();
  319. //检验rinse后面是否存在可用的Metal
  320. if (sequence.ModuleType == ModuleType.Rinse)
  321. {
  322. AnalyseRinseAfterMetalAvaible(sequence);
  323. }
  324. else if (sequence.ModuleType == ModuleType.Prewet)
  325. {
  326. AnalysePrewetAfterMetalAvaible(sequence);
  327. }
  328. }
  329. }
  330. else if (sequence.State == RState.End)
  331. {
  332. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} {_currentSequenceIndex + 1} sequence is End");
  333. _currentSequenceIndex++;
  334. }
  335. }
  336. }
  337. /// <summary>
  338. /// 更新任务结束
  339. /// </summary>
  340. public void UpdateDryerLastSchedulerComplete()
  341. {
  342. SchedulerSequence sequence = _schedulerSequences[_currentSequenceIndex];
  343. sequence.EndTime = DateTime.Now;
  344. sequence.State = RState.End;
  345. sequence.ProcessMilliSeconds = sequence.EndTime.Subtract(sequence.StartTime).TotalMilliseconds;
  346. LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferHolderInfo.Id} {_currentSequenceIndex+1} sequence {sequence.ModuleName} complete, time length {sequence.ProcessMilliSeconds}");
  347. State = WaferHolderTaskState.End;
  348. if (OnTaskComplete != null)
  349. {
  350. OnTaskComplete(ID);
  351. }
  352. LOG.WriteLog(eEvent.EV_SEQUENCE, "Sequence", $"WaferHolder {WaferHolderInfo.Id} task complete");
  353. }
  354. /// <summary>
  355. /// 更新从Loader到Buffer的WaferHolder更新为不可以拉回至Loader
  356. /// </summary>
  357. /// <param name="sequence"></param>
  358. private void UpdateLoaderToBufferWaferHolderToloaderStatus(SchedulerSequence sequence)
  359. {
  360. string currentLocation = WaferHolderInfo.CurrentLocation;
  361. if(!Enum.TryParse(currentLocation,out ModuleName locationName))
  362. {
  363. return;
  364. }
  365. if (!ModuleHelper.IsBuffer(locationName))
  366. {
  367. return;
  368. }
  369. if (sequence.ModuleName == ModuleName.Transporter2)
  370. {
  371. WaferHolderMoveItem waferHolderMoveItem = sequence.Parameters as WaferHolderMoveItem;
  372. if (waferHolderMoveItem.SourceModule == ModuleName.Loader1&&waferHolderMoveItem.DestModuleType==ModuleType.Buffer)
  373. {
  374. WaferHolderInfo.IsToLoader = false;
  375. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} IsToLoader Changed to false;");
  376. }
  377. else if (waferHolderMoveItem.DestModuleType == ModuleType.Buffer && waferHolderMoveItem.SourceModuleType != ModuleType.Loader)
  378. {
  379. WaferHolderInfo.IsToLoader = true;
  380. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} IsToLoader Changed to true;");
  381. }
  382. }
  383. }
  384. /// <summary>
  385. /// 分析错误状态下的调度
  386. /// </summary>
  387. private void AnalyseSchedulerErrorState(SchedulerSequence sequence)
  388. {
  389. if (sequence.ModuleType == ModuleType.Prewet)
  390. {
  391. AnalyseSchedulerPrewetErrorState(sequence);
  392. }
  393. else if (sequence.ModuleType == ModuleType.Dryer)
  394. {
  395. AnalyseSchedulerDryerErrorState(sequence);
  396. }
  397. else if (sequence.ModuleType == ModuleType.Rinse)
  398. {
  399. AnalyseSchedulerRinseErrorState(sequence);
  400. }
  401. else if (sequence.ModuleType == ModuleType.Metal)
  402. {
  403. AnalyseSchedulerMetalErrorState(sequence);
  404. }
  405. }
  406. /// <summary>
  407. /// 判定Buffer中WaferHolder的后面工序是否存在可用资源,不存在的话,则Task直接结束
  408. /// </summary>
  409. /// <param name="sequence"></param>
  410. private bool BufferWaferHolderJudgeResource(SchedulerSequence sequence)
  411. {
  412. string currentLocation = WaferHolderInfo.CurrentLocation;
  413. if (Enum.TryParse(currentLocation, out ModuleName moduleName))
  414. {
  415. //当前WaferHolder处于Buffer中,当前步骤不是第一步,当前调度模块为transporter2
  416. if (ModuleHelper.IsBuffer(moduleName)&&_currentSequenceIndex!=0&&sequence.ModuleName==ModuleName.Transporter2)
  417. {
  418. if (!SchedulerSequenceRecipeManager.Instance.ExistAvaibleProcessCell(WaferHolderInfo.SequenceRecipe, false))
  419. {
  420. for (int i = _currentSequenceIndex; i < _schedulerSequences.Count; i++)
  421. {
  422. SchedulerSequence item = _schedulerSequences[i];
  423. item.State = RState.End;
  424. }
  425. _currentSequenceIndex = _schedulerSequences.Count - 1;
  426. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} exist no avaible cell");
  427. WaferHolderInfo.IsToLoader = true;
  428. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} IsToLoader Changed to true");
  429. RemoveWaferHolderSRDScheduler();
  430. UpdateWaferHolderMisProcessedStatus();
  431. return false;
  432. }
  433. }
  434. }
  435. return true;
  436. }
  437. /// <summary>
  438. /// 检验Prewet后面的Metal是否存在可用
  439. /// </summary>
  440. private void AnalysePrewetAfterMetalAvaible(SchedulerSequence schedulerSequence)
  441. {
  442. //获取可用的Metal以及Rinse
  443. if (!CheckAfterMetalAvaible())
  444. {
  445. LOG.WriteLog(eEvent.WARN_SCHEDULER, "System", $"{WaferHolderInfo.Id} has no avaible metal after prewet");
  446. SkipAfterMetal(schedulerSequence,true);
  447. RemoveWaferHolderSRDScheduler();
  448. UpdateWaferHolderMisProcessedStatus();
  449. //SchedulerSequence nextSchedulerSequence = _schedulerSequences[_currentSequenceIndex];
  450. //if (nextSchedulerSequence.ModuleName != ModuleName.Transporter1)
  451. //{
  452. // return;
  453. //}
  454. //WaferHolderMoveItem waferHolderMoveItem = nextSchedulerSequence.Parameters as WaferHolderMoveItem;
  455. //waferHolderMoveItem.DestModuleType = ModuleType.Dryer;
  456. //waferHolderMoveItem.DestModule = ModuleName.Unknown;
  457. }
  458. }
  459. /// <summary>
  460. /// 检验Rinse后面的Metal是否存在可用
  461. /// </summary>
  462. /// <returns></returns>
  463. private void AnalyseRinseAfterMetalAvaible(SchedulerSequence schedulerSequence)
  464. {
  465. //获取可用的Metal以及Rinse
  466. if(!CheckAfterMetalAvaible())
  467. {
  468. LOG.WriteLog(eEvent.WARN_SCHEDULER, "System", $"{WaferHolderInfo.Id} has no avaible metal after rinse");
  469. SkipAfterMetal(schedulerSequence,true);
  470. RemoveWaferHolderSRDScheduler();
  471. UpdateWaferHolderMisProcessedStatus();
  472. }
  473. }
  474. /// <summary>
  475. /// 检验后续Metal可用性
  476. /// </summary>
  477. /// <returns></returns>
  478. private bool CheckAfterMetalAvaible()
  479. {
  480. for (int i = _currentSequenceIndex + 1; i < _schedulerSequences.Count; i++)
  481. {
  482. SchedulerSequence sequence = _schedulerSequences[i];
  483. if (sequence.ModuleType != ModuleType.Metal)
  484. {
  485. continue ;
  486. }
  487. if (sequence.Recipe == null || !(sequence.Recipe is DepRecipe))
  488. {
  489. continue;
  490. }
  491. DepRecipe depRecipe = (DepRecipe)sequence.Recipe;
  492. bool result= SchedulerSequenceManager.Instance.CalculateAvaibleMetalCellByChemistry(depRecipe.Chemistry, sequence.SequenceType);
  493. if (!result)
  494. {
  495. return false;
  496. }
  497. }
  498. return true;
  499. }
  500. #region Analyse ErrorState Scheduler
  501. /// <summary>
  502. /// Prewet出错重新调度
  503. /// </summary>
  504. /// <param name="sequence"></param>
  505. private void AnalyseSchedulerPrewetErrorState(SchedulerSequence sequence)
  506. {
  507. SkipAfterSchedulerToDry(ModuleName.Transporter2);
  508. sequence.State = RState.End;
  509. sequence.EndTime = DateTime.Now;
  510. sequence.ProcessMilliSeconds= sequence.EndTime.Subtract(sequence.StartTime).TotalMilliseconds;
  511. RemoveWaferHolderSRDScheduler();
  512. UpdateWaferHolderMisProcessedStatus();
  513. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Prewet meet error,scheduler changed to transporter2");
  514. }
  515. /// <summary>
  516. /// 路过后面调度直接至Dryer
  517. /// </summary>
  518. private void SkipAfterSchedulerToDry(ModuleName transporterName)
  519. {
  520. for (int i = _currentSequenceIndex=1; i < _schedulerSequences.Count; i++)
  521. {
  522. SchedulerSequence item = _schedulerSequences[i];
  523. if (item.ModuleName != ModuleName.Transporter1)
  524. {
  525. item.State = RState.End;
  526. item.ProcessMilliSeconds = 0;
  527. }
  528. else
  529. {
  530. if (item.Parameters is WaferHolderMoveItem)
  531. {
  532. WaferHolderMoveItem waferHolderMoveItem = item.Parameters as WaferHolderMoveItem;
  533. if (waferHolderMoveItem.DestModuleType == ModuleType.Dryer)
  534. {
  535. _currentSequenceIndex = i;
  536. item.SchedulerModule = SchedulerManager.Instance.GetScheduler(transporterName);
  537. waferHolderMoveItem.SourceModule = ModuleName.Prewet1;
  538. waferHolderMoveItem.SourceModuleType = ModuleType.Prewet;
  539. break;
  540. }
  541. else
  542. {
  543. item.State = RState.End;
  544. item.ProcessMilliSeconds = 0;
  545. }
  546. }
  547. }
  548. }
  549. }
  550. /// <summary>
  551. /// Dryer出错重新调度,上一步调度修改为transporter2,同时tranporter2搬运源目标为当前Module,目标类型也是Dryer
  552. /// </summary>
  553. /// <param name="sequence"></param>
  554. private void AnalyseSchedulerDryerErrorState(SchedulerSequence sequence)
  555. {
  556. if (SchedulerSequenceManager.Instance.GetAvaibleModuleCell(_sequenceType,ModuleType.Dryer)!=ModuleName.Unknown)
  557. {
  558. sequence.State = RState.Init;
  559. SchedulerSequence preSchedulerSequence = GetPreSchedulerSequence();
  560. preSchedulerSequence.State = RState.Init;
  561. preSchedulerSequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(ModuleName.Transporter2);
  562. WaferHolderMoveItem waferHolderMoveItem = preSchedulerSequence.Parameters as WaferHolderMoveItem;
  563. waferHolderMoveItem.SourceModule = waferHolderMoveItem.DestModule;
  564. waferHolderMoveItem.SourceModuleType = waferHolderMoveItem.DestModuleType;
  565. waferHolderMoveItem.DestModuleType = waferHolderMoveItem.DestModuleType;
  566. waferHolderMoveItem.DestModule = ModuleName.Unknown;
  567. sequence.SchedulerModule = null;
  568. _currentSequenceIndex--;
  569. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Dryer meet error,rescheduler changed to transporter2");
  570. }
  571. else
  572. {
  573. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Dryer meet error,rescheduler has no avaible dryer");
  574. }
  575. }
  576. /// <summary>
  577. /// Rinse出错重新调度,回退至上一步调度
  578. /// </summary>
  579. /// <param name="sequence"></param>
  580. private void AnalyseSchedulerRinseErrorState(SchedulerSequence sequence)
  581. {
  582. ModuleName metalName = SchedulerSequenceManager.Instance.GetPreMetalModuleName(_currentSequenceIndex, _schedulerSequences);
  583. if (metalName == ModuleName.Unknown)
  584. {
  585. return;
  586. }
  587. if (SchedulerSequenceManager.Instance.GetAvaibleModuleCell(_sequenceType, ModuleType.Rinse,metalName) != ModuleName.Unknown)
  588. {
  589. sequence.State = RState.Init;
  590. SchedulerSequence preSchedulerSequence = GetPreSchedulerSequence();
  591. preSchedulerSequence.State = RState.Init;
  592. WaferHolderMoveItem waferHolderMoveItem = preSchedulerSequence.Parameters as WaferHolderMoveItem;
  593. waferHolderMoveItem.SourceModule = waferHolderMoveItem.DestModule;
  594. waferHolderMoveItem.SourceModuleType = waferHolderMoveItem.DestModuleType;
  595. waferHolderMoveItem.DestModuleType = waferHolderMoveItem.DestModuleType;
  596. waferHolderMoveItem.DestModule = ModuleName.Unknown;
  597. sequence.SchedulerModule = null;
  598. _currentSequenceIndex--;
  599. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Rinse meet error,scheduler changed to transporter1");
  600. }
  601. else
  602. {
  603. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Rinse meet error,rescheduler has no avaible rinse");
  604. }
  605. }
  606. /// <summary>
  607. /// Metal出错重新调度,回退至上一步调度
  608. /// </summary>
  609. /// <param name="sequence"></param>
  610. private void AnalyseSchedulerMetalErrorState(SchedulerSequence sequence)
  611. {
  612. //当前步骤结束,WaferHolder状态
  613. UpdateWaferHolderErrorStatus();
  614. sequence.EndTime = DateTime.Now;
  615. sequence.ProcessMilliSeconds= sequence.EndTime.Subtract(sequence.StartTime).TotalMilliseconds;
  616. sequence.State = RState.End;
  617. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Metal meet error,rescheduler changed to next module");
  618. //跳过后面的metal
  619. SkipAfterMetal(sequence,false);
  620. //移除SRD调度
  621. RemoveWaferHolderSRDScheduler();
  622. _currentSequenceIndex++;
  623. }
  624. /// <summary>
  625. /// 跳过后面的Metal
  626. /// </summary>
  627. private void SkipAfterMetal(SchedulerSequence schedulerSequence,bool isSetLastSequenceSourceModule)
  628. {
  629. int startIndex = -1;
  630. int endIndex = -1;
  631. //从下一个Metal直到碰到Dryer
  632. for (int i = _currentSequenceIndex + 1; i < _schedulerSequences.Count; i++)
  633. {
  634. SchedulerSequence item = _schedulerSequences[i];
  635. if (item.ModuleType == ModuleType.Metal && startIndex == -1)
  636. {
  637. startIndex = i;
  638. }
  639. if (item.ModuleType == ModuleType.Dryer)
  640. {
  641. endIndex = i - 1;//Dryer前一步骤为Transporter,保留Dryer前面的transporter
  642. break;
  643. }
  644. }
  645. //将后面的Metal的步骤直接跳过,包含gh g 后面的transporter
  646. if (startIndex != -1)
  647. {
  648. for (int i = startIndex - 1; i < endIndex; i++)
  649. {
  650. SchedulerSequence item = _schedulerSequences[i];
  651. item.State = RState.End;
  652. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} skip {i+1} sequence {item.ModuleType}");
  653. }
  654. }
  655. //是否设置最后调度的源模块
  656. if (isSetLastSequenceSourceModule)
  657. {
  658. SchedulerSequence lastSchedulerSequence = _schedulerSequences[endIndex];
  659. if (lastSchedulerSequence.ModuleType == ModuleType.Transporter)
  660. {
  661. WaferHolderMoveItem waferHolderMoveItem = lastSchedulerSequence.Parameters as WaferHolderMoveItem;
  662. if (schedulerSequence.SchedulerModule != null)
  663. {
  664. waferHolderMoveItem.SourceModule = schedulerSequence.ModuleName;
  665. waferHolderMoveItem.SourceModuleType = schedulerSequence.ModuleType;
  666. }
  667. }
  668. }
  669. }
  670. /// <summary>
  671. /// 移除SRD调度
  672. /// </summary>
  673. private void RemoveWaferHolderSRDScheduler()
  674. {
  675. WaferTask waferATask = WaferTaskManager.Instance.GetWaferTask(WaferHolderInfo.WaferAId);
  676. if (waferATask != null)
  677. {
  678. waferATask.RemoveSrdScheduler();
  679. }
  680. WaferTask waferBTask = WaferTaskManager.Instance.GetWaferTask(WaferHolderInfo.WaferBId);
  681. if (waferBTask != null)
  682. {
  683. waferBTask.RemoveSrdScheduler();
  684. }
  685. }
  686. #endregion
  687. /// <summary>
  688. /// 自动更新LoaderTransporter的工序
  689. /// </summary>
  690. private void AutoChangeLoaderTransporterScheduler()
  691. {
  692. if(_currentSequenceIndex>=_schedulerSequences.Count)
  693. {
  694. return;
  695. }
  696. if(_currentSequenceIndex+2>=_schedulerSequences.Count)
  697. {
  698. return;
  699. }
  700. SchedulerSequence schedulerSequence = _schedulerSequences[_currentSequenceIndex];
  701. if (schedulerSequence == null)
  702. {
  703. return;
  704. }
  705. if(schedulerSequence.ModuleName==ModuleName.Transporter2)
  706. {
  707. if (schedulerSequence.Parameters == null || !(schedulerSequence.Parameters is WaferHolderMoveItem))
  708. {
  709. return;
  710. }
  711. WaferHolderMoveItem waferHolderMoveItem = (WaferHolderMoveItem)schedulerSequence.Parameters;
  712. if(waferHolderMoveItem.DestModuleType!=ModuleType.Buffer)
  713. {
  714. return;
  715. }
  716. SchedulerSequence nextSchedulerSequence = _schedulerSequences[_currentSequenceIndex + 1];
  717. if(nextSchedulerSequence.ModuleName!=ModuleName.Transporter2)
  718. {
  719. return;
  720. }
  721. if(nextSchedulerSequence.Parameters==null||!(nextSchedulerSequence.Parameters is WaferHolderMoveItem))
  722. {
  723. return;
  724. }
  725. WaferHolderMoveItem nextWaferHolderMoveItem = (WaferHolderMoveItem)nextSchedulerSequence.Parameters;
  726. if(nextWaferHolderMoveItem.DestModule==ModuleName.Unknown)
  727. {
  728. if (ProcessJobInfo != null && ProcessJobInfo.SequenceRecipe != null)
  729. {
  730. //后面不存在资源,搬运至Buffer中,而不是进后面cell
  731. if (!SchedulerSequenceRecipeManager.Instance.ExistAvaibleProcessCell(ProcessJobInfo.SequenceRecipe, false))
  732. {
  733. return;
  734. }
  735. }
  736. if (CheckBufferHasUnProcessedWaferHolder())
  737. {
  738. return;
  739. }
  740. //若Buffer后面的cell存在资源,则直接搬运至Cell中
  741. ModuleName avaibleModuleName = SchedulerSequenceManager.Instance.GetAvaibleEmptyModuleCell(nextWaferHolderMoveItem.DestModuleType,_sequenceType);
  742. if(avaibleModuleName==ModuleName.Unknown)
  743. {
  744. return;
  745. }
  746. else
  747. {
  748. schedulerSequence.State = RState.End;
  749. _currentSequenceIndex++;
  750. nextWaferHolderMoveItem.DestModule = avaibleModuleName;
  751. nextWaferHolderMoveItem.SourceModule = ModuleName.Loader1;
  752. nextWaferHolderMoveItem.SourceModuleType = ModuleType.Loader;
  753. UpdateNextSequenceModule(_currentSequenceIndex + 1,avaibleModuleName);
  754. }
  755. }
  756. else if(nextWaferHolderMoveItem.DestModule==ModuleName.Loader1)
  757. {
  758. LoaderEntity loaderEntity = Singleton<RouteManager>.Instance.GetModule<LoaderEntity>(ModuleName.Loader1.ToString());
  759. if(loaderEntity==null)
  760. {
  761. return;
  762. }
  763. if(loaderEntity.WaferHolderInfo!=null)
  764. {
  765. return;
  766. }
  767. if(loaderEntity.IsBusy)
  768. {
  769. return;
  770. }
  771. schedulerSequence.State = RState.End;
  772. _currentSequenceIndex++;
  773. nextWaferHolderMoveItem.SourceModule = waferHolderMoveItem.SourceModule;
  774. nextWaferHolderMoveItem.SourceModuleType = waferHolderMoveItem.SourceModuleType;
  775. }
  776. }
  777. }
  778. /// <summary>
  779. /// 检验Buffer中是否存在未处理的WaferHolder
  780. /// </summary>
  781. /// <returns></returns>
  782. private bool CheckBufferHasUnProcessedWaferHolder()
  783. {
  784. List<string> bufferModules = BufferItemManager.Instance.InstalledModules;
  785. foreach (string module in bufferModules)
  786. {
  787. WaferHolderInfo item = WaferHolderManager.Instance.GetWaferHolder(module);
  788. if (item == null)
  789. {
  790. continue;
  791. }
  792. if (string.IsNullOrEmpty(item.WaferAId))
  793. {
  794. continue;
  795. }
  796. if (string.IsNullOrEmpty(item.WaferBId))
  797. {
  798. continue;
  799. }
  800. WaferInfo waferA=WaferManager.Instance.GetWaferByWaferId(item.WaferAId);
  801. if (waferA == null)
  802. {
  803. continue;
  804. }
  805. if (waferA.ProcessState == EnumWaferProcessStatus.Idle&&waferA.WaferType==WaferType.Production)
  806. {
  807. return true;
  808. }
  809. WaferInfo waferB = WaferManager.Instance.GetWaferByWaferId(item.WaferBId);
  810. if(waferB == null)
  811. {
  812. continue;
  813. }
  814. if (waferB.ProcessState == EnumWaferProcessStatus.Idle && waferB.WaferType == WaferType.Production)
  815. {
  816. return true;
  817. }
  818. }
  819. return false;
  820. }
  821. /// <summary>
  822. /// 更新下一工序的调度模块
  823. /// </summary>
  824. /// <param name="sequenceIndex"></param>
  825. /// <param name="moduleName"></param>
  826. private void UpdateNextSequenceModule(int sequenceIndex,ModuleName moduleName)
  827. {
  828. if(sequenceIndex<_schedulerSequences.Count)
  829. {
  830. SchedulerSequence schedulerSequence = _schedulerSequences[sequenceIndex];
  831. if(schedulerSequence!=null&&schedulerSequence.SchedulerModule==null)
  832. {
  833. schedulerSequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(moduleName);
  834. schedulerSequence.ModuleName = moduleName;
  835. }
  836. }
  837. }
  838. /// <summary>
  839. /// 更新WaferHolder工序完成Wafer状态
  840. /// </summary>
  841. private void UpdateWaferHolderProcessComplete()
  842. {
  843. if (WaferHolderInfo.Status != WaferHolderStatus.Completed)
  844. {
  845. UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus.Completed);
  846. WaferHolderInfo.Status = WaferHolderStatus.Completed;
  847. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Status changed to {WaferHolderInfo.Status}");
  848. }
  849. MaterialTrackerManager.Instance.UpdateModuleMaterial(WaferHolderInfo.CurrentLocation);
  850. }
  851. /// <summary>
  852. /// 更新WaferHolder工序正在加工
  853. /// </summary>
  854. private void UpdateWaferHolderProcessingStatus()
  855. {
  856. if (WaferHolderInfo.Status == WaferHolderStatus.Normal)
  857. {
  858. UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus.InProcess);
  859. WaferHolderInfo.Status = WaferHolderStatus.Processing;
  860. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferHolderInfo.Id} Status changed to {WaferHolderInfo.Status}");
  861. MaterialTrackerManager.Instance.UpdateModuleMaterial(WaferHolderInfo.CurrentLocation);
  862. }
  863. }
  864. /// <summary>
  865. /// 更新WaferHolder工序错误状态
  866. /// </summary>
  867. /// <param name="sequence"></param>
  868. private void UpdateWaferHolderErrorStatus()
  869. {
  870. UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus.Failed);
  871. WaferHolderInfo.Status = WaferHolderStatus.Failed;
  872. MaterialTrackerManager.Instance.UpdateModuleMaterial(WaferHolderInfo.CurrentLocation);
  873. }
  874. /// <summary>
  875. /// 更新WaferHolder工序MisProcessed状态
  876. /// </summary>
  877. /// <param name="sequence"></param>
  878. private void UpdateWaferHolderMisProcessedStatus()
  879. {
  880. UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus.MisProcessed);
  881. WaferHolderInfo.Status = WaferHolderStatus.MisProcessed;
  882. MaterialTrackerManager.Instance.UpdateModuleMaterial(WaferHolderInfo.CurrentLocation);
  883. }
  884. /// <summary>
  885. /// 更新WaferHolder处理状态
  886. /// </summary>
  887. /// <param name="sequence"></param>
  888. /// <param name="processStatus"></param>
  889. private void UpdateWaferHolderWaferProcessStatus(EnumWaferProcessStatus processStatus)
  890. {
  891. if (Enum.TryParse(WaferHolderInfo.CurrentLocation, out ModuleName moduleName))
  892. {
  893. if (!string.IsNullOrEmpty(WaferHolderInfo.WaferAId))
  894. {
  895. WaferInfo waferInfo = WaferManager.Instance.GetWaferByWaferId(WaferHolderInfo.WaferAId);
  896. if (waferInfo != null && waferInfo.WaferType == WaferType.Production)
  897. {
  898. WaferManager.Instance.UpdateWaferProcessStatus(moduleName, 0, processStatus);
  899. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{waferInfo.WaferID} status changed to {processStatus}");
  900. }
  901. }
  902. if (!string.IsNullOrEmpty(WaferHolderInfo.WaferBId))
  903. {
  904. WaferInfo waferInfo = WaferManager.Instance.GetWaferByWaferId(WaferHolderInfo.WaferBId);
  905. if (waferInfo != null && waferInfo.WaferType == WaferType.Production)
  906. {
  907. WaferManager.Instance.UpdateWaferProcessStatus(moduleName, 1, processStatus);
  908. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{waferInfo.WaferID} status changed to {processStatus}");
  909. }
  910. }
  911. }
  912. }
  913. /// <summary>
  914. /// 检验前置条件
  915. /// </summary>
  916. /// <returns></returns>
  917. private bool CheckStartCondition()
  918. {
  919. LoaderEntity loaderEntity = Singleton<RouteManager>.Instance.GetModule<LoaderEntity>(ModuleName.Loader1.ToString());
  920. if (loaderEntity.WaferHolderInfo != null)
  921. {
  922. return false;
  923. }
  924. //if (ProcessJobInfo != null)
  925. //{
  926. // if (!SchedulerSequenceRecipeManager.Instance.ExistAvaibleProcessCell(ProcessJobInfo.SequenceRecipe, false))
  927. // {
  928. // _currentSequenceIndex = _schedulerSequences.Count;
  929. // LOG.WriteLog(eEvent.WARN_SCHEDULER, "System", $"WaferHolder {WaferHolderInfo.Id} start scheduler meet no avaible cell");
  930. // return false;
  931. // }
  932. //}
  933. return true;
  934. }
  935. /// <summary>
  936. /// 释放资源
  937. /// </summary>
  938. public void Dispose()
  939. {
  940. _schedulerSequences.Clear();
  941. }
  942. /// <summary>
  943. /// 暂停
  944. /// </summary>
  945. public void Pause()
  946. {
  947. _pausedIndex = _currentSequenceIndex;
  948. }
  949. /// <summary>
  950. /// 恢复
  951. /// </summary>
  952. public void Resume()
  953. {
  954. _pausedIndex = -1;
  955. }
  956. /// <summary>
  957. /// 获取当前调度阶段
  958. /// </summary>
  959. /// <returns></returns>
  960. public SchedulerSequence GetCurrentSchedulerSequence()
  961. {
  962. return GetSchedulerSequenceByIndex(_currentSequenceIndex);
  963. }
  964. /// <summary>
  965. /// 获取前一个调度阶段
  966. /// </summary>
  967. /// <returns></returns>
  968. public SchedulerSequence GetPreSchedulerSequence()
  969. {
  970. return GetSchedulerSequenceByIndex(_currentSequenceIndex-1);
  971. }
  972. /// <summary>
  973. /// 根据索引获取调度阶段对象
  974. /// </summary>
  975. /// <param name="index"></param>
  976. /// <returns></returns>
  977. private SchedulerSequence GetSchedulerSequenceByIndex(int index)
  978. {
  979. if (index == -1 || index >= _schedulerSequences.Count)
  980. {
  981. return null;
  982. }
  983. return _schedulerSequences[index];
  984. }
  985. /// <summary>
  986. /// 是否调度完成Loader调度
  987. /// </summary>
  988. /// <returns></returns>
  989. public bool IsNotPassLoader()
  990. {
  991. return _currentSequenceIndex <= 1;
  992. }
  993. }
  994. }