MFPMPickRoutine.cs 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. using Aitex.Core.RT.Routine;
  2. using Aitex.Core.RT.SCCore;
  3. using Aitex.Sorter.Common;
  4. using Aitex.Core.Common;
  5. using Venus_RT.Devices;
  6. using MECF.Framework.Common.Routine;
  7. using MECF.Framework.Common.Equipment;
  8. using MECF.Framework.Common.SubstrateTrackings;
  9. using Venus_Core;
  10. using Aitex.Core.RT.Log;
  11. using Aitex.Core.Util;
  12. using Venus_RT.Modules.PMs;
  13. using MECF.Framework.Common.Schedulers;
  14. using System.Collections.Generic;
  15. using System;
  16. using MECF.Framework.Common.DBCore;
  17. namespace Venus_RT.Modules.TM
  18. {
  19. class MFPMPickRoutine : ModuleRoutineBase, IRoutine
  20. {
  21. private enum PickStep
  22. {
  23. WaitPMReady,
  24. PMPrepare,
  25. ArmExtend,
  26. QueryAWC,
  27. DropDownWafer,
  28. PickDelay,
  29. ArmRetract,
  30. SavePickeData,
  31. NotifyDone,
  32. }
  33. private enum PickStepWithHeater
  34. {
  35. WaitPMReady,
  36. PMPrepare,
  37. Picking,
  38. QueryAWC,
  39. SavePickeData,
  40. NotifyDone,
  41. }
  42. private readonly JetTM _JetTM;
  43. private readonly ITransferRobot _robot;
  44. private int _pickingTimeout = 120 * 1000;
  45. private int _pickDelayTime = 0;
  46. private ModuleName _targetModule;
  47. private PMEntity _pmModule;
  48. private int _targetSlot;
  49. private Hand _hand;
  50. private DateTime _starttime;
  51. private bool _queryAwc;
  52. public MFPMPickRoutine(JetTM tm, ITransferRobot robot) : base(ModuleName.TMRobot)
  53. {
  54. _JetTM = tm;
  55. _robot = robot;
  56. Name = "Pick from PM";
  57. if (SC.GetValue<int>($"TM.QueryAWCOption") == 1 || SC.GetValue<int>($"TM.QueryAWCOption") == 3)
  58. _queryAwc = true;
  59. else
  60. _queryAwc = false;
  61. }
  62. public RState Start(params object[] objs)
  63. {
  64. _starttime = DateTime.Now;
  65. if (!_robot.IsHomed)
  66. {
  67. LOG.Write(eEvent.ERR_TM, Module, $"TM Robot is not homed, please home it first");
  68. return RState.Failed;
  69. }
  70. var pickItem = (Queue<MoveItem>)objs[0];
  71. _targetModule = pickItem.Peek().SourceModule;
  72. _targetSlot = pickItem.Peek().SourceSlot;
  73. _hand = pickItem.Peek().RobotHand;
  74. if (ModuleHelper.IsPm(_targetModule) && ModuleHelper.IsInstalled(_targetModule))
  75. {
  76. _pmModule = Singleton<RouteManager>.Instance.GetPM(_targetModule);
  77. }
  78. else
  79. {
  80. LOG.Write(eEvent.ERR_TM, Module, $"Invalid target module : {_targetModule} for picking action");
  81. return RState.Failed;
  82. }
  83. if (WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, (int)_hand))
  84. {
  85. LOG.Write(eEvent.ERR_TM, Module, $"Cannot pick as TM Robot Arm: {_hand} already has a wafer");
  86. return RState.Failed;
  87. }
  88. if (WaferManager.Instance.CheckNoWafer(_targetModule, _targetSlot))
  89. {
  90. LOG.Write(eEvent.ERR_TM, Module, $"Cannot pick as {_targetModule} Slot {_targetSlot + 1} has no wafer");
  91. return RState.Failed;
  92. }
  93. var wafer = WaferManager.Instance.GetWafer(_targetModule, _targetSlot);
  94. if(wafer.ChuckState == EnumWaferChuckStatus.Chucked)
  95. {
  96. LOG.Write(eEvent.ERR_TM, Module, $"Cannot pick the wafer in {_targetModule }as the wafer is chucked");
  97. return RState.Failed;
  98. }
  99. LOG.Write(eEvent.INFO_TM_ROBOT, ModuleName.TMRobot, $"{wafer.WaferOrigin} will be move from {_targetModule} {_targetSlot + 1} to TM Robot {_hand}");
  100. Reset();
  101. _pickingTimeout = SC.GetValue<int>("TM.PickTimeout") * 1000;
  102. _pickDelayTime = SC.GetValue<int>($"{_targetModule}.PickDelayTime");
  103. return Runner.Start(Module, $"Pick from {_targetModule}");
  104. }
  105. public RState Monitor()
  106. {
  107. switch (_pmModule.ChamberType)
  108. {
  109. case JetChamber.Venus:
  110. case JetChamber.Kepler2300:
  111. Runner.Wait(PickStep.WaitPMReady, () => _pmModule.IsIdle, _delay_60s)
  112. .Run(PickStep.PMPrepare, ModulePrepare, IsModulePrepareReady)
  113. .Run(PickStep.ArmExtend, ArmExtend, WaitRobotExtendDone)
  114. .Run(PickStep.QueryAWC, QueryAWC, WaitRobotQueryDone, _delay_1s)
  115. .Run(PickStep.DropDownWafer, NotifyPMPickWafer, WaitPMWaferDropDown)
  116. .Delay(PickStep.PickDelay, _pickDelayTime)
  117. .Run(PickStep.ArmRetract, ArmRetract, WaitRobotRetractDone)
  118. .Run(PickStep.SavePickeData, RecordAWCData, NullFun)
  119. .End(PickStep.NotifyDone, NotifyPMDone, _delay_50ms);
  120. break;
  121. case JetChamber.Kepler2200A:
  122. case JetChamber.Kepler2200B:
  123. Runner.Wait(PickStepWithHeater.WaitPMReady, () => _pmModule.IsIdle, _delay_60s)
  124. .Run(PickStepWithHeater.PMPrepare, ModulePrepare, IsModulePrepareReady)
  125. .Run(PickStepWithHeater.Picking, Picking, WaitPickDone)
  126. .Run(PickStepWithHeater.QueryAWC, QueryAWC, WaitRobotQueryDone)
  127. .Run(PickStepWithHeater.SavePickeData, RecordAWCData, NullFun)
  128. .End(PickStepWithHeater.NotifyDone, NotifyPMDone, _delay_1s);
  129. break;
  130. }
  131. return Runner.Status;
  132. }
  133. private bool ModulePrepare()
  134. {
  135. _pmModule.PostMsg(PMEntity.MSG.PreparePick);
  136. return true;
  137. }
  138. private bool IsModulePrepareReady()
  139. {
  140. return _pmModule.Status == PMEntity.PMStatus.Ready_For_Pick && _pmModule.IsSlitDoorOpen;
  141. }
  142. private bool Picking()
  143. {
  144. return _robot.Pick(_targetModule, _targetSlot, _hand);
  145. }
  146. private bool WaitPickDone()
  147. {
  148. if (_robot.Status == RState.Running)
  149. {
  150. return false;
  151. }
  152. else if (_robot.Status == RState.End)
  153. {
  154. //WaferManager.Instance.WaferMoved(ModuleName.TM, (int)_hand, _targetModule, _targetSlot);
  155. WaferManager.Instance.WaferMoved(_targetModule, _targetSlot, ModuleName.TMRobot, (int)_hand);
  156. return true;
  157. }
  158. else
  159. {
  160. Runner.Stop($"TM Robot Picking failed, {_robot.Status}");
  161. return true;
  162. }
  163. }
  164. private bool ArmExtend()
  165. {
  166. return _robot.PickExtend(_targetModule, _targetSlot, _hand);
  167. }
  168. private bool ArmRetract()
  169. {
  170. return _robot.PickRetract(_targetModule, _targetSlot, _hand);
  171. }
  172. private bool WaitRobotExtendDone()
  173. {
  174. if (_robot.Status == RState.Running)
  175. {
  176. return false;
  177. }
  178. else if (_robot.Status == RState.End)
  179. {
  180. WaferManager.Instance.WaferMoved(_targetModule, _targetSlot, ModuleName.TMRobot, (int)_hand);
  181. return true;
  182. }
  183. else
  184. {
  185. Runner.Stop($"TM Robot Pick Extend failed, {_robot.Status}");
  186. return true;
  187. }
  188. }
  189. private bool QueryAWC()
  190. {
  191. if (!_queryAwc)
  192. return true;
  193. else
  194. return _robot.QueryAwc(); ;
  195. }
  196. private bool WaitRobotQueryDone()
  197. {
  198. if (!_queryAwc)
  199. return true;
  200. if (_robot.Status == RState.Running)
  201. {
  202. return false;
  203. }
  204. else if (_robot.Status == RState.End)
  205. {
  206. return true;
  207. }
  208. else
  209. {
  210. Runner.Stop($"TM Robot Query Awc failed, {_robot.Status}");
  211. return true;
  212. }
  213. }
  214. private bool RecordAWCData()
  215. {
  216. if (!_queryAwc)
  217. return true;
  218. //已经move后的数据
  219. string _origin_module = $"LP{WaferManager.Instance.GetWafer(_targetModule, _targetSlot).OriginStation}";
  220. int _origin_slot = WaferManager.Instance.GetWafer(_targetModule, _targetSlot).OriginSlot;
  221. //查询完毕 插入数据
  222. OffsetDataRecorder.RecordOffsetData(
  223. Guid.NewGuid().ToString(),
  224. _targetModule, _targetSlot,
  225. ModuleName.TMRobot, 0,
  226. _origin_module, _origin_slot,
  227. _hand, RobotArmPan.None,
  228. _robot.Offset_X, _robot.Offset_Y, _robot.Offset_D,
  229. _starttime, DateTime.Now);
  230. return true;
  231. }
  232. private bool NotifyPMPickWafer()
  233. {
  234. _pmModule.PostMsg(PMEntity.MSG.DropDownWafer);
  235. return true;
  236. }
  237. private bool WaitPMWaferDropDown()
  238. {
  239. return _pmModule.Status == PMEntity.PMStatus.Exchange_Ready;
  240. }
  241. private bool WaitRobotRetractDone()
  242. {
  243. if (_robot.Status == RState.Running)
  244. {
  245. return false;
  246. }
  247. else if (_robot.Status == RState.End)
  248. {
  249. return true;
  250. }
  251. else
  252. {
  253. Runner.Stop($"TM Robot Pick Retract failed, {_robot.Status}");
  254. return true;
  255. }
  256. }
  257. private bool NotifyPMDone()
  258. {
  259. _pmModule.PostMsg(PMEntity.MSG.PickReady);
  260. return true;
  261. }
  262. public void Abort()
  263. {
  264. _robot.Halt();
  265. }
  266. }
  267. }