PufPickFromLoaderRoutine.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. using Aitex.Core.RT.DataCenter;
  2. using Aitex.Core.RT.Device;
  3. using Aitex.Core.RT.Event;
  4. using Aitex.Core.RT.Log;
  5. using Aitex.Core.RT.Routine;
  6. using MECF.Framework.Common.Equipment;
  7. using MECF.Framework.Common.Routine;
  8. using MECF.Framework.Common.Utilities;
  9. using CyberX8_Core;
  10. using CyberX8_RT.Devices.AXIS;
  11. using CyberX8_RT.Devices.Loader;
  12. using CyberX8_RT.Devices.PUF;
  13. using CyberX8_RT.Devices.TransPorter;
  14. using System;
  15. using System.Collections.Generic;
  16. using System.Linq;
  17. using System.Text;
  18. using System.Threading.Tasks;
  19. namespace CyberX8_RT.Modules.PUF
  20. {
  21. public class PufPickFromLoaderRoutine : RoutineBase,IRoutine
  22. {
  23. #region 常量
  24. private const string SideA = "SideA";
  25. private const string SideB = "SideB";
  26. private const string CURRENT_STATION_LIST = "CurrentStationList";
  27. #endregion
  28. #region 内部变量
  29. private string _side;
  30. private JetAxisBase _flipAxis;
  31. private JetAxisBase _rotationAxis;
  32. private JetAxisBase _verticalAxis;
  33. private JetAxisBase _gantryAxis;
  34. private LoaderSideDevice _loaderSide;
  35. private PufVacuum _vacuum;
  36. private IRoutine _routine;
  37. private PufNoWaferPickRoutine _noWaferPickRoutine;
  38. private PufWaferPickRoutine _pufWaferPickRoutine;
  39. #endregion
  40. /// <summary>
  41. /// 构造函数
  42. /// </summary>
  43. /// <param name="module"></param>
  44. /// <param name="pufEntity"></param>
  45. public PufPickFromLoaderRoutine(string module) : base(module)
  46. {
  47. _noWaferPickRoutine =new PufNoWaferPickRoutine(module);
  48. _pufWaferPickRoutine=new PufWaferPickRoutine(module);
  49. }
  50. /// <summary>
  51. /// 中止
  52. /// </summary>
  53. public void Abort()
  54. {
  55. _routine.Abort();
  56. }
  57. /// <summary>
  58. /// 监控
  59. /// </summary>
  60. /// <returns></returns>
  61. public RState Monitor()
  62. {
  63. return _routine.Monitor();
  64. }
  65. /// <summary>
  66. /// 启动
  67. /// </summary>
  68. /// <param name="objs"></param>
  69. /// <returns></returns>
  70. public RState Start(params object[] objs)
  71. {
  72. _side = objs[0].ToString();
  73. _flipAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Flip");
  74. _rotationAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Rotation");
  75. _verticalAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Vertical");
  76. _vacuum = DEVICE.GetDevice<PufVacuum>($"{Module}.Vacuum");
  77. _gantryAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Transporter2}.Gantry");
  78. GetLoaderSide();
  79. if (CheckCondition())
  80. {
  81. if (CheckReverseWafer())
  82. {
  83. _routine = _pufWaferPickRoutine;
  84. }
  85. else
  86. {
  87. _routine = _noWaferPickRoutine;
  88. }
  89. _routine.Start(_side);
  90. return RState.Running;
  91. }
  92. else
  93. {
  94. return RState.Failed;
  95. }
  96. }
  97. /// <summary>
  98. /// 检验条件
  99. /// </summary>
  100. /// <returns></returns>
  101. private bool CheckCondition()
  102. {
  103. //Loader1.Rotation 在LOADA
  104. bool isLoaderInstall = ModuleHelper.IsInstalled(ModuleName.Loader1);
  105. if (isLoaderInstall)
  106. {
  107. JetAxisBase loaderRotationAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.Rotation");
  108. double loaderRotationPosition = loaderRotationAxis.MotionData.MotorPosition;
  109. if (!loaderRotationAxis.CheckPositionIsInStation(loaderRotationPosition, "LOADA"))
  110. {
  111. LOG.WriteLog(eEvent.ERR_PUF, Module, $"Loader Rotation {loaderRotationPosition} is not in LOADA");
  112. return false;
  113. }
  114. if (Module == ModuleName.PUF1.ToString())
  115. {
  116. //Loader1.SwingA 在Open
  117. JetAxisBase loaderShuttleAAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.ShuttleA");
  118. double loaderShuttleAPosition = loaderShuttleAAxis.MotionData.MotorPosition;
  119. if (!loaderShuttleAAxis.CheckPositionIsInStation(loaderShuttleAPosition, "OPEN"))
  120. {
  121. LOG.WriteLog(eEvent.ERR_PUF, Module, $"Loader ShuttleA {loaderShuttleAPosition} is not in OPEN");
  122. return false;
  123. }
  124. //Loader1.TiltA 在HORI
  125. JetAxisBase loaderTiltAAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.TiltA");
  126. double loaderTiltAPosition = loaderTiltAAxis.MotionData.MotorPosition;
  127. if (!loaderTiltAAxis.CheckPositionIsInStation(loaderTiltAPosition, "HORI"))
  128. {
  129. LOG.WriteLog(eEvent.ERR_PUF, Module, $"Loader TiltA {loaderTiltAPosition} is not in HORI");
  130. return false;
  131. }
  132. }
  133. if (Module == ModuleName.PUF2.ToString())
  134. {
  135. //Loader1.ShuttleB 在Open
  136. JetAxisBase loaderShuttleBAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.ShuttleB");
  137. double loaderShuttleBPosition = loaderShuttleBAxis.MotionData.MotorPosition;
  138. if (!loaderShuttleBAxis.CheckPositionIsInStation(loaderShuttleBPosition, "OPEN"))
  139. {
  140. LOG.WriteLog(eEvent.ERR_PUF, Module, $"Loader ShuttleB {loaderShuttleBPosition} is not in OPEN");
  141. return false;
  142. }
  143. //Loader1.TiltB 在HORI
  144. JetAxisBase loaderTiltBAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.TiltB");
  145. double loaderTiltBPosition = loaderTiltBAxis.MotionData.MotorPosition;
  146. if (!loaderTiltBAxis.CheckPositionIsInStation(loaderTiltBPosition, "HORI"))
  147. {
  148. LOG.WriteLog(eEvent.ERR_PUF, Module, $"Loader TiltB {loaderTiltBPosition} is not in HORI");
  149. return false;
  150. }
  151. }
  152. //Loader Handle Wafer状态确认
  153. // Lip Seal Vacuum "ON"
  154. if (!_loaderSide.SideData.CRSVacuum)
  155. {
  156. LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 LS Vacuum is off");
  157. return false;
  158. }
  159. //Bernoulli Bladder "ON",Retracted Green Light
  160. if (!_loaderSide.SideData.BernoulliBladder)
  161. {
  162. LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 Bernoulli Bladder is off");
  163. return false;
  164. }
  165. if (_loaderSide.SideData.BernoulliExtended)
  166. {
  167. LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 Bernoulli Retracted is off");
  168. return false;
  169. }
  170. //其他SideA/B均为OFF
  171. if (_loaderSide.SideData.BernoulliN2)
  172. {
  173. LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 Bernoulli N2 is on");
  174. return false;
  175. }
  176. if (!_loaderSide.SideData.DoorUnlock)
  177. {
  178. LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 Door is Locked");
  179. return false;
  180. }
  181. if (_loaderSide.SideData.WHBladder)
  182. {
  183. LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 WS Bladder is on");
  184. return false;
  185. }
  186. if (_loaderSide.SideData.TransBladder)
  187. {
  188. LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 Translate Bladder is on");
  189. return false;
  190. }
  191. if (_loaderSide.SideData.TransHigh)
  192. {
  193. LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 Translate High Pre is on");
  194. return false;
  195. }
  196. }
  197. //Loader Transporter在Loader右侧
  198. bool loaderTransporterInstalled = ModuleHelper.IsInstalled(ModuleName.Transporter2);
  199. if (loaderTransporterInstalled && !_gantryAxis.JudgeCompareTargetStation("Loader", "Right"))
  200. {
  201. LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader Transporter is not in Loader right position");
  202. return false;
  203. }
  204. double verticalPosition = _verticalAxis.MotionData.MotorPosition;
  205. if (!_verticalAxis.CheckPositionIsInStation(verticalPosition,"Park"))
  206. {
  207. LOG.WriteLog(eEvent.ERR_PUF,Module, $"vertical axis {verticalPosition} is not at Park Station");
  208. return false;
  209. }
  210. double rotationPosition = _rotationAxis.MotionData.MotorPosition;
  211. if(_rotationAxis.CheckPositionIsEmpty(rotationPosition))
  212. {
  213. LOG.WriteLog(eEvent.ERR_PUF,Module, $"rotation axis {rotationPosition} is not at Station");
  214. return false;
  215. }
  216. double flipPosition = _flipAxis.MotionData.MotorPosition;
  217. if(_flipAxis.CheckPositionIsEmpty(flipPosition))
  218. {
  219. LOG.WriteLog( eEvent.ERR_PUF,Module, $"flip axis {flipPosition} is not at Station");
  220. return false;
  221. }
  222. return true;
  223. }
  224. /// <summary>
  225. /// 检验反面Wafer Present
  226. /// </summary>
  227. /// <returns></returns>
  228. private bool CheckReverseWafer()
  229. {
  230. if(_side == SideA)
  231. {
  232. return _vacuum.ChuckBWaferPresent;
  233. }
  234. else if(_side == SideB)
  235. {
  236. return _vacuum.ChuckAWaferPresent;
  237. }
  238. else
  239. {
  240. return false;
  241. }
  242. }
  243. /// <summary>
  244. /// 获取LoaderSide
  245. /// </summary>
  246. private void GetLoaderSide()
  247. {
  248. if( Module == ModuleName.PUF1.ToString())
  249. {
  250. _loaderSide= DEVICE.GetDevice<LoaderSideDevice>($"{ModuleName.Loader1}.SideA");
  251. }
  252. else
  253. {
  254. _loaderSide = DEVICE.GetDevice<LoaderSideDevice>($"{ModuleName.Loader1}.SideB");
  255. }
  256. }
  257. }
  258. }