TransporterMoveToRoutine.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  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.Utilities;
  11. using MECF.Framework.Common.WaferHolder;
  12. using CyberX8_Core;
  13. using CyberX8_RT.Devices.AXIS;
  14. using CyberX8_RT.Devices.AXIS.CANOpen;
  15. using CyberX8_RT.Devices.Facilities;
  16. using CyberX8_RT.Devices.TransPorter;
  17. using CyberX8_RT.Modules.Loader;
  18. using System;
  19. using System.Collections.Generic;
  20. using System.Linq;
  21. using System.Text;
  22. using System.Threading.Tasks;
  23. namespace CyberX8_RT.Modules.Transporter
  24. {
  25. public class TransporterMoveToRoutine : RoutineBase, IRoutine
  26. {
  27. private enum MoveToStep
  28. {
  29. CheckStatus,
  30. ElevatorPosition,
  31. ElevatorPositionWait,
  32. ImmobilizeExtend,
  33. ImmobilizeExtendWait,
  34. SafeMoveTo,
  35. CheckMoveToStatus,
  36. GantryPosition,
  37. GantryPositionWait,
  38. End
  39. }
  40. #region 内部变量
  41. private string _cellName;
  42. private JetAxisBase _gantryAxis;
  43. private JetAxisBase _elevatorAxis;
  44. private LoaderEntity _loaderEntity;
  45. private JetAxisBase _loaderRotationAxis;
  46. private TransporterCommon _transporterCommon;
  47. private SystemFacilities _facilities;
  48. private TransporterExtendRoutine _extendRoutine;
  49. private TransporterConflictRoutine _conflictRoutine;
  50. ProcessLayoutCellItem _cellItem;
  51. private bool _waferHolderPresent = false;
  52. #endregion
  53. /// <summary>
  54. /// 构造函数
  55. /// </summary>
  56. /// <param name="module"></param>
  57. public TransporterMoveToRoutine(string module) : base(module)
  58. {
  59. }
  60. /// <summary>
  61. /// 中止
  62. /// </summary>
  63. public void Abort()
  64. {
  65. Runner.Stop("Manual Abort");
  66. }
  67. /// <summary>
  68. /// 监控
  69. /// </summary>
  70. /// <returns></returns>
  71. public RState Monitor()
  72. {
  73. Runner.Run(MoveToStep.CheckStatus, CheckStartPreConfition, NullFun,_delay_1ms)
  74. //1.1 Elevator
  75. .Run(MoveToStep.ElevatorPosition, ElevatorPosition, _delay_1ms)
  76. .WaitWithStopCondition(MoveToStep.ElevatorPositionWait, CheckVerticalPositionStatus, CheckVerticalPositionRunStop)
  77. //1.1 Immobilizer extend
  78. .Run(MoveToStep.ImmobilizeExtend, ImmobilizeExtend, _delay_1ms)
  79. .WaitWithStopCondition(MoveToStep.ImmobilizeExtendWait, CheckImmobilizeExtendStatus, CheckImmobilizeExtendRunStop)
  80. //1.2 Move to 安全
  81. .Run(MoveToStep.SafeMoveTo,SafeMoveTo,_delay_1ms)
  82. .WaitWithStopCondition(MoveToStep.CheckMoveToStatus, () => CommonFunction.CheckRoutineEndState(_conflictRoutine),
  83. CheckSafeMoveToStopStatus)
  84. //1.3 Gantry 移动
  85. .Run(MoveToStep.GantryPosition, GantryPositionToCell, _delay_1ms)
  86. .WaitWithStopCondition(MoveToStep.GantryPositionWait, CheckGantryPositionStatus, CheckGantryPositionRunStop)
  87. .End(MoveToStep.End,NullFun,100);
  88. return Runner.Status;
  89. }
  90. /// <summary>
  91. /// Elevator Position
  92. /// </summary>
  93. /// <returns></returns>
  94. private bool ElevatorPosition()
  95. {
  96. bool result= false;
  97. //状态locked住了 则运动至Up
  98. if(_waferHolderPresent)
  99. {
  100. result= _elevatorAxis.PositionStation("Up");
  101. if(!result)
  102. {
  103. NotifyError(eEvent.ERR_TRANSPORTER, "elevator goto up failed", 0);
  104. }
  105. }
  106. else//不存在Wafer,则运动至Low
  107. {
  108. result= _elevatorAxis.PositionStation("LOW");
  109. if (!result)
  110. {
  111. NotifyError(eEvent.ERR_TRANSPORTER, "elevator goto low failed", 0);
  112. }
  113. }
  114. return result;
  115. }
  116. /// <summary>
  117. /// Immobile Extend
  118. /// </summary>
  119. /// <returns></returns>
  120. private bool ImmobilizeExtend()
  121. {
  122. if(!_waferHolderPresent)
  123. {
  124. return true;
  125. }
  126. else
  127. {
  128. return _extendRoutine.Start(null) == RState.Running;
  129. }
  130. }
  131. /// <summary>
  132. /// 检验Immobilize状态
  133. /// </summary>
  134. /// <returns></returns>
  135. private bool CheckImmobilizeExtendStatus()
  136. {
  137. if(!_waferHolderPresent)
  138. {
  139. return true;
  140. }
  141. else
  142. {
  143. return CommonFunction.CheckRoutineEndState(_extendRoutine);
  144. }
  145. }
  146. /// <summary>
  147. /// 检验Immobilize状态
  148. /// </summary>
  149. /// <returns></returns>
  150. private bool CheckImmobilizeExtendRunStop()
  151. {
  152. if (!_waferHolderPresent)
  153. {
  154. return true;
  155. }
  156. else
  157. {
  158. bool result= CommonFunction.CheckRoutineStopState(_extendRoutine);
  159. if(result)
  160. {
  161. NotifyError(eEvent.ERR_TRANSPORTER, "extend failed", 0);
  162. }
  163. return result;
  164. }
  165. }
  166. /// <summary>
  167. /// 安全避障移动
  168. /// </summary>
  169. /// <returns></returns>
  170. private bool SafeMoveTo()
  171. {
  172. _cellItem = ProcessLayoutManager.Instance.GetProcessLayoutCellItemByModuleName(_cellName);
  173. string stationName = _cellName;
  174. if (_cellItem != null)
  175. {
  176. if (_cellName.ToLower() != "loader" && _cellName.ToLower() != "park")
  177. {
  178. stationName = $"Cell{_cellItem.CellId}";
  179. }
  180. }
  181. else
  182. {
  183. NotifyError(eEvent.ERR_TRANSPORTER, $"{_cellName} not in layout",0);
  184. return false;
  185. }
  186. var result = _gantryAxis.GetPositionByStation(stationName);
  187. if (result.success)
  188. {
  189. bool isPositive = false;
  190. if (_gantryAxis.MotionData.MotorPosition < result.position)
  191. {
  192. isPositive = true;
  193. }
  194. return _conflictRoutine.Start(result.position, isPositive) == RState.Running;
  195. }
  196. else
  197. {
  198. NotifyError(eEvent.ERR_TRANSPORTER, $"{_cellName} not in station list",0);
  199. return false;
  200. }
  201. }
  202. /// <summary>
  203. /// 检验安全避让异常结束状态
  204. /// </summary>
  205. /// <returns></returns>
  206. private bool CheckSafeMoveToStopStatus()
  207. {
  208. bool result = CommonFunction.CheckRoutineStopState(_conflictRoutine);
  209. if (result)
  210. {
  211. NotifyError(eEvent.ERR_TRANSPORTER, "Safe Move failed", 0);
  212. }
  213. return result;
  214. }
  215. /// <summary>
  216. /// Gantry Position To cell
  217. /// </summary>
  218. /// <returns></returns>
  219. private bool GantryPositionToCell()
  220. {
  221. _cellItem= ProcessLayoutManager.Instance.GetProcessLayoutCellItemByModuleName(_cellName);
  222. bool result = false;
  223. if (_cellItem != null)
  224. {
  225. if (_cellName.ToLower() != "loader"&&_cellName.ToLower()!="park")
  226. {
  227. result= _gantryAxis.PositionStation($"Cell{_cellItem.CellId}", false);
  228. }
  229. else
  230. {
  231. result= _gantryAxis.PositionStation(_cellName,false);
  232. }
  233. if (!result)
  234. {
  235. NotifyError(eEvent.ERR_TRANSPORTER, "gantry axis motion failed", 0);
  236. }
  237. return result;
  238. }
  239. else
  240. {
  241. NotifyError(eEvent.ERR_TRANSPORTER, $"{_cellName} not in layout",0);
  242. return false;
  243. }
  244. }
  245. /// <summary>
  246. /// 检验Vertical移动状态
  247. /// </summary>
  248. /// <returns></returns>
  249. private bool CheckVerticalPositionStatus()
  250. {
  251. return _elevatorAxis.Status == RState.End;
  252. }
  253. /// <summary>
  254. /// 检验Vertical是否还在运动
  255. /// </summary>
  256. /// <returns></returns>
  257. private bool CheckVerticalPositionRunStop()
  258. {
  259. bool result= _elevatorAxis.Status == RState.Failed||_elevatorAxis.Status==RState.Timeout;
  260. if (result)
  261. {
  262. NotifyError(eEvent.ERR_TRANSPORTER, "elevator motion failed",0);
  263. }
  264. return result;
  265. }
  266. /// <summary>
  267. /// 检验Gantry移动状态
  268. /// </summary>
  269. /// <returns></returns>
  270. private bool CheckGantryPositionStatus()
  271. {
  272. return _gantryAxis.Status == RState.End;
  273. }
  274. /// <summary>
  275. /// 检验Gantry是否还在运动
  276. /// </summary>
  277. /// <returns></returns>
  278. private bool CheckGantryPositionRunStop()
  279. {
  280. bool result= _gantryAxis.Status == RState.Failed||_gantryAxis.Status==RState.Timeout;
  281. if(result)
  282. {
  283. NotifyError(eEvent.ERR_TRANSPORTER, "gantry motion failed", 0);
  284. }
  285. return result;
  286. }
  287. /// <summary>
  288. /// 启动
  289. /// </summary>
  290. /// <param name="objs"></param>
  291. /// <returns></returns>
  292. public RState Start(params object[] objs)
  293. {
  294. _cellName = objs[0].ToString();
  295. _elevatorAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Elevator");
  296. _gantryAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Gantry");
  297. _loaderEntity = Singleton<RouteManager>.Instance.GetModule<LoaderEntity>(ModuleName.Loader1.ToString());
  298. _loaderRotationAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.Rotation");
  299. _facilities = DEVICE.GetDevice<SystemFacilities>("System.Facilities");
  300. _extendRoutine = new TransporterExtendRoutine(Module);
  301. _conflictRoutine = new TransporterConflictRoutine(Module);
  302. _transporterCommon = DEVICE.GetDevice<TransporterCommon>($"{Module}.Common");
  303. _waferHolderPresent = _transporterCommon.TransporterData.WhPresent1||_transporterCommon.TransporterData.WhPresent2;
  304. return Runner.Start(Module,$"MoveTo {_cellName}");
  305. }
  306. /// <summary>
  307. /// 启动校验条件
  308. /// </summary>
  309. /// <returns></returns>
  310. private bool CheckStartPreConfition()
  311. {
  312. if(!CheckPreCondition())
  313. {
  314. return false;
  315. }
  316. double elevatorPosition = _elevatorAxis.MotionData.MotorPosition;
  317. if (!_elevatorAxis.CheckPositionIsInStation(elevatorPosition, "Up") &&
  318. !_elevatorAxis.CheckPositionIsInStation(elevatorPosition, "Low"))
  319. {
  320. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} elevator axis {elevatorPosition} is not in Up or Low station",-1);
  321. return false;
  322. }
  323. if (!_loaderEntity.IsHomed)
  324. {
  325. NotifyError(eEvent.ERR_TRANSPORTER, $"{ModuleName.Loader1} is not homed",-1);
  326. return false;
  327. }
  328. if (_cellName == "Loader")
  329. {
  330. double loaderRotationPosition = _loaderRotationAxis.MotionData.MotorPosition;
  331. if (!_loaderRotationAxis.CheckPositionIsInStation(loaderRotationPosition, "TRNPA") &&
  332. !_loaderRotationAxis.CheckPositionIsInStation(loaderRotationPosition, "TRNPB"))
  333. {
  334. NotifyError(eEvent.ERR_TRANSPORTER, $"{ModuleName.Loader1} rotation axis {loaderRotationPosition} is not int TRNPA or TRNPB station",-1);
  335. return false;
  336. }
  337. }
  338. if (WaferHolderManager.Instance.HasWaferHolder(Module)&& !_elevatorAxis.CheckPositionIsInStation(elevatorPosition, "Up"))
  339. {
  340. NotifyError(eEvent.ERR_TRANSPORTER,$"{Module} has wafer Shuttle but elevator axis is not in up",-1);
  341. return false;
  342. }
  343. //检验Facilities
  344. var faciltiesResult = _facilities.CheckCDA();
  345. if (!faciltiesResult.result)
  346. {
  347. NotifyError(eEvent.ERR_TRANSPORTER, faciltiesResult.reason,-1);
  348. return false;
  349. }
  350. return true;
  351. }
  352. /// <summary>
  353. /// 检验前置条件
  354. /// </summary>
  355. /// <returns></returns>
  356. private bool CheckPreCondition()
  357. {
  358. if (!_gantryAxis.IsSwitchOn)
  359. {
  360. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} gantry axis is not switch on ",-1);
  361. return false;
  362. }
  363. if (!_gantryAxis.IsHomed)
  364. {
  365. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} gantry axis is not homed ",-1);
  366. return false;
  367. }
  368. if (!_elevatorAxis.IsSwitchOn)
  369. {
  370. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} elevator axis is not switch on ",-1);
  371. return false;
  372. }
  373. if (!_elevatorAxis.IsHomed)
  374. {
  375. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} elevator axis is not homed ",-1);
  376. return false;
  377. }
  378. return true;
  379. }
  380. }
  381. }