Browse Source

update scheduler

chenkui 3 days ago
parent
commit
3eca239970

+ 40 - 0
PunkHPX8_RT/Modules/ModuleMatcherManager.cs

@@ -0,0 +1,40 @@
+using Aitex.Core.Util;
+using MECF.Framework.Common.Equipment;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PunkHPX8_RT.Modules
+{
+    public class ModuleMatcherManager : Singleton<ModuleMatcherManager>
+    {
+        #region 常量
+        private Dictionary<string, string> _matcher =new Dictionary<string, string>
+        {
+            { ModuleName.PlatingCell1.ToString(),ModuleName.PlatingCell2.ToString()},
+            { ModuleName.PlatingCell2.ToString(),ModuleName.PlatingCell1.ToString()},
+            { ModuleName.PlatingCell3.ToString(),ModuleName.PlatingCell4.ToString()},
+            { ModuleName.PlatingCell4.ToString(),ModuleName.PlatingCell3.ToString()},
+            { ModuleName.VPW1.ToString(),ModuleName.VPW2.ToString()},
+            { ModuleName.VPW2.ToString(),ModuleName.VPW1.ToString()},
+        };
+        #endregion
+        /// <summary>
+        /// 获取配对模块
+        /// </summary>
+        /// <param name="module"></param>
+        /// <returns></returns>
+        public string GetMatcherByModule(string module)
+        {
+            if (_matcher.ContainsKey(module)){
+                return _matcher[module];
+            }
+            else
+            {
+                return "";
+            }
+        }
+    }
+}

+ 4 - 5
PunkHPX8_RT/Modules/PlatingCell/PlatingCellEntity.cs

@@ -153,10 +153,11 @@ namespace PunkHPX8_RT.Modules.PlatingCell
         /// 是否为产品模式
         /// </summary>
         public bool IsProduction { get { return _persistentValue != null && _persistentValue.RecipeOperatingMode == PRODUCTION; } }
+
         /// <summary>
-        /// 状态机状态
+        /// 当前状态机状态
         /// </summary>
-        public PlatingCellState State { get { return (PlatingCellState)fsm.State; } }
+        public int State { get { return fsm.State; } }
         /// <summary>
         /// 是否初始化完成
         /// </summary>
@@ -218,6 +219,7 @@ namespace PunkHPX8_RT.Modules.PlatingCell
         {
             _initializeRoutine = new PlatingCellInitializeRoutine(Module.ToString());
             _platingCellCRRoutine = new PlatingCellCCRRoutine(Module.ToString());
+            _runRecipeRoutine=new PlatingCellRunRecipeRoutine(Module.ToString());   
         }
         /// <summary>
         /// 初始化DATA
@@ -434,9 +436,6 @@ namespace PunkHPX8_RT.Modules.PlatingCell
         private bool CycleManualProcess(object[] param)
         {
             bool result = _runRecipeRoutine.Start(param) == RState.Running;
-            if (result)
-            {
-            }
             return result;
         }
         /// <summary>

+ 1 - 1
PunkHPX8_RT/Modules/PlatingCell/PlatingCellRunRecipeRoutine.cs

@@ -38,7 +38,7 @@ namespace PunkHPX8_RT.Modules.PlatingCell
         {
             Runner.Delay(RunRecipeStep.Delay, 5000)
                 .End(RunRecipeStep.End, NullFun);
-            return RState.Init;
+            return Runner.Status;
         }
         /// <summary>
         /// 启动

+ 2 - 0
PunkHPX8_RT/PunkHPX8_RT.csproj

@@ -296,6 +296,7 @@
     <Compile Include="Modules\LPs\LoadPortMapRoutine.cs" />
     <Compile Include="Modules\LPs\LoadPortUnDockRoutine.cs" />
     <Compile Include="Devices\Reservoir\CAPumpOnRoutine.cs" />
+    <Compile Include="Modules\ModuleMatcherManager.cs" />
     <Compile Include="Modules\PlatingCell\PlatingCellCCRRoutine.cs" />
     <Compile Include="Modules\PlatingCell\PlatingCellEntity.cs" />
     <Compile Include="Modules\PlatingCell\PlatingCellInitializeRoutine.cs" />
@@ -351,6 +352,7 @@
     <Compile Include="Modules\VpwMain\VPWMsg.cs" />
     <Compile Include="Schedulers\EfemRobot\RobotMoveHelper.cs" />
     <Compile Include="Schedulers\EfemRobot\SchedulerRobot.cs" />
+    <Compile Include="Schedulers\PlatingCell\SchedulerPlatingCell.cs" />
     <Compile Include="Schedulers\SchedulerDryerTimeManager.cs" />
     <Compile Include="Schedulers\SchedulerPlatingCellTimeManager.cs" />
     <Compile Include="Schedulers\SchedulerModuleEndTime.cs" />

+ 3 - 10
PunkHPX8_RT/Schedulers/EfemRobot/RobotMoveHelper.cs

@@ -113,17 +113,10 @@ namespace PunkHPX8_RT.Schedulers.EfemRobot
             }
             else if (_currentOperation == RobotOperation.PickWait)
             {
-                if (_efemEntity.IsIdle && WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 0)
+                if (_efemEntity.IsIdle && WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, (int)_moveItem.RobotHand)
                     && WaferManager.Instance.CheckNoWafer(_moveItem.SourceModule, _moveItem.SourceSlot))
                 {
-                    if (_moveItem.DestinationType == ModuleType.PUF)
-                    {
-                        _currentOperation = RobotOperation.CheckLoaderPrepare;
-                    }
-                    else
-                    {
-                        _currentOperation = RobotOperation.Place;
-                    }
+                    _currentOperation = RobotOperation.Place;
                 }
             }
             else if (_currentOperation == RobotOperation.Place)
@@ -139,7 +132,7 @@ namespace PunkHPX8_RT.Schedulers.EfemRobot
             }
             else if (_currentOperation == RobotOperation.PlaceWait)
             {
-                if (_efemEntity.IsIdle && WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 0)
+                if (_efemEntity.IsIdle && WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, (int)_moveItem.RobotHand)
                     && WaferManager.Instance.CheckHasWafer(_moveItem.DestinationModule, _moveItem.DestinationSlot))
                 {
                     _state = RState.End;

+ 16 - 0
PunkHPX8_RT/Schedulers/EfemRobot/SchedulerRobot.cs

@@ -15,6 +15,8 @@ using MECF.Framework.Common.SubstrateTrackings;
 using PunkHPX8_RT.Modules.SRD;
 using PunkHPX8_RT.Modules.VpwMain;
 using PunkHPX8_RT.Modules.VpwCell;
+using MECF.Framework.Common.RecipeCenter;
+using PunkHPX8_RT.Modules.PlatingCell;
 
 namespace PunkHPX8_RT.Schedulers.EfemRobot
 {
@@ -210,6 +212,11 @@ namespace PunkHPX8_RT.Schedulers.EfemRobot
         private bool UpdateUnkownTargetModule(List<SchedulerSequence> schedulerSequences, MoveItem moveItem, int sequenceIndex)
         {
             SchedulerSequence currentSchedulerSequence= schedulerSequences[sequenceIndex];
+            if (sequenceIndex >= schedulerSequences.Count - 1)
+            {
+                return false;
+            }
+            SchedulerSequence nextSequence=schedulerSequences[sequenceIndex+1];
             ModuleName moduleName = ModuleName.Unknown;
             if (moveItem.DestinationType == ModuleType.SRD)
             {
@@ -228,6 +235,15 @@ namespace PunkHPX8_RT.Schedulers.EfemRobot
                 }
 
             }
+            else if (moveItem.DestinationType == ModuleType.PlatingCell)
+            {
+                DepRecipe depRecipe = (DepRecipe)nextSequence.Recipe;
+                List<PlatingCellEntity> platingCellEntities= SchedulerSequenceManager.Instance.GetAvaiblePlatingCellList(depRecipe.Chemistry, nextSequence.SequenceType, nextSequence.WaferSize, true);
+                if (platingCellEntities.Count > 0)
+                {
+                    moduleName = platingCellEntities[0].Module;
+                }
+            }
             else
             {
                 return false;

+ 140 - 0
PunkHPX8_RT/Schedulers/PlatingCell/SchedulerPlatingCell.cs

@@ -0,0 +1,140 @@
+using Aitex.Common.Util;
+using Aitex.Core.Common;
+using Aitex.Core.RT.Log;
+using Aitex.Core.Util;
+using PunkHPX8_Core;
+using PunkHPX8_RT.Modules;
+using PunkHPX8_RT.Modules.SRD;
+using MECF.Framework.Common.Equipment;
+using MECF.Framework.Common.RecipeCenter;
+using MECF.Framework.Common.SubstrateTrackings;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using PunkHPX8_RT.Modules.VpwMain;
+using PunkHPX8_RT.Modules.VpwCell;
+using PunkHPX8_RT.Modules.PlatingCell;
+using static PunkHPX8_RT.Modules.PlatingCell.PlatingCellEntity;
+
+namespace PunkHPX8_RT.Schedulers.Srd
+{
+    public class SchedulerPlatingCell : SchedulerModule
+    {
+        #region 内部变量
+        private PlatingCellEntity _entity;
+        private bool _isStartRunRecipe = false;
+        #endregion
+
+        #region 属性
+        /// <summary>
+        /// 是否空闲
+        /// </summary>
+        public override bool IsIdle
+        {
+            get { return _state == RState.End; }
+        }
+        /// <summary>
+        /// 是否错误
+        /// </summary>
+        public override bool IsError
+        {
+            get { return _state == RState.Failed || _state == RState.Timeout; }
+        }
+        #endregion
+        /// <summary>
+        /// 构造函数
+        /// </summary>
+        /// <param name="moduleName"></param>
+        public SchedulerPlatingCell(ModuleName moduleName) : base(moduleName.ToString())
+        {
+            _entity = Singleton<RouteManager>.Instance.GetModule<PlatingCellEntity>(moduleName.ToString());
+        }
+        /// <summary>
+        /// 执行
+        /// </summary>
+        /// <param name="parameter"></param>
+        /// <returns></returns>
+        public override bool RunProcess(object recipe, object parameter, List<SchedulerSyncModuleMessage> syncModuleMessages)
+        {
+            if (!(recipe is DepRecipe))
+            {
+                _state = RState.Failed;
+                LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module.ToString(), "recipe is invalid");
+                return false;
+            }
+            _isStartRunRecipe = false;
+            DepRecipe depRecipe = (DepRecipe)recipe;
+            bool result = _entity.CheckToPostMessage<PlatingCellState, PlatingCellMsg>(eEvent.INFO_PLATINGCELL, Module.ToString(), (int)PlatingCellMsg.RunRecipe, depRecipe, 1);
+            if (result)
+            {
+                _state = RState.Running;
+            }
+            return result;
+        }
+        /// <summary>
+        /// 监控执行
+        /// </summary>
+        /// <returns></returns>
+        public override bool MonitorProcess(SchedulerSequence schedulerSequence,bool hasMatchWafer)
+        {
+            if (!_isStartRunRecipe)
+            {
+                _isStartRunRecipe = _entity.State == (int)PlatingCellState.RunReciping;
+            }
+            if (_isStartRunRecipe && _entity.IsIdle)
+            {
+                _state = RState.End;
+                _isStartRunRecipe = false;
+            }
+            return true;
+        }
+        /// <summary>
+        /// 检验前置条件
+        /// </summary>
+        /// <param name="sequenceIndex"></param>
+        /// <param name="parameter"></param>
+        /// <returns></returns>
+        public override bool CheckPrecondition(List<SchedulerSequence> schedulerSequences, int sequenceIndex, object parameter, string materialId,ref string reason)
+        {
+            if (_state == RState.Running)
+            {
+                reason = "scheduler module is already running";
+                return false;
+            }
+            if (_entity.IsBusy)
+            {
+                reason = $"{_entity.Module} is busy";
+                return false;
+            }
+
+            if(WaferManager.Instance.CheckNoWafer(Module,0))
+            {
+                reason = $"{_entity.Module} has no wafer";
+                return false;
+            }
+
+            string matcher = ModuleMatcherManager.Instance.GetMatcherByModule(Module.ToString());
+            if (string.IsNullOrEmpty(matcher))
+            {
+                reason = $"{Module} has no matcher";
+                return false;
+            }
+
+            PlatingCellEntity matcherEntity = Singleton<RouteManager>.Instance.GetModule<PlatingCellEntity>(matcher);
+            if (matcherEntity == null)
+            {
+                reason = $"{matcher} has no matcher";
+                return false;
+            }
+            if (WaferManager.Instance.CheckNoWafer(matcher, 0))
+            {
+                reason = $"{matcher} has no wafer";
+                return false;
+            }
+
+            return true;
+        }
+    }
+}

+ 1 - 12
PunkHPX8_RT/Schedulers/SchedulerManager.cs

@@ -29,17 +29,6 @@ namespace PunkHPX8_RT.Schedulers
         /// 模块字典
         /// </summary>
         private Dictionary<ModuleName, SchedulerModule> _scheduleModuleDic = new Dictionary<ModuleName, SchedulerModule>();
-        /// <summary>
-        /// 是否启用QDR时间轴
-        /// </summary>
-        private bool _isQdrCheckConflict = false;
-        #endregion
-
-        #region 属性
-        /// <summary>
-        /// 是否启用QDR时间轴
-        /// </summary>
-        public bool IsQdrCheckConflict { get { return _isQdrCheckConflict; } }
         #endregion
 
         #region 初始化
@@ -48,11 +37,11 @@ namespace PunkHPX8_RT.Schedulers
         /// </summary>
         public void Initialize()
         {
-            _isQdrCheckConflict = SC.GetValue<bool>("Scheduler.IsQdrCheckConflict");
             AddScheduleModule(ModuleType.EfemRobot, new SchedulerRobot(ModuleName.EfemRobot));
             AddScheduleModule(ModuleType.Aligner, new SchedulerAligner(ModuleName.Aligner1));
             InitializeSchedulerModules(SrdItemManager.Instance.InstalledModules,ModuleType.SRD,typeof(SchedulerSrd));
             InitializeSchedulerModules(VpwCellItemManager.Instance.InstalledModules, ModuleType.VPW, typeof(SchedulerVPW));
+            InitializeSchedulerModules(PlatingCellItemManager.Instance.InstalledModules, ModuleType.PlatingCell, typeof(SchedulerPlatingCell));
         }
         /// <summary>
         /// 重置

+ 9 - 8
PunkHPX8_RT/Schedulers/SchedulerSequenceManager.cs

@@ -54,7 +54,7 @@ namespace PunkHPX8_RT.Schedulers
                 Hand.Blade1,Flip.Upper,Flip.Upper);
             SchedulerSequence efemRobotSequence = CreateEfemRobotSequence(moveItem, null, sequenceRecipe.SubstrateSize, ref index);
             schedulerSequences.Add(efemRobotSequence);
-            SchedulerSequence alignerSequence = CreateAlignerSequence(sequenceRecipe, ref index);
+            SchedulerSequence alignerSequence = CreateAlignerSequence(sequenceRecipe,sequenceRecipe.SubstrateSize, ref index);
             schedulerSequences.Add(alignerSequence);
             MoveItem alignerToMoveItem = new MoveItem(ModuleName.Aligner1, 0, vpw, 0,Hand.Blade1, Flip.Upper, Flip.Upper);
             SchedulerSequence alignerRobotSequence = CreateEfemRobotSequence(alignerToMoveItem, null, sequenceRecipe.SubstrateSize, ref index);
@@ -100,7 +100,7 @@ namespace PunkHPX8_RT.Schedulers
                     lastToSrdItem.PlaceRobotFlip = Flip.Upper;
                     SchedulerSequence lastToSrdSequence = CreateEfemRobotSequence(lastToSrdItem, null,sequenceRecipe.SubstrateSize, ref index);
                     schedulerSequences.Add(lastToSrdSequence);
-                    SchedulerSequence srdSequence = CreateSRDSequence(srdRecipe, ref index);
+                    SchedulerSequence srdSequence = CreateSRDSequence(srdRecipe,sequenceRecipe.SubstrateSize, ref index);
                     schedulerSequences.Add(srdSequence);
                     //SRD完成后回至LoadPort
                     MoveItem srdToLoadPortItem = new MoveItem();
@@ -153,7 +153,7 @@ namespace PunkHPX8_RT.Schedulers
                 Hand.Blade1, Flip.Upper, Flip.Upper);
             SchedulerSequence efemRobotSequence = CreateEfemRobotSequence(moveItem, null, sequenceRecipe.SubstrateSize, ref index);
             schedulerSequences.Add(efemRobotSequence);
-            SchedulerSequence alignerSequence = CreateAlignerSequence(sequenceRecipe, ref index);
+            SchedulerSequence alignerSequence = CreateAlignerSequence(sequenceRecipe,sequenceRecipe.SubstrateSize, ref index);
             schedulerSequences.Add(alignerSequence);
             MoveItem alignerToMoveItem = new MoveItem(ModuleName.Aligner1, 0, vpw, 0, Hand.Blade1, Flip.Upper, Flip.Upper);
             SchedulerSequence alignerRobotSequence = CreateEfemRobotSequence(alignerToMoveItem, null, sequenceRecipe.SubstrateSize, ref index);
@@ -360,7 +360,7 @@ namespace PunkHPX8_RT.Schedulers
         /// </summary>
         /// <param name="index"></param>
         /// <returns></returns>
-        private SchedulerSequence CreateAlignerSequence(SequenceRecipe recipe,ref int index) 
+        private SchedulerSequence CreateAlignerSequence(SequenceRecipe recipe,int waferSize,ref int index) 
         {
             SchedulerSequence sequence = new SchedulerSequence();
             sequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(ModuleName.Aligner1);
@@ -371,7 +371,7 @@ namespace PunkHPX8_RT.Schedulers
             sequence.ModuleType = ModuleType.Aligner;
             sequence.Parameters = null;
             sequence.MaterialType = MaterialType.Wafer;
-            sequence.WaferSize = sequence.WaferSize;
+            sequence.WaferSize = waferSize;
             index++;
             return sequence;
         }
@@ -380,7 +380,7 @@ namespace PunkHPX8_RT.Schedulers
         /// </summary>
         /// <param name="index"></param>
         /// <returns></returns>
-        private SchedulerSequence CreateSRDSequence(SrdRecipe recipe,ref int index)
+        private SchedulerSequence CreateSRDSequence(SrdRecipe recipe,int waferSize,ref int index)
         {
             SchedulerSequence sequence = new SchedulerSequence();
             sequence.SequenceIndex = index;
@@ -388,6 +388,7 @@ namespace PunkHPX8_RT.Schedulers
             sequence.Recipe = recipe;
             sequence.ModuleType = ModuleType.SRD;
             sequence.MaterialType = MaterialType.Wafer;
+            sequence.WaferSize= waferSize;
             index++;
             return sequence;
         }
@@ -525,7 +526,7 @@ namespace PunkHPX8_RT.Schedulers
                 }
                 foreach (PlatingCellItem subItem in reservoirItem.PlatingCells)
                 {
-                    PlatingCellEntity entity = Singleton<RouteManager>.Instance.GetModule<PlatingCellEntity>($"PlatingCell{subItem.PlatingCellID}");
+                    PlatingCellEntity entity = Singleton<RouteManager>.Instance.GetModule<PlatingCellEntity>(subItem.ModuleName);
                     if (!CheckAvaibleModule(entity, ModuleType.PlatingCell, sequenceType))
                     {
                         continue;
@@ -534,7 +535,7 @@ namespace PunkHPX8_RT.Schedulers
                     {
                         continue;
                     }
-                    if (!isEmpty || (isEmpty && entity.WaferInfo == null))
+                    if (!isEmpty || (isEmpty && entity.WaferInfo.IsEmpty))
                     {
                         metals.Add(entity);
                     }