StaticTransfer.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. using Aitex.Core.RT.Device;
  2. using Aitex.Core.RT.Event;
  3. using Aitex.Core.RT.Routine;
  4. using Aitex.Core.Util;
  5. using Aitex.Sorter.Common;
  6. using athosRT.Devices;
  7. using athosRT.FSM;
  8. using athosRT.Modules.EFEMs.Routine;
  9. using athosRT.tool;
  10. using MECF.Framework.Common.Equipment;
  11. using MECF.Framework.Common.SubstrateTrackings;
  12. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase;
  13. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase;
  14. using System;
  15. using System.Collections.Generic;
  16. using System.Linq;
  17. using System.Reflection.Emit;
  18. using System.Text;
  19. using System.Threading.Tasks;
  20. using IRoutine = athosRT.FSM.IRoutine;
  21. using EV = athosRT.tool.EV;
  22. using athosRT.Modules;
  23. namespace athosRT.Modules.EFEMs
  24. {
  25. public class StaticTransfer
  26. {
  27. private Queue<IRoutine> steps = null;//定义routine队列
  28. private IRoutine curStep = null;//当前routine
  29. private PickRoutine[] pickRoutine = null;
  30. private PlaceRoutine[] placeRoutine = null;
  31. private AlignRoutine[] alignRoutine = null;//对齐
  32. private ModuleName _sourceStation;
  33. private ModuleName _targetStation;
  34. public string Name = "Transfer";
  35. public int Notch1 { get; set; }
  36. public ModuleName SourceStation => _sourceStation;
  37. public ModuleName TargetStation => _targetStation;
  38. private readonly RobotBaseDevice robot;
  39. public StaticTransfer() {
  40. robot = DEVICE.GetDevice<RobotBaseDevice>("Robot");
  41. int IndexNum = 5;
  42. steps = new Queue<IRoutine>();
  43. pickRoutine = new PickRoutine[IndexNum];
  44. for (int index = 0; index < IndexNum; ++index)
  45. {
  46. //LogObject.Info(Name, $"第{index}个 PickRoutine开始实例化");
  47. pickRoutine[index] = new PickRoutine(ModuleName.System);
  48. }
  49. placeRoutine = new PlaceRoutine[IndexNum];
  50. for (int index = 0; index < IndexNum; ++index)
  51. {
  52. //LogObject.Info(Name, $"第{index}个 PickRoutine开始实例化");
  53. placeRoutine[index] = new PlaceRoutine(ModuleName.System);
  54. }
  55. alignRoutine = new AlignRoutine[2];
  56. for (int index = 0; index < 2; ++index)
  57. {
  58. alignRoutine[index] = new AlignRoutine();
  59. }
  60. }
  61. public bool Start(object[] objs)
  62. {
  63. LogObject.Info(Name, "transfer start");
  64. MoveType moveType;
  65. Enum.TryParse<MoveType>(objs[0].ToString(),out moveType);//mov类型
  66. LogObject.Info(Name, "transfer MoveType");
  67. MoveOption moveOption;
  68. Enum.TryParse<MoveOption>(objs[1].ToString(), out moveOption);//mov选项
  69. LogObject.Info(Name, "transfer MoveOption");
  70. //bool flag = (moveOption & MoveOption.Align) == MoveOption.Align || (moveOption & MoveOption.ReadID) == MoveOption.ReadID || (moveOption & MoveOption.ReadID2) == MoveOption.ReadID2;
  71. bool flag = false;
  72. Hand hand;
  73. Enum.TryParse<Hand>(objs[2].ToString(), out hand);//手臂
  74. LogObject.Info(Name, "transfer Hand");
  75. ModuleName moduleName1 = ModuleHelper.Converter(objs[3].ToString());
  76. LogObject.Info(Name, "transfer Source");
  77. _sourceStation = moduleName1;
  78. int num1 = Convert.ToInt32(objs[4]);
  79. LogObject.Info(Name, "transfer source slot");
  80. ModuleName moduleName2= ModuleHelper.Converter(objs[5].ToString());
  81. LogObject.Info(Name, "transfer destination");
  82. _targetStation = moduleName2;
  83. int num2 = Convert.ToInt32(objs[6]);
  84. LogObject.Info(Name, "transfer destiation slot");
  85. steps.Clear();
  86. switch (moveType)
  87. {
  88. case MoveType.Move:
  89. //当目标不是robot的时候(也是就是ll lp等)装入pick队列
  90. if (moduleName1 != ModuleName.Robot)
  91. {
  92. pickRoutine[0].Source = moduleName1;
  93. pickRoutine[0].Slot = num1;
  94. pickRoutine[0].Blade = hand;
  95. steps.Enqueue(pickRoutine[0]);
  96. }
  97. //robot 上wafer 移动到下个目标
  98. else {
  99. placeRoutine[1].Station = moduleName2;
  100. placeRoutine[1].Slot = num2;
  101. placeRoutine[1].Blade = hand;
  102. steps.Enqueue(placeRoutine[1]);
  103. goto case MoveType.Swap;
  104. }
  105. //当目标是Aligner或ReadID1、2时
  106. if (flag)
  107. {
  108. //place的初始点是aligner slot槽是0 blade是hand
  109. placeRoutine[0].Station = ModuleName.Aligner;
  110. placeRoutine[0].Slot = 0;
  111. placeRoutine[0].Blade = hand;
  112. steps.Enqueue(placeRoutine[0]);
  113. //align的选项是moveOption 缺口是motch
  114. alignRoutine[0].Option = moveOption;
  115. alignRoutine[0].Notch = Notch1;
  116. steps.Enqueue(alignRoutine[0]);
  117. switch (moduleName2)
  118. {
  119. //如果目标2是aligner
  120. case ModuleName.Aligner:
  121. goto label_32;
  122. //是robot 从aligner上获取
  123. case ModuleName.Robot:
  124. pickRoutine[1].Source = ModuleName.Aligner;
  125. pickRoutine[1].Slot = 0;
  126. pickRoutine[1].Blade = (Hand)num2;
  127. steps.Enqueue(pickRoutine[1]);
  128. break;
  129. //默认的
  130. default:
  131. pickRoutine[1].Source = ModuleName.Aligner;
  132. pickRoutine[1].Slot = 0;
  133. pickRoutine[1].Blade = hand;
  134. steps.Enqueue(pickRoutine[1]);
  135. placeRoutine[1].Station = moduleName2;
  136. placeRoutine[1].Slot = num2;
  137. placeRoutine[1].Blade = hand;
  138. steps.Enqueue(placeRoutine[1]);
  139. break;
  140. }
  141. goto case MoveType.Swap;
  142. }
  143. else
  144. {
  145. //如果modulename2不为robot
  146. if (moduleName2 != ModuleName.Robot)
  147. {
  148. //place1的目标是module
  149. placeRoutine[1].Station = moduleName2;
  150. placeRoutine[1].Slot = num2;
  151. placeRoutine[1].Blade = hand;
  152. steps.Enqueue(placeRoutine[1]);
  153. }
  154. goto case MoveType.Swap;
  155. }
  156. case MoveType.Swap:
  157. label_32:
  158. //没有入列 count为空
  159. if (steps.Count == 0)
  160. {
  161. LogObject.Error(Name, "没有任务进入队列");
  162. return false;
  163. }
  164. curStep = steps.Dequeue();
  165. //开启当前步骤
  166. if(curStep.Start(objs) != RState.Failed)
  167. {
  168. LogObject.Info(Name, "开始当前步骤");
  169. return true;
  170. }
  171. LogObject.Error(Name,"Failed start transfer");
  172. return false;
  173. default:
  174. ModuleName moduleName3 = (ModuleName)objs[7];
  175. int num3 = (int)objs[8];
  176. ModuleName moduleName4 = (ModuleName)objs[9];
  177. int num4 = (int)objs[10];
  178. //MoveType的数据类型 SPSP SPDP
  179. if (moveType == MoveType.SPSP || moveType == MoveType.SPDP)
  180. {
  181. //如果 起始点、终止点都不是robot
  182. if (moduleName1 != ModuleName.Robot && moduleName3 != ModuleName.Robot)
  183. {
  184. //从pick捡起modulename1
  185. pickRoutine[0].Source = moduleName1;
  186. pickRoutine[0].Slot = num1;
  187. pickRoutine[0].Blade = Hand.Blade1;
  188. steps.Enqueue(pickRoutine[0]);
  189. //从pick捡起modulename3
  190. pickRoutine[1].Source = moduleName3;
  191. pickRoutine[1].Slot = num3;
  192. pickRoutine[1].Blade = Hand.Blade2;
  193. steps.Enqueue(pickRoutine[1]);
  194. }
  195. else if (moduleName1 == ModuleName.Robot)
  196. {
  197. //如果是在robot上 源为m3
  198. pickRoutine[1].Source = moduleName3;
  199. pickRoutine[1].Slot = num3;
  200. pickRoutine[1].Blade = num1 != 0 ? Hand.Blade1 : Hand.Blade2;
  201. steps.Enqueue(pickRoutine[1]);
  202. }
  203. else
  204. {
  205. //如果不是在robot上 则要先从1上取出来
  206. pickRoutine[0].Source = moduleName1;
  207. pickRoutine[0].Slot = num1;
  208. pickRoutine[0].Blade = num3 != 0 ? Hand.Blade1 : Hand.Blade2;
  209. steps.Enqueue(pickRoutine[0]);
  210. }
  211. }
  212. else if (moduleName1 != ModuleName.Robot)
  213. {
  214. //双臂举起
  215. pickRoutine[0].Source = moduleName1;
  216. pickRoutine[0].Slot = num1;
  217. pickRoutine[0].Blade = Hand.Both;
  218. steps.Enqueue(pickRoutine[0]);
  219. }
  220. if (moveType == MoveType.SPSP || moveType == MoveType.DPSP)
  221. {
  222. if (moduleName2 != ModuleName.Robot && moduleName2 != ModuleName.Robot)
  223. {
  224. placeRoutine[1].Station = moduleName2;
  225. placeRoutine[1].Slot = num2;
  226. placeRoutine[1].Blade = Hand.Blade1;
  227. steps.Enqueue(placeRoutine[1]);
  228. placeRoutine[2].Station = moduleName4;
  229. placeRoutine[2].Slot = num4;
  230. placeRoutine[2].Blade = Hand.Blade2;
  231. steps.Enqueue(placeRoutine[2]);
  232. }
  233. else if (moduleName2 == ModuleName.Robot)
  234. {
  235. placeRoutine[2].Station = moduleName4;
  236. placeRoutine[2].Slot = num4;
  237. placeRoutine[2].Blade = num3 != 0 ? Hand.Blade1 : Hand.Blade2;
  238. steps.Enqueue(placeRoutine[2]);
  239. }
  240. else
  241. {
  242. placeRoutine[1].Station = moduleName2;
  243. placeRoutine[1].Slot = num2;
  244. placeRoutine[1].Blade = num1 != 0 ? Hand.Blade1 : Hand.Blade2;
  245. steps.Enqueue(placeRoutine[1]);
  246. }
  247. }
  248. else if (moduleName2 != ModuleName.Robot)
  249. {
  250. placeRoutine[1].Station = moduleName2;
  251. placeRoutine[1].Slot = num2;
  252. placeRoutine[1].Blade = Hand.Both;
  253. steps.Enqueue(placeRoutine[1]);
  254. }
  255. goto case MoveType.Swap;
  256. }
  257. }
  258. /// <summary>
  259. /// monitor只管做队列的头部任务直到结束为止
  260. /// </summary>
  261. /// <param name="objs"></param>
  262. /// <returns>当前任务的执行结果</returns>
  263. public bool Monitor(object[] objs)
  264. {
  265. RState result = RState.Failed;
  266. if(curStep!=null)
  267. result = curStep.Monitor();
  268. switch(result)
  269. {
  270. case RState.End:
  271. curStep = steps.Count <= 0 ? null : steps.Dequeue();//出栈
  272. //没有队列任务了
  273. if (curStep == null)
  274. {
  275. LogObject.Info(Name, "所有Routine已经执行完毕");
  276. return true;
  277. }
  278. //下一步任务start失败
  279. if (curStep.Start() != RState.Failed)
  280. {
  281. //LogObject.Error(Name, "下一个Routine无法开始 请检查任务队列");
  282. return false;
  283. }
  284. //不明确的发错误 可能是想把不包括的情况都认定为错误
  285. PostMsg(RouteManager1.MSG.ERROR);
  286. return true;
  287. case RState.Failed:
  288. LogObject.Error(Name, "当前Routine执行失败 置错误");
  289. PostMsg(RouteManager1.MSG.ERROR);
  290. return true;
  291. default:
  292. return false;
  293. }
  294. }
  295. public bool Return(object[] objs)
  296. {
  297. steps.Clear();
  298. ModuleName lpModule = ModuleName.LP1;
  299. int slot = 0;
  300. if (Singleton<WaferManager>.Instance.CheckHasWafer(ModuleName.Robot, 0))
  301. {
  302. if (!FindEmptySlot(ref lpModule, ref slot))
  303. {
  304. steps.Clear();
  305. return false;
  306. }
  307. placeRoutine[0].Station = lpModule;
  308. placeRoutine[0].Slot = slot;
  309. placeRoutine[0].Blade = Hand.Blade1;
  310. steps.Enqueue(placeRoutine[0]);
  311. }
  312. if (Singleton<WaferManager>.Instance.CheckHasWafer(ModuleName.Robot, 1) || Singleton<WaferManager>.Instance.CheckHasWafer(ModuleName.Robot, 2) || Singleton<WaferManager>.Instance.CheckHasWafer(ModuleName.Robot, 3))
  313. {
  314. ++slot;
  315. if (!FindEmptySlotForMultiBlade(ref lpModule, ref slot))
  316. {
  317. steps.Clear();
  318. return false;
  319. }
  320. placeRoutine[1].Station = lpModule;
  321. placeRoutine[1].Slot = slot;
  322. placeRoutine[1].Blade = Hand.Blade2;
  323. steps.Enqueue(placeRoutine[1]);
  324. }
  325. if (Singleton<WaferManager>.Instance.CheckHasWafer(ModuleName.Aligner, 0))
  326. {
  327. ++slot;
  328. if (!FindEmptySlot(ref lpModule, ref slot))
  329. {
  330. steps.Clear();
  331. return false;
  332. }
  333. pickRoutine[0].Source = ModuleName.Aligner;
  334. pickRoutine[0].Slot = 0;
  335. pickRoutine[0].Blade = Hand.Blade1;
  336. steps.Enqueue(pickRoutine[0]);
  337. placeRoutine[2].Station = lpModule;
  338. placeRoutine[2].Slot = slot;
  339. placeRoutine[2].Blade = Hand.Blade1;
  340. steps.Enqueue(placeRoutine[2]);
  341. }
  342. if (steps.Count == 0)
  343. return false;
  344. curStep = steps.Dequeue();
  345. if (curStep.Start(objs) != RState.Failed)
  346. return true;
  347. EV.PostWarningLog(ModuleName.System.ToString(), "Failed start return");
  348. return false;
  349. }
  350. private bool FindEmptySlot(ref ModuleName lpModule, ref int slot)
  351. {
  352. LoadPortBaseDevice device = DEVICE.GetDevice<LoadPortBaseDevice>(lpModule.ToString());
  353. string reason;
  354. if (device.IsEnableTransferWafer(out reason))
  355. {
  356. for (int slot1 = slot; slot1 < 25; ++slot1)
  357. {
  358. if (Singleton<WaferManager>.Instance.CheckNoWafer(device.Name, slot1))
  359. {
  360. slot = slot1;
  361. return true;
  362. }
  363. }
  364. }
  365. foreach (LoadPortBaseDevice allLoadPort in Singleton<DeviceManager>.Instance.GetAllLoadPorts())
  366. {
  367. if (!(allLoadPort.Name == lpModule.ToString()) && allLoadPort.IsEnableTransferWafer(out reason))
  368. {
  369. for (int slot2 = 0; slot2 < 25; ++slot2)
  370. {
  371. if (Singleton<WaferManager>.Instance.CheckNoWafer(allLoadPort.Name, slot2))
  372. {
  373. lpModule = (ModuleName)Enum.Parse(typeof(ModuleName), allLoadPort.Name);
  374. slot = slot2;
  375. return true;
  376. }
  377. }
  378. }
  379. }
  380. return false;
  381. }
  382. private bool FindEmptySlotForMultiBlade(ref ModuleName lpModule, ref int slot)
  383. {
  384. LoadPortBaseDevice device = DEVICE.GetDevice<LoadPortBaseDevice>(lpModule.ToString());
  385. string reason;
  386. if (device.IsEnableTransferWafer(out reason))
  387. {
  388. for (int slot1 = slot; slot1 < 23; ++slot1)
  389. {
  390. if (Singleton<WaferManager>.Instance.CheckNoWafer(device.Name, slot1) && Singleton<WaferManager>.Instance.CheckNoWafer(device.Name, slot1 + 1) && Singleton<WaferManager>.Instance.CheckNoWafer(device.Name, slot1 + 2))
  391. {
  392. slot = slot1;
  393. return true;
  394. }
  395. }
  396. }
  397. foreach (LoadPortBaseDevice allLoadPort in Singleton<DeviceManager>.Instance.GetAllLoadPorts())
  398. {
  399. if (!(allLoadPort.Name == lpModule.ToString()) && allLoadPort.IsEnableTransferWafer(out reason))
  400. {
  401. for (int slot2 = 0; slot2 < 23; ++slot2)
  402. {
  403. if (Singleton<WaferManager>.Instance.CheckNoWafer(allLoadPort.Name, slot2) && Singleton<WaferManager>.Instance.CheckNoWafer(allLoadPort.Name, slot2 + 1) && Singleton<WaferManager>.Instance.CheckNoWafer(allLoadPort.Name, slot2 + 2))
  404. {
  405. lpModule = (ModuleName)Enum.Parse(typeof(ModuleName), allLoadPort.Name);
  406. slot = slot2;
  407. return true;
  408. }
  409. }
  410. }
  411. }
  412. return false;
  413. }
  414. public void Clear()
  415. {
  416. steps.Clear();
  417. curStep = null;
  418. }
  419. private void PostMsg(RouteManager1.MSG msg, params object[] objs) => Singleton<RouteManager1>.Instance.PostMsg(msg, objs);
  420. }
  421. }