LoaderUnloadSideRoutine.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. using Aitex.Core.RT.Device;
  2. using Aitex.Core.RT.Routine;
  3. using MECF.Framework.Common.Equipment;
  4. using MECF.Framework.Common.Routine;
  5. using CyberX8_Core;
  6. using CyberX8_RT.Devices.AXIS;
  7. using CyberX8_RT.Devices.Loader;
  8. using System;
  9. using System.Collections.Generic;
  10. using Aitex.Core.RT.Log;
  11. using MECF.Framework.Common.Utilities;
  12. using MECF.Framework.Common.CommonData.Loader;
  13. using MECF.Framework.Common.CommonData;
  14. using Aitex.Core.RT.DataCenter;
  15. using Aitex.Core.RT.SCCore;
  16. namespace CyberX8_RT.Modules.Loader
  17. {
  18. public class LoaderUnloadSideRoutine : RoutineBase, IRoutine
  19. {
  20. private enum UnloadStep
  21. {
  22. RotationGoToLOADA,
  23. RotationGoToLOADAWait,
  24. SideUnload,
  25. UnloadAllWait,
  26. End
  27. }
  28. #region 常量
  29. private const string SIDE_A = "SideA";
  30. private const string SIDE_B = "SideB";
  31. private const int LOTTRACK_TIME = 1000;
  32. #endregion
  33. #region 内部变量
  34. private JetAxisBase _rotationAxis;
  35. private string _side;
  36. private LoaderUnloadRoutine _sideUnloadRoutine;
  37. private bool _isSideUnloaded = false;
  38. private bool _isSideStop = false;
  39. /// <summary>
  40. /// lotTrack time
  41. /// </summary>
  42. private DateTime _lotTackTime = DateTime.Now;
  43. /// <summary>
  44. /// Loader Common
  45. /// </summary>
  46. private LoaderCommonDevice _loaderCommon;
  47. /// <summary>
  48. /// LoaderSide
  49. /// </summary>
  50. private LoaderSideDevice _loaderSide;
  51. /// <summary>
  52. /// Loader LotTrackData
  53. /// </summary>
  54. private List<LoaderLotTrackData> _datas = new List<LoaderLotTrackData>();
  55. /// <summary>
  56. /// WaferSize
  57. /// </summary>
  58. private int _waferSize;
  59. #endregion
  60. #region 属性
  61. /// <summary>
  62. /// UnLoad LotTrackData
  63. /// </summary>
  64. public List<LoaderLotTrackData> UnloadLotTrackDatas { get { return _datas; } }
  65. #endregion
  66. /// <summary>
  67. /// 构造函数
  68. /// </summary>
  69. /// <param name="module"></param>
  70. public LoaderUnloadSideRoutine(string module) : base(module)
  71. {
  72. }
  73. /// <summary>
  74. /// 中止
  75. /// </summary>
  76. public void Abort()
  77. {
  78. }
  79. /// <summary>
  80. /// 监控
  81. /// </summary>
  82. /// <returns></returns>
  83. public RState Monitor()
  84. {
  85. LottrackRecord();
  86. Runner.Run(UnloadStep.RotationGoToLOADA,RotationGotoLOADA,_delay_1ms)
  87. .WaitWithStopCondition(UnloadStep.RotationGoToLOADAWait,CheckRotationPositionStatus,CheckRotationPositionRunStop)
  88. .Run(UnloadStep.SideUnload, () => StartUnloadRoutine(_sideUnloadRoutine,_isSideUnloaded), _delay_1ms)
  89. .WaitWithStopCondition(UnloadStep.UnloadAllWait, CheckUnloadAllRoutineEndStatus,CheckUnloadAllRoutineStopStatus)
  90. .End(UnloadStep.End, NullFun, _delay_1ms);
  91. return Runner.Status;
  92. }
  93. /// <summary>
  94. /// Rotation Goto LOADA
  95. /// </summary>
  96. /// <returns></returns>
  97. private bool RotationGotoLOADA()
  98. {
  99. bool result = _rotationAxis.PositionStation($"LOADA{_waferSize}", false);
  100. if (!result)
  101. {
  102. NotifyError(eEvent.ERR_LOADER, "rotation start goto LOADA failed", 0);
  103. }
  104. return result;
  105. }
  106. /// <summary>
  107. /// 检验Rotation移动状态
  108. /// </summary>
  109. /// <returns></returns>
  110. private bool CheckRotationPositionStatus()
  111. {
  112. return _rotationAxis.Status == RState.End;
  113. }
  114. /// <summary>
  115. /// 检验Rotation是否还在运动
  116. /// </summary>
  117. /// <returns></returns>
  118. private bool CheckRotationPositionRunStop()
  119. {
  120. bool result = _rotationAxis.Status == RState.Failed || _rotationAxis.Status == RState.Timeout ;
  121. if (result)
  122. {
  123. NotifyError(eEvent.ERR_LOADER, "rotation goto position failed",0);
  124. }
  125. return result;
  126. }
  127. /// <summary>
  128. /// 启动Unload routine
  129. /// </summary>
  130. /// <param name="unloadRoutine"></param>
  131. /// <returns></returns>
  132. private bool StartUnloadRoutine(LoaderUnloadRoutine unloadRoutine,bool isSideUnloaded)
  133. {
  134. if (isSideUnloaded)
  135. {
  136. return true;
  137. }
  138. bool result= unloadRoutine.Start()==RState.Running;
  139. if(!result)
  140. {
  141. NotifyError(eEvent.ERR_LOADER, unloadRoutine.ErrorMsg, 0);
  142. }
  143. return result;
  144. }
  145. /// <summary>
  146. /// 检验UnloadAll完成状态
  147. /// </summary>
  148. /// <returns></returns>
  149. private bool CheckUnloadAllRoutineEndStatus()
  150. {
  151. bool sideResult = true;
  152. if (!_isSideUnloaded)
  153. {
  154. sideResult = CheckUnloadRoutineEndStatus(_sideUnloadRoutine);
  155. }
  156. return sideResult;
  157. }
  158. /// <summary>
  159. /// 检查UnloadAll停止状态
  160. /// </summary>
  161. /// <returns></returns>
  162. private bool CheckUnloadAllRoutineStopStatus()
  163. {
  164. bool sideComplete = false;
  165. if (!_isSideUnloaded&&!_isSideStop)
  166. {
  167. RState ret = _sideUnloadRoutine.Monitor();
  168. _isSideStop = ret == RState.Failed || ret == RState.Timeout;
  169. sideComplete = (ret != RState.Running);
  170. if (_isSideStop)
  171. {
  172. NotifyError(eEvent.ERR_LOADER, $"unload A failed\r\n{_sideUnloadRoutine.ErrorMsg}", 1);
  173. }
  174. }
  175. return _isSideStop;
  176. }
  177. /// <summary>
  178. /// 检验routine完成状态
  179. /// </summary>
  180. /// <param name="unloadRoutine"></param>
  181. /// <returns></returns>
  182. private bool CheckUnloadRoutineEndStatus(LoaderUnloadRoutine unloadRoutine)
  183. {
  184. return unloadRoutine.Monitor() == RState.End;
  185. }
  186. /// <summary>
  187. /// 检验Routine结束状态
  188. /// </summary>
  189. /// <param name="unloadRoutine"></param>
  190. /// <returns></returns>
  191. private bool CheckUnloadRoutineStopStatus(LoaderUnloadRoutine unloadRoutine,string side)
  192. {
  193. RState state=unloadRoutine.Monitor();
  194. if (state == RState.Failed || state == RState.Timeout)
  195. {
  196. NotifyError(eEvent.ERR_LOADER, $"{side} Unload failed", 0);
  197. return true;
  198. }
  199. return false;
  200. }
  201. /// <summary>
  202. /// 启动
  203. /// </summary>
  204. /// <param name="objs"></param>
  205. /// <returns></returns>
  206. public RState Start(params object[] objs)
  207. {
  208. _side = objs[0].ToString();
  209. _waferSize = SC.GetValue<int>($"Loader1.{_side}WaferSize");
  210. InitializeParameters();
  211. _loaderCommon = DEVICE.GetDevice<LoaderCommonDevice>($"{Module}.Common");
  212. _loaderSide = DEVICE.GetDevice<LoaderSideDevice>($"{Module}.{_side}");
  213. return Runner.Start(Module, "Start UnloadAll");
  214. }
  215. /// <summary>
  216. /// 初始化参数
  217. /// </summary>
  218. private void InitializeParameters()
  219. {
  220. _rotationAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Rotation");
  221. _sideUnloadRoutine = new LoaderUnloadRoutine(ModuleName.Loader1.ToString(), _side);
  222. _isSideUnloaded = false;
  223. _isSideStop = false;
  224. }
  225. /// <summary>
  226. /// 重试
  227. /// </summary>
  228. /// <param name="step"></param>
  229. public RState Retry(int step)
  230. {
  231. InitializeParameters();
  232. List<Enum> preStepIds = new List<Enum>();
  233. return Runner.Retry(UnloadStep.RotationGoToLOADA,preStepIds,Module,"UnloadAll Retry");
  234. }
  235. /// <summary>
  236. /// 检验前面Unload完成状态
  237. /// </summary>
  238. /// <returns></returns>
  239. public bool CheckCompleteCondition(int index)
  240. {
  241. string side = _side == SIDE_A ? "A" : "B";
  242. if (!CheckSideUnloadCondition(side, index,true))
  243. {
  244. return false;
  245. }
  246. return true;
  247. }
  248. /// <summary>
  249. /// 检验Side Unload情况
  250. /// </summary>
  251. /// <param name="side"></param>
  252. /// <param name="index"></param>
  253. /// <returns></returns>
  254. private bool CheckSideUnloadCondition(string side, int index,bool showError)
  255. {
  256. JetAxisBase shuttleAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.Shuttle{side}");
  257. double shuttlePosition = shuttleAxis.MotionData.MotorPosition;
  258. if (!shuttleAxis.CheckPositionInStationIgnoreWaferSize(shuttlePosition, "OUT"))
  259. {
  260. if (showError)
  261. {
  262. NotifyError(eEvent.ERR_LOADER, $"shuttle{side} {shuttlePosition} is not in Out", index);
  263. }
  264. return false;
  265. }
  266. JetAxisBase tiltAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.Tilt{side}");
  267. double tiltPosition = tiltAxis.MotionData.MotorPosition;
  268. if (!tiltAxis.CheckPositionInStationIgnoreWaferSize(tiltPosition, "HORI"))
  269. {
  270. if (showError)
  271. {
  272. NotifyError(eEvent.ERR_LOADER, $"tilt{side} {tiltPosition} is not in HORI", index);
  273. return false;
  274. }
  275. }
  276. JetAxisBase crsAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.LS{side}");
  277. double crsPosition = crsAxis.MotionData.MotorPosition;
  278. if (!crsAxis.CheckPositionInStationIgnoreWaferSize(crsPosition, "Unlock"))
  279. {
  280. if (showError)
  281. {
  282. NotifyError(eEvent.ERR_LOADER, $"LS{side} {crsPosition} is not in Unlock", index);
  283. }
  284. return false;
  285. }
  286. return true;
  287. }
  288. /// <summary>
  289. /// 记录Lottrack
  290. /// </summary>
  291. private void LottrackRecord()
  292. {
  293. //记录Lottrack
  294. if (DateTime.Now.Subtract(_lotTackTime).TotalMilliseconds >= LOTTRACK_TIME)
  295. {
  296. AddLotTrackData();
  297. _lotTackTime = DateTime.Now;
  298. }
  299. }
  300. /// <summary>
  301. /// 获取Lot Track数据
  302. /// </summary>
  303. /// <returns></returns>
  304. private void AddLotTrackData()
  305. {
  306. LoaderLotTrackData data = new LoaderLotTrackData();
  307. data.TimeStamp = DateTime.Now;
  308. data.LoaderABernoulliBladderEnable = _loaderSide.SideData.BernoulliBladder;
  309. data.LoaderABernoulliExtended = _loaderSide.SideData.BernoulliExtended;
  310. data.LoaderABernoulliBladderPressure = _loaderSide.SideData.BernoulliBladderPressure;
  311. data.LoaderABernoulliN2Pressure = _loaderSide.SideData.BernoulliPressure;
  312. data.LoaderACRSVacuum = _loaderSide.SideData.CRSVacuum;
  313. data.LoaderACRSVacuumAnlg = _loaderSide.SideData.CRSVacuumValue;
  314. data.LoaderAWHPressure = _loaderSide.SideData.WHBladderPressure;
  315. data.LoaderATranslatePressure = _loaderSide.SideData.TransPressure;
  316. data.LoaderWHClamped = _loaderCommon.CommonData.WaferHolderClamp;
  317. _datas.Add(data);
  318. }
  319. }
  320. }