TransporterPickDownToRoutine.cs 34 KB

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