using Aitex.Core.Common; using Aitex.Core.RT.Device; using Aitex.Core.RT.Log; using Aitex.Core.RT.Routine; using Aitex.Core.Util; using PunkHPX8_Core; using PunkHPX8_RT.Devices.AXIS; using PunkHPX8_RT.Devices.EFEM; using PunkHPX8_RT.Modules.LPs; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Routine; using MECF.Framework.Common.Schedulers; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.Common.Utilities; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using MECF.Framework.Common.CommonData; using System.Text.Json.Serialization; using Newtonsoft.Json; namespace PunkHPX8_RT.Modules.EFEM { public class CycleRobotCycleNewRoutine : ModuleRoutineBase, IRoutine { private enum CycleRobotCycleStep { LoopStart, LoopRunRobotCycle, LoopRunRobotCycleWait, LoopEnd, End } /// /// Cycle次数 /// private int _cycleTimes; /// /// 当前处于第几次Cycle /// private int _currentCycle; private RobotCycleMoveRoutine _cycleMoveRoutine; private List _sequences; private List _actions; private int _dummySlotNumber = 25; //当前cycle中的dummy slot 数量 public CycleRobotCycleNewRoutine(EfemBase efem) : base(ModuleName.EfemRobot) { _cycleMoveRoutine = new RobotCycleMoveRoutine(efem); } public RState Start(params object[] objs) { _currentCycle = 0; string str = objs[0].ToString(); _sequences = JsonConvert.DeserializeObject>(str); if(!CheckRobotCyclePreCondiction(_sequences)) { return RState.Failed; } _cycleTimes=(int)objs[1]; _actions = new List(); GenerateCycleAction(); if (_cycleTimes < 1) { LOG.Write(eEvent.ERR_EFEM_ROBOT, Module, $"Input Robot Cycle Times{_cycleTimes} error"); return RState.Failed; } return Runner.Start(Module, "Start CycleRobotCycleRoutine"); } private void GenerateCycleAction() { ModuleName sequenceModuleName = _sequences[0].ModuleName; WaferInfo[] waferInfos = WaferManager.Instance.GetWafers(sequenceModuleName); foreach (WaferInfo item in waferInfos) { if (item.IsEmpty) { continue; } // generateCycle的参数:源模块,源模块slot,目的模块,目的模块slot if(_sequences.Count == 1) { _actions.AddRange(GenerateCycle(_sequences[0], item.Slot, _sequences[0].ModuleName, 0)); } else { _actions.AddRange(GenerateCycle(_sequences[0], item.Slot, _sequences[1].ModuleName, 0)); } for (int i = 1; i < _sequences.Count; i++) { if (i == _sequences.Count - 1) { _actions.AddRange(GenerateCycle(_sequences[i], 0, _sequences[0].ModuleName, item.Slot)); } //else (i == 1) else { _actions.AddRange(GenerateCycle(_sequences[i], 0, _sequences[i + 1].ModuleName, 0)); } } } } /// /// 返回从哪儿取,放到哪儿的一个EfemCycleAction列表 /// /// /// /// /// /// private List GenerateCycle(RobotCycleParameter sourceParameter,int sourceSlot,ModuleName destModule,int destSlot) { List actions = new List(); if (sourceParameter.ModuleName == ModuleName.Aligner1) { EfemCycleAction action = new EfemCycleAction(); action.Action = "Align"; action.Parameter = sourceParameter.Parameter; actions.Add(action); } EfemCycleAction pick = new EfemCycleAction(); MoveItem pickMoveItem = new MoveItem(); pickMoveItem.SourceModule = sourceParameter.ModuleName; pickMoveItem.SourceSlot = sourceSlot; pickMoveItem.RobotHand = sourceParameter.RobotArm; pickMoveItem.PickRobotFlip = sourceParameter.PickRobotFlip; pick.Parameter = pickMoveItem; pick.Action = "Pick"; actions.Add(pick); EfemCycleAction place = new EfemCycleAction(); MoveItem placeMoveItem = new MoveItem(); placeMoveItem.DestinationModule = destModule; placeMoveItem.DestinationSlot = destSlot; placeMoveItem.RobotHand = sourceParameter.RobotArm; placeMoveItem.PlaceRobotFlip = sourceParameter.PlaceRobotFlip; place.Parameter = placeMoveItem; place.Action = "Place"; actions.Add(place); return actions; } public RState Monitor() { Runner.LoopStart(CycleRobotCycleStep.LoopStart, "Loop StartCycleRobotCycleRoutine", _cycleTimes, NullFun, _delay_1ms) .LoopRun(CycleRobotCycleStep.LoopRunRobotCycle, () => _cycleMoveRoutine.Start(_actions) == RState.Running,_delay_1ms) .LoopRunWithStopStatus(CycleRobotCycleStep.LoopRunRobotCycleWait, () => { return CommonFunction.CheckRoutineEndState(_cycleMoveRoutine); }, () => CheckRoutineStopStatus(_cycleMoveRoutine, "CycleRobotCycleRoutine failed"), 86400000)//24小时 .LoopEnd(CycleRobotCycleStep.LoopEnd, UpdateCycleCount, _delay_1ms) .End(CycleRobotCycleStep.End, AchievedCycleCount, _delay_1ms); return Runner.Status; } private bool CheckRoutineStopStatus(IRoutine routine, string error) { bool result = CommonFunction.CheckRoutineStopState(routine); if (result) { Stop($"{error}"); } return result; } /// /// Abort /// public void Abort() { Runner.Stop("CycleRobotCycleRoutine Abort"); } /// /// 统计完成的Cycle次数 /// /// private bool UpdateCycleCount() { _currentCycle += 1; return true; } /// /// /// /// private bool AchievedCycleCount() { _currentCycle -= 1; return true; } /// /// 获取当前Cycle次数 /// /// public int GetCurrentCycle() { return _currentCycle; } private bool CheckRobotCyclePreCondiction(List lists) { bool result = true; //Robot if (!CheckRobotStatus()) { return false; } //LP if(lists.FindIndex(O=>O.ModuleName.ToString()==ModuleName.LP1.ToString())!=-1) { if (!CheckLoadPortStatus(ModuleName.LP1)) { return false; }; } else if (lists.FindIndex(O => O.ModuleName.ToString() == ModuleName.LP2.ToString()) != -1) { if (!CheckLoadPortStatus(ModuleName.LP2)) { return false; }; } return result; } //检查robot状态 private bool CheckRobotStatus() { bool result = true; if (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 0)) { Stop($"Efem robot arm already has a wafer, cannot do the RobotCycle action"); result = false; } return result; } //检查loadport状态 private bool CheckLoadPortStatus(ModuleName loadpoartName) { bool result = true; if (ModuleHelper.IsInstalled(loadpoartName)) { Loadport loadPort = GetLoadPort(loadpoartName); if (loadPort == null) { Stop($"{loadpoartName} is null"); return false; } WaferInfo[] waferInfos = WaferManager.Instance.GetWafers(loadpoartName); if (waferInfos.Length < 1) { Stop($"there is no wafer in {loadpoartName}"); return false; } } else { Stop($"{loadpoartName} is not installed"); return false; } return result; } private Loadport GetLoadPort(ModuleName station) { LoadPortModule loadPortModule = Singleton.Instance.EFEM.GetLoadportModule(station - ModuleName.LP1); return loadPortModule.LPDevice; } //Dummy状态判断 private bool CheckDummyStatus(ModuleName dummyName) { bool result = true; if (!ModuleHelper.IsInstalled(dummyName)) { Stop($"{dummyName} is not installed"); return false; } //若dummy存在wafer,需要人工处理 DummyDevice dummyDevice = Singleton.Instance.EFEM.GetDummyDevice(dummyName - ModuleName.Dummy1); if (dummyDevice != null) { if (!dummyDevice.HasCassette) { Stop($"{dummyName} dose not have cassette"); return false; } WaferInfo[] waferInfos = WaferManager.Instance.GetWafers(dummyName); if (waferInfos.Length > 0) { foreach (var item in waferInfos) { if (item != null && !item.IsEmpty) { Stop($"There are wafers inside the {dummyName},cannot do the RobotCycle action"); return false; } } } } return result; } //检查puf private bool CheckPufStatus(ModuleName pufName) { bool result = true; if (!ModuleHelper.IsInstalled(pufName)) { Stop($"{pufName} is not install"); return false; } JetAxisBase puf1RotationAxis = DEVICE.GetDevice($"{ModuleName.PUF1}.Rotation"); if (puf1RotationAxis == null) { Stop("Puf1 Rotation Axis is null"); return false; } double puf1RotationPosition = puf1RotationAxis.MotionData.MotorPosition; if ( !puf1RotationAxis.CheckPositionIsInStation(puf1RotationPosition, "Robot")) { Stop($"PUF1 Rotation {puf1RotationPosition} is not in Robot"); return false; } return result; } //检查srd private bool CheckSrdStatus(ModuleName SrdName) { bool result = true; if (!ModuleHelper.IsInstalled(SrdName)) { Stop($"{SrdName} is not install"); return false; } return result; } } }