LoaderUnloadAllSideRoutine.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  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. namespace CyberX8_RT.Modules.Loader
  16. {
  17. public class LoaderUnloadAllSideRoutine : RoutineBase, IRoutine
  18. {
  19. private enum UnloadStep
  20. {
  21. RotationGoToLOADA,
  22. RotationGoToLOADAWait,
  23. SideAUnload,
  24. Delay,
  25. SideBUnload,
  26. UnloadAllWait,
  27. End
  28. }
  29. #region 常量
  30. private const string SIDE_A = "SideA";
  31. private const string SIDE_B = "SideB";
  32. private const int LOTTRACK_TIME = 1000;
  33. #endregion
  34. #region 内部变量
  35. private JetAxisBase _rotationAxis;
  36. private LoaderUnloadRoutine _sideAUnloadRoutine;
  37. private LoaderUnloadRoutine _sideBUnloadRoutine;
  38. private bool _isSideAUnloaded = false;
  39. private bool _isSideBunloaded = false;
  40. private bool _isSideAStop = false;
  41. private bool _isSideBStop = false;
  42. /// <summary>
  43. /// lotTrack time
  44. /// </summary>
  45. private DateTime _lotTackTime = DateTime.Now;
  46. /// <summary>
  47. /// Loader Common
  48. /// </summary>
  49. private LoaderCommonDevice _loaderCommon;
  50. /// <summary>
  51. /// LoaderSide A
  52. /// </summary>
  53. private LoaderSideDevice _loaderSideA;
  54. /// <summary>
  55. /// LoaderSide B
  56. /// </summary>
  57. private LoaderSideDevice _loaderSideB;
  58. /// <summary>
  59. /// Loader LotTrackData
  60. /// </summary>
  61. private List<LoaderLotTrackData> _datas = new List<LoaderLotTrackData>();
  62. #endregion
  63. #region 属性
  64. /// <summary>
  65. /// UnLoad LotTrackData
  66. /// </summary>
  67. public List<LoaderLotTrackData> UnloadLotTrackDatas { get { return _datas; } }
  68. #endregion
  69. /// <summary>
  70. /// 构造函数
  71. /// </summary>
  72. /// <param name="module"></param>
  73. public LoaderUnloadAllSideRoutine(string module) : base(module)
  74. {
  75. }
  76. /// <summary>
  77. /// 中止
  78. /// </summary>
  79. public void Abort()
  80. {
  81. }
  82. /// <summary>
  83. /// 监控
  84. /// </summary>
  85. /// <returns></returns>
  86. public RState Monitor()
  87. {
  88. LottrackRecord();
  89. Runner.Run(UnloadStep.RotationGoToLOADA,RotationGotoLOADA,_delay_1ms)
  90. .WaitWithStopCondition(UnloadStep.RotationGoToLOADAWait,CheckRotationPositionStatus,CheckRotationPositionRunStop)
  91. .Run(UnloadStep.SideAUnload, () => StartUnloadRoutine(_sideAUnloadRoutine,_isSideAUnloaded), _delay_1ms)
  92. .Delay(UnloadStep.Delay,500)
  93. .Run(UnloadStep.SideBUnload, () => StartUnloadRoutine(_sideBUnloadRoutine,_isSideBunloaded), _delay_1ms)
  94. .WaitWithStopCondition(UnloadStep.UnloadAllWait, CheckUnloadAllRoutineEndStatus,CheckUnloadAllRoutineStopStatus)
  95. .End(UnloadStep.End, NullFun, _delay_1ms);
  96. return Runner.Status;
  97. }
  98. /// <summary>
  99. /// Rotation Goto LOADA
  100. /// </summary>
  101. /// <returns></returns>
  102. private bool RotationGotoLOADA()
  103. {
  104. bool result = _rotationAxis.PositionStation("LOADA", false);
  105. if (!result)
  106. {
  107. NotifyError(eEvent.ERR_LOADER, "rotation start goto LOADA failed", 0);
  108. }
  109. return result;
  110. }
  111. /// <summary>
  112. /// 检验Rotation移动状态
  113. /// </summary>
  114. /// <returns></returns>
  115. private bool CheckRotationPositionStatus()
  116. {
  117. return _rotationAxis.Status == RState.End;
  118. }
  119. /// <summary>
  120. /// 检验Rotation是否还在运动
  121. /// </summary>
  122. /// <returns></returns>
  123. private bool CheckRotationPositionRunStop()
  124. {
  125. bool result = _rotationAxis.Status == RState.Failed || _rotationAxis.Status == RState.Timeout ;
  126. if (result)
  127. {
  128. NotifyError(eEvent.ERR_LOADER, "rotation goto position failed",0);
  129. }
  130. return result;
  131. }
  132. /// <summary>
  133. /// 启动Unload routine
  134. /// </summary>
  135. /// <param name="unloadRoutine"></param>
  136. /// <returns></returns>
  137. private bool StartUnloadRoutine(LoaderUnloadRoutine unloadRoutine,bool isSideUnloaded)
  138. {
  139. if (isSideUnloaded)
  140. {
  141. return true;
  142. }
  143. bool result= unloadRoutine.Start()==RState.Running;
  144. if(!result)
  145. {
  146. NotifyError(eEvent.ERR_LOADER, unloadRoutine.ErrorMsg, 0);
  147. }
  148. return result;
  149. }
  150. /// <summary>
  151. /// 检验UnloadAll完成状态
  152. /// </summary>
  153. /// <returns></returns>
  154. private bool CheckUnloadAllRoutineEndStatus()
  155. {
  156. bool sideAResult = true;
  157. if (!_isSideAUnloaded)
  158. {
  159. sideAResult = CheckUnloadRoutineEndStatus(_sideAUnloadRoutine);
  160. }
  161. bool sideBResult = true;
  162. if (!_isSideBunloaded)
  163. {
  164. sideBResult = CheckUnloadRoutineEndStatus(_sideBUnloadRoutine);
  165. }
  166. return sideAResult && sideBResult;
  167. }
  168. /// <summary>
  169. /// 检查UnloadAll停止状态
  170. /// </summary>
  171. /// <returns></returns>
  172. private bool CheckUnloadAllRoutineStopStatus()
  173. {
  174. bool sideAComplete = false;
  175. if (!_isSideAUnloaded&&!_isSideAStop)
  176. {
  177. RState ret = _sideAUnloadRoutine.Monitor();
  178. _isSideAStop = ret == RState.Failed || ret == RState.Timeout;
  179. sideAComplete = (ret != RState.Running);
  180. if (_isSideAStop)
  181. {
  182. NotifyError(eEvent.ERR_LOADER, $"unload A failed\r\n{_sideAUnloadRoutine.ErrorMsg}", 1);
  183. }
  184. }
  185. bool sideBComplete = false;
  186. if(!_isSideBunloaded&&!_isSideBStop)
  187. {
  188. RState ret = _sideBUnloadRoutine.Monitor();
  189. _isSideBStop = ret == RState.Failed || ret == RState.Timeout;
  190. sideBComplete = (ret != RState.Running);
  191. if (_isSideBunloaded)
  192. {
  193. NotifyError(eEvent.ERR_LOADER, $"unload B failed\r\n{_sideBUnloadRoutine.ErrorMsg}", 1);
  194. }
  195. }
  196. return (_isSideAStop && sideBComplete) || (_isSideBStop && sideAComplete);
  197. }
  198. /// <summary>
  199. /// 检验routine完成状态
  200. /// </summary>
  201. /// <param name="unloadRoutine"></param>
  202. /// <returns></returns>
  203. private bool CheckUnloadRoutineEndStatus(LoaderUnloadRoutine unloadRoutine)
  204. {
  205. return unloadRoutine.Monitor() == RState.End;
  206. }
  207. /// <summary>
  208. /// 检验Routine结束状态
  209. /// </summary>
  210. /// <param name="unloadRoutine"></param>
  211. /// <returns></returns>
  212. private bool CheckUnloadRoutineStopStatus(LoaderUnloadRoutine unloadRoutine,string side)
  213. {
  214. RState state=unloadRoutine.Monitor();
  215. if (state == RState.Failed || state == RState.Timeout)
  216. {
  217. NotifyError(eEvent.ERR_LOADER, $"{side} Unload failed", 0);
  218. return true;
  219. }
  220. return false;
  221. }
  222. /// <summary>
  223. /// 启动
  224. /// </summary>
  225. /// <param name="objs"></param>
  226. /// <returns></returns>
  227. public RState Start(params object[] objs)
  228. {
  229. InitializeParameters();
  230. _loaderCommon = DEVICE.GetDevice<LoaderCommonDevice>($"{Module}.Common");
  231. _loaderSideA = DEVICE.GetDevice<LoaderSideDevice>($"{Module}.SideA");
  232. _loaderSideB = DEVICE.GetDevice<LoaderSideDevice>($"{Module}.SideB");
  233. return Runner.Start(Module, "Start UnloadAll");
  234. }
  235. /// <summary>
  236. /// 初始化参数
  237. /// </summary>
  238. private void InitializeParameters()
  239. {
  240. _rotationAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Rotation");
  241. _sideAUnloadRoutine = new LoaderUnloadRoutine(ModuleName.Loader1.ToString(), "SideA");
  242. _sideBUnloadRoutine = new LoaderUnloadRoutine(ModuleName.Loader1.ToString(), "SideB");
  243. _isSideAUnloaded = false;
  244. _isSideBunloaded = false;
  245. _isSideAStop = false;
  246. _isSideBStop = false;
  247. }
  248. /// <summary>
  249. /// 重试
  250. /// </summary>
  251. /// <param name="step"></param>
  252. public RState Retry(int step)
  253. {
  254. InitializeParameters();
  255. List<Enum> preStepIds = new List<Enum>();
  256. if (step == 0||step==-1)
  257. {
  258. return Runner.Retry(UnloadStep.RotationGoToLOADA,preStepIds,Module,"UnloadAll Retry");
  259. }
  260. else
  261. {
  262. _isSideAUnloaded = CheckSideUnloadCondition("A", step,false);
  263. _isSideBunloaded= CheckSideUnloadCondition("B", step,false);
  264. AddPreSteps(UnloadStep.SideAUnload, preStepIds);
  265. return Runner.Retry(UnloadStep.SideBUnload,preStepIds, Module, $"UnloadAll step {UnloadStep.SideBUnload} Retry");
  266. }
  267. }
  268. /// <summary>
  269. /// 忽略前
  270. /// </summary>
  271. /// <param name="step"></param>
  272. /// <param name="preStepIds"></param>
  273. private void AddPreSteps(UnloadStep step,List<Enum> preStepIds)
  274. {
  275. for(int i = 0;i<(int)step;i++)
  276. {
  277. preStepIds.Add((UnloadStep)i);
  278. }
  279. }
  280. /// <summary>
  281. /// 检验前面Unload完成状态
  282. /// </summary>
  283. /// <returns></returns>
  284. public bool CheckCompleteCondition(int index)
  285. {
  286. if (!CheckSideUnloadCondition("A", index,true))
  287. {
  288. return false;
  289. }
  290. if (!CheckSideUnloadCondition("B", index, true))
  291. {
  292. return false;
  293. }
  294. return true;
  295. }
  296. /// <summary>
  297. /// 检验Side Unload情况
  298. /// </summary>
  299. /// <param name="side"></param>
  300. /// <param name="index"></param>
  301. /// <returns></returns>
  302. private bool CheckSideUnloadCondition(string side, int index,bool showError)
  303. {
  304. JetAxisBase shuttleAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.Shuttle{side}");
  305. double shuttlePosition = shuttleAxis.MotionData.MotorPosition;
  306. if (!shuttleAxis.CheckPositionIsInStation(shuttlePosition, "OPEN"))
  307. {
  308. if (showError)
  309. {
  310. NotifyError(eEvent.ERR_LOADER, $"shuttle{side} {shuttlePosition} is not in open", index);
  311. }
  312. return false;
  313. }
  314. JetAxisBase tiltAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.Tilt{side}");
  315. double tiltPosition = tiltAxis.MotionData.MotorPosition;
  316. if (!tiltAxis.CheckPositionIsInStation(tiltPosition, "HORI"))
  317. {
  318. if (showError)
  319. {
  320. NotifyError(eEvent.ERR_LOADER, $"tilt{side} {tiltPosition} is not in HORI", index);
  321. return false;
  322. }
  323. }
  324. JetAxisBase crsAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.LS{side}");
  325. double crsPosition = crsAxis.MotionData.MotorPosition;
  326. if (!crsAxis.CheckPositionIsInStation(crsPosition, "Unlock"))
  327. {
  328. if (showError)
  329. {
  330. NotifyError(eEvent.ERR_LOADER, $"LS{side} {crsPosition} is not in Unlock", index);
  331. }
  332. return false;
  333. }
  334. LoaderSideDevice loaderSideDevice = DEVICE.GetDevice<LoaderSideDevice>($"{ModuleName.Loader1}.Side{side}");
  335. if (loaderSideDevice.SideData.DoorLowerLocked || loaderSideDevice.SideData.DoorUpperLocked)
  336. {
  337. if (showError)
  338. {
  339. NotifyError(eEvent.ERR_LOADER, $"side{side} door locked", index);
  340. }
  341. }
  342. return true;
  343. }
  344. /// <summary>
  345. /// 记录Lottrack
  346. /// </summary>
  347. private void LottrackRecord()
  348. {
  349. //记录Lottrack
  350. if (DateTime.Now.Subtract(_lotTackTime).TotalMilliseconds >= LOTTRACK_TIME)
  351. {
  352. AddLotTrackData();
  353. _lotTackTime = DateTime.Now;
  354. }
  355. }
  356. /// <summary>
  357. /// 获取Lot Track数据
  358. /// </summary>
  359. /// <returns></returns>
  360. private void AddLotTrackData()
  361. {
  362. LoaderLotTrackData data = new LoaderLotTrackData();
  363. data.TimeStamp = DateTime.Now;
  364. data.LoaderABernoulliBladderEnable = _loaderSideA.SideData.BernoulliBladder;
  365. data.LoaderABernoulliExtended = _loaderSideA.SideData.BernoulliExtended;
  366. data.LoaderABernoulliBladderPressure = _loaderSideA.SideData.BernoulliBladderPressure;
  367. data.LoaderABernoulliN2Pressure = _loaderSideA.SideData.BernoulliPressure;
  368. data.LoaderACRSVacuum = _loaderSideA.SideData.CRSVacuum;
  369. data.LoaderACRSVacuumAnlg = _loaderSideA.SideData.CRSVacuumValue;
  370. data.LoaderAWHPressure = _loaderSideA.SideData.WHBladderPressure;
  371. data.LoaderATranslatePressure = _loaderSideA.SideData.TransPressure;
  372. data.LoaderBBernoulliBladderEnable = _loaderSideB.SideData.BernoulliBladder;
  373. data.LoaderBBernoulliExtended = _loaderSideB.SideData.BernoulliExtended;
  374. data.LoaderBBernoulliBladderPressure = _loaderSideB.SideData.BernoulliBladderPressure;
  375. data.LoaderBBernoulliN2Pressure = _loaderSideB.SideData.BernoulliPressure;
  376. data.LoaderBCRSVacuum = _loaderSideB.SideData.CRSVacuum;
  377. data.LoaderBCRSVacuumAnlg = _loaderSideB.SideData.CRSVacuumValue;
  378. data.LoaderBWHPressure = _loaderSideB.SideData.WHBladderPressure;
  379. data.LoaderBTranslatePressure = _loaderSideB.SideData.TransPressure;
  380. data.LoaderWHClamped = _loaderCommon.CommonData.WaferHolderClamp;
  381. _datas.Add(data);
  382. }
  383. }
  384. }