PufPickFromLoaderRoutine.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  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. using Aitex.Core.RT.SCCore;
  20. namespace CyberX8_RT.Modules.PUF
  21. {
  22. public class PufPickFromLoaderRoutine : RoutineBase,IRoutine
  23. {
  24. #region 常量
  25. private const string SideA = "SideA";
  26. private const string SideB = "SideB";
  27. private const string CURRENT_STATION_LIST = "CurrentStationList";
  28. private const string WAFER_PRESENT = "WaferPresent";
  29. #endregion
  30. private enum PufPickStep
  31. {
  32. SideConditionRoutine,
  33. SideConditionRoutineWait,
  34. RotationLoaderPickup,
  35. RotationLoaderPickupWait,
  36. ChuckOut,
  37. CheckChuckOut,
  38. VacuumOn,
  39. ChuckIn,
  40. CheckChuckIn,
  41. StickDistanceCheck,
  42. RotationHomeStation,
  43. RotationHomeStationWait,
  44. End
  45. }
  46. #region 内部变量
  47. private string _side;
  48. private JetAxisBase _flipAxis;
  49. private JetAxisBase _rotationAxis;
  50. private JetAxisBase _gantryAxis;
  51. private LoaderSideDevice _loaderSide;
  52. private PufVacuum _vacuum;
  53. private PufWaferPickSubRoutine _pufWaferPickSubRoutine;
  54. private PufChuckRoutine _chuckRoutine;
  55. private PufDistanceSensor _distanceSensor;
  56. private bool _enableCheckStickDistanceStatus = false;
  57. #endregion
  58. /// <summary>
  59. /// 构造函数
  60. /// </summary>
  61. /// <param name="module"></param>
  62. /// <param name="pufEntity"></param>
  63. public PufPickFromLoaderRoutine(string module) : base(module)
  64. {
  65. }
  66. /// <summary>
  67. /// 中止
  68. /// </summary>
  69. public void Abort()
  70. {
  71. Runner.Stop("Manual Abort");
  72. }
  73. public RState Monitor()
  74. {
  75. Runner.RunConditionSubRoutine(PufPickStep.SideConditionRoutine, SideConditionIndex, new IRoutine[] { _pufWaferPickSubRoutine }, new object[] { _side })
  76. .WaitConditionSubRoutine(PufPickStep.SideConditionRoutineWait)
  77. .Run(PufPickStep.RotationLoaderPickup, () => { return _rotationAxis.PositionStation("LoaderPickup"); }, NullFun, 100)
  78. .WaitWithStopCondition(PufPickStep.RotationLoaderPickupWait, () => { return _rotationAxis.Status == RState.End; }, () => { return _rotationAxis.Status == RState.Failed; })
  79. .Run(PufPickStep.ChuckOut, () => { return _chuckRoutine.Start(true) == RState.Running; }, NullFun, 100)
  80. .WaitWithStopCondition(PufPickStep.CheckChuckOut, () => CommonFunction.CheckRoutineEndState(_chuckRoutine), () => CommonFunction.CheckRoutineStopState(_chuckRoutine))
  81. .Run(PufPickStep.VacuumOn, VacuumOn, CheckWaferPresent, 5000)
  82. .Run(PufPickStep.ChuckIn, () => { return _chuckRoutine.Start(false) == RState.Running; }, NullFun, 100)
  83. .WaitWithStopCondition(PufPickStep.CheckChuckIn, () => CommonFunction.CheckRoutineEndState(_chuckRoutine), () => CommonFunction.CheckRoutineStopState(_chuckRoutine))
  84. .Wait(PufPickStep.StickDistanceCheck, CheckStickDistanceStatus, 1000)
  85. .Run(PufPickStep.RotationHomeStation, () => { return _rotationAxis.PositionStation("Home"); }, NullFun, 100)
  86. .WaitWithStopCondition(PufPickStep.RotationHomeStationWait, () => { return _rotationAxis.Status == RState.End; }, () => { return _rotationAxis.Status == RState.Failed; })
  87. .End(PufPickStep.End, NullFun);
  88. return Runner.Status;
  89. }
  90. /// <summary>
  91. /// Side条件获取SubRoutine索引
  92. /// </summary>
  93. /// <returns></returns>
  94. private int SideConditionIndex()
  95. {
  96. if (_flipAxis.CheckPositionIsInStation(_flipAxis.MotionData.MotorPosition, _side))
  97. {
  98. return 1;
  99. }
  100. else
  101. {
  102. return 0;
  103. }
  104. }
  105. /// <summary>
  106. /// 检验VacuumLevel
  107. /// </summary>
  108. /// <returns></returns>
  109. private bool CheckVacuumLevel()
  110. {
  111. if (_side == SideA)
  112. {
  113. return _vacuum.ChuckBVacuumStatus == WAFER_PRESENT;
  114. }
  115. else if (_side == SideB)
  116. {
  117. return _vacuum.ChuckAVacuumStatus == WAFER_PRESENT;
  118. }
  119. else
  120. {
  121. return false;
  122. }
  123. }
  124. /// <summary>
  125. /// 检验存在Wafer
  126. /// </summary>
  127. /// <returns></returns>
  128. private bool CheckWaferPresent()
  129. {
  130. if (_side == SideA)
  131. {
  132. return _vacuum.ChuckAVacuumStatus == WAFER_PRESENT;
  133. }
  134. else if (_side == SideB)
  135. {
  136. return _vacuum.ChuckBVacuumStatus == WAFER_PRESENT;
  137. }
  138. else
  139. {
  140. return false;
  141. }
  142. }
  143. /// <summary>
  144. /// 打开Vacuum
  145. /// </summary>
  146. /// <returns></returns>
  147. private bool VacuumOn()
  148. {
  149. if (_side == SideA)
  150. {
  151. _vacuum.VacuumAOn();
  152. return true;
  153. }
  154. else if (_side == SideB)
  155. {
  156. _vacuum.VacuumBOn();
  157. return true;
  158. }
  159. return false;
  160. }
  161. /// <summary>
  162. /// Stick Distance检验结果
  163. /// </summary>
  164. /// <returns></returns>
  165. private bool CheckStickDistanceStatus()
  166. {
  167. if (_enableCheckStickDistanceStatus)
  168. {
  169. return _distanceSensor.CheckStickDistanceStatus();
  170. }
  171. else
  172. {
  173. return true;
  174. }
  175. }
  176. /// <summary>
  177. /// 启动
  178. /// </summary>
  179. /// <param name="objs"></param>
  180. /// <returns></returns>
  181. public RState Start(params object[] objs)
  182. {
  183. _side = objs[0].ToString();
  184. _flipAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Flip");
  185. _rotationAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Rotation");
  186. _vacuum = DEVICE.GetDevice<PufVacuum>($"{Module}.Vacuum");
  187. _gantryAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Transporter2}.Gantry");
  188. _distanceSensor = DEVICE.GetDevice<PufDistanceSensor>($"{Module}.DistanceSensor");
  189. _pufWaferPickSubRoutine = new PufWaferPickSubRoutine(Module);
  190. _enableCheckStickDistanceStatus = SC.GetValue<bool>($"{Module}.EnableCheckStickDistanceStatus");
  191. _chuckRoutine = new PufChuckRoutine(Module);
  192. _loaderSide = DEVICE.GetDevice<LoaderSideDevice>($"{ModuleName.Loader1}.{_side}");
  193. if (CheckCondition())
  194. {
  195. return Runner.Start(Module, "PickFrom Loader");
  196. }
  197. else
  198. {
  199. return RState.Failed;
  200. }
  201. }
  202. /// <summary>
  203. /// 检验条件
  204. /// </summary>
  205. /// <returns></returns>
  206. private bool CheckCondition()
  207. {
  208. //Loader1.Rotation 在LOADA
  209. bool isLoaderInstall = ModuleHelper.IsInstalled(ModuleName.Loader1);
  210. if (isLoaderInstall)
  211. {
  212. JetAxisBase loaderRotationAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.Rotation");
  213. double loaderRotationPosition = loaderRotationAxis.MotionData.MotorPosition;
  214. string loadStation = _side == SideA ? "LOADA" : "LOADB";
  215. if (!loaderRotationAxis.CheckPositionInStationIgnoreWaferSize(loaderRotationPosition, loadStation))
  216. {
  217. LOG.WriteLog(eEvent.ERR_PUF, Module, $"Loader Rotation {loaderRotationPosition} is not in {loadStation}");
  218. return false;
  219. }
  220. string side = _side==SideA ? "A" : "B";
  221. //Loader1.SwingA 在Open
  222. JetAxisBase loaderShuttleAAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.Shuttle{side}");
  223. double loaderShuttleAPosition = loaderShuttleAAxis.MotionData.MotorPosition;
  224. if (!loaderShuttleAAxis.CheckPositionInStationIgnoreWaferSize(loaderShuttleAPosition, "OUT"))
  225. {
  226. LOG.WriteLog(eEvent.ERR_PUF, Module, $"Loader ShuttleA {loaderShuttleAPosition} is not in OUT");
  227. return false;
  228. }
  229. //Loader1.TiltA 在HORI
  230. JetAxisBase loaderTiltAAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.Tilt{side}");
  231. double loaderTiltAPosition = loaderTiltAAxis.MotionData.MotorPosition;
  232. if (!loaderTiltAAxis.CheckPositionIsInStation(loaderTiltAPosition, "HORI"))
  233. {
  234. LOG.WriteLog(eEvent.ERR_PUF, Module, $"Loader Tilt{side} {loaderTiltAPosition} is not in HORI");
  235. return false;
  236. }
  237. //Loader Handle Wafer状态确认
  238. // Lip Seal Vacuum "ON"
  239. if (!_loaderSide.SideData.CRSVacuum)
  240. {
  241. LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 LS Vacuum is off");
  242. return false;
  243. }
  244. //Bernoulli Bladder "ON",Retracted Green Light
  245. if (!_loaderSide.SideData.BernoulliBladder)
  246. {
  247. LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 Bernoulli Bladder is off");
  248. return false;
  249. }
  250. //其他SideA/B均为OFF
  251. if (_loaderSide.SideData.BernoulliN2)
  252. {
  253. LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 Bernoulli N2 is on");
  254. return false;
  255. }
  256. if (_loaderSide.SideData.WHBladder)
  257. {
  258. LOG.WriteLog(eEvent.ERR_PUF, Module, "Loader1 WS Bladder is on");
  259. return false;
  260. }
  261. }
  262. double rotationPosition = _rotationAxis.MotionData.MotorPosition;
  263. if(_rotationAxis.CheckPositionIsEmpty(rotationPosition))
  264. {
  265. LOG.WriteLog(eEvent.ERR_PUF,Module, $"rotation axis {rotationPosition} is not at Station");
  266. return false;
  267. }
  268. double flipPosition = _flipAxis.MotionData.MotorPosition;
  269. if(_flipAxis.CheckPositionIsEmpty(flipPosition))
  270. {
  271. LOG.WriteLog( eEvent.ERR_PUF,Module, $"flip axis {flipPosition} is not at Station");
  272. return false;
  273. }
  274. return true;
  275. }
  276. }
  277. }