Browse Source

add dummy station number config;
dummy wafer skip vpw recipe when vpws have different wafersize;

chenkui 2 weeks ago
parent
commit
76dc0707de

+ 12 - 7
PunkHPX8_RT/Config/System.sccfg

@@ -107,15 +107,20 @@
 			<config default="58" name="Cassete100Station_Blade1_Upper" nameView="Cassete100Station_Blade1_Upper" description="Wafer 100 Cassete station number" max="120" min="0" paramter="" tag="" unit="s" type="Integer" visible="false"/>
 		</configs>
 		<configs name="Dummy1" nameView="Dummy1" visible="false">
-			<config default="1" name="Cassete200Station_Blade1_Upper" nameView="Cassete200Station_Blade1_Upper" description="Wafer 200 Cassete station number" max="120" min="0" paramter="" tag="" unit="s" type="Integer" visible="false"/>
-			<config default="65" name="Cassete150Station_Blade1_Upper" nameView="Cassete150Station_Blade1_Upper" description="Wafer 150 Cassete station number" max="120" min="0" paramter="" tag="" unit="s" type="Integer" visible="false"/>
-			<config default="66" name="Cassete100Station_Blade1_Upper" nameView="Cassete100Station_Blade1_Upper" description="Wafer 100 Cassete station number" max="120" min="0" paramter="" tag="" unit="s" type="Integer" visible="false"/>
+			<config default="12" name="Cassete200Station_Blade1_Upper" nameView="Cassete200Station_Blade1_Upper" description="Wafer 200 Cassete station number" max="120" min="0" paramter="" tag="" unit="s" type="Integer" visible="false"/>
+			<config default="112" name="Cassete200Station_Blade2_Upper" nameView="Cassete200Station_Blade2_Upper" description="Wafer 200 Cassete station number" max="120" min="0" paramter="" tag="" unit="s" type="Integer" visible="false"/>
+			<config default="168" name="Cassete150Station_Blade1_Upper" nameView="Cassete150Station_Blade1_Upper" description="Wafer 150 Cassete station number" max="120" min="0" paramter="" tag="" unit="s" type="Integer" visible="false"/>
+			<config default="169" name="Cassete150Station_Blade2_Upper" nameView="Cassete150Station_Blade2_Upper" description="Wafer 150 Cassete station number" max="120" min="0" paramter="" tag="" unit="s" type="Integer" visible="false"/>
+			<config default="69" name="Cassete100Station_Blade1_Upper" nameView="Cassete100Station_Blade1_Upper" description="Wafer 100 Cassete station number" max="120" min="0" paramter="" tag="" unit="s" type="Integer" visible="false"/>
+			<config default="69" name="Cassete100Station_Blade2_Upper" nameView="Cassete100Station_Blade2_Upper" description="Wafer 100 Cassete station number" max="120" min="0" paramter="" tag="" unit="s" type="Integer" visible="false"/>
 		</configs>
 		<configs name="Dummy2" nameView="Dummy2" visible="false">
-			<config default="62" name="Cassete200Station_Blade1_Upper" nameView="Cassete200Station_Blade1_Upper" description="Wafer 200 Cassete station number" max="120" min="0" paramter="" tag="" unit="s" type="Integer" visible="false"/>
-			<config default="63" name="Cassete150Station_Blade1_Upper" nameView="Cassete150Station_Blade1_Upper" description="Wafer 150 Cassete station number" max="120" min="0" paramter="" tag="" unit="s" type="Integer" visible="false"/>
-			<config default="64" name="Cassete100Station_Blade1_Upper" nameView="Cassete100Station_Blade1_Upper" description="Wafer 100 Cassete station number" max="120" min="0" paramter="" tag="" unit="s" type="Integer" visible="false"/>
-		    <config default="200" name="WaferSize" nameView="WaferSize" description="DummyWaferSize" max="300" min="0" paramter="" tag="" unit="" type="Integer" visible="true"/>
+			<config default="12" name="Cassete200Station_Blade1_Upper" nameView="Cassete200Station_Blade1_Upper" description="Wafer 200 Cassete station number" max="120" min="0" paramter="" tag="" unit="s" type="Integer" visible="false"/>
+			<config default="112" name="Cassete200Station_Blade2_Upper" nameView="Cassete200Station_Blade2_Upper" description="Wafer 200 Cassete station number" max="120" min="0" paramter="" tag="" unit="s" type="Integer" visible="false"/>
+			<config default="168" name="Cassete150Station_Blade1_Upper" nameView="Cassete150Station_Blade1_Upper" description="Wafer 150 Cassete station number" max="120" min="0" paramter="" tag="" unit="s" type="Integer" visible="false"/>
+			<config default="169" name="Cassete150Station_Blade2_Upper" nameView="Cassete150Station_Blade2_Upper" description="Wafer 150 Cassete station number" max="120" min="0" paramter="" tag="" unit="s" type="Integer" visible="false"/>
+			<config default="69" name="Cassete100Station_Blade1_Upper" nameView="Cassete100Station_Blade1_Upper" description="Wafer 100 Cassete station number" max="120" min="0" paramter="" tag="" unit="s" type="Integer" visible="false"/>
+			<config default="69" name="Cassete100Station_Blade2_Upper" nameView="Cassete100Station_Blade2_Upper" description="Wafer 100 Cassete station number" max="120" min="0" paramter="" tag="" unit="s" type="Integer" visible="false"/>
 		</configs>
 		<configs name="SRD1" nameView="SRD1" visible="false">
 			<config default="6" name="Cassete200Station_Blade1_Upper" nameView="Cassete200Station_Blade1_Upper" description="Wafer 200 Cassete station number" max="120" min="0" paramter="" tag="" unit="s" type="Integer" visible="false"/>

+ 35 - 0
PunkHPX8_RT/Devices/EFEM/DummyDevice.cs

@@ -79,5 +79,40 @@ namespace PunkHPX8_RT.Devices.EFEM
             WaferManager.Instance.SubscribeLocation(_module, _dummyItem.MaxNumberOfSlots);
             MaxSlotNumber = _dummyItem.MaxNumberOfSlots;
         }
+        /// <summary>
+        /// 是否包含wafer
+        /// </summary>
+        /// <returns></returns>
+        public bool HasWafer()
+        {
+            for (int i = 0; i < MaxSlotNumber; i++)
+            {
+                if (WaferManager.Instance.CheckHasWafer(_module, i))
+                {
+                    return true;
+                }
+            }
+            return false;
+        }
+        /// <summary>
+        /// 获取Wafer
+        /// </summary>
+        /// <param name="waferSize"></param>
+        /// <returns></returns>
+        public WaferInfo GetWaferBySize(int waferSize)
+        {
+            if ((int)WaferSize != waferSize)
+            {
+                return null;
+            }
+            for (int i = 0; i < MaxSlotNumber; i++)
+            {
+                if (WaferManager.Instance.CheckHasWafer(_module, i))
+                {
+                    return WaferManager.Instance.GetWafer(_module, i);
+                }
+            }
+            return null;
+        }
     }
 }

+ 23 - 2
PunkHPX8_RT/Devices/EFEM/SunWayRobot.cs

@@ -129,11 +129,11 @@ namespace PunkHPX8_RT.Devices.EFEM
             InitializeModuleStation(ModuleName.LP1);
             InitializeModuleStation(ModuleName.LP2);
             InitializeModuleStation(ModuleName.LP3);
-            InitializeModuleStation(ModuleName.Dummy1);
-            InitializeModuleStation(ModuleName.Dummy2);
             InitializeModuleStation(ModuleName.Aligner1);
             InitializeModuleStation(ModuleName.SRD1);
             InitializeModuleStation(ModuleName.SRD2);
+            InitializeDummyModuleStation(ModuleName.Dummy1);
+            InitializeDummyModuleStation(ModuleName.Dummy2);
             InitializeVPWModuleStation(ModuleName.VPW1);
             InitializeVPWModuleStation(ModuleName.VPW2);
             InitializePlatingCellModuleStation(ModuleName.PlatingCell1);
@@ -180,6 +180,27 @@ namespace PunkHPX8_RT.Devices.EFEM
         /// 初始化vpw module Station
         /// </summary>
         /// <param name="module"></param>
+        private void InitializeDummyModuleStation(ModuleName module)
+        {
+            int cassete200Station_Blade1_Upper = SC.GetValue<int>($"EFEM.{module}.Cassete200Station_Blade1_Upper");
+            _moduleStationNumberDictionary[$"{module}_200_Blade1_Upper"] = cassete200Station_Blade1_Upper;
+            int cassete200Station_Blade2_Upper = SC.GetValue<int>($"EFEM.{module}.Cassete200Station_Blade2_Upper");
+            _moduleStationNumberDictionary[$"{module}_200_Blade2_Upper"] = cassete200Station_Blade2_Upper;
+
+            int cassete150Station_Blade1_Upper = SC.GetValue<int>($"EFEM.{module}.Cassete150Station_Blade1_Upper");
+            _moduleStationNumberDictionary[$"{module}_150_Blade1_Upper"] = cassete150Station_Blade1_Upper;
+            int cassete150Station_Blade2_Upper = SC.GetValue<int>($"EFEM.{module}.Cassete150Station_Blade2_Upper");
+            _moduleStationNumberDictionary[$"{module}_150_Blade2_Upper"] = cassete150Station_Blade2_Upper;
+
+            int cassete100Station_Blade1_Upper = SC.GetValue<int>($"EFEM.{module}.Cassete100Station_Blade1_Upper");
+            _moduleStationNumberDictionary[$"{module}_100_Blade1_Upper"] = cassete100Station_Blade1_Upper;
+            int cassete100Station_Blade2_Upper = SC.GetValue<int>($"EFEM.{module}.Cassete100Station_Blade2_Upper");
+            _moduleStationNumberDictionary[$"{module}_100_Blade2_Upper"] = cassete100Station_Blade2_Upper;
+        }
+        /// <summary>
+        /// 初始化vpw module Station
+        /// </summary>
+        /// <param name="module"></param>
         private void InitializeVPWModuleStation(ModuleName module)
         {
             int cassete200Station_Blade1_Upper = SC.GetValue<int>($"EFEM.{module}.Cassete200Station_Blade1_Upper");

+ 56 - 30
PunkHPX8_RT/Devices/VpwMain/VpwMainDevice.cs

@@ -172,6 +172,10 @@ namespace PunkHPX8_RT.Devices.VpwMain
         /// 检测到cell flow 满足设定条件的时间
         /// </summary>
         private bool _totalFlowAbnormal;
+        /// <summary>
+        /// 锁
+        /// </summary>
+        private object _locker = new object();
         #endregion
 
         #region 属性
@@ -505,14 +509,23 @@ namespace PunkHPX8_RT.Devices.VpwMain
         /// <returns></returns>
         public bool BoosterPumpEnableOperation(string cmd, object[] param)
         {
-            if (_status == RState.Running)
+            lock (_locker)
             {
-                LOG.WriteLog(eEvent.ERR_PREWET, Module.ToString(), $"{Module} current execute {_currentOperation},cannot Pump enable");
-                return false;
+                if (_status == RState.Running)
+                {
+                    if (_currentOperation != VPWOperation.PumpEnable) {
+                        LOG.WriteLog(eEvent.ERR_PREWET, Module.ToString(), $"{Module} current execute {_currentOperation},cannot Pump enable");
+                        return false;
+                    }
+                    else
+                    {
+                        return true;
+                    }
+                }
+                _status = _boosterPumpEnableRoutine.Start();
+                _currentOperation = VPWOperation.PumpEnable;
+                return _status == RState.Running;
             }
-            _status = _boosterPumpEnableRoutine.Start();
-            _currentOperation = VPWOperation.PumpEnable;
-            return _status == RState.Running;
         }
         /// <summary> 
         /// pump disable 操作
@@ -522,14 +535,24 @@ namespace PunkHPX8_RT.Devices.VpwMain
         /// <returns></returns>
         public bool BoosterPumpDisableOperation(string cmd, object[] param)
         {
-            if (_status == RState.Running)
+            lock (_locker)
             {
-                LOG.WriteLog(eEvent.ERR_PREWET, Module.ToString(), $"{Module} current execute {_currentOperation},cannot Pump disable");
-                return false;
+                if (_status == RState.Running)
+                {
+                    if (_currentOperation != VPWOperation.PumpDisable)
+                    {
+                        LOG.WriteLog(eEvent.ERR_PREWET, Module.ToString(), $"{Module} current execute {_currentOperation},cannot Pump disable");
+                        return false;
+                    }
+                    else
+                    {
+                        return true;
+                    }
+                }
+                _status = _boosterPumpDisableRoutine.Start();
+                _currentOperation = VPWOperation.PumpDisable;
+                return _status == RState.Running;
             }
-            _status = _boosterPumpDisableRoutine.Start();
-            _currentOperation = VPWOperation.PumpDisable;
-            return _status == RState.Running;
             //return PumpDisable();
         }
         /// <summary>
@@ -845,31 +868,34 @@ namespace PunkHPX8_RT.Devices.VpwMain
             _commonData.BoosterPumpPressureData.MaxError = SC.GetValue<double>($"VPWMain.PumpPressure.Error_Max");
             _commonData.BoosterPumpPressureData.MaxWarning = SC.GetValue<double>($"VPWMain.PumpPressure.Warning_Max");
             _commonData.PressureTarget = SC.GetValue<double>($"VPWMain.PressureTarget");
-            if (_status == RState.Running)
+            lock (_locker)
             {
-                IRoutine routine = GetCurrentRoutine();
-                if (routine != null)
+                if (_status == RState.Running)
                 {
-                    RState rsState = routine.Monitor();
-                    if (rsState == RState.Failed || rsState == RState.Timeout)
-                    {
-                        _status = RState.Failed;
-                        _currentOperation = VPWOperation.None;
-                        LOG.WriteLog(eEvent.ERR_VPWMAIN, Module.ToString(), $"{_currentOperation} error");
-                        _isStartAutoSpeed = false;
-                    }
-                    else if (rsState == RState.End)
+                    IRoutine routine = GetCurrentRoutine();
+                    if (routine != null)
                     {
-                        if (_currentOperation == VPWOperation.PumpEnable)
+                        RState rsState = routine.Monitor();
+                        if (rsState == RState.Failed || rsState == RState.Timeout)
                         {
-                            _isStartAutoSpeed = true;
+                            _status = RState.Failed;
+                            _currentOperation = VPWOperation.None;
+                            LOG.WriteLog(eEvent.ERR_VPWMAIN, Module.ToString(), $"{_currentOperation} error");
+                            _isStartAutoSpeed = false;
                         }
-                        else if (_currentOperation == VPWOperation.PumpDisable)
+                        else if (rsState == RState.End)
                         {
-                            _isStartAutoSpeed = false;
+                            if (_currentOperation == VPWOperation.PumpEnable)
+                            {
+                                _isStartAutoSpeed = true;
+                            }
+                            else if (_currentOperation == VPWOperation.PumpDisable)
+                            {
+                                _isStartAutoSpeed = false;
+                            }
+                            _status = RState.End;
+                            _currentOperation = VPWOperation.None;
                         }
-                        _status = RState.End;
-                        _currentOperation = VPWOperation.None;
                     }
                 }
             }

+ 19 - 18
PunkHPX8_RT/Dispatch/JobProcesser.cs

@@ -274,26 +274,27 @@ namespace PunkHPX8_RT.Dispatch
                     ClearWafersSeqName(cj);
                     return false;
                 }
-                int dummyCount = 0;
-                DummyDevice dummy1Device = Singleton<RouteManager>.Instance.EFEM.GetDummyDevice(0);
-                if(dummy1Device!=null&&dummy1Device.HasCassette&&dummy1Device.WaferSize==waferSize)
+                if (pj.SlotWafers.Count % 2 == 1)
                 {
-                    dummyCount++;
-                }
-                DummyDevice dummy2Device = Singleton<RouteManager>.Instance.EFEM.GetDummyDevice(1);
-                if (dummy2Device != null && dummy2Device.HasCassette && dummy2Device.WaferSize == waferSize)
-                {
-                    dummyCount++;
-                }
-                if (dummyCount == 0)
-                {
-                    reason = $"dummy is not matched wafer wafersize {waferSize}";
-                    LOG.WriteLog(eEvent.WARN_ROUTER, ModuleName.System.ToString(), reason);
-                    ClearWafersSeqName(cj);
-                    return false;
+                    int dummyCount = 0;
+                    DummyDevice dummy1Device = Singleton<RouteManager>.Instance.EFEM.GetDummyDevice(0);
+                    if (dummy1Device != null && dummy1Device.WaferSize == waferSize&&dummy1Device.HasWafer())
+                    {
+                        dummyCount++;
+                    }
+                    DummyDevice dummy2Device = Singleton<RouteManager>.Instance.EFEM.GetDummyDevice(1);
+                    if (dummy2Device != null && dummy2Device.HasCassette && dummy2Device.WaferSize == waferSize&&dummy2Device.HasWafer())
+                    {
+                        dummyCount++;
+                    }
+                    if (dummyCount == 0)
+                    {
+                        reason = $"dummy has no {waferSize} wafer";
+                        LOG.WriteLog(eEvent.ERR_ROUTER, ModuleName.System.ToString(), reason);
+                        ClearWafersSeqName(cj);
+                        return false;
+                    }
                 }
-                string crsType = pj.SequenceRecipe.CrsType;
-                List<string> chemistries = SchedulerSequenceRecipeManager.Instance.GetSequenceChemistry(pj.SequenceRecipe);
                 pjs.Add(pj);
             }
 

+ 4 - 1
PunkHPX8_RT/Dispatch/WaferTaskDispatcher.cs

@@ -28,9 +28,12 @@ namespace PunkHPX8_RT.Dispatch
                 }
                 if (currentSequence.ModuleName == ModuleName.EfemRobot)
                 {
-
+                    DealEfemRobot(currentSequence, item, waferTasks);
                 }
+                else
+                {
                     item.Run();
+                }
             }
         }
         /// <summary>

+ 4 - 10
PunkHPX8_RT/Dispatch/WaferTaskManager.cs

@@ -311,17 +311,10 @@ namespace PunkHPX8_RT.Dispatch
                 if (Enum.TryParse(item, out ModuleName dummyModule))
                 {
                     DummyDevice dummyDevice= Singleton<RouteManager>.Instance.EFEM.GetDummyDevice(dummyModule - ModuleName.Dummy1);
-                    if ((int)dummyDevice.WaferSize != waferSize)
+                    WaferInfo waferInfo = dummyDevice.GetWaferBySize(waferSize);
+                    if (waferInfo!=null&&!waferInfo.IsEmpty)
                     {
-                        continue;
-                    }
-                    int maxSlot = dummyDevice.MaxSlotNumber;
-                    for (int i = 0; i < maxSlot; i++)
-                    {
-                        if (WaferManager.Instance.CheckHasWafer(item, i))
-                        {
-                            return WaferManager.Instance.GetWafer(dummyModule, i);
-                        }
+                        return waferInfo;
                     }
                 }
             }
@@ -342,6 +335,7 @@ namespace PunkHPX8_RT.Dispatch
             {
                 waferTask.MateWaferTask = mateWafeTask;
             }
+            waferTask.OnTaskStart += WaferTask_OnTaskStart;
             waferTask.OnTaskComplete += WaferTask_OnTaskComplete;
             LOG.WriteLog(eEvent.EV_SEQUENCE, "Scheduler", $"Create wafer {waferInfo.WaferID} task");
             InitializeTask(waferTask);

+ 1 - 1
PunkHPX8_RT/Modules/EFEM/EfemPlaceRoutine.cs

@@ -80,7 +80,7 @@ namespace PunkHPX8_RT.Modules.EFEM
         }
         private bool CheckPreCondition()
         {
-            if (ModuleHelper.IsDummy(_targetModule) || ModuleHelper.IsAligner(_targetModule) || ModuleHelper.IsLoadPort(_targetModule))
+            if (ModuleHelper.IsAligner(_targetModule) || ModuleHelper.IsLoadPort(_targetModule))
             {
                 if (_hand == Hand.Blade2)
                 {

+ 16 - 3
PunkHPX8_RT/Modules/RouteManager.cs

@@ -33,6 +33,7 @@ using MECF.Framework.Common.ProcessCell;
 using System.Reflection;
 using PunkHPX8_RT.Modules.VpwMain;
 using PunkHPX8_RT.Modules.PlatingCell;
+using PunkHPX8_RT.Devices.EFEM;
 
 namespace PunkHPX8_RT.Modules
 {
@@ -523,14 +524,21 @@ namespace PunkHPX8_RT.Modules
             ModuleName chamber = ModuleHelper.Converter(args[0].ToString());
             int slot = (int)args[1];
             WaferStatus state = WaferStatus.Normal;
-
+            WaferType waferType = WaferType.Production;
+            WaferSize waferSize = WaferSize.WS8;
+            if (ModuleHelper.IsDummy(chamber))
+            {
+                waferType = WaferType.Assit;
+                DummyDevice dummyDevice = Singleton<RouteManager>.Instance.EFEM.GetDummyDevice((int)chamber-(int)ModuleName.Dummy1);
+                waferSize = dummyDevice.WaferSize;
+            }
             if (WaferManager.Instance.IsWaferSlotLocationValid(chamber, slot))
             {
                 if (WaferManager.Instance.CheckHasWafer(chamber, slot))
                 {
                     LOG.Write(eEvent.EV_ROUTER, "System", string.Format("{0} slot {1} already has wafer.create wafer is not valid", chamber, slot));
                 }
-                else if (WaferManager.Instance.CreateWafer(chamber, slot, state) != null)
+                else if (WaferManager.Instance.CreateWafer(chamber, slot,state,waferType,waferSize) != null)
                 {
                     LOG.Write(eEvent.EV_WAFER_CREATE, ModuleName.System, chamber.ToString(), (slot + 1).ToString(), state.ToString());
                 }
@@ -831,7 +839,12 @@ namespace PunkHPX8_RT.Modules
         }
         private bool FsmStartAutoTransfer(object[] objs)
         {
-            return _jobCycle.Start(objs) == RState.Running;
+            bool result= _jobCycle.Start(objs) == RState.Running;
+            if (result)
+            {
+                SchedulerSequenceManager.Instance.ConfirmVPW();
+            }
+            return result;
         }
 
         private bool FsmAutoTransfer(object[] objs)

+ 62 - 21
PunkHPX8_RT/Schedulers/SchedulerSequenceManager.cs

@@ -41,6 +41,30 @@ namespace PunkHPX8_RT.Schedulers
         private const string TRNPA = "TRNPA";
         private const string TRNPB = "TRNPB";
         #endregion
+
+        #region 内部变量
+        /// <summary>
+        /// VPW是否包含相同尺寸
+        /// </summary>
+        private bool _vpwHasSameSize = false;
+        #endregion
+
+        #region 属性
+        /// <summary>
+        /// VPW是否包含相同尺寸
+        /// </summary>
+        public bool VPWHasSameSize
+        {
+            get { return _vpwHasSameSize; }
+        }
+        #endregion
+        /// <summary>
+        /// 初始化
+        /// </summary>
+        public void ConfirmVPW()
+        {
+            _vpwHasSameSize = CheckSystemHasTheSameSizeVpw();
+        }
         /// <summary>
         /// 解析Wafer所有调度工序
         /// </summary>
@@ -159,18 +183,31 @@ namespace PunkHPX8_RT.Schedulers
             SchedulerSequence alignerRobotSequence = CreateEfemRobotSequence(alignerToMoveItem, null, sequenceRecipe.SubstrateSize, ref index);
             schedulerSequences.Add(alignerRobotSequence);
             //解析sequence recipe后续的工序
-            var sequences = AnalyseSequenceRecipeScheduler(sequenceRecipe,vpw, false);
+            var sequences = AnalyseSequenceRecipeScheduler(sequenceRecipe,vpw, true);
             if (sequences.Count == 0)
             {
                 return schedulerSequences;
             }
-            SchedulerSequence firstSequence = sequences[0];
-            if (firstSequence.ModuleType != ModuleType.VPW)
+            if (_vpwHasSameSize)
             {
-                return schedulerSequences;
+                SchedulerSequence firstSequence = sequences[0];
+                if (firstSequence.ModuleType != ModuleType.VPW)
+                {
+                    return schedulerSequences;
+                }
+                firstSequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(vpw);
+                firstSequence.ModuleName = vpw;
+            }
+            else
+            {
+                SchedulerSequence firstSequence = sequences[0];
+                if (firstSequence.ModuleType != ModuleType.EfemRobot)
+                {
+                    return schedulerSequences;
+                }
+                MoveItem firstMoveItem=firstSequence.Parameters as MoveItem;
+                firstMoveItem.SourceModule = vpw;
             }
-            firstSequence.SchedulerModule = SchedulerManager.Instance.GetScheduler(vpw);
-            firstSequence.ModuleName = vpw;
             //调整工序后面的索引
             foreach (SchedulerSequence item in sequences)
             {
@@ -181,17 +218,17 @@ namespace PunkHPX8_RT.Schedulers
 
             SchedulerSequence lastSequence=sequences[sequences.Count - 1];
             //若无SRD,直接从VPW转LoadPort
-            MoveItem srdToLoadPortItem = new MoveItem();
-            srdToLoadPortItem.SourceModule = ModuleName.Unknown;
-            srdToLoadPortItem.SourceType = lastSequence.ModuleType;
-            srdToLoadPortItem.SourceSlot = 0;
-            srdToLoadPortItem.DestinationType = ModuleType.Dummy;
-            srdToLoadPortItem.DestinationModule = (ModuleName)waferInfo.OriginStation;
-            srdToLoadPortItem.DestinationSlot = waferInfo.OriginSlot;
-            srdToLoadPortItem.RobotHand = Hand.Blade1;
-            srdToLoadPortItem.PickRobotFlip = Flip.Upper;
-            srdToLoadPortItem.PlaceRobotFlip = Flip.Upper;
-            SchedulerSequence toDummySequence = CreateEfemRobotSequence(srdToLoadPortItem, null, sequenceRecipe.SubstrateSize, ref index);
+            MoveItem srdToDummyItem = new MoveItem();
+            srdToDummyItem.SourceModule = ModuleName.Unknown;
+            srdToDummyItem.SourceType = lastSequence.ModuleType;
+            srdToDummyItem.SourceSlot = 0;
+            srdToDummyItem.DestinationType = ModuleType.Dummy;
+            srdToDummyItem.DestinationModule = (ModuleName)waferInfo.OriginStation;
+            srdToDummyItem.DestinationSlot = waferInfo.OriginSlot;
+            srdToDummyItem.RobotHand = Hand.Blade2;
+            srdToDummyItem.PickRobotFlip = Flip.Down;
+            srdToDummyItem.PlaceRobotFlip = Flip.Upper;
+            SchedulerSequence toDummySequence = CreateEfemRobotSequence(srdToDummyItem, null, sequenceRecipe.SubstrateSize, ref index);
             schedulerSequences.Add(toDummySequence);
             return schedulerSequences;
         }
@@ -241,9 +278,13 @@ namespace PunkHPX8_RT.Schedulers
             int index = 0;
             for(int i=0;i<tmpLst.Count;i++)
             {
-                tmpLst[i].SequenceIndex = 0;
-                schedulerSequences.Add(tmpLst[i]);
-                index++;
+                //不同尺寸的Dummy wafer跳过VPW recipe步骤
+                if (_vpwHasSameSize || !isDummy || tmpLst[i].ModuleType!=ModuleType.VPW)
+                {
+                    tmpLst[i].SequenceIndex = 0;
+                    schedulerSequences.Add(tmpLst[i]);
+                    index++;
+                }
                 if (i < tmpLst.Count - 1)
                 {
                     MoveItem moveItem = new MoveItem();
@@ -576,7 +617,7 @@ namespace PunkHPX8_RT.Schedulers
         /// 检验VPW是否相同尺寸
         /// </summary>
         /// <returns></returns>
-        public bool CheckSystemHasTheSameSizeVpw()
+        private bool CheckSystemHasTheSameSizeVpw()
         {
             VpwCellEntity vpwCellEntity1 = Singleton<RouteManager>.Instance.GetModule<VpwCellEntity>(ModuleName.VPW1.ToString());
             VpwCellEntity vpwCellEntity2 = Singleton<RouteManager>.Instance.GetModule<VpwCellEntity>(ModuleName.VPW2.ToString());

+ 46 - 11
PunkHPX8_RT/Schedulers/VPW/SchedulerVPW.cs

@@ -15,6 +15,7 @@ using System.Text;
 using System.Threading.Tasks;
 using PunkHPX8_RT.Modules.VpwMain;
 using PunkHPX8_RT.Modules.VpwCell;
+using System.Runtime.CompilerServices;
 
 namespace PunkHPX8_RT.Schedulers.Srd
 {
@@ -88,9 +89,13 @@ namespace PunkHPX8_RT.Schedulers.Srd
                 {
                     return true;
                 }
+                if(SchedulerSequenceManager.Instance.VPWHasSameSize && !CheckMatcherIdle())
+                {
+                    return true;
+                }
                 if (vpwMainEntity.IsChamberClosed)
                 {
-                    vpwMainEntity.CheckToPostMessage<VPWCellState, VPWCellMsg>(eEvent.INFO_VPW, Module.ToString(), (int)VPWMainMsg.ChamberDown);
+                    vpwMainEntity.CheckToPostMessage<VPWCellState, VPWCellMsg>(eEvent.INFO_VPW, Module.ToString(), (int)VPWMainMsg.ChamberDown);                    
                 }
                 else
                 {
@@ -104,6 +109,28 @@ namespace PunkHPX8_RT.Schedulers.Srd
             return true;
         }
         /// <summary>
+        /// 检验另一个配对的vpw是否Idle
+        /// </summary>
+        /// <returns></returns>
+        private bool CheckMatcherIdle()
+        {
+            string matcher = ModuleMatcherManager.Instance.GetMatcherByModule(Module.ToString());
+            if (string.IsNullOrEmpty(matcher))
+            {
+                return true;
+            }
+            VpwCellEntity matcherCellEntity = Singleton<RouteManager>.Instance.GetModule<VpwCellEntity>(matcher);
+            if (matcherCellEntity == null)
+            {
+                return true;
+            }
+            if (!matcherCellEntity.IsAuto)
+            {
+                return true;
+            }
+            return matcherCellEntity.IsIdle;
+        }
+        /// <summary>
         /// 检验前置条件
         /// </summary>
         /// <param name="sequenceIndex"></param>
@@ -128,30 +155,38 @@ namespace PunkHPX8_RT.Schedulers.Srd
                 return false;
             }
 
-            if (!SchedulerSequenceManager.Instance.CheckSystemHasTheSameSizeVpw())
+            if (!SchedulerSequenceManager.Instance.VPWHasSameSize)
             {
                 return true;
             }
 
-            VpwCellEntity vpwCellEntity1 = Singleton<RouteManager>.Instance.GetModule<VpwCellEntity>(ModuleName.VPW1.ToString());
-            VpwCellEntity vpwCellEntity2 = Singleton<RouteManager>.Instance.GetModule<VpwCellEntity>(ModuleName.VPW2.ToString());
-
-            if (vpwCellEntity1.State != (int)VPWCellState.WaitForRunRecipe && vpwCellEntity1.State != (int)VPWCellState.RunReciping)
+            VpwCellEntity vpwCellEntity = Singleton<RouteManager>.Instance.GetModule<VpwCellEntity>(Module.ToString());
+            string matcher = ModuleMatcherManager.Instance.GetMatcherByModule(Module.ToString());
+            VpwCellEntity matcherCellEntity = Singleton<RouteManager>.Instance.GetModule<VpwCellEntity>(matcher);
+            if (matcherCellEntity == null)
+            {
+                return true;
+            }
+            if (!matcherCellEntity.IsAuto)
+            {
+                return true;
+            }
+            if (vpwCellEntity.State != (int)VPWCellState.WaitForRunRecipe && vpwCellEntity.State != (int)VPWCellState.RunReciping)
             {
                 return false;
             }
-            if (WaferManager.Instance.CheckNoWafer(ModuleName.VPW1, 0))
+            if (WaferManager.Instance.CheckNoWafer(Module, 0))
             {
-                reason = $"{ModuleName.VPW1} has no wafer";
+                reason = $"{Module} has no wafer";
                 return false;
             }
-            if (vpwCellEntity2.State != (int)VPWCellState.WaitForRunRecipe&&vpwCellEntity2.State!=(int)VPWCellState.RunReciping)
+            if (matcherCellEntity.State != (int)VPWCellState.WaitForRunRecipe&&matcherCellEntity.State!=(int)VPWCellState.RunReciping)
             {
                 return false;
             }
-            if (WaferManager.Instance.CheckNoWafer(ModuleName.VPW2, 0))
+            if (WaferManager.Instance.CheckNoWafer(matcherCellEntity.Module, 0))
             {
-                reason = $"{ModuleName.VPW2} has no wafer";
+                reason = $"{matcherCellEntity.Module} has no wafer";
                 return false;
             }
             return true;

+ 1 - 1
PunkHPX8_Twincate/PunkHPX8/PlcTest/POUs/MAIN.TcPOU

@@ -921,7 +921,7 @@ ELSE
 	VPW_AI_8CHANNEL_0_10V_EL3068_N105_1:=29500;
 END_IF
 
-IF MAIN_IO_RELAY_4CHANNEL_EL2624_N106_1=TRUE AND VPW_PNEU_SMC_EX260_BYTE1.4=TRUE AND VPW_PNEU_SMC_EX260_BYTE1.4=FALSE THEN
+IF MAIN_IO_RELAY_4CHANNEL_EL2624_N106_1=TRUE AND VPW_PNEU_SMC_EX260_BYTE1.4=TRUE AND VPW_PNEU_SMC_EX260_BYTE1.6=FALSE THEN
 	VPW_AI_8CHANNEL_0_10V_EL3068_N105_2:=25000;
 ELSE
 	VPW_AI_8CHANNEL_0_10V_EL3068_N105_2:=29500;