using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Sorter.Common; using CyberX8_RT.Devices; using MECF.Framework.Common.Routine; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using CyberX8_Core; using Aitex.Core.RT.Log; using Aitex.Core.Util; using MECF.Framework.Common.Schedulers; using System.Collections.Generic; using CyberX8_RT.Devices.EFEM; using CyberX8_RT.Modules.SRD; using CyberX8_RT.Modules.PUF; using CyberX8_RT.Devices.AXIS; using Aitex.Core.RT.Device; using MECF.Framework.Common.Utilities; using System; using CyberX8_RT.Modules.LPs; namespace CyberX8_RT.Modules.EFEM { class EfemPlaceRoutine : RoutineBase, IRoutine { private enum PlaceStep { WaitModuleReady, Placing1, Placing2, End, } private int _moveTimeout = 20 * 1000; private ModuleName _targetModule = ModuleName.System; int _targetSlot; string _targetPufSlot; int _targetSlot2; Hand _hand; Hand _hand2; EfemBase _efem; bool _bDoublePlace = false; private SRDEntity _srdModule; private PUFEntity _pufModule; private Queue _moveItems; public EfemPlaceRoutine(EfemBase efem) : base(ModuleName.EfemRobot.ToString()) { _efem = efem; } public RState Start(params object[] objs) { _bDoublePlace = false; _moveItems = (Queue)objs[0]; _targetModule = _moveItems.Peek().DestinationModule; _targetSlot = _moveItems.Peek().DestinationSlot; _hand = _moveItems.Peek().RobotHand; if (!CheckPreCondition()) { return RState.Failed; } _moveTimeout = SC.GetValue($"EFEM.MotionTimeout") * 1000; return Runner.Start(Module, $"Place to {_targetModule}"); } private Loadport GetLoadPort(ModuleName station) { LoadPortModule loadPortModule = Singleton.Instance.EFEM.GetLoadportModule(station - ModuleName.LP1); return loadPortModule.LPDevice; } private bool CheckPreCondition() { //LoadPort状态判断 if (ModuleHelper.IsLoadPort(_targetModule) && ModuleHelper.IsInstalled(_targetModule)) { Loadport loadPort = GetLoadPort(_targetModule); if (loadPort == null) { return false; } if (!loadPort.IsLoaded) { NotifyError(eEvent.ERR_EFEM_ROBOT, $"LoadPort not load, cannot do the pick action", -1); return false; } } if (ModuleHelper.IsSRD(_targetModule) && ModuleHelper.IsInstalled(_targetModule)) { _srdModule = Singleton.Instance.GetModule(_targetModule.ToString()); if (!_srdModule.IsHomed) { NotifyError(eEvent.ERR_EFEM_ROBOT, $"{_targetModule} is not homed, please home it first",-1); return false; } //判断arm是否在home位置上 JetAxisBase jetAxisBase = DEVICE.GetDevice($"{_targetModule}.Arm"); double position = jetAxisBase.MotionData.MotorPosition; bool result = jetAxisBase.CheckPositionIsInStation(position, "Home"); if (!result) { NotifyError(eEvent.ERR_EFEM_ROBOT, $"{_targetModule} armaxis {position} is not in homed place",-1); return false; } if (_srdModule.IsSrdDoorClosed) { NotifyError(eEvent.ERR_EFEM_ROBOT, $"{_targetModule} door closed, can not place",-1); return false; } } if (ModuleHelper.IsPUF(_targetModule) && ModuleHelper.IsInstalled(_targetModule)) { _pufModule = Singleton.Instance.GetModule(_targetModule.ToString()); if (!_pufModule.IsHomed) { NotifyError(eEvent.ERR_EFEM_ROBOT, $"{_targetModule} is not homed, please home it first",-1); return false; } if (!_pufModule.IsInRobotStation) { NotifyError(eEvent.ERR_EFEM_ROBOT, $"{_targetModule} not in robot station, cannot do the place action",-1); return false; } } if (WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, (int)_hand)) { NotifyError(eEvent.ERR_EFEM_ROBOT, $"Efem robot arm{_hand} already has no wafer, cannot do the place action",-1); return false; } if (WaferManager.Instance.CheckHasWafer(_targetModule, _targetSlot)) { if (ModuleHelper.IsPUF(_targetModule)) { _targetPufSlot = _targetSlot == 0 ? "SideA" : "SideB"; NotifyError(eEvent.ERR_EFEM_ROBOT, $"The target: {_targetModule}.{_targetPufSlot} has a wafer, cannot do the place action",-1); } else { NotifyError(eEvent.ERR_EFEM_ROBOT, $"The target: {_targetModule}.{_targetSlot + 1} has a wafer, cannot do the place action",-1); } return false; } if (_moveItems.Count >= 2) { if (!ModuleHelper.IsLoadPort(_targetModule)) { NotifyError(eEvent.ERR_EFEM_ROBOT,$"Wrong double place command, target is not loadport",-1); return false; } _hand2 = _hand != Hand.Blade1 ? Hand.Blade1 : Hand.Blade2; if (WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, (int)_hand2)) { NotifyError(eEvent.ERR_EFEM_ROBOT,$"Efem robot arm{_hand2} has no wafer, cannot do the double place action",-1); return false; } _targetSlot2 = _moveItems.ToArray()[1].DestinationSlot; if (WaferManager.Instance.CheckHasWafer(_targetModule, _targetSlot2)) { NotifyError(eEvent.ERR_EFEM_ROBOT, $"The target: {_targetModule}.{_targetSlot2 + 1} has a wafer, cannot do the double pick action",-1); return false; } } return true; } public RState Monitor() { if (_bDoublePlace) { Runner.Wait(PlaceStep.WaitModuleReady, WaitModuleReady) .Run(PlaceStep.Placing1, Place1, Place1Done, _moveTimeout) .Run(PlaceStep.Placing2, Place2, Place2Done, _moveTimeout) .End(PlaceStep.End, ActionDone); } else { Runner.Wait(PlaceStep.WaitModuleReady, WaitModuleReady) .Run(PlaceStep.Placing1, Place1, Place1Done, _moveTimeout) .End(PlaceStep.End, ActionDone); } return Runner.Status; } public void Abort() { _efem.Halt(); } private bool WaitModuleReady() { return _efem.Status == RState.End; } private bool Place1() { return _efem.Place(_targetModule, _targetSlot, _hand); } private bool Place1Done() { if (_efem.Status == RState.End) { WaferManager.Instance.WaferMoved(ModuleName.EfemRobot, (int)_hand, _targetModule, _targetSlot); return true; } else if (_efem.Status == RState.Failed) { NotifyError(eEvent.ERR_EFEM_ROBOT, $"Efem robot place failed: {_efem.Status}",-1); return true; } return false; } private bool Place2() { return _efem.Place(_targetModule, _targetSlot2, _hand2); } private bool Place2Done() { if (_efem.Status == RState.End) { WaferManager.Instance.WaferMoved(ModuleName.EfemRobot, (int)_hand2, _targetModule, _targetSlot2); return true; } else if (_efem.Status == RState.Failed) { NotifyError(eEvent.ERR_EFEM_ROBOT, $"Efem robot place failed: {_efem.Status}",-1); return true; } return false; } private bool ActionDone() { return true; } /// /// 重试 /// /// public RState Retry(int step) { if (!CheckPreCondition()) { return RState.Failed; } _efem.Reset(); List preStepIds = new List(); AddPreSteps(PlaceStep.Placing1, preStepIds); return Runner.Retry(PlaceStep.Placing1, preStepIds, Module, "Place Retry"); } /// /// 忽略前 /// /// /// private void AddPreSteps(PlaceStep step, List preStepIds) { for (int i = 0; i < (int)step; i++) { preStepIds.Add((PlaceStep)i); } } /// /// 检验前面完成状态 /// /// public bool CheckCompleteCondition(int index) { if (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, (int)_hand)) { NotifyError(eEvent.ERR_EFEM_ROBOT, $"Efem robot arm{_hand} has no wafer", -1); return false; } if (WaferManager.Instance.CheckNoWafer(_targetModule, _targetSlot)) { NotifyError(eEvent.ERR_EFEM_ROBOT, $"{_targetModule} Slot{_targetSlot} has no wafer", -1); return false; } return true; } } }