EfemPlaceRoutine.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. using Aitex.Core.RT.Routine;
  2. using Aitex.Core.RT.SCCore;
  3. using Aitex.Sorter.Common;
  4. using CyberX8_RT.Devices;
  5. using MECF.Framework.Common.Routine;
  6. using MECF.Framework.Common.Equipment;
  7. using MECF.Framework.Common.SubstrateTrackings;
  8. using CyberX8_Core;
  9. using Aitex.Core.RT.Log;
  10. using Aitex.Core.Util;
  11. using MECF.Framework.Common.Schedulers;
  12. using System.Collections.Generic;
  13. using CyberX8_RT.Devices.EFEM;
  14. using CyberX8_RT.Modules.SRD;
  15. using CyberX8_RT.Modules.PUF;
  16. using CyberX8_RT.Devices.AXIS;
  17. using Aitex.Core.RT.Device;
  18. using MECF.Framework.Common.Utilities;
  19. using System;
  20. using CyberX8_RT.Modules.LPs;
  21. namespace CyberX8_RT.Modules.EFEM
  22. {
  23. class EfemPlaceRoutine : RoutineBase, IRoutine
  24. {
  25. private enum PlaceStep
  26. {
  27. WaitModuleReady,
  28. Placing1,
  29. Placing2,
  30. End,
  31. }
  32. private int _moveTimeout = 20 * 1000;
  33. private ModuleName _targetModule = ModuleName.System;
  34. int _targetSlot;
  35. string _targetPufSlot;
  36. int _targetSlot2;
  37. Hand _hand;
  38. Hand _hand2;
  39. EfemBase _efem;
  40. bool _bDoublePlace = false;
  41. private SRDEntity _srdModule;
  42. private PUFEntity _pufModule;
  43. private Queue<MoveItem> _moveItems;
  44. public EfemPlaceRoutine(EfemBase efem) : base(ModuleName.EfemRobot.ToString())
  45. {
  46. _efem = efem;
  47. }
  48. public RState Start(params object[] objs)
  49. {
  50. _bDoublePlace = false;
  51. _moveItems = (Queue<MoveItem>)objs[0];
  52. _targetModule = _moveItems.Peek().DestinationModule;
  53. _targetSlot = _moveItems.Peek().DestinationSlot;
  54. _hand = _moveItems.Peek().RobotHand;
  55. if (!CheckPreCondition())
  56. {
  57. return RState.Failed;
  58. }
  59. _moveTimeout = SC.GetValue<int>($"EFEM.MotionTimeout") * 1000;
  60. return Runner.Start(Module, $"Place to {_targetModule}");
  61. }
  62. private Loadport GetLoadPort(ModuleName station)
  63. {
  64. LoadPortModule loadPortModule = Singleton<RouteManager>.Instance.EFEM.GetLoadportModule(station - ModuleName.LP1);
  65. return loadPortModule.LPDevice;
  66. }
  67. private bool CheckPreCondition()
  68. {
  69. //LoadPort状态判断
  70. if (ModuleHelper.IsLoadPort(_targetModule) && ModuleHelper.IsInstalled(_targetModule))
  71. {
  72. Loadport loadPort = GetLoadPort(_targetModule);
  73. if (loadPort == null)
  74. {
  75. return false;
  76. }
  77. if (!loadPort.IsLoaded)
  78. {
  79. NotifyError(eEvent.ERR_EFEM_ROBOT, $"LoadPort not load, cannot do the pick action", -1);
  80. return false;
  81. }
  82. }
  83. if (ModuleHelper.IsSRD(_targetModule) && ModuleHelper.IsInstalled(_targetModule))
  84. {
  85. _srdModule = Singleton<RouteManager>.Instance.GetModule<SRDEntity>(_targetModule.ToString());
  86. if (!_srdModule.IsHomed)
  87. {
  88. NotifyError(eEvent.ERR_EFEM_ROBOT, $"{_targetModule} is not homed, please home it first",-1);
  89. return false;
  90. }
  91. //判断arm是否在home位置上
  92. JetAxisBase jetAxisBase = DEVICE.GetDevice<JetAxisBase>($"{_targetModule}.Arm");
  93. double position = jetAxisBase.MotionData.MotorPosition;
  94. bool result = jetAxisBase.CheckPositionIsInStation(position, "Home");
  95. if (!result)
  96. {
  97. NotifyError(eEvent.ERR_EFEM_ROBOT, $"{_targetModule} armaxis {position} is not in homed place",-1);
  98. return false;
  99. }
  100. if (_srdModule.IsSrdDoorClosed)
  101. {
  102. NotifyError(eEvent.ERR_EFEM_ROBOT, $"{_targetModule} door closed, can not place",-1);
  103. return false;
  104. }
  105. }
  106. if (ModuleHelper.IsPUF(_targetModule) && ModuleHelper.IsInstalled(_targetModule))
  107. {
  108. _pufModule = Singleton<RouteManager>.Instance.GetModule<PUFEntity>(_targetModule.ToString());
  109. if (!_pufModule.IsHomed)
  110. {
  111. NotifyError(eEvent.ERR_EFEM_ROBOT, $"{_targetModule} is not homed, please home it first",-1);
  112. return false;
  113. }
  114. if (!_pufModule.IsInRobotStation)
  115. {
  116. NotifyError(eEvent.ERR_EFEM_ROBOT, $"{_targetModule} not in robot station, cannot do the place action",-1);
  117. return false;
  118. }
  119. }
  120. if (WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, (int)_hand))
  121. {
  122. NotifyError(eEvent.ERR_EFEM_ROBOT, $"Efem robot arm{_hand} already has no wafer, cannot do the place action",-1);
  123. return false;
  124. }
  125. if (WaferManager.Instance.CheckHasWafer(_targetModule, _targetSlot))
  126. {
  127. if (ModuleHelper.IsPUF(_targetModule))
  128. {
  129. _targetPufSlot = _targetSlot == 0 ? "SideA" : "SideB";
  130. NotifyError(eEvent.ERR_EFEM_ROBOT, $"The target: {_targetModule}.{_targetPufSlot} has a wafer, cannot do the place action",-1);
  131. }
  132. else
  133. {
  134. NotifyError(eEvent.ERR_EFEM_ROBOT, $"The target: {_targetModule}.{_targetSlot + 1} has a wafer, cannot do the place action",-1);
  135. }
  136. return false;
  137. }
  138. if (_moveItems.Count >= 2)
  139. {
  140. if (!ModuleHelper.IsLoadPort(_targetModule))
  141. {
  142. NotifyError(eEvent.ERR_EFEM_ROBOT,$"Wrong double place command, target is not loadport",-1);
  143. return false;
  144. }
  145. _hand2 = _hand != Hand.Blade1 ? Hand.Blade1 : Hand.Blade2;
  146. if (WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, (int)_hand2))
  147. {
  148. NotifyError(eEvent.ERR_EFEM_ROBOT,$"Efem robot arm{_hand2} has no wafer, cannot do the double place action",-1);
  149. return false;
  150. }
  151. _targetSlot2 = _moveItems.ToArray()[1].DestinationSlot;
  152. if (WaferManager.Instance.CheckHasWafer(_targetModule, _targetSlot2))
  153. {
  154. NotifyError(eEvent.ERR_EFEM_ROBOT, $"The target: {_targetModule}.{_targetSlot2 + 1} has a wafer, cannot do the double pick action",-1);
  155. return false;
  156. }
  157. }
  158. return true;
  159. }
  160. public RState Monitor()
  161. {
  162. if (_bDoublePlace)
  163. {
  164. Runner.Wait(PlaceStep.WaitModuleReady, WaitModuleReady)
  165. .Run(PlaceStep.Placing1, Place1, Place1Done, _moveTimeout)
  166. .Run(PlaceStep.Placing2, Place2, Place2Done, _moveTimeout)
  167. .End(PlaceStep.End, ActionDone);
  168. }
  169. else
  170. {
  171. Runner.Wait(PlaceStep.WaitModuleReady, WaitModuleReady)
  172. .Run(PlaceStep.Placing1, Place1, Place1Done, _moveTimeout)
  173. .End(PlaceStep.End, ActionDone);
  174. }
  175. return Runner.Status;
  176. }
  177. public void Abort()
  178. {
  179. _efem.Halt();
  180. }
  181. private bool WaitModuleReady()
  182. {
  183. return _efem.Status == RState.End;
  184. }
  185. private bool Place1()
  186. {
  187. return _efem.Place(_targetModule, _targetSlot, _hand);
  188. }
  189. private bool Place1Done()
  190. {
  191. if (_efem.Status == RState.End)
  192. {
  193. WaferManager.Instance.WaferMoved(ModuleName.EfemRobot, (int)_hand, _targetModule, _targetSlot);
  194. return true;
  195. }
  196. else if (_efem.Status == RState.Failed)
  197. {
  198. NotifyError(eEvent.ERR_EFEM_ROBOT, $"Efem robot place failed: {_efem.Status}",-1);
  199. return true;
  200. }
  201. return false;
  202. }
  203. private bool Place2()
  204. {
  205. return _efem.Place(_targetModule, _targetSlot2, _hand2);
  206. }
  207. private bool Place2Done()
  208. {
  209. if (_efem.Status == RState.End)
  210. {
  211. WaferManager.Instance.WaferMoved(ModuleName.EfemRobot, (int)_hand2, _targetModule, _targetSlot2);
  212. return true;
  213. }
  214. else if (_efem.Status == RState.Failed)
  215. {
  216. NotifyError(eEvent.ERR_EFEM_ROBOT, $"Efem robot place failed: {_efem.Status}",-1);
  217. return true;
  218. }
  219. return false;
  220. }
  221. private bool ActionDone()
  222. {
  223. return true;
  224. }
  225. /// <summary>
  226. /// 重试
  227. /// </summary>
  228. /// <param name="step"></param>
  229. public RState Retry(int step)
  230. {
  231. if (!CheckPreCondition())
  232. {
  233. return RState.Failed;
  234. }
  235. _efem.Reset();
  236. List<Enum> preStepIds = new List<Enum>();
  237. AddPreSteps(PlaceStep.Placing1, preStepIds);
  238. return Runner.Retry(PlaceStep.Placing1, preStepIds, Module, "Place Retry");
  239. }
  240. /// <summary>
  241. /// 忽略前
  242. /// </summary>
  243. /// <param name="step"></param>
  244. /// <param name="preStepIds"></param>
  245. private void AddPreSteps(PlaceStep step, List<Enum> preStepIds)
  246. {
  247. for (int i = 0; i < (int)step; i++)
  248. {
  249. preStepIds.Add((PlaceStep)i);
  250. }
  251. }
  252. /// <summary>
  253. /// 检验前面完成状态
  254. /// </summary>
  255. /// <returns></returns>
  256. public bool CheckCompleteCondition(int index)
  257. {
  258. if (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, (int)_hand))
  259. {
  260. NotifyError(eEvent.ERR_EFEM_ROBOT, $"Efem robot arm{_hand} has no wafer", -1);
  261. return false;
  262. }
  263. if (WaferManager.Instance.CheckNoWafer(_targetModule, _targetSlot))
  264. {
  265. NotifyError(eEvent.ERR_EFEM_ROBOT, $"{_targetModule} Slot{_targetSlot} has no wafer", -1);
  266. return false;
  267. }
  268. return true;
  269. }
  270. }
  271. }