TransporterTransferRoutine.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  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. #region 属性
  55. public string SourceCell { get { return _fromCellName; } }
  56. public string TargetCell { get { return _toCellName; } }
  57. #endregion
  58. /// <summary>
  59. /// 构造函数
  60. /// </summary>
  61. /// <param name="module"></param>
  62. public TransporterTransferRoutine(string module) : base(module)
  63. {
  64. _pickUpRoutine=new TransporterPickUpFromRoutine(module);
  65. _moveToRoutine = new TransporterMoveToRoutine(module);
  66. _placeRoutine=new TransporterPickDownToRoutine(module);
  67. }
  68. /// <summary>
  69. /// 中止
  70. /// </summary>
  71. public void Abort()
  72. {
  73. Runner.Stop("Manual Abort");
  74. }
  75. /// <summary>
  76. /// 监控
  77. /// </summary>
  78. /// <returns></returns>
  79. public RState Monitor()
  80. {
  81. Runner.Run(TransferStep.CheckPreCondition,CheckStartPreConfition,_delay_1ms)
  82. //1.1 PickupFrom
  83. .Run(TransferStep.PickUpFrom, () => { return _pickUpRoutine.Start(_fromCellName) == RState.Running; }, _delay_1ms)
  84. .WaitWithStopCondition(TransferStep.PickUpFromWait, ()=>CommonFunction.CheckRoutineEndState(_pickUpRoutine),
  85. ()=> CheckRoutineStopStatus(_pickUpRoutine,"PickUp Routine", _pickUpRoutine.ErrorMsg,0))
  86. //1.2 Move to
  87. .Run(TransferStep.MoveTo, () => { return _moveToRoutine.Start(_toCellName) == RState.Running; }, _delay_1ms)
  88. .WaitWithStopCondition(TransferStep.MoveToWait, ()=>CommonFunction.CheckRoutineEndState(_moveToRoutine),
  89. ()=> CheckRoutineStopStatus(_moveToRoutine,"MoveTo Routine",_moveToRoutine.ErrorMsg,1))
  90. //1.3 Place
  91. .Run(TransferStep.Place, () => { return _placeRoutine.Start(_toCellName) == RState.Running; },_delay_1ms)
  92. .WaitWithStopCondition(TransferStep.PlaceWait, () => CommonFunction.CheckRoutineEndState(_placeRoutine),
  93. ()=> CheckRoutineStopStatus(_placeRoutine,"Place Routine",_placeRoutine.ErrorMsg,2))
  94. .End(TransferStep.End,LastChangeWafer,100);
  95. return Runner.Status;
  96. }
  97. /// <summary>
  98. /// 检验Routine异常结束状态
  99. /// </summary>
  100. /// <param name="routine"></param>
  101. /// <returns></returns>
  102. private bool CheckRoutineStopStatus(IRoutine routine,string routineName,string errorMsg,int step)
  103. {
  104. RState ret = routine.Monitor();
  105. if (ret == RState.Failed || ret == RState.Timeout)
  106. {
  107. NotifyError(eEvent.ERR_TRANSPORTER, $"Transfer WaferHolder Routine\r\n{routineName}\\r\n{errorMsg}",step);
  108. return true;
  109. }
  110. return false;
  111. }
  112. /// <summary>
  113. /// 检验前置条件
  114. /// </summary>
  115. /// <returns></returns>
  116. private bool CheckPreCondition()
  117. {
  118. if(!_gantryAxis.IsSwitchOn)
  119. {
  120. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} gantry axis is not switch on ",-1);
  121. return false;
  122. }
  123. if (!_gantryAxis.IsHomed)
  124. {
  125. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} gantry axis is not homed ", -1);
  126. return false;
  127. }
  128. if (!_elevatorAxis.IsSwitchOn)
  129. {
  130. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} elevator axis is not switch on ",-1);
  131. return false;
  132. }
  133. if (!_elevatorAxis.IsHomed)
  134. {
  135. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} elevator axis is not homed ", -1);
  136. return false;
  137. }
  138. return true;
  139. }
  140. /// <summary>
  141. /// 最后交换Wafer
  142. /// </summary>
  143. /// <returns></returns>
  144. private bool LastChangeWafer()
  145. {
  146. ModuleName sourceModule;
  147. if (_fromCellName.ToLower() == "loader")
  148. {
  149. sourceModule = ModuleName.Loader1;
  150. }
  151. else
  152. {
  153. sourceModule = (ModuleName)Enum.Parse(typeof(ModuleName), _fromCellName);
  154. }
  155. ModuleName destModule;
  156. if (_toCellName.ToLower() == "loader")
  157. {
  158. destModule = ModuleName.Loader1;
  159. }
  160. else
  161. {
  162. destModule = (ModuleName)Enum.Parse(typeof(ModuleName), _toCellName);
  163. }
  164. if (WaferManager.Instance.CheckHasWafer(sourceModule, 0))
  165. {
  166. WaferManager.Instance.WaferMoved(sourceModule, 0, destModule, 0);
  167. }
  168. if (WaferManager.Instance.CheckHasWafer(sourceModule, 1))
  169. {
  170. WaferManager.Instance.WaferMoved(sourceModule, 1, destModule, 1);
  171. }
  172. return true;
  173. }
  174. /// <summary>
  175. /// 启动
  176. /// </summary>
  177. /// <param name="objs"></param>
  178. /// <returns></returns>
  179. public RState Start(params object[] objs)
  180. {
  181. _fromCellName = objs[0].ToString();
  182. _toCellName = objs[1].ToString();
  183. _bypassWaferHolderPresent = SC.GetValue<bool>("Transporter.BypassWaferHolderPresent");
  184. InitializeParameters();
  185. return Runner.Start(Module, $"Transfer from {_fromCellName} to {_toCellName}");
  186. }
  187. /// <summary>
  188. /// 初始化参数
  189. /// </summary>
  190. private void InitializeParameters()
  191. {
  192. _elevatorAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Elevator");
  193. _gantryAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Gantry");
  194. _loaderEntity = Singleton<RouteManager>.Instance.GetModule<LoaderEntity>(ModuleName.Loader1.ToString());
  195. _loaderRotationAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.Rotation");
  196. _facilities = DEVICE.GetDevice<SystemFacilities>("System.Facilities");
  197. _transporterCommon = DEVICE.GetDevice<TransporterCommon>($"{Module}.Common");
  198. }
  199. /// <summary>
  200. /// 启动校验条件
  201. /// </summary>
  202. /// <returns></returns>
  203. private bool CheckStartPreConfition()
  204. {
  205. if(!CheckPreCondition())
  206. {
  207. return false;
  208. }
  209. double elevatorPosition = _elevatorAxis.MotionData.MotorPosition;
  210. //if (!_elevatorAxis.CheckPositionIsInStation(elevatorPosition, "Up"))
  211. //{
  212. // NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} elevator axis {elevatorPosition} is not in Up station",-1);
  213. // return false;
  214. //}
  215. if (!_loaderEntity.IsHomed)
  216. {
  217. NotifyError(eEvent.ERR_TRANSPORTER, $"{ModuleName.Loader1} is not homed", -1);
  218. return false;
  219. }
  220. if (_toCellName == "Loader" || _fromCellName == "Loader")
  221. {
  222. double loaderRotationPosition = _loaderRotationAxis.MotionData.MotorPosition;
  223. if (!_loaderRotationAxis.CheckPositionIsInStation(loaderRotationPosition, "TRNPA") &&
  224. !_loaderRotationAxis.CheckPositionIsInStation(loaderRotationPosition, "TRNPB"))
  225. {
  226. NotifyError(eEvent.ERR_TRANSPORTER, $"{ModuleName.Loader1} rotation axis {loaderRotationPosition} is not int TRNPA or TRNPB station", -1);
  227. return false;
  228. }
  229. }
  230. if (WaferHolderManager.Instance.HasWaferHolder(Module))
  231. {
  232. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} has wafer shuttle", -1);
  233. return false;
  234. }
  235. if (!WaferHolderManager.Instance.HasWaferHolder(_fromCellName))
  236. {
  237. NotifyError(eEvent.ERR_TRANSPORTER, $"{_fromCellName} does not has wafer shuttle", -1);
  238. return false;
  239. }
  240. if (WaferHolderManager.Instance.HasWaferHolder(_toCellName))
  241. {
  242. NotifyError(eEvent.ERR_TRANSPORTER, $"{_toCellName} already has wafer shuttle",-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. }