using Aitex.Core.Common; using Aitex.Core.RT.Log; using Aitex.Core.RT.Routine; using Aitex.Core.Util; using CyberX8_Core; using CyberX8_RT.Devices.EFEM; using CyberX8_RT.Modules.Rinse; 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; namespace CyberX8_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 object[] param; private RobotCycleMoveRoutine _cycleMoveRoutine; private List _sequences; private int _alignerAngle; 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) { string str = objs[0].ToString(); _sequences = new List(); foreach(string item in str.Split('-')) { _sequences.Add((ModuleName)Enum.Parse(typeof(ModuleName), item)); } _cycleTimes=(int)objs[1]; _alignerAngle = (int)objs[2]; _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() { if (!ModuleHelper.IsLoadPort(_sequences[0])) { return; } WaferInfo[] waferInfos = WaferManager.Instance.GetWafers(_sequences[0]); int count = 0; foreach (WaferInfo item in waferInfos) { if (item.IsEmpty) { continue; } _actions.AddRange(GenerateCycle(_sequences[0], item.Slot, _sequences[1], ModuleHelper.IsDummy(_sequences[1]) ? count : 0)); for (int i = 1; i < _sequences.Count; i++) { if (i == 1) { _actions.AddRange(GenerateCycle(_sequences[i], ModuleHelper.IsDummy(_sequences[i]) ? count : 0, _sequences[i + 1], ModuleHelper.IsDummy(_sequences[i + 1]) ? count : 0)); } else if (i == _sequences.Count - 1) { _actions.AddRange(GenerateCycle(_sequences[i], ModuleHelper.IsDummy(_sequences[i]) ? count : 0, _sequences[0], item.Slot)); } if (ModuleHelper.IsDummy(_sequences[i])) { WaferInfo[] dummywaferInfos = WaferManager.Instance.GetWafers(_sequences[i]); if (dummywaferInfos != null) { _dummySlotNumber = dummywaferInfos.Length; } } } count++; if(count >= _dummySlotNumber) { count = 0; } } } private List GenerateCycle(ModuleName source,int sourceSlot,ModuleName destModule,int destSlot) { List actions = new List(); if (source == ModuleName.Aligner1) { EfemCycleAction action = new EfemCycleAction(); action.Action = "Align"; action.Parameter = _alignerAngle; actions.Add(action); } EfemCycleAction pick = new EfemCycleAction(); MoveItem pickMoveItem = new MoveItem(); pickMoveItem.SourceModule = source; pickMoveItem.SourceSlot = sourceSlot; pick.Parameter = pickMoveItem; pick.Action = "Pick"; actions.Add(pick); EfemCycleAction place = new EfemCycleAction(); MoveItem placeMoveItem = new MoveItem(); placeMoveItem.DestinationModule = destModule; placeMoveItem.DestinationSlot = destSlot; 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")) .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; } } }