TransporterPickDownToRoutine.cs 32 KB

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