LoaderUnloadSideRoutine.cs 12 KB

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