TransporterTransferRoutine.cs 13 KB

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