Browse Source

update scheduler

chenkui 3 weeks ago
parent
commit
7849fa3cd1

+ 1 - 1
CyberX8_MainPages/Views/JobOperationView.xaml

@@ -163,7 +163,7 @@
                                 <TextBlock Text="{Binding LP3WaferCount}" FontSize="15" FontFamily="Arial"/>
                             </StackPanel>
 
-                            <customControls:PathButton Grid.Row="1" IsEnabled="{Binding IsLP3Unable}" Content="Load" Width="90" Height="33" Command="{Binding LPMapCommand}"   CommandParameter="LP3"/>
+                            <customControls:PathButton Grid.Row="1" IsEnabled="{Binding IsLP3Unable}" Content="Map" Width="90" Height="33" Command="{Binding LPMapCommand}"   CommandParameter="LP3"/>
                         </Grid>
                     </Border>
 

+ 0 - 6
CyberX8_RT/Devices/Loader/LoaderUnloadRoutine.cs

@@ -465,12 +465,6 @@ namespace CyberX8_RT.Devices.Loader
             LoaderSideData sideData = _sideDevice.SideData;
             LoaderCommonData commonData = _loaderCommonDevice.CommonData;
 
-            //Bernoulli Bladder(WS Bladder on)
-            if (!sideData.BernoulliBladder)
-            {
-                NotifyError(eEvent.ERR_LOADER, "Bernoulli Bladder is off", -1);
-                return false;
-            }
             //Bernoulli N2(BernoulliN2 off)
             if (sideData.BernoulliN2)
             {

+ 9 - 2
CyberX8_RT/Dispatch/WaferHolderTask.cs

@@ -124,7 +124,7 @@ namespace CyberX8_RT.Dispatch
         /// </summary>
         /// <param name="waferHolderInfo"></param>
         /// <param name="schedulerSequences"></param>
-        public WaferHolderTask(WaferHolderInfo waferHolderInfo,ProcessJobInfo processJobInfo,List<SchedulerSequence> schedulerSequences)
+        public WaferHolderTask(WaferHolderInfo waferHolderInfo,ProcessJobInfo processJobInfo)
         {
             ID=Guid.NewGuid().ToString();
             WaferHolderInfo=waferHolderInfo;
@@ -142,12 +142,19 @@ namespace CyberX8_RT.Dispatch
                 AnalyseProductionProcessJobInfo();
             }
             ProcessJobInfo=processJobInfo;
-            _schedulerSequences = schedulerSequences;
             State = WaferHolderTaskState.Created;
             _puf1Entity = Singleton<RouteManager>.Instance.GetModule<PUFEntity>(ModuleName.PUF1.ToString());
             _puf2Entity = Singleton<RouteManager>.Instance.GetModule<PUFEntity>(ModuleName.PUF2.ToString());
         }
         /// <summary>
+        /// 初始化调度步骤
+        /// </summary>
+        /// <param name="schedulers"></param>
+        public void InitialSchedulers(List<SchedulerSequence> schedulers)
+        {
+            _schedulerSequences = schedulers;
+        }
+        /// <summary>
         /// 分析生产片的ProcessJob信息
         /// </summary>
         private void AnalyseProductionProcessJobInfo()

+ 55 - 21
CyberX8_RT/Dispatch/WaferHolderTaskManager.cs

@@ -59,19 +59,39 @@ namespace CyberX8_RT.Dispatch
                     {
                         waferHolderInfo.OriginalBuffer = waferHolderInfo.CurrentLocation;
                     }
-                    List<SchedulerSequence> sequences = SchedulerSequenceManager.Instance.AnalyWaferHolderAllSchedulerSequence(waferHolderInfo, jobs[0].SequenceRecipe);
-                    WaferHolderTask waferHolderTask = new WaferHolderTask(waferHolderInfo, jobs[0],sequences);
-                    waferHolderTask.OnTaskComplete += WaferHolderTask_OnTaskComplete;
-                    _waferHolderTaskDic.TryAdd(waferHolderTask.ID,waferHolderTask);
+                    WaferHolderTask waferHolderTask = new WaferHolderTask(waferHolderInfo, jobs[0]);
+                    waferHolderTask.OnTaskComplete += WaferHolderTask_OnTaskComplete;                   
+                    WaferInfo waferInfo = GetPreLoaderHasWafer();
+                    int waferTaskCount = 0;
+                    if (waferInfo==null)
+                    {
+                        waferTaskCount= WaferTaskManager.Instance.CreateWaferTask(jobs, waferHolderInfo, waferHolderTask);
+                    }
+                    else
+                    {
+                        string waferHasMatch = WaferTaskManager.Instance.CheckWaferHasMatch(waferInfo.WaferID);
+                        if(string.IsNullOrEmpty(waferHasMatch))
+                        {
+                            waferTaskCount = 1;
+                        }
+                        else
+                        {
+                            waferTaskCount = 2;
+                        }
+                    }
+                    if(waferTaskCount == 0)
+                    {
+                        return true;
+                    }
+                    _waferHolderTaskDic.TryAdd(waferHolderTask.ID, waferHolderTask);
                     lock (_waferHolderTaskObject)
                     {
                         _waferHolderTaskList.Add(waferHolderTask);
                     }
                     LOG.WriteLog(eEvent.EV_SEQUENCE, "Scheduler", $"Create wafer Shuttle {waferHolderInfo.Id} task");
-                    if (GetPreLoaderHasWafer()==null)
-                    {
-                        WaferTaskManager.Instance.CreateWaferTask(jobs, waferHolderInfo, waferHolderTask);
-                    }
+                    List<SchedulerSequence> sequences = SchedulerSequenceManager.Instance.AnalyWaferHolderAllSchedulerSequence(waferHolderInfo, jobs[0].SequenceRecipe,waferTaskCount);
+                    waferHolderTask.InitialSchedulers(sequences);
+
                     return true;
                 }
             }
@@ -143,12 +163,6 @@ namespace CyberX8_RT.Dispatch
                 waferInfo = WaferManager.Instance.GetWafer(ModuleName.PUF1, 1);
                 return CheckWaferTaskForward(waferInfo);
             }
-            //PUF2 B面
-            if (WaferManager.Instance.CheckHasWafer(ModuleName.PUF2, 1))
-            {
-                waferInfo = WaferManager.Instance.GetWafer(ModuleName.PUF2, 1);
-                return CheckWaferTaskForward(waferInfo);
-            }
             return waferInfo;
         }
         /// <summary>
@@ -191,19 +205,39 @@ namespace CyberX8_RT.Dispatch
                         List<WaferInfo> waferInfos = DummyWaferManager.Instance.LoadDummyWafersByWaferHolder(waferHolderInfo);
                         if (waferInfos.Count != 0)
                         {
-                            List<SchedulerSequence> sequences = SchedulerSequenceManager.Instance.AnalyseDummyWaferHolderAllSchedulerSequence(waferHolderInfo);
-                            WaferHolderTask waferHolderTask = new WaferHolderTask(waferHolderInfo, null, sequences);
+                            WaferHolderTask waferHolderTask = new WaferHolderTask(waferHolderInfo, null);
                             waferHolderTask.OnTaskComplete += WaferHolderTask_OnTaskComplete;
+                            int waferTaskCount = 0;
+                            WaferInfo waferInfo = GetPreLoaderHasWafer();
+                            if (waferInfo==null)
+                            {
+                                waferTaskCount= WaferTaskManager.Instance.CreateDummyWaferTask(waferInfos, waferHolderInfo.SequenceRecipe, waferHolderTask);
+                            }
+                            else
+                            {
+                                string waferHasMatch = WaferTaskManager.Instance.CheckWaferHasMatch(waferInfo.WaferID);
+                                if (string.IsNullOrEmpty(waferHasMatch))
+                                {
+                                    waferTaskCount = 1;
+                                }
+                                else
+                                {
+                                    waferTaskCount = 2;
+                                }
+                            }
+                            if (waferTaskCount == 0)
+                            {
+                                break;
+                            }
+
                             _waferHolderTaskDic.TryAdd(waferHolderTask.ID, waferHolderTask);
                             lock (_waferHolderTaskObject)
                             {
-                                _waferHolderTaskList.Add(waferHolderTask);    
+                                _waferHolderTaskList.Add(waferHolderTask);
                             }
                             LOG.WriteLog(eEvent.EV_SEQUENCE, "Scheduler", $"Create dummy wafer Shuttle {waferHolderInfo.Id} task");
-                            if (GetPreLoaderHasWafer()==null)
-                            {
-                                WaferTaskManager.Instance.CreateDummyWaferTask(waferInfos, waferHolderInfo.SequenceRecipe, waferHolderTask);
-                            }
+                            List<SchedulerSequence> sequences = SchedulerSequenceManager.Instance.AnalyseDummyWaferHolderAllSchedulerSequence(waferHolderInfo,waferTaskCount);
+                            waferHolderTask.InitialSchedulers(sequences);
                             break;
                         }
                     }

+ 26 - 2
CyberX8_RT/Dispatch/WaferTaskManager.cs

@@ -121,7 +121,7 @@ namespace CyberX8_RT.Dispatch
         /// <summary>
         /// 创建Wafer任务
         /// </summary>
-        public void CreateWaferTask(List<ProcessJobInfo> processJobInfos, WaferHolderInfo waferHolderInfo,WaferHolderTask waferHolderTask)
+        public int CreateWaferTask(List<ProcessJobInfo> processJobInfos, WaferHolderInfo waferHolderInfo,WaferHolderTask waferHolderTask)
         {
             int count = 0;
             string mateWaferTask = "";
@@ -209,17 +209,20 @@ namespace CyberX8_RT.Dispatch
                         _waferTaskMatchDic[dummyWafers[0].WaferID] = waferInfo.WaferID;
                         _waferWaferHolderTaskDic[waferInfo.WaferID] = waferHolderTask;
                         _waferWaferHolderTaskDic[dummyWafers[0].WaferID] = waferHolderTask;
+                        return 2;
                     }
                     else
                     {
                         CreateWaferTaskSchedulerSequence(waferInfo, pufModuleName, waferHolderInfo, waferInfo.ProcessJob.SequenceRecipe, "",waferSide);
                         _waferWaferHolderTaskDic[waferInfo.WaferID] = waferHolderTask;
+                        return 1;
                     }
                 }
                 else
                 {
                     CreateWaferTaskSchedulerSequence(waferInfo, pufModuleName, waferHolderInfo, waferInfo.ProcessJob.SequenceRecipe, "",waferSide);
                     _waferWaferHolderTaskDic[waferInfo.WaferID] = waferHolderTask;
+                    return 1;
                 }
             }
             else if (wafers.Count >= 2)
@@ -242,7 +245,9 @@ namespace CyberX8_RT.Dispatch
                 _waferTaskMatchDic[wafers[1].WaferID] = wafers[0].WaferID;
                 _waferWaferHolderTaskDic[wafers[0].WaferID] = waferHolderTask;
                 _waferWaferHolderTaskDic[wafers[1].WaferID] = waferHolderTask;
+                return 2;
             }
+            return 0;
         }
         /// <summary>
         /// 检验WaferHolder是否存在两片生产片
@@ -313,15 +318,17 @@ namespace CyberX8_RT.Dispatch
         /// 创建DummyWaferTask
         /// </summary>
         /// <param name="waferInfos"></param>
-        public void CreateDummyWaferTask(List<WaferInfo> waferInfos,SequenceRecipe sequenceRecipe,WaferHolderTask waferHolderTask)
+        public int CreateDummyWaferTask(List<WaferInfo> waferInfos,SequenceRecipe sequenceRecipe,WaferHolderTask waferHolderTask)
         {
             string mateWaferTask = "";
+            int waferCount = 0;
             for (int i = 0; i < waferInfos.Count; i++)
             {
                 WaferInfo waferInfo = waferInfos[i];
                 int orginalSlot = waferInfo.OriginSlot;
                 ModuleName pufModuleName = ModuleName.PUF1;
                 string side = orginalSlot == 0 ? SIDE_A : SIDE_B;
+                waferCount = i;
                 if (!Contains(waferInfo.WaferID))
                 {
                     if (i == 0)
@@ -340,6 +347,7 @@ namespace CyberX8_RT.Dispatch
                     }
                 }
             }
+            return waferCount + 1;
         }
         /// <summary>
         /// 创建Dummy Wafer Task 调度工序
@@ -480,5 +488,21 @@ namespace CyberX8_RT.Dispatch
             }
             return result;
         }
+        /// <summary>
+        /// 检验Wafer存在匹配的wafer任务(wafer是单片任务还是双片任务)
+        /// </summary>
+        /// <param name="waferId"></param>
+        /// <returns></returns>
+        public string CheckWaferHasMatch(string waferId)
+        {
+            if (_waferTaskMatchDic.ContainsKey(waferId))
+            {
+                return _waferTaskMatchDic[waferId];
+            }
+            else
+            {
+                return "";
+            }
+        }
     }
 }

+ 2 - 2
CyberX8_RT/Modules/Loader/LoaderEntity.cs

@@ -539,7 +539,7 @@ namespace CyberX8_RT.Modules.Loader
         /// </summary>
         /// <param name="param"></param>
         /// <returns></returns>
-        private bool UnloadSide(object param)
+        private bool UnloadSide(object[] param)
         {
             bool result= _unloadSideRoutine.Start(param) == RState.Running;
             if(result)
@@ -663,7 +663,7 @@ namespace CyberX8_RT.Modules.Loader
         /// </summary>
         /// <param name="param"></param>
         /// <returns></returns>
-        private bool LoadSide(object param)
+        private bool LoadSide(object[] param)
         {
             bool result= _loadSideRoutine.Start(param) == RState.Running;
             if(result)

+ 19 - 5
CyberX8_RT/Modules/Loader/LoaderLoadSideRoutine.cs

@@ -16,6 +16,8 @@ using MECF.Framework.Common.CommonData.Loader;
 using CyberX8_RT.Modules.Dryer;
 using MECF.Framework.Common.Persistent.Temperature;
 using MECF.Framework.Common.WaferHolder;
+using Aitex.Core.Common;
+using Aitex.Core.RT.SCCore;
 
 namespace CyberX8_RT.Modules.Loader
 {
@@ -37,6 +39,7 @@ namespace CyberX8_RT.Modules.Loader
         private const string SIDE_B = "SideB";
         private const int LOTTRACK_TIME = 1000;
         #endregion
+
         #region 内部变量
         private JetAxisBase _rotationAxis;
         private LoaderLoadRoutine _sideLoadRoutine;
@@ -71,6 +74,14 @@ namespace CyberX8_RT.Modules.Loader
         /// 
         /// </summary>
         private string _side = "";
+        /// <summary>
+        /// WaferSize
+        /// </summary>
+        private int _waferSize;
+        /// <summary>
+        /// load是否完成
+        /// </summary>
+        private bool _loadComplete = false;
         #endregion
 
         #region 属性
@@ -112,11 +123,12 @@ namespace CyberX8_RT.Modules.Loader
             LottrackRecord();
             Runner.Run(LoadStep.SideLoad, () => StartLoadRoutine(_sideLoadRoutine,_isSideLoaded), _delay_1ms)
                 .WaitWithStopCondition(LoadStep.SideAllLoadWait, CheckLoadAllRoutineEndStatus,CheckLoadAllRoutineStopStatus)
-                .Run(LoadStep.LeakTest, StartFlowTest, _delay_1ms)
-                .WaitWithStopCondition(LoadStep.LeakTestWait, CheckFlowTestEndStatus, CheckFlowTestStopStatus)
-                .Run(LoadStep.RotationGoToTRNPA,RotationGotoTransporterA,_delay_1s)
-                .WaitWithStopCondition(LoadStep.RotationGoToTRNPAWait,CheckRotationPositionStatus,CheckRotationPositionRunStop)
-                .Run(LoadStep.UnclampWaferHolder,WaferHolderClampOffAction,_delay_1ms)
+                //临时注释,待模拟器定好后恢复 2025-03-11 17:14
+                //.Run(LoadStep.LeakTest, StartFlowTest, _delay_1ms)
+                //.WaitWithStopCondition(LoadStep.LeakTestWait, CheckFlowTestEndStatus, CheckFlowTestStopStatus)
+                .RunIf(LoadStep.RotationGoToTRNPA,_loadComplete,RotationGotoTransporterA,_delay_1s)
+                .WaitWithStopConditionIf(LoadStep.RotationGoToTRNPAWait,_loadComplete, CheckRotationPositionStatus,CheckRotationPositionRunStop)
+                .RunIf(LoadStep.UnclampWaferHolder,_loadComplete, WaferHolderClampOffAction,_delay_1ms)
                 .End(LoadStep.End, UpdateWaferHolderUse, _delay_1ms);
             return Runner.Status;
         }
@@ -291,6 +303,8 @@ namespace CyberX8_RT.Modules.Loader
         public RState Start(params object[] objs)
         {
             _side = objs[0].ToString();
+            _loadComplete=(bool)objs[1];
+            _waferSize = SC.GetValue<int>($"Loader1.{_side}WaferSize");
             InitializeParameters();
             _loaderCommon = DEVICE.GetDevice<LoaderCommonDevice>($"{Module}.Common");
             _loaderSide = DEVICE.GetDevice<LoaderSideDevice>($"{Module}.{_side}");

+ 7 - 1
CyberX8_RT/Modules/Loader/LoaderUnloadSideRoutine.cs

@@ -12,6 +12,7 @@ using MECF.Framework.Common.Utilities;
 using MECF.Framework.Common.CommonData.Loader;
 using MECF.Framework.Common.CommonData;
 using Aitex.Core.RT.DataCenter;
+using Aitex.Core.RT.SCCore;
 
 namespace CyberX8_RT.Modules.Loader
 {
@@ -54,6 +55,10 @@ namespace CyberX8_RT.Modules.Loader
         /// Loader LotTrackData
         /// </summary>
         private List<LoaderLotTrackData> _datas = new List<LoaderLotTrackData>();
+        /// <summary>
+        /// WaferSize
+        /// </summary>
+        private int _waferSize;
         #endregion
 
         #region 属性
@@ -96,7 +101,7 @@ namespace CyberX8_RT.Modules.Loader
         /// <returns></returns>
         private bool RotationGotoLOADA()
         {
-            bool result = _rotationAxis.PositionStation("LOADA", false);
+            bool result = _rotationAxis.PositionStation($"LOADA{_waferSize}", false);
             if (!result)
             {
                 NotifyError(eEvent.ERR_LOADER, "rotation start goto LOADA failed", 0);
@@ -206,6 +211,7 @@ namespace CyberX8_RT.Modules.Loader
         public RState Start(params object[] objs)
         {
             _side = objs[0].ToString();
+            _waferSize = SC.GetValue<int>($"Loader1.{_side}WaferSize");
             InitializeParameters();
             _loaderCommon = DEVICE.GetDevice<LoaderCommonDevice>($"{Module}.Common");
             _loaderSide = DEVICE.GetDevice<LoaderSideDevice>($"{Module}.{_side}");

+ 19 - 23
CyberX8_RT/Modules/ModuleHomeAllRoutine.cs

@@ -20,12 +20,16 @@ namespace CyberX8_RT.Modules
         private enum HomeStep
         {
             DualPufHome,
+            DelayPuf,
             DualPufHomeWait,
             LoaderHome,
+            LoaderDelay,
             LoaderHomeWait,
             LoaderTransporterHome,
+            LoaderTransporterDelay,
             LoaderTransporterHomeWait,
             ProcessTransporterHome,
+            ProcessTransporterDelay,
             ProcessTransporterHomeWait,
             End
         }
@@ -58,12 +62,16 @@ namespace CyberX8_RT.Modules
         public RState Monitor()
         {
             Runner.Run(HomeStep.DualPufHome, HomeDualPuf, _delay_1ms)
+                .Delay(HomeStep.DelayPuf, _delay_1s)
                 .WaitWithStopCondition(HomeStep.DualPufHomeWait, CheckHomeDualPufStatus, CheckHomeDualPufStopStatus)
                 .Run(HomeStep.LoaderHome, HomeLoaderEntity, _delay_1ms)
+                .Delay(HomeStep.LoaderDelay, _delay_1s)
                 .WaitWithStopCondition(HomeStep.LoaderHomeWait, CheckHomeLoaderStatus, CheckHomeLoaderStopStatus)
                 .Run(HomeStep.LoaderTransporterHome, HomeLoaderTransporterEntity, _delay_1ms)
+                .Delay(HomeStep.LoaderTransporterDelay, _delay_1s)
                 .WaitWithStopCondition(HomeStep.LoaderTransporterHomeWait, CheckHomeLoaderTransporterStatus, CheckHomeLoaderTransporterStopStatus)
                 .Run(HomeStep.ProcessTransporterHome, HomeProcessTransporterEntity, _delay_1ms)
+                .Delay(HomeStep.ProcessTransporterDelay, _delay_1s)
                 .WaitWithStopCondition(HomeStep.ProcessTransporterHomeWait, CheckHomeProcessTransporterStatus, CheckHomeProcessTransporterStopStatus)
                 .End(HomeStep.End, NullFun, _delay_1ms);
             return Runner.Status;
@@ -74,16 +82,9 @@ namespace CyberX8_RT.Modules
         /// <returns></returns>
         private bool HomeDualPuf()
         {
-            if(ModuleHelper.IsInstalled(ModuleName.PUF1))
-            {
-                if(_puf1Entity.Invoke("HomeAll")==(int)FSM_MSG.ALARM)
-                {
-                    return false;
-                }
-            }
-            if(ModuleHelper.IsInstalled(ModuleName.PUF2))
+            if (ModuleHelper.IsInstalled(ModuleName.PUF1))
             {
-                if(_puf2Entity.Invoke("HomeAll")==(int)FSM_MSG.ALARM)
+                if (_puf1Entity.Invoke("HomeAll") == (int)FSM_MSG.ALARM)
                 {
                     return false;
                 }
@@ -97,16 +98,11 @@ namespace CyberX8_RT.Modules
         private bool CheckHomeDualPufStatus()
         {
             bool puf1Result = true;
-            if(ModuleHelper.IsInstalled(ModuleName.PUF1))
+            if (ModuleHelper.IsInstalled(ModuleName.PUF1))
             {
-                puf1Result= _puf1Entity.IsIdle;
+                puf1Result = _puf1Entity.IsIdle;
             }
-            bool puf2Result = true;
-            if(ModuleHelper.IsInstalled(ModuleName.PUF2))
-            { 
-                puf2Result= _puf2Entity.IsIdle;
-            }
-            return puf1Result && puf2Result;
+            return puf1Result;
         }
 
         /// <summary>
@@ -118,12 +114,12 @@ namespace CyberX8_RT.Modules
             bool puf1Result = false;
             if (ModuleHelper.IsInstalled(ModuleName.PUF1))
             {
-                puf1Result = _puf1Entity.State == (int)PUFSTATE.Error;
+                puf1Result = _puf1Entity.State != (int)PUFSTATE.Idle && _puf1Entity.State != (int)PUFSTATE.Homing; ;
             }
             bool puf2Result = false;
             if (ModuleHelper.IsInstalled(ModuleName.PUF2))
             {
-                puf2Result = _puf2Entity.State == (int)PUFSTATE.Error;
+                puf2Result = _puf2Entity.State != (int)PUFSTATE.Idle && _puf2Entity.State != (int)PUFSTATE.Homing;
             }
             return puf1Result && puf2Result;
         }
@@ -166,7 +162,7 @@ namespace CyberX8_RT.Modules
             bool result = false;
             if (ModuleHelper.IsInstalled(ModuleName.Loader1))
             {
-                result = _loaderEntity.State == (int)LOADERSTATE.Error;
+                result = _loaderEntity.State != (int)LOADERSTATE.Idle && _loaderEntity.State != (int)LOADERSTATE.Homing;
             }
             return result;
         }
@@ -211,7 +207,7 @@ namespace CyberX8_RT.Modules
             bool result = false;
             if (ModuleHelper.IsInstalled(ModuleName.Transporter2))
             {
-                result = _loaderTransporterEntity.State == (int)TransporterState.Error;
+                result = _loaderTransporterEntity.State != (int)TransporterState.Idle && _loaderTransporterEntity.State != (int)TransporterState.Homing;
             }
             return result;
         }
@@ -255,7 +251,7 @@ namespace CyberX8_RT.Modules
             bool result = false;
             if (ModuleHelper.IsInstalled(ModuleName.Transporter1))
             {
-                result = _processTransporterEntity.State == (int)TransporterState.Error;
+                result = _processTransporterEntity.State != (int)TransporterState.Idle && _processTransporterEntity.State != (int)TransporterState.Homing;
             }
             return result;
         }
@@ -267,7 +263,7 @@ namespace CyberX8_RT.Modules
             _loaderEntity = Singleton<RouteManager>.Instance.GetModule<LoaderEntity>(ModuleName.Loader1.ToString());
             _loaderTransporterEntity = Singleton<RouteManager>.Instance.GetModule<TransporterEntity>(ModuleName.Transporter2.ToString());
             _processTransporterEntity = Singleton<RouteManager>.Instance.GetModule<TransporterEntity>(ModuleName.Transporter1.ToString());
-            return Runner.Start("System","System Home All");
+            return Runner.Start("System", "System Home All");
         }
     }
 }

+ 30 - 26
CyberX8_RT/Modules/PUF/PufSwapRoutine.cs

@@ -50,17 +50,19 @@ namespace CyberX8_RT.Modules.PUF
         private const string CURRENT_STATION_LIST = "CurrentStationList";
         private const string WAFER_PRESENT = "WaferPresent";
         private const string SIDE_A = "SideA";
+        private const string SIDE_B = "SideB";
         #endregion
 
         #region 内部变量
         private LoaderEntity _loaderEntity;
         private JetAxisBase _flipAxis;
         private JetAxisBase _rotationAxis;
-        private LoaderSideDevice _loaderSide;
+        private LoaderSideDevice _loaderSideDevice;
         private PufVacuum _vacuum;
         private PufDistanceSensor _distanceSensor;
         private PufPlaceToLoaderRoutine _placeToLoaderRoutine;
         private PufChuckRoutine _chuckRoutine;
+        private string _loaderSide;
         #endregion
 
         /// <summary>
@@ -96,7 +98,7 @@ namespace CyberX8_RT.Modules.PUF
                 .Run(SwapStep.SideAVacuumOn, SideAVacuumOn, CheckSideAWaferPresent, 5000)
                 .Wait(SwapStep.StickDistanceCheck, CheckStickDistanceStatus, 1000)
                 .Run(SwapStep.ChuckIn, () => { return _chuckRoutine.Start(false) == RState.Running; }, NullFun, 100)
-                .WaitWithStopCondition(SwapStep.CheckChuckOut, () => CommonFunction.CheckRoutineEndState(_chuckRoutine),
+                .WaitWithStopCondition(SwapStep.CheckChuckIn, () => CommonFunction.CheckRoutineEndState(_chuckRoutine),
                     () => { return CheckChuckRoutineStopStatus(false, 1); })
                 .Run(SwapStep.RotationFlip, () => { return AxisGotoPosition(_rotationAxis,"Flip",1); }, _delay_1ms)
                 .WaitWithStopCondition(SwapStep.WaitRotationFlip, () => { return _rotationAxis.Status == RState.End; }, 
@@ -136,7 +138,7 @@ namespace CyberX8_RT.Modules.PUF
                 if(loaderEntity!=null)
                 {
                     WaferHolderInfo waferHolder = loaderEntity.WaferHolderInfo;
-                    if(_loaderSide.Name==SIDE_A)
+                    if(_loaderSideDevice.Name==SIDE_A)
                     {
                         if (WaferManager.Instance.CheckHasWafer(ModuleName.Loader1, 0))
                         {
@@ -266,7 +268,6 @@ namespace CyberX8_RT.Modules.PUF
             _rotationAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Rotation");
             _vacuum = DEVICE.GetDevice<PufVacuum>($"{Module}.Vacuum");
             _distanceSensor = DEVICE.GetDevice<PufDistanceSensor>($"{Module}.DistanceSensor");
-            GetLoaderSide();
         }
         /// <summary>
         /// 检验条件
@@ -280,20 +281,28 @@ namespace CyberX8_RT.Modules.PUF
             {
                 JetAxisBase loaderRotationAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.Rotation");
                 double loaderRotationPosition = loaderRotationAxis.MotionData.MotorPosition;
-                if (!loaderRotationAxis.CheckPositionIsInStation(loaderRotationPosition, "LOADA"))
+                if (!loaderRotationAxis.CheckPositionInStationIgnoreWaferSize(loaderRotationPosition, "LOAD"))
                 {
-                    NotifyError(eEvent.ERR_PUF, $"Loader Rotation {loaderRotationPosition} is not in LOADA",-1);
+                    NotifyError(eEvent.ERR_PUF, $"Loader Rotation {loaderRotationPosition} is not in LOAD",-1);
                     return false;
                 }
+                bool isLoadA = loaderRotationAxis.CheckPositionInStationIgnoreWaferSize(loaderRotationPosition, "LOADA");
+                bool isLoadB = loaderRotationAxis.CheckPositionInStationIgnoreWaferSize(loaderRotationPosition, "LOADB");
+                _loaderSide = isLoadA ? SIDE_A : SIDE_B;
+                GetLoaderSide();
+                string side = isLoadA ? "A" : "B";
                 if (Module == ModuleName.PUF1.ToString())
                 {
                     //Loader1.SwingA 在Open
-                    JetAxisBase loaderShuttleAAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.ShuttleA");
-                    double loaderShuttleAPosition = loaderShuttleAAxis.MotionData.MotorPosition;
-                    if (!loaderShuttleAAxis.CheckPositionIsInStation(loaderShuttleAPosition, "OPEN"))
+                    JetAxisBase loaderShuttleAAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.Shuttle{side}");
+                    if (loaderShuttleAAxis != null)
                     {
-                        NotifyError(eEvent.ERR_PUF, $"Loader ShuttleA {loaderShuttleAPosition} is not in OPEN",-1);
-                        return false;
+                        double loaderShuttleAPosition = loaderShuttleAAxis.MotionData.MotorPosition;
+                        if (!loaderShuttleAAxis.CheckPositionInStationIgnoreWaferSize(loaderShuttleAPosition, "OUT"))
+                        {
+                            NotifyError(eEvent.ERR_PUF, $"Loader Shuttle{side} {loaderShuttleAPosition} is not in OUT", -1);
+                            return false;
+                        }
                     }
                     //Loader1.TiltA 在HORI
                     JetAxisBase loaderTiltAAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.TiltA");
@@ -307,44 +316,39 @@ namespace CyberX8_RT.Modules.PUF
 
                 //Loader Handle Wafer状态确认
                 // Lip Seal Vacuum "ON"
-                if (!_loaderSide.SideData.CRSVacuum)
+                if (!_loaderSideDevice.SideData.CRSVacuum)
                 {
                     NotifyError(eEvent.ERR_PUF, "Loader1 LS Vacuum is off",-1);
                     return false;
                 }
                 //Bernoulli Bladder "ON",Retracted Green Light
-                if (!_loaderSide.SideData.BernoulliBladder)
+                if (!_loaderSideDevice.SideData.BernoulliBladder)
                 {
                     NotifyError(eEvent.ERR_PUF, "Loader1 Bernoulli Bladder is off",-1);
                     return false;
                 }
-                if (_loaderSide.SideData.BernoulliExtended)
+                if (_loaderSideDevice.SideData.BernoulliExtended)
                 {
                     NotifyError(eEvent.ERR_PUF, "Loader1 Bernoulli Retracted is off",-1);
                     return false;
                 }
                 //其他SideA/B均为OFF
-                if (_loaderSide.SideData.BernoulliN2)
+                if (_loaderSideDevice.SideData.BernoulliN2)
                 {
                     NotifyError(eEvent.ERR_PUF, "Loader1 Bernoulli N2 is on",-1);
                     return false;
                 }
-                if (!_loaderSide.SideData.DoorUnlock)
-                {
-                    NotifyError(eEvent.ERR_PUF, "Loader1 Door is Locked",-1);
-                    return false;
-                }
                 //if (_loaderSide.SideData.WHBladder)
                 //{
                 //    NotifyError(eEvent.ERR_PUF,, "Loader1 WS Bladder is on");
                 //    return false;
                 //}
-                if (_loaderSide.SideData.TransBladder)
+                if (_loaderSideDevice.SideData.TransBladder)
                 {
                     NotifyError(eEvent.ERR_PUF, "Loader1 Translate Bladder is on",-1);
                     return false;
                 }
-                if (_loaderSide.SideData.TransHigh)
+                if (_loaderSideDevice.SideData.TransHigh)
                 {
                     NotifyError(eEvent.ERR_PUF, "Loader1 Translate High Pre is on",-1);
                     return false;
@@ -364,7 +368,7 @@ namespace CyberX8_RT.Modules.PUF
                 return false;
             }
             //A面
-            if (_loaderSide.Name == SIDE_A)
+            if (_loaderSideDevice.Name == SIDE_A)
             {
                 if (WaferManager.Instance.CheckNoWafer(ModuleName.Loader1, 0))
                 {
@@ -388,13 +392,13 @@ namespace CyberX8_RT.Modules.PUF
         /// </summary>
         private void GetLoaderSide()
         {
-            if (Module == ModuleName.PUF1.ToString())
+            if (_loaderSide==SIDE_A)
             {
-                _loaderSide = DEVICE.GetDevice<LoaderSideDevice>($"{ModuleName.Loader1}.SideA");
+                _loaderSideDevice = DEVICE.GetDevice<LoaderSideDevice>($"{ModuleName.Loader1}.SideA");
             }
             else
             {
-                _loaderSide = DEVICE.GetDevice<LoaderSideDevice>($"{ModuleName.Loader1}.SideB");
+                _loaderSideDevice = DEVICE.GetDevice<LoaderSideDevice>($"{ModuleName.Loader1}.SideB");
             }
         }
 

+ 47 - 20
CyberX8_RT/Schedulers/Loader/SchedulerLoader.cs

@@ -24,13 +24,14 @@ namespace CyberX8_RT.Schedulers.Loader
         private enum SchedulerStep
         {
             WaitLoad,
-            Loading,
+            LoadingFirst,
+            LoadingSecond
         }
         #region 内部变量
         private LoaderEntity _loaderEntity;
         private PUFEntity _puf1Entity;
-        private PUFEntity _puf2Entity;
         private SchedulerStep _currentStep;
+        private int _currentWaferIndex = 0;
         #endregion
 
         #region 属性
@@ -52,7 +53,6 @@ namespace CyberX8_RT.Schedulers.Loader
         {
             _loaderEntity = Singleton<RouteManager>.Instance.GetModule<LoaderEntity>(module.ToString());
             _puf1Entity = Singleton<RouteManager>.Instance.GetModule<PUFEntity>(ModuleName.PUF1.ToString());
-            _puf2Entity = Singleton<RouteManager>.Instance.GetModule<PUFEntity>(ModuleName.PUF2.ToString());
         }
 
         /// <summary>
@@ -64,6 +64,7 @@ namespace CyberX8_RT.Schedulers.Loader
         {
             _state = RState.Running;
             _currentStep = SchedulerStep.WaitLoad;
+            _currentWaferIndex = 0;
             return true;
         }
         /// <summary>
@@ -72,44 +73,70 @@ namespace CyberX8_RT.Schedulers.Loader
         /// <returns></returns>
         public override bool MonitorProcess(SchedulerSequence schedulerSequence, bool hasMatchWafer)
         {
+            int waferTaskCount =(int)schedulerSequence.Parameters;
+            bool loadComplete = waferTaskCount == _currentWaferIndex;
             if (_currentStep == SchedulerStep.WaitLoad)
             {
                 if (_loaderEntity.State != (int)LOADERSTATE.WaitForLoad)
                 {
                     return false;
                 }
-                if (_puf1Entity.State == (int)PUFSTATE.AferSwapParkStation||(_puf1Entity.IsIdle && _puf1Entity.IsBackToParkStation))
+                bool result = ExecuteLoadSide(loadComplete);
+                if (result)
                 {
-                    JetAxisBase tiltAAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.TiltA");
-                    JetAxisBase tiltBAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.TiltB");
-                    double tiltAPosition = tiltAAxis.MotionData.MotorPosition;
-                    double tiltBPosition= tiltBAxis.MotionData.MotorPosition;
-                    bool tiltAHori = tiltAAxis.CheckPositionIsInStation(tiltAPosition, "HORI");
-                    bool tiltBHori = tiltBAxis.CheckPositionIsInStation(tiltBPosition, "HORI");
-                    string side = tiltAHori ? "SideA" : (tiltBHori ? "SideB" : "");
-                    if (string.IsNullOrEmpty(side))
+                    _currentStep = SchedulerStep.LoadingFirst;
+                }
+            }
+            else if (_currentStep == SchedulerStep.LoadingFirst)
+            {
+                if (_loaderEntity.IsIdle)
+                {
+                    if (waferTaskCount == 1)
                     {
-                        return false;
+                        _state = RState.End;
                     }
-                    bool result = _loaderEntity.CheckToPostMessage<LOADERSTATE, LoaderMSG>(eEvent.WARN_LOADER, Module.ToString(),
-                    (int)LoaderMSG.LoadSide,side);
-                    if (result)
+                    else
                     {
-                        _currentStep = SchedulerStep.Loading;
+                        bool result = ExecuteLoadSide(true);
+                        if (result)
+                        {
+                            _currentStep = SchedulerStep.LoadingSecond;
+                        }
                     }
                 }
             }
-            if(_currentStep==SchedulerStep.Loading)
+            else if (_currentStep == SchedulerStep.LoadingSecond)
             {
-                if(_loaderEntity.IsIdle)
+                if (_loaderEntity.IsIdle)
                 {
                     _state = RState.End;
                 }
             }
-
             return true;
         }
 
+        private bool ExecuteLoadSide(bool loadComplete)
+        {
+            if (_puf1Entity.State == (int)PUFSTATE.AferSwapParkStation || (_puf1Entity.IsIdle && _puf1Entity.IsBackToParkStation))
+            {
+                JetAxisBase tiltAAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.TiltA");
+                JetAxisBase tiltBAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.TiltB");
+                double tiltAPosition = tiltAAxis.MotionData.MotorPosition;
+                double tiltBPosition = tiltBAxis.MotionData.MotorPosition;
+                bool tiltAHori = tiltAAxis.CheckPositionIsInStation(tiltAPosition, "HORI");
+                bool tiltBHori = tiltBAxis.CheckPositionIsInStation(tiltBPosition, "HORI");
+                string side = tiltAHori ? "SideA" : (tiltBHori ? "SideB" : "");
+                if (string.IsNullOrEmpty(side))
+                {
+                    return false;
+                }
+                bool result = _loaderEntity.CheckToPostMessage<LOADERSTATE, LoaderMSG>(eEvent.WARN_LOADER, Module.ToString(),
+                (int)LoaderMSG.LoadSide, side, loadComplete);
+                return result;
+            }
+            return false;
+        } 
+
         /// <summary>
         /// 检验前置条件
         /// </summary>

+ 7 - 31
CyberX8_RT/Schedulers/Puf/SchedulerPuf.cs

@@ -267,39 +267,15 @@ namespace CyberX8_RT.Schedulers.Puf
         /// </summary>
         private void PostPufEntityGotoRobotForPick()
         {
-            if (_pufEntity.Module == ModuleName.PUF2)
+            if (_pufEntity.State == (int)PUFSTATE.AferSwapParkStation)
             {
-                if (_pufEntity.State == (int)PUFSTATE.AferSwapParkStation)
-                {
-                    bool result = _pufEntity.CheckToPostMessage<PUFSTATE, PUFMSG>(eEvent.ERR_PUF, Module.ToString(),
-                        (int)PUFMSG.ReadyForRobotPick);
-                    if (result)
-                    {
-                        NotifyWaferTaskSchedulerLoaderComplete();
-                        _currentOperation = OperationStep.GotoRobotForPick;
-                        LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is GotoRobotForPick");
-                    }
-                }
-            }
-            else
-            {
-                if (_pufEntity.State == (int)PUFSTATE.AferSwapParkStation)
+                bool result = _pufEntity.CheckToPostMessage<PUFSTATE, PUFMSG>(eEvent.ERR_PUF, Module.ToString(),
+                    (int)PUFMSG.ReadyForRobotPick);
+                if (result)
                 {
-                    JetAxisBase loaderRotationAxis = DEVICE.GetDevice<JetAxisBase>($"{ModuleName.Loader1}.Rotation");
-                    if (loaderRotationAxis != null && loaderRotationAxis.CheckPositionIsInStation(loaderRotationAxis.MotionData.MotorPosition, "TRNPA"))
-                    {
-                        if (_loaderEntity.State == (int)LOADERSTATE.Loading || _loaderEntity.IsIdle)
-                        {
-                            bool result = _pufEntity.CheckToPostMessage<PUFSTATE, PUFMSG>(eEvent.ERR_PUF, Module.ToString(),
-                        (int)PUFMSG.ReadyForRobotPick);
-                            if (result)
-                            {
-                                NotifyWaferTaskSchedulerLoaderComplete();
-                                _currentOperation = OperationStep.GotoRobotForPick;
-                                LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is GotoRobotForPick");
-                            }
-                        }
-                    }
+                    NotifyWaferTaskSchedulerLoaderComplete();
+                    _currentOperation = OperationStep.GotoRobotForPick;
+                    LOG.WriteLog(eEvent.INFO_PUF, Module.ToString(), "Current Operation is GotoRobotForPick");
                 }
             }
         }

+ 6 - 5
CyberX8_RT/Schedulers/SchedulerSequenceManager.cs

@@ -137,7 +137,7 @@ namespace CyberX8_RT.Schedulers
         /// <param name="waferHolderInfo"></param>
         /// <param name="sequenceRecipe"></param>
         /// <returns></returns>
-        public List<SchedulerSequence> AnalyWaferHolderAllSchedulerSequence(WaferHolderInfo waferHolderInfo, SequenceRecipe sequenceRecipe)
+        public List<SchedulerSequence> AnalyWaferHolderAllSchedulerSequence(WaferHolderInfo waferHolderInfo, SequenceRecipe sequenceRecipe,int waferCount)
         {
             int index = 0;
             List<SchedulerSequence> schedulerSequences = new List<SchedulerSequence>();
@@ -147,7 +147,7 @@ namespace CyberX8_RT.Schedulers
             SchedulerSequence bufferToLoaderSequence = CreateLoaderTransporterSequence(bufferMoveToLoaderItem, ref index);
             schedulerSequences.Add(bufferToLoaderSequence);
             //Loader
-            SchedulerSequence loaderSequence = CreateLoaderSequence(ref index);
+            SchedulerSequence loaderSequence = CreateLoaderSequence(waferCount,ref index);
             schedulerSequences.Add(loaderSequence);
             //wafer holder装载后的recipe工序
             List<SchedulerSequence> waferHolderAfterLoadedAllSequences = WaferHolderAfterLoadedAllSchedulerSequences(waferHolderInfo, sequenceRecipe,ref index);
@@ -159,7 +159,7 @@ namespace CyberX8_RT.Schedulers
         /// </summary>
         /// <param name="waferHolderInfo"></param>
         /// <returns></returns>
-        public List<SchedulerSequence> AnalyseDummyWaferHolderAllSchedulerSequence(WaferHolderInfo waferHolderInfo)
+        public List<SchedulerSequence> AnalyseDummyWaferHolderAllSchedulerSequence(WaferHolderInfo waferHolderInfo,int waferCount)
         {
             int index = 0;
             List<SchedulerSequence> schedulerSequences = new List<SchedulerSequence>();
@@ -170,7 +170,7 @@ namespace CyberX8_RT.Schedulers
             SchedulerSequence bufferToLoaderSequence = CreateLoaderTransporterSequence(bufferMoveToLoaderItem, ref index);
             schedulerSequences.Add(bufferToLoaderSequence);
             //Loader
-            SchedulerSequence loaderSequence = CreateLoaderSequence(ref index);
+            SchedulerSequence loaderSequence = CreateLoaderSequence(waferCount,ref index);
             schedulerSequences.Add(loaderSequence);
             //Loader To Buffer
             WaferHolderMoveItem loaderMoveToBufferItem = new WaferHolderMoveItem(ModuleName.Loader1, ModuleType.Loader,
@@ -417,7 +417,7 @@ namespace CyberX8_RT.Schedulers
         /// </summary>
         /// <param name="index"></param>
         /// <returns></returns>
-        private SchedulerSequence CreateLoaderSequence(ref int index)
+        private SchedulerSequence CreateLoaderSequence(int waferCount,ref int index)
         {
             SchedulerSequence sequence = new SchedulerSequence();
             sequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(ModuleName.Loader1);
@@ -425,6 +425,7 @@ namespace CyberX8_RT.Schedulers
             sequence.ModuleName = ModuleName.Loader1;
             sequence.State = RState.Init;
             sequence.Recipe = null;
+            sequence.Parameters = waferCount;
             sequence.ModuleType = ModuleType.Loader;
             sequence.MaterialType = MaterialType.WaferHolder;
             index++;