TransporterTransferRoutine.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  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.Beckhoff.Station;
  7. using MECF.Framework.Common.Equipment;
  8. using MECF.Framework.Common.Layout;
  9. using MECF.Framework.Common.Routine;
  10. using MECF.Framework.Common.SubstrateTrackings;
  11. using MECF.Framework.Common.Utilities;
  12. using MECF.Framework.Common.WaferHolder;
  13. using CyberX8_Core;
  14. using CyberX8_RT.Devices.AXIS;
  15. using CyberX8_RT.Devices.AXIS.CANOpen;
  16. using CyberX8_RT.Devices.Facilities;
  17. using CyberX8_RT.Devices.TransPorter;
  18. using CyberX8_RT.Modules.Loader;
  19. using System;
  20. using System.Collections.Generic;
  21. using System.Linq;
  22. using System.Text;
  23. using System.Threading.Tasks;
  24. using Aitex.Core.RT.Fsm;
  25. namespace CyberX8_RT.Modules.Transporter
  26. {
  27. public class TransporterTransferRoutine : RoutineBase, IRoutine
  28. {
  29. private enum TransferStep
  30. {
  31. CheckPreCondition,
  32. PickUpFrom,
  33. PickUpFromWait,
  34. MoveTo,
  35. MoveToWait,
  36. Place,
  37. PlaceWait,
  38. End
  39. }
  40. #region 内部变量
  41. private string _fromCellName;
  42. private string _toCellName;
  43. private JetAxisBase _gantryAxis;
  44. private JetAxisBase _elevatorAxis;
  45. private LoaderEntity _loaderEntity;
  46. private JetAxisBase _loaderRotationAxis;
  47. private SystemFacilities _facilities;
  48. private TransporterPickUpFromRoutine _pickUpRoutine;
  49. private TransporterMoveToRoutine _moveToRoutine;
  50. private TransporterPickDownToRoutine _placeRoutine;
  51. #endregion
  52. /// <summary>
  53. /// 构造函数
  54. /// </summary>
  55. /// <param name="module"></param>
  56. public TransporterTransferRoutine(string module) : base(module)
  57. {
  58. _pickUpRoutine=new TransporterPickUpFromRoutine(module);
  59. _moveToRoutine = new TransporterMoveToRoutine(module);
  60. _placeRoutine=new TransporterPickDownToRoutine(module);
  61. }
  62. /// <summary>
  63. /// 中止
  64. /// </summary>
  65. public void Abort()
  66. {
  67. Runner.Stop("Manual Abort");
  68. }
  69. /// <summary>
  70. /// 监控
  71. /// </summary>
  72. /// <returns></returns>
  73. public RState Monitor()
  74. {
  75. Runner.Run(TransferStep.CheckPreCondition,CheckStartPreConfition,_delay_1ms)
  76. //1.1 PickupFrom
  77. .Run(TransferStep.PickUpFrom, () => { return _pickUpRoutine.Start(_fromCellName) == RState.Running; }, _delay_1ms)
  78. .WaitWithStopCondition(TransferStep.PickUpFromWait, ()=>CommonFunction.CheckRoutineEndState(_pickUpRoutine),
  79. ()=> CheckRoutineStopStatus(_pickUpRoutine,"PickUp Routine", _pickUpRoutine.ErrorMsg,0))
  80. //1.2 Move to
  81. .Run(TransferStep.MoveTo, () => { return _moveToRoutine.Start(_toCellName) == RState.Running; }, _delay_1ms)
  82. .WaitWithStopCondition(TransferStep.MoveToWait, ()=>CommonFunction.CheckRoutineEndState(_moveToRoutine),
  83. ()=> CheckRoutineStopStatus(_moveToRoutine,"MoveTo Routine",_moveToRoutine.ErrorMsg,1))
  84. //1.3 Place
  85. .Run(TransferStep.Place, () => { return _placeRoutine.Start(_toCellName) == RState.Running; },_delay_1ms)
  86. .WaitWithStopCondition(TransferStep.PlaceWait, () => CommonFunction.CheckRoutineEndState(_placeRoutine),
  87. ()=> CheckRoutineStopStatus(_placeRoutine,"Place Routine",_placeRoutine.ErrorMsg,2))
  88. .End(TransferStep.End,LastChangeWafer,100);
  89. return Runner.Status;
  90. }
  91. /// <summary>
  92. /// 检验Routine异常结束状态
  93. /// </summary>
  94. /// <param name="routine"></param>
  95. /// <returns></returns>
  96. private bool CheckRoutineStopStatus(IRoutine routine,string routineName,string errorMsg,int step)
  97. {
  98. RState ret = routine.Monitor();
  99. if (ret == RState.Failed || ret == RState.Timeout)
  100. {
  101. NotifyError(eEvent.ERR_TRANSPORTER, $"Transfer WaferHolder Routine\r\n{routineName}\\r\n{errorMsg}",step);
  102. return true;
  103. }
  104. return false;
  105. }
  106. /// <summary>
  107. /// 检验前置条件
  108. /// </summary>
  109. /// <returns></returns>
  110. private bool CheckPreCondition()
  111. {
  112. if(!_gantryAxis.IsSwitchOn)
  113. {
  114. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} gantry axis is not switch on ",-1);
  115. return false;
  116. }
  117. if (!_gantryAxis.IsHomed)
  118. {
  119. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} gantry axis is not homed ", -1);
  120. return false;
  121. }
  122. if (!_elevatorAxis.IsSwitchOn)
  123. {
  124. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} elevator axis is not switch on ",-1);
  125. return false;
  126. }
  127. if (!_elevatorAxis.IsHomed)
  128. {
  129. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} elevator axis is not homed ", -1);
  130. return false;
  131. }
  132. return true;
  133. }
  134. /// <summary>
  135. /// 最后交换Wafer
  136. /// </summary>
  137. /// <returns></returns>
  138. private bool LastChangeWafer()
  139. {
  140. ModuleName sourceModule;
  141. if (_fromCellName.ToLower() == "loader")
  142. {
  143. sourceModule = ModuleName.Loader1;
  144. }
  145. else
  146. {
  147. sourceModule = (ModuleName)Enum.Parse(typeof(ModuleName), _fromCellName);
  148. }
  149. ModuleName destModule;
  150. if (_toCellName.ToLower() == "loader")
  151. {
  152. destModule = ModuleName.Loader1;
  153. }
  154. else
  155. {
  156. destModule = (ModuleName)Enum.Parse(typeof(ModuleName), _toCellName);
  157. }
  158. if (WaferManager.Instance.CheckHasWafer(sourceModule, 0))
  159. {
  160. WaferManager.Instance.WaferMoved(sourceModule, 0, destModule, 0);
  161. }
  162. if (WaferManager.Instance.CheckHasWafer(sourceModule, 1))
  163. {
  164. WaferManager.Instance.WaferMoved(sourceModule, 1, destModule, 1);
  165. }
  166. return true;
  167. }
  168. /// <summary>
  169. /// 启动
  170. /// </summary>
  171. /// <param name="objs"></param>
  172. /// <returns></returns>
  173. public RState Start(params object[] objs)
  174. {
  175. _fromCellName = objs[0].ToString();
  176. _toCellName = objs[1].ToString();
  177. InitializeParameters();
  178. return Runner.Start(Module, $"Transfer from {_fromCellName} to {_toCellName}");
  179. }
  180. /// <summary>
  181. /// 初始化参数
  182. /// </summary>
  183. private void InitializeParameters()
  184. {
  185. _elevatorAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Elevator");
  186. _gantryAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Gantry");
  187. _loaderEntity = Singleton<RouteManager>.Instance.GetModule<LoaderEntity>(ModuleName.Loader1.ToString());
  188. _loaderRotationAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.Rotation");
  189. _facilities = DEVICE.GetDevice<SystemFacilities>("System.Facilities");
  190. }
  191. /// <summary>
  192. /// 启动校验条件
  193. /// </summary>
  194. /// <returns></returns>
  195. private bool CheckStartPreConfition()
  196. {
  197. if(!CheckPreCondition())
  198. {
  199. return false;
  200. }
  201. double elevatorPosition = _elevatorAxis.MotionData.MotorPosition;
  202. if (!_elevatorAxis.CheckPositionIsInStation(elevatorPosition, "Up") &&
  203. !_elevatorAxis.CheckPositionIsInStation(elevatorPosition,"Low"))
  204. {
  205. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} elevator axis {elevatorPosition} is not in Up or Low station",-1);
  206. return false;
  207. }
  208. if (!_loaderEntity.IsHomed)
  209. {
  210. NotifyError(eEvent.ERR_TRANSPORTER, $"{ModuleName.Loader1} is not homed", -1);
  211. return false;
  212. }
  213. if (_toCellName == "Loader" || _fromCellName == "Loader")
  214. {
  215. double loaderRotationPosition = _loaderRotationAxis.MotionData.MotorPosition;
  216. if (!_loaderRotationAxis.CheckPositionIsInStation(loaderRotationPosition, "TRNPA") &&
  217. !_loaderRotationAxis.CheckPositionIsInStation(loaderRotationPosition, "TRNPB"))
  218. {
  219. NotifyError(eEvent.ERR_TRANSPORTER, $"{ModuleName.Loader1} rotation axis {loaderRotationPosition} is not int TRNPA or TRNPB station", -1);
  220. return false;
  221. }
  222. }
  223. if (WaferHolderManager.Instance.HasWaferHolder(Module))
  224. {
  225. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} has wafer shuttle", -1);
  226. return false;
  227. }
  228. if (!WaferHolderManager.Instance.HasWaferHolder(_fromCellName))
  229. {
  230. NotifyError(eEvent.ERR_TRANSPORTER, $"{_fromCellName} does not has wafer shuttle", -1);
  231. return false;
  232. }
  233. if (WaferHolderManager.Instance.HasWaferHolder(_toCellName))
  234. {
  235. NotifyError(eEvent.ERR_TRANSPORTER, $"{_toCellName} already has wafer shuttle",-1);
  236. return false;
  237. }
  238. //检验Facilities
  239. var faciltiesResult = _facilities.CheckCDA();
  240. if (!faciltiesResult.result)
  241. {
  242. NotifyError(eEvent.ERR_TRANSPORTER, faciltiesResult.reason, -1);
  243. return false;
  244. }
  245. return true;
  246. }
  247. /// <summary>
  248. /// 重试
  249. /// </summary>
  250. /// <param name="step"></param>
  251. public RState Retry(int step)
  252. {
  253. InitializeParameters();
  254. if(string.IsNullOrEmpty(_fromCellName))
  255. {
  256. NotifyError(eEvent.ERR_TRANSPORTER, "source cell is empty", step);
  257. return RState.Failed;
  258. }
  259. if (string.IsNullOrEmpty(_toCellName))
  260. {
  261. NotifyError(eEvent.ERR_TRANSPORTER, "target cell is empty", step);
  262. return RState.Failed;
  263. }
  264. List<Enum> preStepIds = new List<Enum>();
  265. if (step == 0 || step == -1)
  266. {
  267. return Runner.Retry(TransferStep.CheckPreCondition, preStepIds, Module, "Transfer Retry");
  268. }
  269. else if(step==1)
  270. {
  271. AddPreSteps(TransferStep.MoveTo, preStepIds);
  272. return Runner.Retry(TransferStep.MoveTo, preStepIds, Module, $"Transfer step {TransferStep.MoveTo} Retry");
  273. }
  274. else
  275. {
  276. AddPreSteps(TransferStep.Place, preStepIds);
  277. return Runner.Retry(TransferStep.Place, preStepIds, Module, $"Transfer step {TransferStep.Place} Retry");
  278. }
  279. }
  280. /// <summary>
  281. /// 忽略前
  282. /// </summary>
  283. /// <param name="step"></param>
  284. /// <param name="preStepIds"></param>
  285. private void AddPreSteps(TransferStep step, List<Enum> preStepIds)
  286. {
  287. for (int i = 0; i < (int)step; i++)
  288. {
  289. preStepIds.Add((TransferStep)i);
  290. }
  291. }
  292. /// <summary>
  293. /// 检验前面完成状态
  294. /// </summary>
  295. /// <returns></returns>
  296. public bool CheckCompleteCondition(int index)
  297. {
  298. TransporterEntity transporterEntity = Singleton<RouteManager>.Instance.GetModule<TransporterEntity>(Module);
  299. if (transporterEntity.WaferHolderInfo != null)
  300. {
  301. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} has waferholder", index);
  302. return false;
  303. }
  304. if(!WaferHolderManager.Instance.HasWaferHolder(_toCellName))
  305. {
  306. NotifyError(eEvent.ERR_TRANSPORTER, $"{_toCellName} does not have waferholder", index);
  307. return false;
  308. }
  309. double gantryPosition = _gantryAxis.MotionData.MotorPosition;
  310. if (!_gantryAxis.CheckPositionIsInStation(gantryPosition, _toCellName))
  311. {
  312. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} gantry {gantryPosition} not in {_toCellName}", index);
  313. return false;
  314. }
  315. return true;
  316. }
  317. }
  318. }