TransporterPickDownToRoutine.cs 31 KB

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