TransporterPickDownToRoutine.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  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.Loader;
  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 CyberX8_RT.Devices.Metal;
  25. using CyberX8_RT.Devices.Rinse;
  26. using static Mono.Security.X509.X520;
  27. namespace CyberX8_RT.Modules.Transporter
  28. {
  29. public class TransporterPickDownToRoutine : RoutineBase, IRoutine
  30. {
  31. private enum PutDownStep
  32. {
  33. CheckPreStatus,
  34. ElevatorUp,
  35. ElevatorUpWait,
  36. SafeMoveTo,
  37. CheckMoveToStatus,
  38. GantryPosition,
  39. GantryPositiolWait,
  40. ElevatorPositionToCellTop,
  41. ElevatorPositionToCellTopWait,
  42. Delay,
  43. CalculatePlaceSpeed,
  44. PlaceDelay,
  45. ElevatorPositionToCell,
  46. ElevatorPositionToCellWait,
  47. DropBlockLockoff,
  48. ElevatorGotoUp,
  49. ElevatorGotoUpWait,
  50. ConfirmWSPresent,
  51. UpdateWaferHolder,
  52. GantryPositionPark,
  53. GantryPositionParkWait,
  54. End
  55. }
  56. #region 内部变量
  57. private string _cellName;
  58. private string _otherModule;
  59. private JetAxisBase _gantryAxis;
  60. private JetAxisBase _elevatorAxis;
  61. private JetAxisBase _otherElevatorAxis;
  62. private JetAxisBase _loaderRotationAxis;
  63. private SystemFacilities _facilities;
  64. private TransporterCommon _transporterCommon;
  65. private TransporterConflictRoutine _conflictRoutine;
  66. private LoaderCommonDevice _loaderCommonDevice;
  67. ProcessLayoutCellItem _cellItem;
  68. private int _placeTime;
  69. private int _placeDelayTime;
  70. private int _velocity;
  71. private int _acceleration;
  72. private bool _bypassWaferHolderPresent;
  73. #endregion
  74. /// <summary>
  75. /// 构造函数
  76. /// </summary>
  77. /// <param name="module"></param>
  78. public TransporterPickDownToRoutine(string module) : base(module)
  79. {
  80. }
  81. /// <summary>
  82. /// 中止
  83. /// </summary>
  84. public void Abort()
  85. {
  86. Runner.Stop("Manual Abort");
  87. }
  88. /// <summary>
  89. /// 监控
  90. /// </summary>
  91. /// <returns></returns>
  92. public RState Monitor()
  93. {
  94. Runner.Run(PutDownStep.CheckPreStatus,CheckStartPreConfition,_delay_1ms)
  95. //1. Elevator 移动至Up
  96. .Run(PutDownStep.ElevatorUp, ElevatorGotoUp, _delay_1ms)
  97. .WaitWithStopCondition(PutDownStep.ElevatorUpWait, CheckElevatorPositionEndStatus, CheckElevatorPositionStopStatus)
  98. //2. other Transporter Safe Move
  99. .Run(PutDownStep.SafeMoveTo, SafeMoveTo, _delay_1ms)
  100. .WaitWithStopCondition(PutDownStep.CheckMoveToStatus, () => CommonFunction.CheckRoutineEndState(_conflictRoutine),
  101. CheckSafeMoveToStopStatus)
  102. //3. Gantry 移动
  103. .Run(PutDownStep.GantryPosition, GantryPositionToCell, _delay_1ms)
  104. .WaitWithStopCondition(PutDownStep.GantryPositiolWait, CheckGantryPositionStatus, CheckGantryPositionRunStop)
  105. //6. Elevator 移动至cellTop
  106. .Run(PutDownStep.ElevatorPositionToCellTop, ElevatorPositionToCellTop, _delay_1ms)
  107. .WaitWithStopCondition(PutDownStep.ElevatorPositionToCellTopWait, CheckElevatorPositionEndStatus, CheckElevatorPositionStopStatus)
  108. .Delay(PutDownStep.Delay, 500)
  109. //4. 确认Place 速度和加速度
  110. .Run(PutDownStep.CalculatePlaceSpeed, CalculatePownDownSpeed, _delay_1ms)
  111. //5. Pickup delay
  112. .Delay(PutDownStep.PlaceDelay, _placeDelayTime * 1000)
  113. //7. Elevator 移动至cell
  114. .Run(PutDownStep.ElevatorPositionToCell, ElevatorPositionToCell, _delay_1ms)
  115. .WaitWithStopCondition(PutDownStep.ElevatorPositionToCellWait, CheckElevatorPositionEndStatus, CheckElevatorPositionStopStatus)
  116. //8. DropBlockLock off
  117. .Run(PutDownStep.DropBlockLockoff, DropBlockLockoff , _delay_1ms)
  118. //9. Elevator移动至Up
  119. .Run(PutDownStep.ElevatorGotoUp, ElevatorGotoUp, _delay_1ms)
  120. .WaitWithStopCondition(PutDownStep.ElevatorGotoUpWait, CheckElevatorPositionEndStatus, CheckElevatorPositionStopStatus)
  121. //10. 确认WSPresent信号
  122. .Wait(PutDownStep.ConfirmWSPresent,ConfirmWSPresentSensorOff,_delay_2s)
  123. //11. Wafer Holder location update
  124. .Run(PutDownStep.UpdateWaferHolder,WaferHolderTransfer,_delay_1ms)
  125. //12. Gantry Position To Park
  126. .Run(PutDownStep.GantryPositionPark, GantryBackToPark, _delay_1ms)
  127. .WaitWithStopCondition(PutDownStep.GantryPositionParkWait, CheckGantryParkPositionStatus, CheckGantryParkPositionRunStop)
  128. .End(PutDownStep.End,NullFun,100);
  129. return Runner.Status;
  130. }
  131. /// <summary>
  132. /// Elevator goto Up
  133. /// </summary>
  134. /// <returns></returns>
  135. private bool ElevatorGotoUp()
  136. {
  137. bool result= _elevatorAxis.PositionStation("UP", false);
  138. if (!result)
  139. {
  140. NotifyError(eEvent.ERR_TRANSPORTER, "elevator goto up failed", 0);
  141. }
  142. return result;
  143. }
  144. /// <summary>
  145. /// 检验前置条件
  146. /// </summary>
  147. /// <returns></returns>
  148. private bool CheckPreCondition()
  149. {
  150. if(!_gantryAxis.IsSwitchOn)
  151. {
  152. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} gantry axis is not switch on ", -1);
  153. return false;
  154. }
  155. if (!_gantryAxis.IsHomed)
  156. {
  157. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} gantry axis is not homed ",-1);
  158. return false;
  159. }
  160. if (!_elevatorAxis.IsSwitchOn)
  161. {
  162. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} elevator axis is not switch on ", -1);
  163. return false;
  164. }
  165. if (!_elevatorAxis.IsHomed)
  166. {
  167. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} elevator axis is not homed ",-1);
  168. return false;
  169. }
  170. return true;
  171. }
  172. /// <summary>
  173. /// 安全避障移动
  174. /// </summary>
  175. /// <returns></returns>
  176. private bool SafeMoveTo()
  177. {
  178. _cellItem = ProcessLayoutManager.Instance.GetProcessLayoutCellItemByModuleName(_cellName);
  179. string stationName = _cellName;
  180. if (_cellItem != null)
  181. {
  182. if (_cellName.ToLower() != "loader" && _cellName.ToLower() != "park")
  183. {
  184. stationName = $"Cell{_cellItem.CellId}";
  185. }
  186. }
  187. else
  188. {
  189. NotifyError(eEvent.ERR_TRANSPORTER, $"{_cellName} not in layout",0);
  190. return false;
  191. }
  192. var result = _gantryAxis.GetPositionByStation(stationName);
  193. if (result.success)
  194. {
  195. bool isPositive = false;
  196. if (_gantryAxis.MotionData.MotorPosition < result.position)
  197. {
  198. isPositive = true;
  199. }
  200. return _conflictRoutine.Start(result.position, isPositive) == RState.Running;
  201. }
  202. else
  203. {
  204. NotifyError(eEvent.ERR_TRANSPORTER, $"{_cellName} not in station list",0);
  205. return false;
  206. }
  207. }
  208. /// <summary>
  209. /// 检验安全避让异常结束状态
  210. /// </summary>
  211. /// <returns></returns>
  212. private bool CheckSafeMoveToStopStatus()
  213. {
  214. bool result = CommonFunction.CheckRoutineStopState(_conflictRoutine);
  215. if (result)
  216. {
  217. NotifyError(eEvent.ERR_TRANSPORTER, "Safe Move failed", 0);
  218. }
  219. return result;
  220. }
  221. /// <summary>
  222. /// Gantry Position To cell
  223. /// </summary>
  224. /// <returns></returns>
  225. private bool GantryPositionToCell()
  226. {
  227. _cellItem= ProcessLayoutManager.Instance.GetProcessLayoutCellItemByModuleName(_cellName);
  228. bool result = false;
  229. if (_cellItem != null)
  230. {
  231. if (_cellName.ToLower() != "loader"&&_cellName.ToLower()!="park")
  232. {
  233. result= _gantryAxis.PositionStation($"Cell{_cellItem.CellId}",false);
  234. }
  235. else
  236. {
  237. result = _gantryAxis.PositionStation(_cellName,false);
  238. }
  239. if (!result)
  240. {
  241. NotifyError(eEvent.ERR_TRANSPORTER, "gantry axis motion failed", 0);
  242. }
  243. return result;
  244. }
  245. else
  246. {
  247. NotifyError(eEvent.ERR_TRANSPORTER, $"{_cellName} not in layout",0);
  248. return false;
  249. }
  250. }
  251. /// <summary>
  252. /// Elevator Position to cellTop
  253. /// </summary>
  254. /// <returns></returns>
  255. private bool ElevatorPositionToCellTop()
  256. {
  257. bool result = _elevatorAxis.PositionStation("CellTop", false, _velocity, _acceleration, _acceleration);
  258. if (!result)
  259. {
  260. NotifyError(eEvent.ERR_TRANSPORTER, "elevator goto CellTop failed", 0);
  261. }
  262. return result;
  263. }
  264. /// <summary>
  265. /// Elevator Position to cell
  266. /// </summary>
  267. /// <returns></returns>
  268. private bool ElevatorPositionToCell()
  269. {
  270. bool result= false;
  271. if( _cellItem != null )
  272. {
  273. if (_cellName.ToLower()!="loader")
  274. {
  275. result= _elevatorAxis.PositionStation($"Cell{_cellItem.CellId}",false,_velocity,_acceleration,_acceleration);
  276. }
  277. else
  278. {
  279. result= _elevatorAxis.PositionStation(_cellName,false,_velocity,_acceleration,_acceleration);
  280. }
  281. if (!result)
  282. {
  283. NotifyError(eEvent.ERR_TRANSPORTER, "elevator axis motion failed", 0);
  284. }
  285. return result;
  286. }
  287. else
  288. {
  289. NotifyError(eEvent.ERR_TRANSPORTER, $"{_cellName} not in layout",0);
  290. return false;
  291. }
  292. }
  293. /// <summary>
  294. /// 检验Elevator移动状态
  295. /// </summary>
  296. /// <returns></returns>
  297. private bool CheckElevatorPositionEndStatus()
  298. {
  299. return _elevatorAxis.Status == RState.End;
  300. }
  301. /// <summary>
  302. /// 检验Vertical是否还在运动
  303. /// </summary>
  304. /// <returns></returns>
  305. private bool CheckElevatorPositionStopStatus()
  306. {
  307. bool result= _elevatorAxis.Status == RState.Failed||_elevatorAxis.Status==RState.Timeout;
  308. if(result)
  309. {
  310. NotifyError(eEvent.ERR_TRANSPORTER, "elevator axis motion failed", 0);
  311. }
  312. return result;
  313. }
  314. /// <summary>
  315. /// 检验Gantry移动状态
  316. /// </summary>
  317. /// <returns></returns>
  318. private bool CheckGantryPositionStatus()
  319. {
  320. return _gantryAxis.Status == RState.End;
  321. }
  322. /// <summary>
  323. /// 检验Gantry是否还在运动
  324. /// </summary>
  325. /// <returns></returns>
  326. private bool CheckGantryPositionRunStop()
  327. {
  328. bool result= _gantryAxis.Status == RState.Failed||_gantryAxis.Status==RState.Timeout;
  329. if(result)
  330. {
  331. NotifyError(eEvent.ERR_TRANSPORTER, "gantry axis motion failed", 0);
  332. }
  333. return result;
  334. }
  335. /// <summary>
  336. /// 计算放下速度
  337. /// </summary>
  338. /// <returns></returns>
  339. private bool CalculatePownDownSpeed()
  340. {
  341. if(_placeTime==0)
  342. {
  343. return true;
  344. }
  345. BeckhoffStationAxis stationAxis = BeckhoffStationLocationManager.Instance.GetStationAxis(Module, "Elevator", 0);
  346. Station upStation = stationAxis.Stations.Find(O => O.Name.EndsWith("CellTop")); Station cellStation = null;
  347. if (_cellName == "Loader")
  348. {
  349. cellStation = stationAxis.Stations.Find(O => O.Name.EndsWith("Loader"));
  350. }
  351. else
  352. {
  353. cellStation = stationAxis.Stations.Find(O => O.Name.EndsWith($"Cell{_cellItem.CellId}"));
  354. }
  355. if (upStation==null)
  356. {
  357. NotifyError(eEvent.ERR_TRANSPORTER, "CellTop is not in Station List", 0);
  358. return false;
  359. }
  360. if(cellStation==null)
  361. {
  362. NotifyError(eEvent.ERR_TRANSPORTER, $"Cell{_cellItem.CellId} is not in Station List",0);
  363. return false;
  364. }
  365. if(!double.TryParse(cellStation.Position,out double cellStationPosition))
  366. {
  367. NotifyError(eEvent.ERR_TRANSPORTER, $"Cell{_cellItem.CellId} Station Position is invalid",0);
  368. return false;
  369. }
  370. if (!double.TryParse(upStation.Position, out double upStationPosition))
  371. {
  372. NotifyError(eEvent.ERR_TRANSPORTER, $"Cell{_cellItem.CellId} Station Position is invalid",0);
  373. return false;
  374. }
  375. int distance =(int)(Math.Round(Math.Abs(cellStationPosition - upStationPosition)));
  376. double tmpVelocity = (double) distance/ _placeTime;
  377. _velocity = _elevatorAxis.CalculateMultiplySpeedRatio(_elevatorAxis.CalculateValueMultiplyScale(tmpVelocity));
  378. double tmpAccelaration = (double)(2 * distance) / Math.Pow(_placeTime, 2);
  379. _acceleration = _elevatorAxis.CalculateMultiplyAccelerationRatio(_elevatorAxis.CalculateValueMultiplyScale(tmpAccelaration));
  380. LOG.WriteBackgroundLog(eEvent.INFO_TRANSPORTER, Module, "adjust profile speed");
  381. return true;
  382. }
  383. /// <summary>
  384. /// 更新WaferHolder移动信息
  385. /// </summary>
  386. /// <returns></returns>
  387. private bool WaferHolderTransfer()
  388. {
  389. bool result= WaferHolderManager.Instance.TransferWaferHolder(Module,Module, _cellName);
  390. if (!result)
  391. {
  392. NotifyError(eEvent.ERR_TRANSPORTER, "tranfer waferHolder message failed", 0);
  393. }
  394. else
  395. {
  396. if (Singleton<RouteManager>.Instance.IsAutoRunning)
  397. {
  398. WaferHolderInfo waferHolderInfo = WaferHolderManager.Instance.GetWaferHolder(_cellName);
  399. if (waferHolderInfo != null)
  400. {
  401. string strTime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
  402. waferHolderInfo.SchedulerModules.Add($"{strTime} {Module} => {_cellName}");
  403. }
  404. }
  405. }
  406. return result;
  407. }
  408. /// <summary>
  409. /// 确认WH Present Sensor off
  410. /// </summary>
  411. /// <returns></returns>
  412. private bool ConfirmWSPresentSensorOff()
  413. {
  414. if (_bypassWaferHolderPresent) return true;
  415. bool result= !_transporterCommon.TransporterData.WSHoldPresent;
  416. if(!result)
  417. {
  418. LOG.WriteLog(eEvent.INFO_TRANSPORTER, Module, "confirm WS Present sensor failed");
  419. }
  420. return result;
  421. }
  422. /// <summary>
  423. /// Gabtry是否需要回到
  424. /// </summary>
  425. /// <returns></returns>
  426. private bool NeedGantryBackToPark()
  427. {
  428. switch(_cellName)
  429. {
  430. case "Loader":
  431. case "Prewet":
  432. return true;
  433. default:
  434. return false;
  435. }
  436. }
  437. /// <summary>
  438. /// Gantry 回至Park
  439. /// </summary>
  440. /// <returns></returns>
  441. private bool GantryBackToPark()
  442. {
  443. if (NeedGantryBackToPark())
  444. {
  445. bool result= _gantryAxis.PositionStation("Park", false);
  446. if(!result)
  447. {
  448. NotifyError(eEvent.ERR_TRANSPORTER, "gantry back to park failed",0);
  449. }
  450. return result;
  451. }
  452. else
  453. {
  454. return true;
  455. }
  456. }
  457. /// <summary>
  458. /// 检验Gantry Park移动状态
  459. /// </summary>
  460. /// <returns></returns>
  461. private bool CheckGantryParkPositionStatus()
  462. {
  463. if (NeedGantryBackToPark())
  464. {
  465. return _gantryAxis.Status == RState.End;
  466. }
  467. else
  468. {
  469. return true;
  470. }
  471. }
  472. /// <summary>
  473. /// 检验Gantry Park是否还在运动
  474. /// </summary>
  475. /// <returns></returns>
  476. private bool CheckGantryParkPositionRunStop()
  477. {
  478. if (NeedGantryBackToPark())
  479. {
  480. bool result = _gantryAxis.Status == RState.Failed||_gantryAxis.Status==RState.Timeout;
  481. if(result)
  482. {
  483. NotifyError(eEvent.ERR_TRANSPORTER, "gantry motion failed", 0);
  484. }
  485. return result;
  486. }
  487. else
  488. {
  489. return false;
  490. }
  491. }
  492. /// <summary>
  493. /// 关闭DropBlockLock
  494. /// </summary>
  495. /// <returns></returns>
  496. private bool DropBlockLockoff()
  497. {
  498. if (_transporterCommon.TransporterData.Lock)
  499. {
  500. return _transporterCommon.UnlockOperation("", null);
  501. }
  502. return true;
  503. }
  504. /// <summary>
  505. /// 启动
  506. /// </summary>
  507. /// <param name="objs"></param>
  508. /// <returns></returns>
  509. public RState Start(params object[] objs)
  510. {
  511. _cellName = objs[0].ToString();
  512. _velocity = 0;
  513. _acceleration = 0;
  514. InitializeParameters();
  515. string preConfig = SC.GetConfigPreContent(_cellName);
  516. _bypassWaferHolderPresent = SC.GetValue<bool>("Transporter.BypassWaferHolderPresent");
  517. if (SC.ContainsItem($"{preConfig}.PlaceTimeSeconds"))
  518. {
  519. _placeTime = SC.GetValue<int>($"{preConfig}.PlaceTimeSeconds");
  520. }
  521. if (SC.ContainsItem($"{preConfig}.PlaceDelaySeconds"))
  522. {
  523. _placeDelayTime = SC.GetValue<int>($"{preConfig}.PlaceDelaySeconds");
  524. }
  525. return Runner.Start(Module, $"Pun Down To {_cellName}");
  526. }
  527. /// <summary>
  528. /// 初始化参数
  529. /// </summary>
  530. private void InitializeParameters()
  531. {
  532. _elevatorAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Elevator");
  533. _gantryAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Gantry");
  534. _loaderRotationAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.Rotation");
  535. _facilities = DEVICE.GetDevice<SystemFacilities>("System.Facilities");
  536. _conflictRoutine = new TransporterConflictRoutine(Module);
  537. _transporterCommon = DEVICE.GetDevice<TransporterCommon>($"{Module}.Common");
  538. _otherModule = Module == "Transporter2" ? "Transporter1" : "Transporter2";
  539. _otherElevatorAxis = DEVICE.GetDevice<JetAxisBase>($"{_otherModule}.Elevator");
  540. _loaderCommonDevice = DEVICE.GetDevice<LoaderCommonDevice>($"{ModuleName.Loader1}.Common");
  541. }
  542. /// <summary>
  543. /// 启动校验条件
  544. /// </summary>
  545. /// <returns></returns>
  546. private bool CheckStartPreConfition()
  547. {
  548. //所有轴上电并Homed
  549. bool result = CheckPreCondition();
  550. if(!result)
  551. {
  552. return false;
  553. }
  554. //Loader is Home
  555. if(ModuleHelper.IsInstalled(ModuleName.Loader1))
  556. {
  557. LoaderEntity loaderEntity = Singleton<RouteManager>.Instance.GetModule<LoaderEntity>(ModuleName.Loader1.ToString());
  558. if (loaderEntity != null && !loaderEntity.IsHomed)
  559. {
  560. NotifyError(eEvent.ERR_TRANSPORTER, $"{ModuleName.Loader1} is not homed", -1);
  561. return false;
  562. }
  563. }
  564. //若目标Cell为Loader, 则Loader需在TRNA或TRANB位置且WaferShuttlePresent信号on
  565. if (_cellName == "Loader")
  566. {
  567. double loaderRotationPosition = _loaderRotationAxis.MotionData.MotorPosition;
  568. if (!_loaderRotationAxis.CheckPositionIsInStation(loaderRotationPosition, "TRNPA") &&
  569. !_loaderRotationAxis.CheckPositionIsInStation(loaderRotationPosition, "TRNPB"))
  570. {
  571. NotifyError(eEvent.ERR_TRANSPORTER, $"{ModuleName.Loader1} rotation axis {loaderRotationPosition} is not int TRNPA or TRNPB station", -1);
  572. return false;
  573. }
  574. if (_loaderCommonDevice.CommonData.WaferHolderPresent)
  575. {
  576. NotifyError(eEvent.ERR_TRANSPORTER, $"{ModuleName.Loader1} WaferShuttlePresent is on", -1);
  577. return false;
  578. }
  579. }
  580. //Transporter应有WS信息
  581. if (!WaferHolderManager.Instance.HasWaferHolder(Module))
  582. {
  583. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} does not has wafer Shuttle",-1);
  584. return false;
  585. }
  586. //目标Cell没有WS信息
  587. if (WaferHolderManager.Instance.HasWaferHolder(_cellName))
  588. {
  589. NotifyError(eEvent.ERR_TRANSPORTER, $"Cell {_cellName} already has wafer Shuttle", -1);
  590. return false;
  591. }
  592. //检验Lock
  593. if (!_transporterCommon.TransporterData.Lock)
  594. {
  595. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} Drop block lock is off ", -1);
  596. return false;
  597. }
  598. //检验Wafer shuttle hold present
  599. if (!_bypassWaferHolderPresent && !_transporterCommon.TransporterData.WSHoldPresent)
  600. {
  601. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} Wafer shuttle hold present sensor is off ",-1);
  602. return false;
  603. }
  604. //检验Facilities
  605. //var faciltiesResult = _facilities.CheckCDA();
  606. //if (!faciltiesResult.result)
  607. //{
  608. // NotifyError(eEvent.ERR_TRANSPORTER, faciltiesResult.reason, -1);
  609. // return false;
  610. //}
  611. return true;
  612. }
  613. /// <summary>
  614. /// 重试
  615. /// </summary>
  616. /// <param name="step"></param>
  617. public RState Retry(int step)
  618. {
  619. InitializeParameters();
  620. List<Enum> preStepIds = new List<Enum>();
  621. return Runner.Retry(PutDownStep.CheckPreStatus, preStepIds, Module, "PickUp Moveto Retry");
  622. }
  623. /// <summary>
  624. /// 检验前面Unload完成状态
  625. /// </summary>
  626. /// <returns></returns>
  627. public bool CheckCompleteCondition(int index)
  628. {
  629. TransporterEntity transporterEntity = Singleton<RouteManager>.Instance.GetModule<TransporterEntity>(Module);
  630. if (transporterEntity.WaferHolderInfo != null)
  631. {
  632. NotifyError(eEvent.ERR_TRANSPORTER, $"{Module} has waferholder", index);
  633. return false;
  634. }
  635. if (!WaferHolderManager.Instance.HasWaferHolder(_cellName))
  636. {
  637. NotifyError(eEvent.ERR_TRANSPORTER, $"{_cellName} does not have waferholder", index);
  638. return false;
  639. }
  640. return true;
  641. }
  642. }
  643. }