WaferHolderTask.cs 44 KB

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