LoaderUnloadSideRoutine.cs 13 KB

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