Преглед изворни кода

update EFEM Map with Upper Hand

chenkui пре 6 дана
родитељ
комит
d8edabb91b

+ 0 - 1
PunkHPX8_RT/Devices/EFEM/EfemBase.cs

@@ -110,7 +110,6 @@ namespace PunkHPX8_RT.Devices.EFEM
         public abstract bool Grip(Hand blade, bool isGrip);
         public abstract bool GotoMap(ModuleName mod, Hand hand,string extend="EX");
         public abstract bool Map(ModuleName mod);
-
         public abstract bool Pause();
 
         public abstract bool Resume();

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

@@ -663,7 +663,7 @@ namespace PunkHPX8_RT.Devices.EFEM
                 Operation = EfemOperation.Map,
                 Module = mod
             };
-            string cmd = $"MAP {stationNumber} ARM {_armString[Hand.Blade1]}\r";
+            string cmd = $"MAP {stationNumber} ARM {_armString[Hand.Blade2]}\r";
             _status = RState.Running;
             return WriteCommand(cmd);
         }
@@ -696,7 +696,7 @@ namespace PunkHPX8_RT.Devices.EFEM
                 Operation = EfemOperation.RequestMapResult,
                 Module = mod
             };
-            string cmd = $"RSR {stationNumber} ARM {_armString[Hand.Blade1]}\r";
+            string cmd = $"RSR {stationNumber} ARM {_armString[Hand.Blade2]}\r";
             _status = RState.Running;
             return WriteCommand(cmd);
         }

+ 2 - 2
PunkHPX8_RT/Modules/EFEM/EfemRobotMapRoutine.cs

@@ -77,7 +77,7 @@ namespace PunkHPX8_RT.Modules.EFEM
         }
         private bool GotoMap()
         {
-            return _efem.GotoMap(_module, Hand.Blade1);
+            return _efem.GotoMap(_module, Hand.Blade2);
         }
         private bool Map()
         {
@@ -86,7 +86,7 @@ namespace PunkHPX8_RT.Modules.EFEM
 
         private bool Back()
         {
-            return _efem.GotoMap(_module, Hand.Blade1, "RE");
+            return _efem.GotoMap(_module, Hand.Blade2, "RE");
         }
 
         private bool RequestMap()

+ 65 - 18
PunkHPX8_RT/Modules/PlatingCell/PlatingCellEntity.cs

@@ -34,23 +34,7 @@ using System.Threading.Tasks;
 namespace PunkHPX8_RT.Modules.PlatingCell
 {
     public class PlatingCellEntity : Entity, IEntity, IModuleEntity
-    {
-        public enum PlatingCellMsg
-        {
-            NONE,
-            Error,
-            ResumeError,
-            Initialize,
-            Manual,
-            Auto,
-            CloseFlowValve,
-            OpenFlowValve,
-            RunRecipe,
-            Abort,
-            Init,
-            CCR,
-            CCRAbort,
-        }
+    {       
 
         #region 常量
         private const string STRATUS = "Stratus";
@@ -95,6 +79,10 @@ namespace PunkHPX8_RT.Modules.PlatingCell
         /// </summary>
         private PlatingCellRunRecipeRoutine _runRecipeRoutine;
         /// <summary>
+        /// Unload Routine
+        /// </summary>
+        private PlatingCellUnloadRoutine _unloadRoutine;
+        /// <summary>
         /// 工艺当前执行小步骤
         /// </summary>
         private string _currentStepState = "Init";
@@ -239,6 +227,7 @@ namespace PunkHPX8_RT.Modules.PlatingCell
             _initializeRoutine = new PlatingCellInitializeRoutine(Module.ToString());
             _platingCellCRRoutine = new PlatingCellCCRRoutine(Module.ToString());
             _runRecipeRoutine=new PlatingCellRunRecipeRoutine(Module.ToString());   
+            _unloadRoutine=new PlatingCellUnloadRoutine(Module.ToString());
         }
         /// <summary>
         /// 初始化DATA
@@ -305,7 +294,11 @@ namespace PunkHPX8_RT.Modules.PlatingCell
             //Cycle Manual Process
             Transition(PlatingCellState.Idle, PlatingCellMsg.RunRecipe, CycleManualProcess, PlatingCellState.RunReciping);
             Transition(PlatingCellState.RunReciping, FSM_MSG.TIMER, CycleManualMonitor, PlatingCellState.Idle);
-            Transition(PlatingCellState.RunReciping, VPWCellMsg.Abort, RunRecipeAbort, PlatingCellState.Idle);
+            Transition(PlatingCellState.RunReciping, PlatingCellMsg.Abort, RunRecipeAbort, PlatingCellState.Idle);
+            //Unload
+            Transition(PlatingCellState.Idle, PlatingCellMsg.Unload, Unload, PlatingCellState.Unloading);
+            Transition(PlatingCellState.Unloading, FSM_MSG.TIMER, UnloadMonitor, PlatingCellState.Idle);
+            Transition(PlatingCellState.Unloading, PlatingCellMsg.Abort, UnloadAbort, PlatingCellState.Idle);
             //直接进入Idle
             Transition(PlatingCellState.Initialized, FSM_MSG.TIMER, NullFunc, PlatingCellState.Idle);
             //Enter Init
@@ -528,6 +521,43 @@ namespace PunkHPX8_RT.Modules.PlatingCell
         }
         #endregion
 
+        #region unload
+        /// <summary>
+        /// unload
+        /// </summary>
+        /// <param name="param"></param>
+        /// <returns></returns>
+        private bool Unload(object[] param)
+        {
+            return _unloadRoutine.Start(param) == RState.Running;
+        }
+        /// <summary>
+        /// 监控
+        /// </summary>
+        /// <param name="param"></param>
+        /// <returns></returns>
+        private bool UnloadMonitor(object[] param)
+        {
+            RState state = _unloadRoutine.Monitor();
+            if (state == RState.Failed || state == RState.Timeout)
+            {
+                PostMsg(PlatingCellMsg.Error);
+                return false;
+            }
+            return state == RState.End;
+        }
+        /// <summary>
+        /// 中止
+        /// </summary>
+        /// <param name="param"></param>
+        /// <returns></returns>
+        private bool UnloadAbort(object[] param)
+        {
+            _unloadRoutine.Abort();
+            return true;
+        }
+        #endregion
+
         public bool Check(int msg, out string reason, params object[] args)
         {
             reason = "";
@@ -560,4 +590,21 @@ namespace PunkHPX8_RT.Modules.PlatingCell
             return (int)FSM_MSG.NONE;
         }
     }
+    public enum PlatingCellMsg
+    {
+        NONE,
+        Error,
+        ResumeError,
+        Initialize,
+        Manual,
+        Auto,
+        CloseFlowValve,
+        OpenFlowValve,
+        RunRecipe,
+        Abort,
+        Init,
+        CCR,
+        CCRAbort,
+        Unload
+    }
 }

+ 115 - 115
PunkHPX8_RT/Modules/PlatingCell/PlatingCellUnloadRoutine.cs

@@ -1,117 +1,117 @@
-using Aitex.Core.RT.Device;
-using Aitex.Core.RT.Routine;
-using Aitex.Core.RT.SCCore;
-using Aitex.Core.Util;
-using MECF.Framework.Common.RecipeCenter;
-using MECF.Framework.Common.Routine;
-using MECF.Framework.Common.Utilities;
-using PunkHPX8_Core;
-using PunkHPX8_RT.Devices.AXIS;
-using PunkHPX8_RT.Devices.PlatingCell;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace PunkHPX8_RT.Modules.PlatingCell
-{
-    public class PlatingCellUnloadRoutine : RoutineBase, IRoutine
-    {
-        private enum RunRecipeStep
-        {
-            VerticalGotoLoad,
-            CheckVerticalGotoLoad,
-            ClamShellOpen,
-            End
-        }
-        #region 常量
-        #endregion
-
-        /// <summary>
-        /// Platingcell device
-        /// </summary>
-        private PlatingCellDevice _device;
-        /// <summary>
-        /// vertical axis entity
-        /// </summary>
-        private PlatingCellVerticalEntity _verticalEntity;
-        /// <summary>
-        /// 构造函数
-        /// </summary>
-        /// <param name="module"></param>
-        public PlatingCellUnloadRoutine(string module) : base(module)
-        {
-
-        }
-        /// <summary>
-        /// 中止
-        /// </summary>
-        public void Abort()
-        {
-            Runner.Stop("Manual Abort");
-        }
-        /// <summary>
-        /// 监控
-        /// </summary>
-        /// <returns></returns>
-        public RState Monitor()
-        {
-            Runner.Run(RunRecipeStep.VerticalGotoLoad, () => StartVertical("Load"), _delay_1ms)
-                  .WaitWithStopCondition(RunRecipeStep.CheckVerticalGotoLoad, CheckVerticalEnd, CheckVerticalError)
-                  .Run(RunRecipeStep.ClamShellOpen, () => _device.ClamShellOpen(), CheckClamShellOpen, _delay_1s)
-                  .End(RunRecipeStep.End, NullFun);
-            return Runner.Status;
-        }
-        /// <summary>
-        /// vertical 运行
-        /// </summary>
-        /// <param name="positionName"></param> 目标位置名称
-        /// <param name="offset"></param> 偏移量
-        /// <returns></returns>
-        private bool StartVertical(string positionName)
-        {
-            return _verticalEntity.CheckToPostMessage<PlatingCellVerticalState, PlatingCellVerticalEntity.VerticalMsg>(Aitex.Core.RT.Log.eEvent.INFO_PLATINGCELL,
-                    Module, (int)PlatingCellVerticalEntity.VerticalMsg.Position, positionName,0);
-        }
-        /// <summary>
-        /// 检验垂直电机是否运动完成
-        /// </summary>
-        /// <returns></returns>
-        private bool CheckVerticalEnd()
-        {
-            return _verticalEntity.IsIdle;
-        }
-        /// <summary>
-        /// 检验垂直是否出现错误
-        /// </summary>
-        /// <returns></returns>
-        private bool CheckVerticalError()
-        {
-            return _verticalEntity.IsError;
+using Aitex.Core.RT.Device;
+using Aitex.Core.RT.Routine;
+using Aitex.Core.RT.SCCore;
+using Aitex.Core.Util;
+using MECF.Framework.Common.RecipeCenter;
+using MECF.Framework.Common.Routine;
+using MECF.Framework.Common.Utilities;
+using PunkHPX8_Core;
+using PunkHPX8_RT.Devices.AXIS;
+using PunkHPX8_RT.Devices.PlatingCell;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PunkHPX8_RT.Modules.PlatingCell
+{
+    public class PlatingCellUnloadRoutine : RoutineBase, IRoutine
+    {
+        private enum RunRecipeStep
+        {
+            VerticalGotoLoad,
+            CheckVerticalGotoLoad,
+            ClamShellOpen,
+            End
         }
+        #region 常量
+        #endregion
+
+        /// <summary>
+        /// Platingcell device
+        /// </summary>
+        private PlatingCellDevice _device;
+        /// <summary>
+        /// vertical axis entity
+        /// </summary>
+        private PlatingCellVerticalEntity _verticalEntity;
+        /// <summary>
+        /// 构造函数
+        /// </summary>
+        /// <param name="module"></param>
+        public PlatingCellUnloadRoutine(string module) : base(module)
+        {
 
-        /// <summary>
-        /// 检查ClamShell是否Open
-        /// </summary>
-        /// <returns></returns>
-        private bool CheckClamShellOpen()
-        {
-            return _device.PlatingCellDeviceData.ClamShellOpened;
-        }
-        /// <summary>
-        /// 启动
-        /// </summary>
-        /// <param name="objs"></param>
-        /// <returns></returns>
-        public RState Start(params object[] objs)
-        {
-            _device = DEVICE.GetDevice<PlatingCellDevice>(Module);
-            //获取vertical entity
-            string vertical = ModuleMatcherManager.Instance.GetPlatingVerticalByCell(Module);
-            _verticalEntity = Singleton<RouteManager>.Instance.GetModule<PlatingCellVerticalEntity>(vertical);
-            return Runner.Start(Module, "start unload");
-        }
-    }
-}
+        }
+        /// <summary>
+        /// 中止
+        /// </summary>
+        public void Abort()
+        {
+            Runner.Stop("Manual Abort");
+        }
+        /// <summary>
+        /// 监控
+        /// </summary>
+        /// <returns></returns>
+        public RState Monitor()
+        {
+            Runner.Run(RunRecipeStep.VerticalGotoLoad, () => StartVertical("Load"), _delay_1ms)
+                  .WaitWithStopCondition(RunRecipeStep.CheckVerticalGotoLoad, CheckVerticalEnd, CheckVerticalError)
+                  .Run(RunRecipeStep.ClamShellOpen, () => _device.ClamShellOpen(), CheckClamShellOpen, _delay_1s)
+                  .End(RunRecipeStep.End, NullFun);
+            return Runner.Status;
+        }
+        /// <summary>
+        /// vertical 运行
+        /// </summary>
+        /// <param name="positionName"></param> 目标位置名称
+        /// <param name="offset"></param> 偏移量
+        /// <returns></returns>
+        private bool StartVertical(string positionName)
+        {
+            return _verticalEntity.CheckToPostMessage<PlatingCellVerticalState, PlatingCellVerticalEntity.VerticalMsg>(Aitex.Core.RT.Log.eEvent.INFO_PLATINGCELL,
+                    Module, (int)PlatingCellVerticalEntity.VerticalMsg.Position, positionName,0);
+        }
+        /// <summary>
+        /// 检验垂直电机是否运动完成
+        /// </summary>
+        /// <returns></returns>
+        private bool CheckVerticalEnd()
+        {
+            return _verticalEntity.IsIdle;
+        }
+        /// <summary>
+        /// 检验垂直是否出现错误
+        /// </summary>
+        /// <returns></returns>
+        private bool CheckVerticalError()
+        {
+            return _verticalEntity.IsError;
+        }
+
+        /// <summary>
+        /// 检查ClamShell是否Open
+        /// </summary>
+        /// <returns></returns>
+        private bool CheckClamShellOpen()
+        {
+            return _device.PlatingCellDeviceData.ClamShellOpened;
+        }
+        /// <summary>
+        /// 启动
+        /// </summary>
+        /// <param name="objs"></param>
+        /// <returns></returns>
+        public RState Start(params object[] objs)
+        {
+            _device = DEVICE.GetDevice<PlatingCellDevice>(Module);
+            //获取vertical entity
+            string vertical = ModuleMatcherManager.Instance.GetPlatingVerticalByCell(Module);
+            _verticalEntity = Singleton<RouteManager>.Instance.GetModule<PlatingCellVerticalEntity>(vertical);
+            return Runner.Start(Module, "start unload");
+        }
+    }
+}

+ 4 - 0
PunkHPX8_RT/Modules/RouteManager.cs

@@ -773,6 +773,10 @@ namespace PunkHPX8_RT.Modules
                     homeCount++;
                 }
             }
+            if (homeCount != _reservoirCellRoutines.Count)
+            {
+                return false;
+            }
             if (idleCount == keys.Count)
             {
                 return true;

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

@@ -22,6 +22,8 @@ using PunkHPX8_RT.Dispatch;
 using MECF.Framework.Common.ToolLayout;
 using Aitex.Core.Common;
 using PunkHPX8_RT.Devices.VpwMain;
+using PunkHPX8_RT.Devices.PlatingCell;
+using Aitex.Core.RT.Device;
 
 namespace PunkHPX8_RT.Schedulers.EfemRobot
 {
@@ -179,6 +181,10 @@ namespace PunkHPX8_RT.Schedulers.EfemRobot
             {
                 return CheckVpw(moveItem, schedulerSequences, sequenceIndex, ref reason);
             }
+            if (ModuleHelper.IsPlatingCell(moveItem.DestinationModule))
+            {
+                return CheckPlatingCell(moveItem,  ref reason);
+            }
             return true;
         }
         /// <summary>
@@ -251,6 +257,42 @@ namespace PunkHPX8_RT.Schedulers.EfemRobot
             }
             return false;
         }
+
+        /// <summary>
+        /// 检验VPW
+        /// </summary>
+        /// <param name="moveItem"></param>
+        /// <param name="schedulerSequences"></param>
+        /// <param name="sequenceIndex"></param>
+        /// <param name="reason"></param>
+        /// <returns></returns>
+        private bool CheckPlatingCell(MoveItem moveItem,ref string reason)
+        {
+            PlatingCellEntity entity = Singleton<RouteManager>.Instance.GetModule<PlatingCellEntity>(moveItem.DestinationModule.ToString());
+            PlatingCellDevice platingCellDevice = DEVICE.GetDevice<PlatingCellDevice>(moveItem.DestinationModule.ToString());
+            if (entity != null&&platingCellDevice!=null)
+            {
+                if (entity.State == (int)PlatingCellState.Idle&&platingCellDevice.PlatingCellDeviceData.ClamShellOpened)
+                {
+                    return true;
+                }
+                else
+                {
+                    if (entity.IsIdle)
+                    {
+                        entity.CheckToPostMessage<PlatingCellState, PlatingCellMsg>(eEvent.INFO_PLATINGCELL, Module.ToString(),
+                            (int)PlatingCellMsg.Unload);
+                    }
+                    reason = $"{moveItem.DestinationModule} state is not idle";
+                    return false;
+                }
+            }
+            else
+            {
+                reason = $"{moveItem.DestinationModule} is null";
+            }
+            return false;
+        }
         /// <summary>
         /// 更新未知源模块
         /// </summary>

+ 22 - 25
PunkHPX8_RT/Schedulers/SchedulerSequenceManager.cs

@@ -219,14 +219,14 @@ namespace PunkHPX8_RT.Schedulers
             SchedulerSequence lastSequence=sequences[sequences.Count - 1];
             //若无SRD,直接从VPW转LoadPort
             MoveItem srdToDummyItem = new MoveItem();
-            srdToDummyItem.SourceModule = ModuleName.Unknown;
-            srdToDummyItem.SourceType = lastSequence.ModuleType;
+            srdToDummyItem.SourceModule = vpw;
+            srdToDummyItem.SourceType = ModuleType.VPW;
             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.RobotHand = Hand.Blade1;
+            srdToDummyItem.PickRobotFlip = Flip.Upper;
             srdToDummyItem.PlaceRobotFlip = Flip.Upper;
             SchedulerSequence toDummySequence = CreateEfemRobotSequence(srdToDummyItem, null, sequenceRecipe.SubstrateSize, ref index);
             schedulerSequences.Add(toDummySequence);
@@ -320,29 +320,26 @@ namespace PunkHPX8_RT.Schedulers
                 else
                 {
                     //生产片最后退至VPW中转
-                    if (!isDummy)
+                    MoveItem moveItem = new MoveItem();
+                    moveItem.SourceModule = tmpLst[i].ModuleName;
+                    moveItem.SourceType = tmpLst[i].ModuleType;
+                    moveItem.SourceSlot = 0;
+                    moveItem.DestinationModule = vpw;
+                    moveItem.DestinationSlot = 0;
+                    moveItem.DestinationType = ModuleType.VPW;
+                    moveItem.RobotHand = Hand.Blade2;
+                    //源来自于Plating cell,向下取
+                    if (tmpLst[i].ModuleType == ModuleType.PlatingCell)
                     {
-                        MoveItem moveItem = new MoveItem();
-                        moveItem.SourceModule = tmpLst[i].ModuleName;
-                        moveItem.SourceType = tmpLst[i].ModuleType;
-                        moveItem.SourceSlot = 0;
-                        moveItem.DestinationModule = vpw;
-                        moveItem.DestinationSlot = 0;
-                        moveItem.DestinationType = ModuleType.VPW;
-                        moveItem.RobotHand = Hand.Blade2;
-                        //源来自于Plating cell,向下取
-                        if (tmpLst[i].ModuleType == ModuleType.PlatingCell)
-                        {
-                            moveItem.PickRobotFlip = Flip.Down;
-                        }
-                        else
-                        {
-                            moveItem.PickRobotFlip = Flip.Upper;
-                        }
-                        moveItem.PlaceRobotFlip = Flip.Upper;
-                        SchedulerSequence robotSequence = CreateEfemRobotSequence(moveItem, null, sequenceRecipe.SubstrateSize, ref index);
-                        schedulerSequences.Add(robotSequence);
+                        moveItem.PickRobotFlip = Flip.Down;
                     }
+                    else
+                    {
+                        moveItem.PickRobotFlip = Flip.Upper;
+                    }
+                    moveItem.PlaceRobotFlip = Flip.Upper;
+                    SchedulerSequence robotSequence = CreateEfemRobotSequence(moveItem, null, sequenceRecipe.SubstrateSize, ref index);
+                    schedulerSequences.Add(robotSequence);
                 }
             }
             return schedulerSequences;