SchedulerLoaderTransporter.cs 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862
  1. using Aitex.Core.RT.Fsm;
  2. using Aitex.Core.Util;
  3. using MECF.Framework.Common.CommonData;
  4. using MECF.Framework.Common.Equipment;
  5. using MECF.Framework.Common.SubstrateTrackings;
  6. using CyberX8_Core;
  7. using CyberX8_RT.Modules;
  8. using CyberX8_RT.Modules.Loader;
  9. using CyberX8_RT.Modules.Transporter;
  10. using CyberX8_RT.Modules.PUF;
  11. using System;
  12. using System.Collections.Generic;
  13. using System.Linq;
  14. using System.ServiceModel.Syndication;
  15. using System.Text;
  16. using System.Threading.Tasks;
  17. using CyberX8_RT.Modules.Prewet;
  18. using Aitex.Core.RT.Device;
  19. using CyberX8_RT.Devices.AXIS;
  20. using MECF.Framework.Common.WaferHolder;
  21. using Aitex.Core.RT.Log;
  22. using MECF.Framework.Common.Schedulers;
  23. using Aitex.Core.RT.SCCore;
  24. using CyberX8_RT.Dispatch;
  25. using MECF.Framework.Common.RecipeCenter;
  26. namespace CyberX8_RT.Schedulers.Transporter
  27. {
  28. public class SchedulerLoaderTransporter : SchedulerModule
  29. {
  30. private enum TransBufferToLoaderStep
  31. {
  32. None,
  33. NotifyLoaderPrepare,
  34. WaitLoaderPrePare,
  35. PickUpValidate,
  36. PickUpValidateMoveto,
  37. Place,
  38. End
  39. }
  40. private enum TransporterFlip
  41. {
  42. None,
  43. WaitPickUp,
  44. LoaderFlip,
  45. WaitLoader,
  46. WaitPlace,
  47. }
  48. #region 内部变量
  49. private LoaderEntity _loaderEntity;
  50. private TransporterEntity _loaderTransporterEntity;
  51. private TransporterEntity _processTransporterEntity;
  52. private TransBufferToLoaderStep _transBufferToLoaderStep = TransBufferToLoaderStep.None;
  53. private SchedulerPostMsg _schedulerPostMsg = new SchedulerPostMsg();
  54. private bool _postMsgResult = false;
  55. private TransporterFlip _transporterFlip=TransporterFlip.None;
  56. #endregion
  57. #region 属性
  58. public override bool IsIdle
  59. {
  60. get { return _state == RState.End; }
  61. }
  62. public bool IsBusy
  63. {
  64. get { return _state == RState.Running; }
  65. }
  66. public override bool IsError
  67. {
  68. get { return _state==RState.Failed||_state==RState.Timeout; }
  69. }
  70. #endregion
  71. /// <summary>
  72. /// 构造函数
  73. /// </summary>
  74. /// <param name="module"></param>
  75. public SchedulerLoaderTransporter(ModuleName module) : base(module.ToString())
  76. {
  77. _loaderEntity = Singleton<RouteManager>.Instance.GetModule<LoaderEntity>(ModuleName.Loader1.ToString());
  78. _loaderTransporterEntity = Singleton<RouteManager>.Instance.GetModule<TransporterEntity>(ModuleName.Transporter2.ToString());
  79. _processTransporterEntity = Singleton<RouteManager>.Instance.GetModule<TransporterEntity>(ModuleName.Transporter1.ToString());
  80. }
  81. /// <summary>
  82. /// 执行
  83. /// </summary>
  84. /// <param name="parameter"></param>
  85. /// <returns></returns>
  86. public override bool RunProcess(object recipe, object parameter,List<SchedulerSyncModuleMessage> syncMessages)
  87. {
  88. if (parameter==null)
  89. {
  90. return false;
  91. }
  92. TransporterAction action = (TransporterAction)parameter;
  93. if (action.ActionMsg == TransporterMSG.Transfer)
  94. {
  95. SynchorinzeModuleMessages(syncMessages);
  96. WaferHolderMoveItem waferHolderMoveItem = (WaferHolderMoveItem)action.Parameter;
  97. if (waferHolderMoveItem.SourceModule != ModuleName.Unknown && waferHolderMoveItem.DestModule != ModuleName.Unknown)
  98. {
  99. SchedulerProcessTransporter schedulerProcessTransporter = (SchedulerProcessTransporter)SchedulerManager.Instance.GetScheduler(ModuleName.Transporter1);
  100. if (schedulerProcessTransporter.IsBusy && _processTransporterEntity.IsIdle)
  101. {
  102. return false;
  103. }
  104. if (!_loaderTransporterEntity.CheckOtherEntityStatus(waferHolderMoveItem.SourceModule.ToString()))
  105. {
  106. return false;
  107. }
  108. if (!_loaderTransporterEntity.CheckOtherEntityStatus(waferHolderMoveItem.DestModule.ToString()))
  109. {
  110. return false;
  111. }
  112. string strSource = waferHolderMoveItem.SourceModule.ToString();
  113. if (waferHolderMoveItem.SourceModule == ModuleName.Loader1)
  114. {
  115. strSource = "Loader";
  116. }
  117. //由于PickUpValidate可能存在校验失败的现象
  118. if (!WaferHolderManager.Instance.HasWaferHolder(strSource) && _loaderTransporterEntity.State != (int)TransporterState.PickUpValidateComplete)
  119. {
  120. return false;
  121. }
  122. string strDest = waferHolderMoveItem.DestModule.ToString();
  123. if (waferHolderMoveItem.DestModule == ModuleName.Loader1)
  124. {
  125. strDest = "Loader";
  126. }
  127. if (WaferHolderManager.Instance.HasWaferHolder(strDest))
  128. {
  129. return false;
  130. }
  131. if (CheckProcessTransporterWillMeetConflict(strSource, strDest))
  132. {
  133. return false;
  134. }
  135. if (waferHolderMoveItem.DestModule == ModuleName.Loader1)
  136. {
  137. return TransferWaferHolderToLoader(waferHolderMoveItem);
  138. }
  139. else if (waferHolderMoveItem.SourceModule == ModuleName.Loader1)
  140. {
  141. return TransWaferHolderFromLoader(waferHolderMoveItem);
  142. }
  143. else if (waferHolderMoveItem.SourceModuleType != ModuleType.Loader && waferHolderMoveItem.DestModuleType != ModuleType.Loader)
  144. {
  145. return TransferWaferHolderNonLoader(waferHolderMoveItem);
  146. }
  147. }
  148. }
  149. else if (action.ActionMsg == TransporterMSG.Flip)
  150. {
  151. return FlipLoader();
  152. }
  153. return true;
  154. }
  155. /// <summary>
  156. /// 检验是否将与ProcessTransporter存在冲突的风险
  157. /// </summary>
  158. /// <returns></returns>
  159. private bool CheckProcessTransporterWillMeetConflict(string source, string dest)
  160. {
  161. bool transporter1Priority = SC.GetValue<bool>("Scheduler.EnableTransporter1Priority");
  162. if (!transporter1Priority)
  163. {
  164. return false;
  165. }
  166. if (!SchedulerManager.Instance.IsQdrCheckConflict)
  167. {
  168. return false;
  169. }
  170. var result = SchedulerTransporterTimeManager.Instance.GetCurrentTransporter1Scheduler(DateTime.Now);
  171. if (string.IsNullOrEmpty(result.waferHolderId))
  172. {
  173. return false;
  174. }
  175. WaferHolderTask waferHolderTask = WaferHolderTaskManager.Instance.GetWaferHolderTaskByWaferHolderId(result.waferHolderId);
  176. if (waferHolderTask == null)
  177. {
  178. return false;
  179. }
  180. SchedulerSequence schedulerSequence = waferHolderTask.GetSchedulerSequenceByIndex(result.sequenceIndex);
  181. if (schedulerSequence == null)
  182. {
  183. return false;
  184. }
  185. if (schedulerSequence.SchedulerModule == null)
  186. {
  187. return false;
  188. }
  189. if (schedulerSequence.SchedulerModule.Module != ModuleName.Transporter1)
  190. {
  191. return false;
  192. }
  193. if (!(schedulerSequence.Parameters is TransporterAction))
  194. {
  195. return false;
  196. }
  197. TransporterAction action = schedulerSequence.Parameters as TransporterAction;
  198. if(!(action.Parameter is WaferHolderMoveItem))
  199. {
  200. return false;
  201. }
  202. WaferHolderMoveItem waferHolderMoveItem = action.Parameter as WaferHolderMoveItem;
  203. bool isLog = SC.GetValue<bool>("Scheduler.IsShowLog");
  204. if (waferHolderMoveItem.SourceModule != ModuleName.Unknown)
  205. {
  206. if (_loaderTransporterEntity.CheckOtherModuleConflict(ModuleName.Transporter1.ToString(), waferHolderMoveItem.SourceModule.ToString(), source))
  207. {
  208. if (isLog)
  209. {
  210. LOG.WriteLog(eEvent.EV_SCHEDULER, Module.ToString(), $"transporter2 source {source} will meet {waferHolderTask.WaferHolderInfo.Id} scheduler index {result.sequenceIndex} transporter1 source {waferHolderMoveItem.SourceModule}");
  211. }
  212. return true;
  213. }
  214. if (_loaderTransporterEntity.CheckOtherModuleConflict(ModuleName.Transporter1.ToString(), waferHolderMoveItem.SourceModule.ToString(), dest))
  215. {
  216. if (isLog)
  217. {
  218. LOG.WriteLog(eEvent.EV_SCHEDULER, Module.ToString(), $"transporter2 dest {dest} will meet {waferHolderTask.WaferHolderInfo.Id} scheduler index {result.sequenceIndex} transporter1 source {waferHolderMoveItem.SourceModule}");
  219. }
  220. return true;
  221. }
  222. }
  223. if (waferHolderMoveItem.DestModule != ModuleName.Unknown)
  224. {
  225. //Transporter1目标是Transporter2的起点,这样容易Transporter2不取走,Transporter1放不进去导致卡住
  226. if (waferHolderMoveItem.DestModule.ToString() == source)
  227. {
  228. return false;
  229. }
  230. if (_loaderTransporterEntity.CheckOtherModuleConflict(ModuleName.Transporter1.ToString(), waferHolderMoveItem.DestModule.ToString(), source))
  231. {
  232. if (isLog)
  233. {
  234. LOG.WriteLog(eEvent.EV_SCHEDULER, Module.ToString(), $"transporter2 source {source} will meet {waferHolderTask.WaferHolderInfo.Id} scheduler index {result.sequenceIndex} transporter1 dest {waferHolderMoveItem.DestModule}");
  235. }
  236. return true;
  237. }
  238. if (_loaderTransporterEntity.CheckOtherModuleConflict(ModuleName.Transporter1.ToString(), waferHolderMoveItem.DestModule.ToString(), dest))
  239. {
  240. if (isLog)
  241. {
  242. LOG.WriteLog(eEvent.EV_SCHEDULER, Module.ToString(), $"transporter2 dest {dest} will meet {waferHolderTask.WaferHolderInfo.Id} scheduler index {result.sequenceIndex} transporter1 dest {waferHolderMoveItem.DestModule}");
  243. }
  244. return true;
  245. }
  246. }
  247. return false;
  248. }
  249. /// <summary>
  250. /// Loader 开始Flip
  251. /// </summary>
  252. /// <returns></returns>
  253. private bool FlipLoader()
  254. {
  255. if (_loaderEntity.WaferHolderInfo == null)
  256. {
  257. return false;
  258. }
  259. if (_loaderTransporterEntity.WaferHolderInfo != null)
  260. {
  261. return false;
  262. }
  263. bool result = _loaderTransporterEntity.CheckToPostMessage<TransporterState, TransporterMSG>(eEvent.INFO_TRANSPORTER,
  264. Module.ToString(), (int)TransporterMSG.PickUpFrom, "Loader");
  265. if (result)
  266. {
  267. _state = RState.Running;
  268. _schedulerPostMsg.Reset();
  269. _postMsgResult = false;
  270. _transporterFlip = TransporterFlip.WaitPickUp;
  271. }
  272. return result;
  273. }
  274. /// <summary>
  275. /// WaferHolder从Loader移动至Buffer
  276. /// </summary>
  277. private bool TransWaferHolderFromLoader(WaferHolderMoveItem waferHolderMoveItem)
  278. {
  279. if (_loaderEntity.IsBusy)
  280. {
  281. return false;
  282. }
  283. if (_loaderEntity.WaferHolderInfo == null)
  284. {
  285. return false;
  286. }
  287. bool result = _loaderTransporterEntity.CheckToPostMessage<TransporterState, TransporterMSG>(Aitex.Core.RT.Log.eEvent.INFO_TRANSPORTER,
  288. Module.ToString(), (int)TransporterMSG.Transfer, "Loader", waferHolderMoveItem.DestModule.ToString());
  289. if (result)
  290. {
  291. _state = RState.Running;
  292. _schedulerPostMsg.Reset();
  293. _postMsgResult = false;
  294. }
  295. return result;
  296. }
  297. /// <summary>
  298. /// WaferHolder从Buffer移动至Loader
  299. /// </summary>
  300. private bool TransferWaferHolderToLoader(WaferHolderMoveItem waferHolderMoveItem)
  301. {
  302. if (_loaderEntity.WaferHolderInfo != null)
  303. {
  304. return false;
  305. }
  306. if (_loaderEntity.IsIdle)
  307. {
  308. bool loaderResult = _loaderEntity.CheckToPostMessage<LOADERSTATE, LoaderMSG>(eEvent.INFO_LOADER,
  309. _loaderEntity.Module.ToString(), (int)LoaderMSG.PrepareForPlace);
  310. if (loaderResult)
  311. {
  312. _transBufferToLoaderStep = TransBufferToLoaderStep.WaitLoaderPrePare;
  313. }
  314. return false;
  315. }
  316. else if (_loaderEntity.State == (int)LOADERSTATE.WaitForUnload&&_transBufferToLoaderStep<TransBufferToLoaderStep.PickUpValidate)
  317. {
  318. _transBufferToLoaderStep = TransBufferToLoaderStep.PickUpValidate;
  319. return false;
  320. }
  321. else if (_transBufferToLoaderStep == TransBufferToLoaderStep.WaitLoaderPrePare)
  322. {
  323. if (_loaderEntity.State == (int)LOADERSTATE.WaitForUnload)
  324. {
  325. _transBufferToLoaderStep = TransBufferToLoaderStep.PickUpValidate;
  326. }
  327. return false;
  328. }
  329. else if (_transBufferToLoaderStep == TransBufferToLoaderStep.PickUpValidate)
  330. {
  331. if(_loaderTransporterEntity.IsBusy)
  332. {
  333. return false;
  334. }
  335. if (!_loaderTransporterEntity.CheckOtherEntityStatus(waferHolderMoveItem.SourceModule.ToString()))
  336. {
  337. return false;
  338. }
  339. if (!_loaderTransporterEntity.CheckOtherEntityStatus(waferHolderMoveItem.DestModule.ToString()))
  340. {
  341. return false;
  342. }
  343. bool result = _loaderTransporterEntity.CheckToPostMessage<TransporterState, TransporterMSG>(Aitex.Core.RT.Log.eEvent.INFO_TRANSPORTER,
  344. Module.ToString(), (int)TransporterMSG.PickUpValidate, waferHolderMoveItem.SourceModule.ToString());
  345. if (result)
  346. {
  347. _transBufferToLoaderStep= TransBufferToLoaderStep.PickUpValidateMoveto;
  348. _state = RState.Running;
  349. _schedulerPostMsg.Reset();
  350. _postMsgResult = false;
  351. return true;
  352. }
  353. }
  354. return false;
  355. }
  356. /// <summary>
  357. /// 传输WaferHolder(无WaferHolder)
  358. /// </summary>
  359. /// <param name="waferHolderMoveItem"></param>
  360. private bool TransferWaferHolderNonLoader(WaferHolderMoveItem waferHolderMoveItem)
  361. {
  362. IModuleEntity moduleEntity = Singleton<RouteManager>.Instance.GetModule<IModuleEntity>(waferHolderMoveItem.DestModule.ToString());
  363. if (moduleEntity != null)
  364. {
  365. if (waferHolderMoveItem.SourceModule == ModuleName.Unknown || waferHolderMoveItem.DestModule == ModuleName.Unknown)
  366. {
  367. return false;
  368. }
  369. if (moduleEntity.Module == ModuleName.Prewet1)
  370. {
  371. PrewetEntity prewetEntity = moduleEntity as PrewetEntity;
  372. if(prewetEntity.State!=(int)PrewetState.WaitForPlace)
  373. {
  374. return false;
  375. }
  376. }
  377. else
  378. {
  379. if (!moduleEntity.IsIdle)
  380. {
  381. return false;
  382. }
  383. }
  384. if (waferHolderMoveItem.SourceModule != ModuleName.Unknown)
  385. {
  386. if (!_loaderTransporterEntity.CheckOtherEntityStatus(waferHolderMoveItem.SourceModule.ToString()))
  387. {
  388. return false;
  389. }
  390. }
  391. if (waferHolderMoveItem.DestModule != ModuleName.Unknown)
  392. {
  393. if (!_loaderTransporterEntity.CheckOtherEntityStatus(waferHolderMoveItem.DestModule.ToString()))
  394. {
  395. return false;
  396. }
  397. }
  398. bool result = _loaderTransporterEntity.CheckToPostMessage<TransporterState, TransporterMSG>(Aitex.Core.RT.Log.eEvent.INFO_TRANSPORTER,
  399. Module.ToString(), (int)TransporterMSG.Transfer, waferHolderMoveItem.SourceModule.ToString(), waferHolderMoveItem.DestModule.ToString());
  400. if (result)
  401. {
  402. _state = RState.Running;
  403. _postMsgResult = false;
  404. _schedulerPostMsg.Reset();
  405. }
  406. return result;
  407. }
  408. return false;
  409. }
  410. /// <summary>
  411. /// 监控执行
  412. /// </summary>
  413. /// <returns></returns>
  414. public override bool MonitorProcess(SchedulerSequence schedulerSequence, bool hasMatchWafer)
  415. {
  416. TransporterAction action=schedulerSequence.Parameters as TransporterAction;
  417. if (action.ActionMsg == TransporterMSG.Transfer)
  418. {
  419. WaferHolderMoveItem moveItem = action.Parameter as WaferHolderMoveItem;
  420. //检验PostMsg的结果
  421. if (!_postMsgResult)
  422. {
  423. if (_loaderTransporterEntity.IsError)
  424. {
  425. return false;
  426. }
  427. _postMsgResult = CheckPostMsg(moveItem);
  428. if (!_postMsgResult)
  429. {
  430. return false;
  431. }
  432. }
  433. if (moveItem.DestModule == ModuleName.Loader1)
  434. {
  435. if (_transBufferToLoaderStep == TransBufferToLoaderStep.PickUpValidateMoveto)
  436. {
  437. if (_loaderTransporterEntity.IsIdle)
  438. {
  439. _state = RState.Failed;
  440. _transBufferToLoaderStep = TransBufferToLoaderStep.None;
  441. return false;
  442. }
  443. if (_loaderTransporterEntity.State == (int)TransporterState.PickUpValidateComplete)
  444. {
  445. if (!_loaderTransporterEntity.CheckOtherEntityStatus("Loader"))
  446. {
  447. return false;
  448. }
  449. bool result = _loaderTransporterEntity.CheckToPostMessage<TransporterState, TransporterMSG>(Aitex.Core.RT.Log.eEvent.INFO_TRANSPORTER,
  450. Module.ToString(), (int)TransporterMSG.MoveTo, "Loader");
  451. if (result)
  452. {
  453. _transBufferToLoaderStep = TransBufferToLoaderStep.Place;
  454. }
  455. }
  456. return true;
  457. }
  458. else if (_transBufferToLoaderStep == TransBufferToLoaderStep.Place)
  459. {
  460. if (_loaderTransporterEntity.State == (int)TransporterState.ValidateMoveToComplete)
  461. {
  462. bool result = _loaderTransporterEntity.CheckToPostMessage<TransporterState, TransporterMSG>(Aitex.Core.RT.Log.eEvent.INFO_TRANSPORTER,
  463. Module.ToString(), (int)TransporterMSG.Place, "Loader");
  464. if (result)
  465. {
  466. _transBufferToLoaderStep = TransBufferToLoaderStep.End;
  467. }
  468. }
  469. return true;
  470. }
  471. }
  472. if (_loaderTransporterEntity.IsIdle)
  473. {
  474. if (_loaderTransporterEntity.WaferHolderInfo != null)
  475. {
  476. return false;
  477. }
  478. PrewetPickComplete(schedulerSequence);
  479. _state = RState.End;
  480. _transBufferToLoaderStep=TransBufferToLoaderStep.None;
  481. }
  482. }
  483. else if (action.ActionMsg == TransporterMSG.Flip)
  484. {
  485. LoaderTransporterFlip(action.Parameter.ToString());
  486. }
  487. return true;
  488. }
  489. /// <summary>
  490. /// Flip
  491. /// </summary>
  492. private void LoaderTransporterFlip(string strTransporter)
  493. {
  494. if(_transporterFlip==TransporterFlip.WaitPickUp)
  495. {
  496. //检验PostMsg的结果
  497. if (!_postMsgResult)
  498. {
  499. if (_loaderTransporterEntity.IsError)
  500. {
  501. return;
  502. }
  503. _postMsgResult = _schedulerPostMsg.PostMsg<TransporterState, TransporterMSG>(_loaderTransporterEntity, _loaderTransporterEntity.State,
  504. eEvent.INFO_TRANSPORTER, Module.ToString(), (int)TransporterMSG.PickUpFrom,(int)TransporterState.PickUping, "Loader");
  505. if (!_postMsgResult)
  506. {
  507. return;
  508. }
  509. }
  510. if (_loaderTransporterEntity.IsIdle && _loaderTransporterEntity.WaferHolderInfo != null)
  511. {
  512. _transporterFlip = TransporterFlip.LoaderFlip;
  513. }
  514. }
  515. else if (_transporterFlip == TransporterFlip.LoaderFlip)
  516. {
  517. bool result = _loaderEntity.CheckToPostMessage<LOADERSTATE, LoaderMSG>(eEvent.INFO_LOADER, Module.ToString(), (int)LoaderMSG.PrepareForPlace, strTransporter);
  518. if (result)
  519. {
  520. _transporterFlip = TransporterFlip.WaitLoader;
  521. }
  522. }
  523. else if(_transporterFlip==TransporterFlip.WaitLoader)
  524. {
  525. if (_loaderEntity.State == (int)LOADERSTATE.WaitForUnload)
  526. {
  527. bool result = _loaderTransporterEntity.CheckToPostMessage<TransporterState, TransporterMSG>(eEvent.INFO_TRANSPORTER,
  528. Module.ToString(), (int)TransporterMSG.Place, "Loader");
  529. if (result)
  530. {
  531. _transporterFlip = TransporterFlip.WaitPlace;
  532. }
  533. }
  534. }
  535. else if (_transporterFlip == TransporterFlip.WaitPlace)
  536. {
  537. if (_loaderTransporterEntity.IsIdle && _loaderTransporterEntity.WaferHolderInfo == null)
  538. {
  539. _state = RState.End;
  540. _transporterFlip = TransporterFlip.None;
  541. }
  542. }
  543. }
  544. /// <summary>
  545. /// 检验PostMsg的结果
  546. /// </summary>
  547. /// <param name="waferHolderMoveItem"></param>
  548. /// <returns></returns>
  549. private bool CheckPostMsg(WaferHolderMoveItem waferHolderMoveItem)
  550. {
  551. if (waferHolderMoveItem.DestModule == ModuleName.Loader1)
  552. {
  553. return _schedulerPostMsg.PostMsg<TransporterState,TransporterMSG>(_loaderTransporterEntity, _loaderTransporterEntity.State,
  554. eEvent.INFO_TRANSPORTER,Module.ToString(), (int)TransporterMSG.PickUpValidate,
  555. (int)TransporterState.PickUpValidating, waferHolderMoveItem.SourceModule.ToString());
  556. }
  557. else
  558. {
  559. return _schedulerPostMsg.PostMsg<TransporterState, TransporterMSG>(_loaderTransporterEntity, _loaderTransporterEntity.State,
  560. eEvent.INFO_TRANSPORTER, Module.ToString(), (int)TransporterMSG.Transfer,
  561. (int)TransporterState.Transfering, waferHolderMoveItem.SourceModule.ToString(),waferHolderMoveItem.DestModule.ToString());
  562. }
  563. }
  564. /// <summary>
  565. /// PrewetPick完成事件
  566. /// </summary>
  567. private void PrewetPickComplete(SchedulerSequence sequence)
  568. {
  569. if (sequence.Parameters is TransporterAction)
  570. {
  571. TransporterAction action = (TransporterAction)sequence.Parameters;
  572. if (action.ActionMsg!=TransporterMSG.Transfer)
  573. {
  574. return;
  575. }
  576. WaferHolderMoveItem waferHolderMoveItem = (WaferHolderMoveItem)action.Parameter;
  577. if (waferHolderMoveItem.SourceModule == ModuleName.Prewet1)
  578. {
  579. PrewetEntity prewetEntity = Singleton<RouteManager>.Instance.GetModule<PrewetEntity>(ModuleName.Prewet1.ToString());
  580. if (prewetEntity.State == (int)PrewetState.WaitForPick)
  581. {
  582. prewetEntity.CheckToPostMessage<PrewetState, PrewetMsg>(Aitex.Core.RT.Log.eEvent.INFO_PREWET, ModuleName.Prewet1.ToString(),
  583. (int)PrewetMsg.PickComplete);
  584. }
  585. }
  586. }
  587. }
  588. /// <summary>
  589. /// 检验前置条件
  590. /// </summary>
  591. /// <param name="sequenceIndex"></param>
  592. /// <param name="parameter"></param>
  593. /// <returns></returns>
  594. public override bool CheckPrecondition(List<SchedulerSequence> schedulerSequences, int sequenceIndex, object parameter, string materialId, ref string reason)
  595. {
  596. _state = RState.Init;
  597. if(!(parameter is TransporterAction))
  598. {
  599. reason = "parameter is not TransporterAction";
  600. return false;
  601. }
  602. TransporterAction action = (TransporterAction)parameter;
  603. if (_state == RState.Running)
  604. {
  605. reason = "scheduler module is already running";
  606. return false;
  607. }
  608. if (_loaderTransporterEntity.IsBusy)
  609. {
  610. reason = "loader transporter entity is busy";
  611. return false;
  612. }
  613. if (_loaderTransporterEntity.WaferHolderInfo != null&& _loaderTransporterEntity.State != (int)TransporterState.PickUpValidateComplete)
  614. {
  615. reason = "loader transporter has wafer shuttle,but state is not PickUpValidateComplete";
  616. return false;
  617. }
  618. //电机是否还在执行动作
  619. JetAxisBase gantryAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Transporter2}.Gantry");
  620. if (gantryAxis == null)
  621. {
  622. reason = "loader transporter gantry is null";
  623. return false;
  624. }
  625. if (gantryAxis.Status == RState.Running)
  626. {
  627. reason = "loader transporter gantry is running";
  628. return false;
  629. }
  630. JetAxisBase elevatorAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Transporter2}.Elevator");
  631. if (elevatorAxis == null)
  632. {
  633. reason = "loader transporter elevator is null";
  634. return false;
  635. }
  636. if (elevatorAxis.Status == RState.Running)
  637. {
  638. reason = "loader transporter elevator is running";
  639. return false;
  640. }
  641. if (action.ActionMsg == TransporterMSG.Transfer)
  642. {
  643. WaferHolderMoveItem waferHolderMoveItem = (WaferHolderMoveItem)action.Parameter;
  644. //更新未知目标模块
  645. bool result = UpdateUnkownTargetModule(schedulerSequences, waferHolderMoveItem, sequenceIndex, materialId);
  646. if (!result)
  647. {
  648. reason = "loader transporter moveitem target module is unknown";
  649. return false;
  650. }
  651. //更新未知源模块
  652. UpdateUnkownSourceModule(schedulerSequences, waferHolderMoveItem, sequenceIndex, materialId);
  653. if (waferHolderMoveItem.SourceModule != ModuleName.Unknown)
  654. {
  655. if (!_loaderTransporterEntity.CheckOtherEntityStatus(waferHolderMoveItem.SourceModule.ToString()))
  656. {
  657. reason = $"loader transporter {waferHolderMoveItem.SourceModule} conflict process transporter";
  658. return false;
  659. }
  660. }
  661. if (waferHolderMoveItem.DestModule != ModuleName.Unknown)
  662. {
  663. if (!_loaderTransporterEntity.CheckOtherEntityStatus(waferHolderMoveItem.DestModule.ToString()))
  664. {
  665. reason = $"loader transporter {waferHolderMoveItem.DestModule} conflict process transporter";
  666. return false;
  667. }
  668. if (WaferHolderManager.Instance.HasWaferHolder(waferHolderMoveItem.DestModule.ToString()))
  669. {
  670. reason = $"loader transporter {waferHolderMoveItem.DestModule} has wafer shuttle";
  671. return false;
  672. }
  673. }
  674. //目标为Prewet
  675. if (waferHolderMoveItem.DestModule == ModuleName.Prewet1)
  676. {
  677. bool prewetCondition = CheckTargetPrewetCondition();
  678. if (!prewetCondition)
  679. {
  680. reason = "loader transporter destmodule prewet condition is not avaible";
  681. }
  682. return prewetCondition;
  683. }
  684. //源为Prewet
  685. if (waferHolderMoveItem.SourceModule == ModuleName.Prewet1)
  686. {
  687. bool prewetCondition = CheckSourcePrewetCondition();
  688. if (!prewetCondition)
  689. {
  690. reason = "loader transporter sourcemodule prewet condition is not avaible";
  691. }
  692. }
  693. //已经确定了Pwt的Rinse
  694. if (waferHolderMoveItem.DestModuleType == ModuleType.Rinse && waferHolderMoveItem.DestModule != ModuleName.Unknown)
  695. {
  696. if (SchedulerManager.Instance.IsQdrCheckConflict && !SchedulerWaferHolderTimeManager.Instance.Contained(materialId))
  697. {
  698. SchedulerSequence qdrSequence = schedulerSequences[sequenceIndex + 1];
  699. QdrRecipe qdrRecipe = qdrSequence.Recipe as QdrRecipe;
  700. int recipeTime = qdrRecipe.CalculateRunRecipeTime();
  701. int transporterTransferSeconds = SC.GetValue<int>("Transporter.TransporterTransferSeconds");
  702. DateTime startTime = DateTime.Now.AddSeconds(transporterTransferSeconds).AddSeconds(recipeTime);
  703. result = SchedulerModuleTimeManager.Instance.ConfirmAllMetalQdrAndDryer(schedulerSequences, materialId, sequenceIndex, true, startTime);
  704. if (result)
  705. {
  706. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"scheduler transporter wafer shuttle {materialId} has avaible cells after Prewet");
  707. }
  708. return result;
  709. }
  710. }
  711. }
  712. return true;
  713. }
  714. /// <summary>
  715. /// 更新未知目标模块
  716. /// </summary>
  717. private bool UpdateUnkownTargetModule(List<SchedulerSequence> schedulerSequences, WaferHolderMoveItem waferHolderMoveItem, int sequenceIndex,string materialId)
  718. {
  719. SchedulerSequence currentSequence = schedulerSequences[sequenceIndex];
  720. if (waferHolderMoveItem.DestModule == ModuleName.Unknown)
  721. {
  722. ModuleName moduleName = SchedulerSequenceManager.Instance.GetAvaibleEmptyModuleCell(waferHolderMoveItem.DestModuleType,currentSequence.SequenceType);
  723. if (moduleName == ModuleName.Unknown)
  724. {
  725. return false;
  726. }
  727. else
  728. {
  729. bool result = true;
  730. if (SchedulerManager.Instance.IsQdrCheckConflict)
  731. {
  732. DateTime startTime = DateTime.Now;
  733. bool isPwt = false;
  734. if (waferHolderMoveItem.DestModuleType == ModuleType.Prewet)
  735. {
  736. PrewetEntity prewetEntity = Singleton<RouteManager>.Instance.GetModule<PrewetEntity>(ModuleName.Prewet1.ToString());
  737. SchedulerSequence pwtSequence = schedulerSequences[sequenceIndex + 1];
  738. PwtRecipe pwtRecipe = pwtSequence.Recipe as PwtRecipe;
  739. int recipeTime = prewetEntity.CalculateRecipeTime(pwtRecipe);
  740. int transporterTransferSeconds = SC.GetValue<int>("Transporter.TransporterTransferSeconds");
  741. startTime = DateTime.Now.AddSeconds(transporterTransferSeconds).AddSeconds(recipeTime);
  742. isPwt = true;
  743. }
  744. else if (waferHolderMoveItem.DestModuleType == ModuleType.Rinse)
  745. {
  746. SchedulerSequence qdrSequence = schedulerSequences[sequenceIndex + 1];
  747. QdrRecipe qdrRecipe = qdrSequence.Recipe as QdrRecipe;
  748. int recipeTime = qdrRecipe.CalculateRunRecipeTime();
  749. int transporterTransferSeconds = SC.GetValue<int>("Transporter.TransporterTransferSeconds");
  750. startTime = DateTime.Now.AddSeconds(transporterTransferSeconds).AddSeconds(recipeTime);
  751. isPwt = true;
  752. }
  753. if (isPwt)
  754. {
  755. result = SchedulerModuleTimeManager.Instance.ConfirmAllMetalQdrAndDryer(schedulerSequences, materialId, sequenceIndex, true, startTime);
  756. if (result)
  757. {
  758. LOG.WriteLog(eEvent.EV_SCHEDULER, "System", $"scheduler transporter wafer shuttle {materialId} has avaible cells after Prewet");
  759. }
  760. else
  761. {
  762. return false;
  763. }
  764. }
  765. }
  766. if (result)
  767. {
  768. waferHolderMoveItem.DestModule = moduleName;
  769. if (sequenceIndex + 1 < schedulerSequences.Count)
  770. {
  771. SchedulerSequence sequence = schedulerSequences[sequenceIndex + 1];
  772. if (sequence.SchedulerModule == null)
  773. {
  774. sequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(moduleName);
  775. sequence.ModuleName = moduleName;
  776. LOG.WriteLog(eEvent.INFO_TRANSPORTER, Module.ToString(), $"{materialId} loadertransporter confirm source module {moduleName}");
  777. }
  778. }
  779. }
  780. }
  781. }
  782. return true;
  783. }
  784. /// <summary>
  785. /// 更新未知源模块
  786. /// </summary>
  787. private void UpdateUnkownSourceModule(List<SchedulerSequence> schedulerSequences, WaferHolderMoveItem waferHolderMoveItem,int sequenceIndex,string materialId)
  788. {
  789. if (waferHolderMoveItem.SourceModule == ModuleName.Unknown)
  790. {
  791. if (sequenceIndex >= 1 && sequenceIndex - 1 < schedulerSequences.Count)
  792. {
  793. SchedulerSequence preSchedulerSequence = schedulerSequences[sequenceIndex - 1];
  794. if (preSchedulerSequence != null && preSchedulerSequence.SchedulerModule != null)
  795. {
  796. waferHolderMoveItem.SourceModule = preSchedulerSequence.SchedulerModule.Module;
  797. LOG.WriteLog(eEvent.INFO_TRANSPORTER, Module.ToString(), $"{materialId} loadertransporter confirm source module {preSchedulerSequence.SchedulerModule.Module}");
  798. }
  799. }
  800. }
  801. }
  802. /// <summary>
  803. /// 检验目标Prewet前置条件
  804. /// </summary>
  805. /// <returns></returns>
  806. private bool CheckTargetPrewetCondition()
  807. {
  808. PrewetEntity prewetEntity = Singleton<RouteManager>.Instance.GetModule<PrewetEntity>(ModuleName.Prewet1.ToString());
  809. if(prewetEntity.IsIdle)
  810. {
  811. prewetEntity.CheckToPostMessage<PrewetState, PrewetMsg>(Aitex.Core.RT.Log.eEvent.INFO_PREWET, ModuleName.Prewet1.ToString(),
  812. (int)PrewetMsg.PrepareToPlace);
  813. }
  814. else if(prewetEntity.State==(int)PrewetState.WaitForPlace)
  815. {
  816. return true;
  817. }
  818. return false;
  819. }
  820. /// <summary>
  821. /// 检验源Prewet前置条件
  822. /// </summary>
  823. /// <returns></returns>
  824. private bool CheckSourcePrewetCondition()
  825. {
  826. PrewetEntity prewetEntity = Singleton<RouteManager>.Instance.GetModule<PrewetEntity>(ModuleName.Prewet1.ToString());
  827. if (prewetEntity.State == (int)PrewetState.WaitForPick||prewetEntity.IsError)
  828. {
  829. return true;
  830. }
  831. return false;
  832. }
  833. public override void ResetTask()
  834. {
  835. base.ResetTask();
  836. _schedulerPostMsg.Reset();
  837. _postMsgResult = false;
  838. }
  839. }
  840. }