SingleArmMoveManager.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Security.AccessControl;
  4. using Aitex.Core.Common;
  5. using Aitex.Core.RT.Device;
  6. using Aitex.Core.RT.Event;
  7. using Aitex.Core.RT.Routine;
  8. using Aitex.Core.RT.SCCore;
  9. using Aitex.Core.Util;
  10. using Aitex.Sorter.Common;
  11. using Aitex.Sorter.RT.Module;
  12. using Aitex.Sorter.RT.SorterCommonFrame.Routines;
  13. using MECF.Framework.Common.Equipment;
  14. using MECF.Framework.Common.SubstrateTrackings;
  15. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts;
  16. namespace Aitex.Sorter.RT.SorterCommonFrame.Modules
  17. {
  18. public class SingleMoveManager : IMoveManager
  19. {
  20. public event Action<MoveErrorArgument> OnMoveError;
  21. public Hand Blade { get; set; }
  22. public int TaskCount { get { return tasks.Count; } }
  23. public bool IsPaused { get { return !_pause; } }
  24. public int WaferCompleted
  25. {
  26. get
  27. {
  28. int count = tasks.Count;
  29. int completed = lastTaskCount - count;
  30. lastTaskCount = count;
  31. return completed;
  32. }
  33. }
  34. private PickRoutine pickRoutine = null;
  35. private PlaceRoutine placeRoutine = null;
  36. private AlignRoutine alignRoutine = null;
  37. private List<MoveTask> tasks = new List<MoveTask>();
  38. private IRoutine _robotRoutine = null;
  39. private AlignRoutine _alignerRoutine = null;
  40. private MoveTask task1 = null;
  41. private int lastTaskCount = 0;
  42. private bool _verifyFail = false;
  43. private bool _pause = true;
  44. public SingleMoveManager()
  45. {
  46. pickRoutine = new PickRoutine("System", "PickRoutine");
  47. pickRoutine.Initalize();
  48. placeRoutine = new PlaceRoutine("System", "PlaceRoutine");
  49. placeRoutine.Initalize();
  50. alignRoutine = new AlignRoutine("System", "AlignRoutine");
  51. alignRoutine.Initalize();
  52. }
  53. public bool Initialize()
  54. {
  55. return true;
  56. }
  57. public bool Pause()
  58. {
  59. _pause = true;
  60. return true;
  61. }
  62. public bool Resume()
  63. {
  64. _pause = false;
  65. return true;
  66. }
  67. public bool Stop()
  68. {
  69. tasks.Clear();
  70. if (task1 != null)
  71. tasks.Add(task1);
  72. _pause = false;
  73. return true;
  74. }
  75. public bool Start(List<MoveTask> tasks)
  76. {
  77. _robotRoutine = null;
  78. _alignerRoutine = null;
  79. this.tasks = tasks;
  80. _pause = false;
  81. bool bCheck = true;
  82. foreach (MoveTask task in tasks)
  83. {
  84. if (IsSwap(task))
  85. {
  86. string reason = string.Format("single arm can't support swap operation. {0}:{1} ---> {2}:{3}.",
  87. ((ModuleName)task.SourceStaion).ToString(),
  88. task.SourceSlot,
  89. ((ModuleName)task.DestStaion).ToString(),
  90. task.DestSlot);
  91. EV.PostMessage(ModuleName.System.ToString(),EventEnum.DefaultWarning, reason);
  92. bCheck = false;
  93. }
  94. }
  95. if (!bCheck)
  96. return false;
  97. foreach (MoveTask task in tasks)
  98. {
  99. WaferManager.Instance.UpdateWaferProcessStatus(task.WaferID, ProcessStatus.Wait);
  100. task.WaferID = WaferManager.Instance.GetWaferID(task.SourceStaion, task.SourceSlot);
  101. }
  102. newTask();
  103. if (task1 == null)
  104. {
  105. return true;
  106. }
  107. _robotRoutine = null;
  108. _alignerRoutine = null;
  109. lastTaskCount = tasks.Count;
  110. return true;
  111. }
  112. private void newTask()
  113. {
  114. if (tasks.Count > 0)
  115. task1 = tasks[0];
  116. if (task1 != null)
  117. {
  118. WaferManager.Instance.UpdateWaferProcessStatus(task1.WaferID, ProcessStatus.Busy);
  119. }
  120. }
  121. private bool IsSwap(MoveTask task)
  122. {
  123. if ((task.DestStaion == task.SourceStaion) && (task.DestSlot == task.SourceSlot))
  124. return false;
  125. return WaferManager.Instance.CheckHasWafer(task.DestStaion, task.DestSlot);
  126. }
  127. public bool Monitor(object[] objs)
  128. {
  129. Result ret = Result.RUN;
  130. if (tasks.Count == 0 && task1 == null)
  131. {
  132. return true; //completed
  133. }
  134. if (task1 == null)
  135. {
  136. if (!_pause)
  137. newTask();
  138. }
  139. if (_alignerRoutine != null)
  140. {
  141. ret = _alignerRoutine.Monitor();
  142. if (ret == Result.DONE)
  143. {
  144. _alignerRoutine = null;
  145. AlignCompleted();
  146. return false;
  147. }
  148. else if (ret == Result.FAIL)
  149. {
  150. WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 0, ProcessStatus.Failed);
  151. WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 1, ProcessStatus.Failed);
  152. WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Aligner, 0, ProcessStatus.Failed);
  153. NotifyError("Aligner", "Aligner Error");
  154. return true; //failed
  155. }
  156. }
  157. if (_robotRoutine != null)
  158. {
  159. ret = _robotRoutine.Monitor();
  160. if (ret == Result.DONE)
  161. {
  162. _robotRoutine = null;
  163. return false;
  164. }
  165. else if (ret == Result.FAIL)
  166. {
  167. WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 0, ProcessStatus.Failed);
  168. WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 1, ProcessStatus.Failed);
  169. WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Aligner, 0, ProcessStatus.Failed);
  170. NotifyError("Robot", "Robot Error");
  171. return true; //failed
  172. }
  173. }
  174. else
  175. {
  176. if (!_pause)
  177. {
  178. IRoutine rountine = NextRoutine();
  179. if (rountine != null)
  180. {
  181. rountine.Start();
  182. _robotRoutine = rountine;
  183. }
  184. }
  185. }
  186. return false;
  187. }
  188. public Result Monitor()
  189. {
  190. Result ret = Result.RUN;
  191. if (tasks.Count == 0 && task1 == null)
  192. {
  193. return Result.DONE; //completed
  194. }
  195. if (task1 == null)
  196. {
  197. if (!_pause)
  198. newTask();
  199. }
  200. if (_alignerRoutine != null)
  201. {
  202. ret = _alignerRoutine.Monitor();
  203. if (ret == Result.DONE)
  204. {
  205. _alignerRoutine = null;
  206. AlignCompleted();
  207. return Result.RUN;
  208. }
  209. else if (ret == Result.FAIL)
  210. {
  211. WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 0, ProcessStatus.Failed);
  212. WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 1, ProcessStatus.Failed);
  213. WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Aligner, 0, ProcessStatus.Failed);
  214. NotifyError("Aligner", "Aligner Error");
  215. return Result.FAIL; //failed
  216. }
  217. else if (ret == Result.VERIFYFAIL)
  218. {
  219. // _alignerRoutine = null;
  220. if (SC.ContainsItem(SorterCommon.ScPathName.Process_LMMismatchHandle))
  221. switch (SC.GetValue<int>(SorterCommon.ScPathName.Process_LMMismatchHandle))
  222. {
  223. case 2:
  224. task1.DestStaion = task1.SourceStaion;
  225. task1.DestSlot = task1.SourceSlot;
  226. WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Aligner, 0, ProcessStatus.Failed);
  227. _verifyFail = true;
  228. break;
  229. case 3:
  230. ModuleName handleLp;
  231. if (SC.ContainsItem(SorterCommon.ScPathName.Process_MismatchCollectPort))
  232. {
  233. handleLp = ModuleHelper.Converter(SC.GetStringValue(SorterCommon.ScPathName.Process_MismatchCollectPort));
  234. if (!ModuleHelper.IsLoadPort(handleLp)) break;
  235. //handleLp = ModuleName.LP1;
  236. }
  237. else break;
  238. task1.DestStaion = handleLp;
  239. int startSlot = SC.ContainsItem("LoadPort." + handleLp.ToString() + "StartSlot")
  240. ? SC.GetValue<int>("LoadPort." + handleLp.ToString() + "StartSlot") : 1;
  241. if (startSlot > 25 || startSlot < 1) startSlot = 1;
  242. int endSlot = SC.ContainsItem("LoadPort." + handleLp.ToString() + "EndSlot")
  243. ? SC.GetValue<int>("LoadPort." + handleLp.ToString() + "EndSlot") : 25;
  244. if (endSlot > 25 || endSlot < 1) endSlot = 25;
  245. WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Aligner, 0, ProcessStatus.Failed);
  246. _verifyFail = true;
  247. var emptySlot = DEVICE.GetDevice<LoadPort>(handleLp.ToString()).GetEmptySlot();
  248. foreach(int slot in emptySlot)
  249. {
  250. if (slot < startSlot || slot > endSlot) emptySlot.Remove(slot);
  251. }
  252. if (emptySlot.Count != 0)
  253. {
  254. if (SC.ContainsItem("Process.PlaceFromTopOnHostLPMode") && SC.GetValue<bool>("Process.PlaceFromTopOnHostLPMode"))
  255. {
  256. task1.DestSlot = emptySlot[emptySlot.Count - 1];
  257. }
  258. else
  259. {
  260. task1.DestSlot = emptySlot[0];
  261. }
  262. break;
  263. }
  264. else
  265. {
  266. Singleton<RouteManagerSorter>.Instance.PostMsg(RouteManagerSorter.MSG.PauseRecipe);
  267. EV.PostWarningLog(handleLp.ToString(), $"{handleLp} is full.");
  268. break;
  269. }
  270. }
  271. //AlignCompleted();
  272. _alignerRoutine.PostAlignValue = SC.ContainsItem("Aligner." + task1.DestStaion + "PostAlignAngle") ?
  273. SC.GetValue<double>("Aligner." + task1.DestStaion + "PostAlignAngle") : 0;
  274. return Result.RUN;
  275. }
  276. }
  277. if (_robotRoutine != null)
  278. {
  279. ret = _robotRoutine.Monitor();
  280. if (ret == Result.DONE)
  281. {
  282. _robotRoutine = null;
  283. return Result.RUN;
  284. }
  285. else if (ret == Result.FAIL)
  286. {
  287. WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 0, ProcessStatus.Failed);
  288. WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Robot, 1, ProcessStatus.Failed);
  289. WaferManager.Instance.UpdateWaferProcessStatus(ModuleName.Aligner, 0, ProcessStatus.Failed);
  290. NotifyError("Robot", "Robot Error");
  291. return Result.FAIL; //failed
  292. }
  293. }
  294. else
  295. {
  296. if (!_pause)
  297. {
  298. IRoutine rountine = NextRoutine();
  299. if (rountine != null)
  300. {
  301. rountine.Start();
  302. _robotRoutine = rountine;
  303. }
  304. }
  305. }
  306. return Result.RUN;
  307. }
  308. private void AlignCompleted()
  309. {
  310. if (task1 != null)
  311. {
  312. if (task1.Step == MoveStep.WaitAligner)
  313. {
  314. task1.Step = MoveStep.PickFromAligner;
  315. }
  316. }
  317. }
  318. private IRoutine NextRoutine()
  319. {
  320. IRoutine routine = null;
  321. if (task1.Step == MoveStep.PickFromSource)
  322. {
  323. pickRoutine.Source = task1.SourceStaion;
  324. pickRoutine.Slot = task1.SourceSlot;
  325. pickRoutine.Blade = GetEmptyHand();
  326. task1.Blade = pickRoutine.Blade;
  327. routine = pickRoutine;
  328. if (PassTurnOver(task1.option) && PassAligner(task1.option))
  329. {
  330. task1.Step = MoveStep.PlaceToAligner;
  331. }
  332. else if(PassTurnOver(task1.option))
  333. {
  334. task1.Step = MoveStep.PlaceToTurnOver;
  335. }
  336. else if (PassAligner(task1.option))
  337. {
  338. task1.Step = MoveStep.PlaceToAligner;
  339. }
  340. else
  341. {
  342. task1.Step = MoveStep.PlaceToDest;
  343. }
  344. }
  345. else if (task1.Step == MoveStep.PlaceToTurnOver)
  346. {
  347. placeRoutine.Station = ModuleName.TurnOverStation;
  348. placeRoutine.Slot = 0;
  349. placeRoutine.Blade = task1.Blade;
  350. task1.Step = MoveStep.PickFromTurnOver;
  351. routine = placeRoutine;
  352. }
  353. else if (task1.Step == MoveStep.PlaceToAligner)
  354. {
  355. placeRoutine.Station = ModuleName.Aligner;
  356. placeRoutine.Slot = 0;
  357. placeRoutine.Blade = task1.Blade;
  358. task1.Step = MoveStep.Aligning;
  359. routine = placeRoutine;
  360. }
  361. else if (task1.Step == MoveStep.Aligning)
  362. {
  363. alignRoutine.Option = task1.option;
  364. alignRoutine.Notch = task1.Notch;
  365. alignRoutine.IsVerifyAny = task1.VerifyAny;
  366. alignRoutine.IsVerifyLM1 = task1.VerifyLaserMaker;
  367. alignRoutine.StrLaserMark1 = task1.LaserMaker;
  368. alignRoutine.IsVerifyLM2 = task1.VerifyT7Code;
  369. alignRoutine.StrLaserMark2 = task1.T7Code;
  370. alignRoutine.PostAlignValue = SC.ContainsItem("Aligner." + task1.DestStaion + "PostAlignAngle") ?
  371. SC.GetValue<double>("Aligner." + task1.DestStaion + "PostAlignAngle") : 0;
  372. _alignerRoutine = alignRoutine;
  373. _alignerRoutine.Start();
  374. task1.Step = MoveStep.WaitAligner;
  375. }
  376. else if (task1.Step == MoveStep.PickFromTurnOver)
  377. {
  378. pickRoutine.Source = ModuleName.TurnOverStation;
  379. pickRoutine.Slot = 0;
  380. pickRoutine.Blade = task1.Blade;
  381. task1.Step = MoveStep.PlaceToDest;
  382. routine = pickRoutine;
  383. }
  384. else if (task1.Step == MoveStep.PickFromAligner)
  385. {
  386. if (_alignerRoutine == null) //aligning completed
  387. {
  388. if (PassTurnOver(task1.option))
  389. {
  390. pickRoutine.Source = ModuleName.Aligner;
  391. pickRoutine.Slot = 0;
  392. pickRoutine.Blade = task1.Blade;
  393. task1.Step = MoveStep.PlaceToTurnOver;
  394. routine = pickRoutine;
  395. }
  396. else
  397. {
  398. pickRoutine.Source = ModuleName.Aligner;
  399. pickRoutine.Slot = 0;
  400. pickRoutine.Blade = task1.Blade;
  401. task1.Step = MoveStep.PlaceToDest;
  402. routine = pickRoutine;
  403. }
  404. }
  405. }
  406. else if (task1.Step == MoveStep.PlaceToDest)
  407. {
  408. placeRoutine.Station = task1.DestStaion;
  409. placeRoutine.Slot = task1.DestSlot;
  410. placeRoutine.Blade = task1.Blade;
  411. task1.Step = MoveStep.Completed;
  412. routine = placeRoutine;
  413. }
  414. else if (task1.Step == MoveStep.Completed)
  415. {
  416. if (_verifyFail)
  417. {
  418. WaferManager.Instance.UpdateWaferProcessStatus(task1.DestStaion, task1.DestSlot, ProcessStatus.Failed);
  419. _verifyFail = false;
  420. }
  421. else
  422. WaferManager.Instance.UpdateWaferProcessStatus(task1.DestStaion, task1.DestSlot, ProcessStatus.Completed);
  423. tasks.Remove(task1);
  424. task1 = GetNextTask();
  425. }
  426. return routine;
  427. }
  428. private bool PassAligner(MoveOption option)
  429. {
  430. return (((option & MoveOption.Align) == MoveOption.Align) || ((option & MoveOption.ReadID) == MoveOption.ReadID)
  431. || ((option & MoveOption.ReadID2) == MoveOption.ReadID2));
  432. }
  433. private bool PassTurnOver(MoveOption option)
  434. {
  435. return (option & MoveOption.Turnover) == MoveOption.Turnover;
  436. }
  437. private Hand GetEmptyHand()
  438. {
  439. return this.Blade;
  440. /*
  441. if (!WaferManager.Instance.CheckWafer(UnitName.Robot, 0, WaferStatus.Normal))
  442. {
  443. return Hand.Blade1;
  444. }
  445. if (!WaferManager.Instance.CheckWafer(UnitName.Robot, 1, WaferStatus.Normal))
  446. {
  447. return Hand.Blade2;
  448. }
  449. */
  450. //return Hand.Blade1;
  451. }
  452. private MoveTask GetNextTask()
  453. {
  454. MoveTask newTask = null;
  455. if (tasks.Count > 0)
  456. newTask = tasks[0];
  457. if (newTask != null)
  458. {
  459. WaferManager.Instance.UpdateWaferProcessStatus(newTask.WaferID, ProcessStatus.Busy);
  460. }
  461. return newTask;
  462. }
  463. //private void PostMsg(RouteManager.MSG msg, params object[] objs)
  464. //{
  465. // Singleton<RouteManager>.Instance.PostMsg(msg, objs);
  466. //}
  467. private void NotifyError(string module, string message)
  468. {
  469. if (OnMoveError != null)
  470. {
  471. OnMoveError(new MoveErrorArgument(module, message));
  472. }
  473. }
  474. }
  475. }