TransporterPickUpValidateRoutine.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. using Aitex.Core.RT.Device;
  2. using Aitex.Core.RT.Log;
  3. using Aitex.Core.RT.Routine;
  4. using Aitex.Core.RT.SCCore;
  5. using Aitex.Core.Util;
  6. using MECF.Framework.Common.Routine;
  7. using MECF.Framework.Common.Utilities;
  8. using MECF.Framework.Common.WaferHolder;
  9. using CyberX8_Core;
  10. using CyberX8_RT.Devices.AXIS;
  11. using CyberX8_RT.Devices.TransPorter;
  12. using CyberX8_RT.Modules.Loader;
  13. using System;
  14. using System.Collections.Generic;
  15. using System.Linq;
  16. using System.Text;
  17. using System.Threading.Tasks;
  18. using Aitex.Core.Common;
  19. using MECF.Framework.Common.Alarm;
  20. using MECF.Framework.Common.CommonData;
  21. using System.Threading;
  22. using MECF.Framework.Common.SubstrateTrackings;
  23. namespace CyberX8_RT.Modules.Transporter
  24. {
  25. public class TransporterPickUpValidateRoutine : RoutineBase, IRoutine
  26. {
  27. private enum PickUpStep
  28. {
  29. PickUp,
  30. PickUpWait,
  31. ReadBarcodeConfirm,
  32. Place,
  33. PlaceWait,
  34. End
  35. }
  36. #region 内部变量
  37. private string _cellName;
  38. private TransporterPickUpFromRoutine _pickupFromRoutine;
  39. private TransporterPickDownToRoutine _placeRoutine;
  40. private JetAxisBase _gantryAxis;
  41. private TransporterCommon _transporterCommon;
  42. private bool _validate = false;
  43. #endregion
  44. #region 属性
  45. public string SourceCell { get { return _cellName; } }
  46. #endregion
  47. /// <summary>
  48. /// 构造函数
  49. /// </summary>
  50. /// <param name="module"></param>
  51. public TransporterPickUpValidateRoutine(string module) : base(module)
  52. {
  53. _pickupFromRoutine=new TransporterPickUpFromRoutine(module);
  54. _placeRoutine=new TransporterPickDownToRoutine(module);
  55. }
  56. /// <summary>
  57. /// 中止
  58. /// </summary>
  59. public void Abort()
  60. {
  61. Runner.Stop("Manual Abort");
  62. }
  63. /// <summary>
  64. /// 监控
  65. /// </summary>
  66. /// <returns></returns>
  67. public RState Monitor()
  68. {
  69. //1.1 PickupFrom
  70. Runner .Run(PickUpStep.PickUp, () => { return _pickupFromRoutine.Start(_cellName) == RState.Running; }, _delay_1ms)
  71. .WaitWithStopCondition(PickUpStep.PickUpWait, () => CommonFunction.CheckRoutineEndState(_pickupFromRoutine),
  72. () => CheckRoutineStopStatus(_pickupFromRoutine, "PickUpValidate Routine", _pickupFromRoutine.ErrorMsg, 0))
  73. //2.1 Read Barcode 确认与Material Tracking的转移是否一致
  74. .Run(PickUpStep.ReadBarcodeConfirm, ReadBarcode, _delay_1ms)
  75. .RunIf(PickUpStep.Place, !_validate, ()=> { return _placeRoutine.Start(_cellName) == RState.Running; },_delay_1ms )
  76. .WaitWithStopConditionIf(PickUpStep.PlaceWait,!_validate, () => CommonFunction.CheckRoutineEndState(_placeRoutine),
  77. () => CheckRoutineStopStatus(_placeRoutine, "Place Routine", _placeRoutine.ErrorMsg, 1))
  78. .End(PickUpStep.End,NullFun,100);
  79. return Runner.Status;
  80. }
  81. /// <summary>
  82. /// 检验Routine异常结束状态
  83. /// </summary>
  84. /// <param name="routine"></param>
  85. /// <returns></returns>
  86. private bool CheckRoutineStopStatus(IRoutine routine, string routineName, string errorMsg, int step)
  87. {
  88. RState ret = routine.Monitor();
  89. if (ret == RState.Failed || ret == RState.Timeout)
  90. {
  91. NotifyError(eEvent.ERR_TRANSPORTER, $"PickUp Validate WaferHolder Routine\r\n{routineName}\\r\n{errorMsg}", step);
  92. return true;
  93. }
  94. return false;
  95. }
  96. /// <summary>
  97. /// 读取条码
  98. /// </summary>
  99. /// <returns></returns>
  100. private bool ReadBarcode()
  101. {
  102. //临时注销reader barcode 2025-03-15
  103. _validate = true;
  104. return true;
  105. TransporterEntity transporterEntity = Singleton<RouteManager>.Instance.GetModule<TransporterEntity>(Module.ToString());
  106. if (transporterEntity == null)
  107. {
  108. return true;
  109. }
  110. WaferHolderInfo waferHolderInfo = transporterEntity.WaferHolderInfo;
  111. if (waferHolderInfo == null)
  112. {
  113. return true;
  114. }
  115. bool isSimulator = SC.GetValue<bool>("System.IsSimulatorMode");
  116. string str = CycleReadBarcode(isSimulator);
  117. string error = "";
  118. if(!string.IsNullOrEmpty(str))
  119. {
  120. if (waferHolderInfo.Id == str)
  121. {
  122. _validate = true;
  123. }
  124. else
  125. {
  126. error = $"Wafer Shuttle Id {waferHolderInfo?.Id} is not matched with reader {str}";
  127. _validate = false;
  128. }
  129. }
  130. else
  131. {
  132. if (isSimulator)
  133. {
  134. _validate = true;
  135. return true;
  136. }
  137. error = $"reader data is empty";
  138. }
  139. if (!_validate)
  140. {
  141. if (CheckWaferHolderAllAssistWafers(waferHolderInfo))
  142. {
  143. WaferHolderManager.Instance.DisableWaferHolder(waferHolderInfo);
  144. LOG.WriteLog(eEvent.WARN_TRANSPORTER, Module, error);
  145. LOG.WriteLog(eEvent.WARN_TRANSPORTER, Module, $"disable WaferHolder {waferHolderInfo.Id}");
  146. AlarmList alarmList = new AlarmList(Module.ToString(), "", 0, error, 0, (int)AlarmType.Warning);
  147. AlarmListManager.Instance.AddAlarm(alarmList);
  148. }
  149. else
  150. {
  151. _validate = true;
  152. }
  153. }
  154. return true;
  155. }
  156. /// <summary>
  157. /// 检验WaferHolder所有的Wafer是辅助片
  158. /// </summary>
  159. /// <param name="waferHolderInfo"></param>
  160. /// <returns></returns>
  161. private bool CheckWaferHolderAllAssistWafers(WaferHolderInfo waferHolderInfo)
  162. {
  163. if (!string.IsNullOrEmpty(waferHolderInfo.WaferAId))
  164. {
  165. WaferInfo waferInfo = WaferManager.Instance.GetWaferByWaferId(waferHolderInfo.WaferAId);
  166. if (waferInfo!=null&&waferInfo.WaferType!=WaferType.Assit)
  167. {
  168. return false;
  169. }
  170. }
  171. if (!string.IsNullOrEmpty(waferHolderInfo.WaferBId))
  172. {
  173. WaferInfo waferInfo = WaferManager.Instance.GetWaferByWaferId(waferHolderInfo.WaferBId);
  174. if (waferInfo != null && waferInfo.WaferType != WaferType.Assit)
  175. {
  176. return false;
  177. }
  178. }
  179. return true;
  180. }
  181. /// <summary>
  182. /// 循环读取Barcode
  183. /// </summary>
  184. /// <param name="isSimulator"></param>
  185. /// <returns></returns>
  186. private string CycleReadBarcode(bool isSimulator)
  187. {
  188. int count = 0;
  189. string str = "";
  190. //读取Barcode3遍
  191. while (count < 3)
  192. {
  193. str = _transporterCommon.ReaderBarcode();
  194. str = str.Trim();
  195. if (!string.IsNullOrEmpty(str))
  196. {
  197. break;
  198. }
  199. if (isSimulator)
  200. {
  201. break;
  202. }
  203. Thread.Sleep(10);
  204. }
  205. return str;
  206. }
  207. /// <summary>
  208. /// 启动
  209. /// </summary>
  210. /// <param name="objs"></param>
  211. /// <returns></returns>
  212. public RState Start(params object[] objs)
  213. {
  214. _cellName = objs[0].ToString();
  215. _transporterCommon = DEVICE.GetDevice<TransporterCommon>($"{Module}.Common");
  216. _gantryAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Gantry");
  217. _validate = false;
  218. return Runner.Start(Module, $"PickUpValidate {_cellName}");
  219. }
  220. /// <summary>
  221. /// 重试
  222. /// </summary>
  223. /// <param name="step"></param>
  224. public RState Retry(int step)
  225. {
  226. if (string.IsNullOrEmpty(_cellName))
  227. {
  228. NotifyError(eEvent.ERR_TRANSPORTER, "source cell is empty", step);
  229. return RState.Failed;
  230. }
  231. List<Enum> preStepIds = new List<Enum>();
  232. if (step == 0 || step == -1)
  233. {
  234. return Runner.Retry(PickUpStep.PickUp, preStepIds, Module, "PickUp Validate Retry");
  235. }
  236. else
  237. {
  238. AddPreSteps(PickUpStep.Place, preStepIds);
  239. return Runner.Retry(PickUpStep.Place, preStepIds, Module, $"Pickup Validate step {PickUpStep.Place} Retry");
  240. }
  241. }
  242. /// <summary>
  243. /// 忽略前步骤
  244. /// </summary>
  245. /// <param name="step"></param>
  246. /// <param name="preStepIds"></param>
  247. private void AddPreSteps(PickUpStep step, List<Enum> preStepIds)
  248. {
  249. for (int i = 0; i < (int)step; i++)
  250. {
  251. preStepIds.Add((PickUpStep)i);
  252. }
  253. }
  254. /// <summary>
  255. /// 检验前面Unload完成状态
  256. /// </summary>
  257. /// <returns></returns>
  258. public bool CheckCompleteCondition(int index)
  259. {
  260. TransporterEntity transporterEntity = Singleton<RouteManager>.Instance.GetModule<TransporterEntity>(Module);
  261. if (transporterEntity.WaferHolderInfo == null)
  262. {
  263. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} does not have waferholder", index);
  264. return false;
  265. }
  266. double gantryPsition = _gantryAxis.MotionData.MotorPosition;
  267. if (!_gantryAxis.CheckPositionIsInStation(gantryPsition, _cellName))
  268. {
  269. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} gantry not in {_cellName}", index);
  270. return false;
  271. }
  272. return true;
  273. }
  274. }
  275. }