WaferTask.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. using Aitex.Core.Common;
  2. using Aitex.Core.RT.IOCore;
  3. using Aitex.Core.RT.Log;
  4. using Aitex.Core.Util;
  5. using MECF.Framework.Common.Equipment;
  6. using MECF.Framework.Common.Jobs;
  7. using MECF.Framework.Common.SubstrateTrackings;
  8. using MECF.Framework.Common.WaferHolder;
  9. using CyberX8_Core;
  10. using CyberX8_RT.Modules;
  11. using CyberX8_RT.Modules.Loader;
  12. using CyberX8_RT.Modules.PUF;
  13. using CyberX8_RT.Schedulers;
  14. using CyberX8_RT.Schedulers.EfemRobot;
  15. using System;
  16. using System.Collections.Generic;
  17. using System.Linq;
  18. using System.Text;
  19. using System.Threading.Tasks;
  20. using MECF.Framework.Common.RecipeCenter;
  21. using MECF.Framework.Common.Schedulers;
  22. using System.Windows;
  23. using MECF.Framework.RT.Core.Equipments;
  24. using CyberX8_RT.Modules.SRD;
  25. namespace CyberX8_RT.Dispatch
  26. {
  27. public enum WaferTaskState
  28. {
  29. Created,
  30. Processing,
  31. End,
  32. Paused,
  33. Error
  34. }
  35. /// <summary>
  36. /// WaferTask完成
  37. /// </summary>
  38. /// <param name="id"></param>
  39. public delegate void WaferTaskComplete(string id);
  40. /// <summary>
  41. /// WaferTask开始
  42. /// </summary>
  43. /// <param name="id"></param>
  44. public delegate void WaferTaskStart(string id);
  45. public class WaferTask
  46. {
  47. #region 内部变量
  48. /// <summary>
  49. /// 调度步骤
  50. /// </summary>
  51. private List<SchedulerSequence> _schedulerSequences;
  52. /// <summary>
  53. /// 当前步骤索引
  54. /// </summary>
  55. private int _currentSequenceIndex = 0;
  56. /// <summary>
  57. /// PUF实例
  58. /// </summary>
  59. private PUFEntity _pufEntity;
  60. /// <summary>
  61. /// 是否开始执行
  62. /// </summary>
  63. private bool _isStart = false;
  64. /// <summary>
  65. /// 暂停时的索引
  66. /// </summary>
  67. private int _pausedIndex = -1;
  68. /// <summary>
  69. /// 日志trigger
  70. /// </summary>
  71. private R_TRIG _sequenceConditionTrigger = new R_TRIG();
  72. /// <summary>
  73. /// 错误上升触发
  74. /// </summary>
  75. private R_TRIG _sequenceErrorTigger = new R_TRIG();
  76. #endregion
  77. #region 属性
  78. /// <summary>
  79. /// Wafer信息
  80. /// </summary>
  81. public string WaferId { get; set; }
  82. /// <summary>
  83. /// 状态
  84. /// </summary>
  85. public WaferTaskState State { get; private set; }
  86. /// <summary>
  87. /// 匹配WaferTask
  88. /// </summary>
  89. public string MateWaferTask { get; set; }
  90. /// <summary>
  91. /// 调度集合
  92. /// </summary>
  93. public List<SchedulerSequence> SchedulerSequences { get { return _schedulerSequences; } }
  94. #endregion
  95. #region 事件
  96. /// <summary>
  97. /// 任务完成事件
  98. /// </summary>
  99. public event WaferTaskComplete OnTaskComplete;
  100. /// <summary>
  101. /// 任务启动
  102. /// </summary>
  103. public event WaferTaskStart OnTaskStart;
  104. #endregion
  105. /// <summary>
  106. /// 构造函数
  107. /// </summary>
  108. /// <param name="waferInfo"></param>
  109. /// <param name="schedulerSequences"></param>
  110. public WaferTask(WaferInfo waferInfo,PUFEntity pufEntity, List<SchedulerSequence> schedulerSequences)
  111. {
  112. this.WaferId = waferInfo.WaferID;
  113. _schedulerSequences = schedulerSequences;
  114. State = WaferTaskState.Created;
  115. _pufEntity = pufEntity;
  116. }
  117. /// <summary>
  118. /// 执行
  119. /// </summary>
  120. public void Run()
  121. {
  122. if (State == WaferTaskState.Error)
  123. {
  124. return;
  125. }
  126. if (_currentSequenceIndex >= _schedulerSequences.Count)
  127. {
  128. State = WaferTaskState.End;
  129. if (OnTaskComplete != null)
  130. {
  131. OnTaskComplete(WaferId);
  132. }
  133. return;
  134. }
  135. SchedulerSequence sequence = _schedulerSequences[_currentSequenceIndex];
  136. if (_currentSequenceIndex == _schedulerSequences.Count - 1 && sequence.State == RState.End)
  137. {
  138. State = WaferTaskState.End;
  139. if(OnTaskComplete!=null)
  140. {
  141. OnTaskComplete(WaferId);
  142. }
  143. return;
  144. }
  145. if (!_isStart)
  146. {
  147. bool preCondition = CheckStartCondition();
  148. if (!preCondition)
  149. {
  150. return;
  151. }
  152. _isStart = true;
  153. WaferTaskManager.Instance.RemoveWaferIdMatchWaferHolderTaskDic(WaferId);
  154. }
  155. //暂停中
  156. if(sequence.State==RState.Init&&_currentSequenceIndex>=_pausedIndex&&_pausedIndex!=-1)
  157. {
  158. return;
  159. }
  160. if(sequence.IsWaitNotify)
  161. {
  162. if (sequence.State == RState.End)
  163. {
  164. _currentSequenceIndex++;
  165. }
  166. return;
  167. }
  168. if(sequence.MaterialType==MaterialType.WaferHolder)
  169. {
  170. if(sequence.State==RState.End)
  171. {
  172. _currentSequenceIndex++;
  173. }
  174. return;
  175. }
  176. if (_currentSequenceIndex < _schedulerSequences.Count)
  177. {
  178. if (sequence.State == RState.Init)
  179. {
  180. string reason = "";
  181. bool sequeceCondition = sequence.SchedulerModule.CheckPrecondition(_schedulerSequences, _currentSequenceIndex,sequence.Parameters,WaferId,ref reason);
  182. _sequenceConditionTrigger.CLK = !sequeceCondition;
  183. if (sequeceCondition)
  184. {
  185. bool result = sequence.SchedulerModule.RunProcess(sequence.Recipe,sequence.Parameters,sequence.SynchronousModuleMessages);
  186. if (result)
  187. {
  188. if (State == WaferTaskState.Created)
  189. {
  190. State = WaferTaskState.Processing;
  191. if(OnTaskStart!=null)
  192. {
  193. OnTaskStart(WaferId);
  194. }
  195. }
  196. sequence.State = RState.Running;
  197. sequence.StartTime = DateTime.Now;
  198. LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferId} Start {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module}");
  199. }
  200. }
  201. else
  202. {
  203. if (_sequenceConditionTrigger.Q)
  204. {
  205. LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferId} Start {_currentSequenceIndex + 1} sequence {sequence.SchedulerModule.Module} failed,{reason}");
  206. if (sequence.SchedulerModule.Module == ModuleName.EfemRobot)
  207. {
  208. AnalyseSchedulerSrdState(sequence);
  209. }
  210. }
  211. }
  212. }
  213. else if (sequence.State == RState.Running)
  214. {
  215. bool hasMatched=!string.IsNullOrEmpty(WaferTaskManager.Instance.GetMatchWaferIdByWaferId(this.WaferId));
  216. sequence.SchedulerModule.MonitorProcess(sequence,hasMatched);
  217. _sequenceErrorTigger.CLK = sequence.SchedulerModule.IsError;
  218. if (sequence.SchedulerModule.IsIdle)
  219. {
  220. sequence.EndTime = DateTime.Now;
  221. sequence.State = RState.End;
  222. sequence.ProcessMilliSeconds = sequence.EndTime.Subtract(sequence.StartTime).TotalMilliseconds;
  223. LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferId} {_currentSequenceIndex + 1} sequence complete, time length {sequence.ProcessMilliSeconds}");
  224. _currentSequenceIndex++;
  225. }
  226. }
  227. else if(sequence.State==RState.End)
  228. {
  229. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferId} {_currentSequenceIndex + 1} sequence is End");
  230. _currentSequenceIndex++;
  231. }
  232. }
  233. }
  234. /// <summary>
  235. /// 分析错误状态下的调度
  236. /// </summary>
  237. private void AnalyseSchedulerSrdState(SchedulerSequence sequence)
  238. {
  239. if(!(sequence.Parameters is MoveItem))
  240. {
  241. return;
  242. }
  243. MoveItem moveItem = sequence.Parameters as MoveItem;
  244. bool exsitSRD = false;
  245. if (moveItem.DestinationType == ModuleType.SRD)
  246. {
  247. SRDEntity srdEntity1 = Singleton<RouteManager>.Instance.GetModule<SRDEntity>(ModuleName.SRD1.ToString());
  248. if (srdEntity1 != null&&(srdEntity1.IsBusy||srdEntity1.IsIdle)&&srdEntity1.IsAuto)
  249. {
  250. exsitSRD = true;
  251. return;
  252. }
  253. SRDEntity srdEntity2 = Singleton<RouteManager>.Instance.GetModule<SRDEntity>(ModuleName.SRD2.ToString());
  254. if (srdEntity2 != null && (srdEntity2.IsBusy || srdEntity2.IsIdle) && srdEntity2.IsAuto)
  255. {
  256. exsitSRD = true;
  257. return;
  258. }
  259. if (!exsitSRD)
  260. {
  261. WaferInfo waferInfo = WaferManager.Instance.GetWaferByWaferId(WaferId);
  262. if (waferInfo == null || waferInfo.IsEmpty)
  263. {
  264. return;
  265. }
  266. WaferManager.Instance.UpdateWaferProcessStatus(moveItem.SourceModule, moveItem.SourceSlot, EnumWaferProcessStatus.MisSrdProcess);
  267. MaterialTrackerManager.Instance.UpdateModuleMaterial(moveItem.SourceModule.ToString());
  268. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{waferInfo.WaferID} status changed to {EnumWaferProcessStatus.MisSrdProcess}");
  269. moveItem.DestinationModule = (ModuleName)waferInfo.OriginStation;
  270. moveItem.DestinationSlot = waferInfo.OriginSlot;
  271. moveItem.DestinationType = ModuleType.LoadPort;
  272. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferId} has no avaible srd changed to {moveItem.DestinationModule}.{moveItem.DestinationSlot}");
  273. for(int i = _currentSequenceIndex + 1; i < _schedulerSequences.Count; i++)
  274. {
  275. SchedulerSequence item = _schedulerSequences[i];
  276. item.State = RState.End;
  277. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"{WaferId} skip {i + 1} sequence {item.ModuleType}");
  278. }
  279. }
  280. }
  281. }
  282. /// <summary>
  283. /// 释放资源
  284. /// </summary>
  285. public void Dispose()
  286. {
  287. _schedulerSequences.Clear();
  288. }
  289. /// <summary>
  290. /// 检验前置条件
  291. /// </summary>
  292. /// <returns></returns>
  293. private bool CheckStartCondition()
  294. {
  295. EfemEntity efemEntity = Singleton<RouteManager>.Instance.EFEM;
  296. if(!efemEntity.IsIdle)
  297. {
  298. return false;
  299. }
  300. SchedulerRobot schedulerEfemRobot = (SchedulerRobot)SchedulerManager.Instance.GetScheduler(ModuleName.EfemRobot);
  301. if(schedulerEfemRobot==null)
  302. {
  303. return false;
  304. }
  305. if(!schedulerEfemRobot.IsIdle)
  306. {
  307. return false;
  308. }
  309. if(WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot,0))
  310. {
  311. return false;
  312. }
  313. if(WaferManager.Instance.CheckHasWafer(ModuleName.Aligner1, 0))
  314. {
  315. return false;
  316. }
  317. if(!_pufEntity.IsIdle)
  318. {
  319. return false;
  320. }
  321. //PUF B面无Wafer
  322. if(WaferManager.Instance.CheckHasWafer(_pufEntity.Module,1))
  323. {
  324. return false;
  325. }
  326. //if(!WaferHolderManager.Instance.HasWaferHolder("Loader"))
  327. //{
  328. // return false;
  329. //}
  330. LoaderEntity loaderEntity = Singleton<RouteManager>.Instance.GetModule<LoaderEntity>(ModuleName.Loader1.ToString());
  331. if (loaderEntity == null)
  332. {
  333. return false;
  334. }
  335. if(loaderEntity.IsBusy&&loaderEntity.State!=(int)LOADERSTATE.WaitForUnload)
  336. {
  337. return false;
  338. }
  339. if(!string.IsNullOrEmpty(MateWaferTask))
  340. {
  341. WaferTask mateTask=WaferTaskManager.Instance.GetWaferTask(MateWaferTask);
  342. if(mateTask!=null)
  343. {
  344. if(mateTask.State==WaferTaskState.Created)
  345. {
  346. return false;
  347. }
  348. }
  349. }
  350. //WaferHolderTask waferHolderTask = WaferTaskManager.Instance.GetWaferHolderTaskByWaferId(WaferId);
  351. //if (waferHolderTask != null)
  352. //{
  353. // if(waferHolderTask.State==WaferHolderTaskState.Created||waferHolderTask.State==WaferHolderTaskState.Error)
  354. // {
  355. // return false;
  356. // }
  357. //}
  358. return true;
  359. }
  360. /// <summary>
  361. /// 同步更新Loader工序完成
  362. /// </summary>
  363. public void UpdateLoaderSchedulerSequenceComplete()
  364. {
  365. SchedulerSequence schedulerSequence = _schedulerSequences[_currentSequenceIndex];
  366. if (schedulerSequence != null)
  367. {
  368. if (schedulerSequence.ModuleType == ModuleType.PUF&&schedulerSequence.IsWaitNotify)
  369. {
  370. bool forward = (bool)schedulerSequence.Parameters;
  371. if (!forward)
  372. {
  373. schedulerSequence.StartTime = DateTime.Now;
  374. schedulerSequence.EndTime = DateTime.Now;
  375. schedulerSequence.State = RState.End;
  376. schedulerSequence.ProcessMilliSeconds = schedulerSequence.EndTime.Subtract(schedulerSequence.StartTime).TotalMilliseconds;
  377. LOG.WriteLog(eEvent.EV_SEQUENCE, "System", $"{WaferId} {_currentSequenceIndex + 1} puf sequence task synchronize notify complete");
  378. }
  379. }
  380. }
  381. }
  382. /// <summary>
  383. /// 暂停
  384. /// </summary>
  385. public void Pause()
  386. {
  387. _pausedIndex = _currentSequenceIndex;
  388. }
  389. /// <summary>
  390. /// 恢复
  391. /// </summary>
  392. public void Resume()
  393. {
  394. _pausedIndex = -1;
  395. }
  396. /// <summary>
  397. /// 移除SRD调度
  398. /// </summary>
  399. public void RemoveSrdScheduler()
  400. {
  401. WaferInfo waferInfo=WaferManager.Instance.GetWaferByWaferId(WaferId);
  402. if (waferInfo != null && waferInfo.WaferType == WaferType.Production&&waferInfo.ProcessJob!=null
  403. &&waferInfo.ProcessJob.SequenceRecipe!=null)
  404. {
  405. if (SequenceRecipeManager.Instance.IsContainedSrd(waferInfo.ProcessJob.SequenceRecipe))
  406. {
  407. for(int i=_currentSequenceIndex;i<_schedulerSequences.Count;i++)
  408. {
  409. SchedulerSequence item= _schedulerSequences[i];
  410. if(item.ModuleType==ModuleType.SRD&&i+1<_schedulerSequences.Count&&i>0)
  411. {
  412. SchedulerSequence preSequence = _schedulerSequences[i - 1];
  413. SchedulerSequence nextSequence = _schedulerSequences[i + 1];
  414. if (preSequence.ModuleName == ModuleName.EfemRobot&&nextSequence.ModuleName==ModuleName.EfemRobot)
  415. {
  416. MoveItem moveItem=preSequence.Parameters as MoveItem;
  417. MoveItem nextMoveItem=nextSequence.Parameters as MoveItem;
  418. moveItem.DestinationModule = nextMoveItem.DestinationModule;
  419. moveItem.DestinationSlot= nextMoveItem.DestinationSlot;
  420. moveItem.DestinationType= nextMoveItem.DestinationType;
  421. _schedulerSequences.RemoveAt(i + 1);
  422. _schedulerSequences.RemoveAt(i);
  423. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"Wafer {WaferId} remove SRD Scheduler");
  424. }
  425. break;
  426. }
  427. }
  428. }
  429. }
  430. }
  431. /// <summary>
  432. /// 步骤是否进入Loader及之后
  433. /// </summary>
  434. /// <returns></returns>
  435. public bool IsSchedulerForward()
  436. {
  437. //0-EfemRobot,1-Aligner,2-EfemRobot,3-Puf(正向),4-PUF(工艺结束返回)
  438. return _currentSequenceIndex < 4;
  439. }
  440. }
  441. }