TransporterMoveToRoutine.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  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. SafeMoveTo,
  33. CheckMoveToStatus,
  34. GantryPosition,
  35. GantryPositionWait,
  36. End
  37. }
  38. #region 内部变量
  39. private string _cellName;
  40. private string _otherModule;
  41. private JetAxisBase _gantryAxis;
  42. private JetAxisBase _elevatorAxis;
  43. private JetAxisBase _otherElevatorAxis;
  44. private LoaderEntity _loaderEntity;
  45. private JetAxisBase _loaderRotationAxis;
  46. private TransporterCommon _transporterCommon;
  47. private SystemFacilities _facilities;
  48. private TransporterConflictRoutine _conflictRoutine;
  49. ProcessLayoutCellItem _cellItem;
  50. private bool _waferHolderPresent = false;
  51. #endregion
  52. /// <summary>
  53. /// 构造函数
  54. /// </summary>
  55. /// <param name="module"></param>
  56. public TransporterMoveToRoutine(string module) : base(module)
  57. {
  58. }
  59. /// <summary>
  60. /// 中止
  61. /// </summary>
  62. public void Abort()
  63. {
  64. Runner.Stop("Manual Abort");
  65. }
  66. /// <summary>
  67. /// 监控
  68. /// </summary>
  69. /// <returns></returns>
  70. public RState Monitor()
  71. {
  72. Runner.Run(MoveToStep.CheckStatus, CheckStartPreConfition, NullFun,_delay_1ms)
  73. //1. Elevator
  74. .Run(MoveToStep.ElevatorPosition, ElevatorPosition, _delay_1ms)
  75. .WaitWithStopCondition(MoveToStep.ElevatorPositionWait, CheckElevatorPositionStatus, CheckElevatorPositionRunStop)
  76. //2. other Transporter Safe Move
  77. .Run(MoveToStep.SafeMoveTo, SafeMoveTo, _delay_1ms)
  78. .WaitWithStopCondition(MoveToStep.CheckMoveToStatus, () => CommonFunction.CheckRoutineEndState(_conflictRoutine),
  79. CheckSafeMoveToStopStatus)
  80. //3. this Gantry Move To Target Cell
  81. .Run(MoveToStep.GantryPosition, GantryPositionToCell, _delay_1ms)
  82. .WaitWithStopCondition(MoveToStep.GantryPositionWait, CheckGantryPositionStatus, CheckGantryPositionRunStop)
  83. .End(MoveToStep.End,NullFun,100);
  84. return Runner.Status;
  85. }
  86. /// <summary>
  87. /// Elevator Position
  88. /// </summary>
  89. /// <returns></returns>
  90. private bool ElevatorPosition()
  91. {
  92. bool result= false;
  93. //运动至UP
  94. double elevatorPosition = _elevatorAxis.MotionData.MotorPosition;
  95. if (!_elevatorAxis.CheckPositionIsInStation(elevatorPosition, "UP"))
  96. {
  97. result= _elevatorAxis.PositionStation("UP");
  98. if(!result)
  99. {
  100. NotifyError(eEvent.ERR_TRANSPORTER, "elevator goto up failed", 0);
  101. }
  102. }
  103. else
  104. {
  105. result = true;
  106. }
  107. return result;
  108. }
  109. /// <summary>
  110. /// 安全避障移动
  111. /// </summary>
  112. /// <returns></returns>
  113. private bool SafeMoveTo()
  114. {
  115. _cellItem = ProcessLayoutManager.Instance.GetProcessLayoutCellItemByModuleName(_cellName);
  116. string stationName = _cellName;
  117. if (_cellItem != null)
  118. {
  119. if (_cellName.ToLower() != "loader" && _cellName.ToLower() != "park")
  120. {
  121. stationName = $"Cell{_cellItem.CellId}";
  122. }
  123. }
  124. else
  125. {
  126. NotifyError(eEvent.ERR_TRANSPORTER, $"{_cellName} not in layout",0);
  127. return false;
  128. }
  129. var result = _gantryAxis.GetPositionByStation(stationName);
  130. if (result.success)
  131. {
  132. bool isPositive = false;
  133. if (_gantryAxis.MotionData.MotorPosition < result.position)
  134. {
  135. isPositive = true;
  136. }
  137. return _conflictRoutine.Start(result.position, isPositive) == RState.Running;
  138. }
  139. else
  140. {
  141. NotifyError(eEvent.ERR_TRANSPORTER, $"{_cellName} not in station list",0);
  142. return false;
  143. }
  144. }
  145. /// <summary>
  146. /// 检验安全避让异常结束状态
  147. /// </summary>
  148. /// <returns></returns>
  149. private bool CheckSafeMoveToStopStatus()
  150. {
  151. bool result = CommonFunction.CheckRoutineStopState(_conflictRoutine);
  152. if (result)
  153. {
  154. NotifyError(eEvent.ERR_TRANSPORTER, "Safe Move failed", 0);
  155. }
  156. return result;
  157. }
  158. /// <summary>
  159. /// Gantry Position To cell
  160. /// </summary>
  161. /// <returns></returns>
  162. private bool GantryPositionToCell()
  163. {
  164. _cellItem= ProcessLayoutManager.Instance.GetProcessLayoutCellItemByModuleName(_cellName);
  165. bool result = false;
  166. if (_cellItem != null)
  167. {
  168. if (_cellName.ToLower() != "loader"&&_cellName.ToLower()!="park")
  169. {
  170. result= _gantryAxis.PositionStation($"Cell{_cellItem.CellId}", false);
  171. }
  172. else
  173. {
  174. result= _gantryAxis.PositionStation(_cellName,false);
  175. }
  176. if (!result)
  177. {
  178. NotifyError(eEvent.ERR_TRANSPORTER, "gantry axis motion failed", 0);
  179. }
  180. return result;
  181. }
  182. else
  183. {
  184. NotifyError(eEvent.ERR_TRANSPORTER, $"{_cellName} not in layout",0);
  185. return false;
  186. }
  187. }
  188. /// <summary>
  189. /// 检验Elevator移动状态
  190. /// </summary>
  191. /// <returns></returns>
  192. private bool CheckElevatorPositionStatus()
  193. {
  194. return _elevatorAxis.Status == RState.End;
  195. }
  196. /// <summary>
  197. /// 检验Elevator是否还在运动
  198. /// </summary>
  199. /// <returns></returns>
  200. private bool CheckElevatorPositionRunStop()
  201. {
  202. bool result= _elevatorAxis.Status == RState.Failed||_elevatorAxis.Status==RState.Timeout;
  203. if (result)
  204. {
  205. NotifyError(eEvent.ERR_TRANSPORTER, "elevator motion failed",0);
  206. }
  207. return result;
  208. }
  209. /// <summary>
  210. /// 检验Gantry移动状态
  211. /// </summary>
  212. /// <returns></returns>
  213. private bool CheckGantryPositionStatus()
  214. {
  215. return _gantryAxis.Status == RState.End;
  216. }
  217. /// <summary>
  218. /// 检验Gantry是否还在运动
  219. /// </summary>
  220. /// <returns></returns>
  221. private bool CheckGantryPositionRunStop()
  222. {
  223. bool result= _gantryAxis.Status == RState.Failed||_gantryAxis.Status==RState.Timeout;
  224. if(result)
  225. {
  226. NotifyError(eEvent.ERR_TRANSPORTER, "gantry motion failed", 0);
  227. }
  228. return result;
  229. }
  230. /// <summary>
  231. /// 启动
  232. /// </summary>
  233. /// <param name="objs"></param>
  234. /// <returns></returns>
  235. public RState Start(params object[] objs)
  236. {
  237. _cellName = objs[0].ToString();
  238. _elevatorAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Elevator");
  239. _otherModule = Module == "Transporter2" ? "Transporter1" : "Transporter2";
  240. _otherElevatorAxis = DEVICE.GetDevice<JetAxisBase>($"{_otherModule}.Elevator");
  241. _gantryAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Gantry");
  242. _loaderEntity = Singleton<RouteManager>.Instance.GetModule<LoaderEntity>(ModuleName.Loader1.ToString());
  243. _loaderRotationAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.Rotation");
  244. _conflictRoutine = new TransporterConflictRoutine(Module);
  245. _transporterCommon = DEVICE.GetDevice<TransporterCommon>($"{Module}.Common");
  246. return Runner.Start(Module,$"MoveTo {_cellName}");
  247. }
  248. /// <summary>
  249. /// 启动校验条件
  250. /// </summary>
  251. /// <returns></returns>
  252. private bool CheckStartPreConfition()
  253. {
  254. //所有轴上电并Homed
  255. if(!CheckPreCondition())
  256. {
  257. return false;
  258. }
  259. //若目标Cell为Loader, 则Loader应在TRNPA或TRNPB位
  260. if (_cellName == "Loader")
  261. {
  262. double loaderRotationPosition = _loaderRotationAxis.MotionData.MotorPosition;
  263. if (!_loaderRotationAxis.CheckPositionIsInStation(loaderRotationPosition, "TRNPA") &&
  264. !_loaderRotationAxis.CheckPositionIsInStation(loaderRotationPosition, "TRNPB"))
  265. {
  266. NotifyError(eEvent.ERR_TRANSPORTER, $"{ModuleName.Loader1} rotation axis {loaderRotationPosition} is not int TRNPA or TRNPB station",-1);
  267. return false;
  268. }
  269. }
  270. //检验Facilities
  271. //var faciltiesResult = _facilities.CheckCDA();
  272. //if (!faciltiesResult.result)
  273. //{
  274. // NotifyError(eEvent.ERR_TRANSPORTER, faciltiesResult.reason, -1);
  275. // return false;
  276. //}
  277. return true;
  278. }
  279. /// <summary>
  280. /// 检验前置条件
  281. /// </summary>
  282. /// <returns></returns>
  283. private bool CheckPreCondition()
  284. {
  285. if (!_gantryAxis.IsSwitchOn)
  286. {
  287. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} gantry axis is not switch on ",-1);
  288. return false;
  289. }
  290. if (!_gantryAxis.IsHomed)
  291. {
  292. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} gantry axis is not homed ",-1);
  293. return false;
  294. }
  295. if (!_elevatorAxis.IsSwitchOn)
  296. {
  297. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} elevator axis is not switch on ",-1);
  298. return false;
  299. }
  300. if (!_elevatorAxis.IsHomed)
  301. {
  302. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} elevator axis is not homed ",-1);
  303. return false;
  304. }
  305. return true;
  306. }
  307. }
  308. }