Browse Source

Revise SRD related Routines; Add SRD Galil simulator;

niuyx 2 weeks ago
parent
commit
ed99981344

+ 28 - 0
CyberX8_RT/Config/Devices/GalilControllerCfg-Simulator.xml

@@ -238,4 +238,32 @@
 			<PositiveTorqueLimit>20</PositiveTorqueLimit>
 		</GalilAxisConfig>
 	</GalilDeviceConfig>
+	<GalilDeviceConfig Module="SRD1" IpAddress="127.0.0.1" Port="58682" SendTimeout="2000" RecvTimeout="2000" GalilType="Galil21">
+		<Dig_In>
+			<DI Name="DI0"  Address="0" Invert="false"/>
+			<DI Name="DI1"  Address="1" Invert="false"/>
+			<DI Name="DI2"  Address="2" Invert="false"/>
+			<DI Name="DI3"  Address="3" Invert="false"/>
+			<DI Name="D14"  Address="4" Invert="false"/>
+			<DI Name="DI5"  Address="5" Invert="false"/>
+			<DI Name="DI6"  Address="6" Invert="false"/>
+			<DI Name="DI7"  Address="7" Invert="false"/>
+			<DI Name="DI8"  Address="8" Invert="false"/>
+			<DI Name="DI9"  Address="9" Invert="false"/>
+		</Dig_In>
+		<GalilAxisConfig Name="Rotation" Index="0" Type="Galil" CNType="-1">
+			<Speed>200000</Speed>
+			<Acceleration>200000</Acceleration>
+			<Deceleration>200000</Deceleration>
+			<HomingSpeed>10000</HomingSpeed>
+			<HomingOffset>0</HomingOffset>
+			<HomingTimeOut>60000</HomingTimeOut>
+			<HomingAcceleration>200000</HomingAcceleration>
+			<HomingDeceleration>400000</HomingDeceleration>
+			<ReverseSoftwareLimit>0</ReverseSoftwareLimit>
+			<ForwardSoftwareLimit>0</ForwardSoftwareLimit>
+			<NegativeTorqueLimit>130</NegativeTorqueLimit>
+			<PositiveTorqueLimit>20</PositiveTorqueLimit>
+		</GalilAxisConfig>		
+	</GalilDeviceConfig>
 </GalilControllerConfig>

+ 10 - 10
CyberX8_RT/Devices/DeviceManager.cs

@@ -284,18 +284,18 @@ namespace CyberX8_RT.Instances
         /// <param name="moduleName"></param>
         private void InitialSRD(ModuleName moduleName)
         {
-            BeckhoffAxis armBeckhoffAxis = BeckhoffAxisManager.Instance.GetAxis($"{moduleName}.Arm");
-            if (armBeckhoffAxis != null)
-            {
-                JetAxisBase armAxis = AxisManager.Instance.GetAxisInstance(armBeckhoffAxis.MotorType, moduleName.ToString(), "Arm");
-                AddCustomModuleDevice(armAxis);
-                armAxis.InterLock = new SrdArmAxisInterLock(armAxis);
-                AxisManager.Instance.AddModuleAxis(moduleName.ToString(), armAxis);
-            }
-            BeckhoffAxis rotationBeckhoffAxis = BeckhoffAxisManager.Instance.GetAxis($"{moduleName}.Rotation");
+            //GalilAxisConfig armBeckhoffAxis = GalilControllerCfgManager.Instance.GetGalilAxisConfig(moduleName.ToString(), "Arm"); ;
+            //if (armBeckhoffAxis != null)
+            //{
+            //    JetAxisBase armAxis = AxisManager.Instance.GetAxisInstance(armBeckhoffAxis.Type, moduleName.ToString(), "Arm");
+            //    AddCustomModuleDevice(armAxis);
+            //    armAxis.InterLock = new SrdArmAxisInterLock(armAxis);
+            //    AxisManager.Instance.AddModuleAxis(moduleName.ToString(), armAxis);
+            //}
+            GalilAxisConfig rotationBeckhoffAxis = GalilControllerCfgManager.Instance.GetGalilAxisConfig(moduleName.ToString(), "Rotation");
             if (rotationBeckhoffAxis != null)
             {
-                JetAxisBase rotationAxis = AxisManager.Instance.GetAxisInstance(rotationBeckhoffAxis.MotorType, moduleName.ToString(), "Rotation");
+                JetAxisBase rotationAxis = AxisManager.Instance.GetAxisInstance(rotationBeckhoffAxis.Type, moduleName.ToString(), "Rotation");
                 AddCustomModuleDevice(rotationAxis);
                 rotationAxis.InterLock = new SrdRotationAxisInterLock(rotationAxis);
                 AxisManager.Instance.AddModuleAxis(moduleName.ToString(), rotationAxis);

+ 32 - 16
CyberX8_RT/Devices/SRD/SrdCommonDevice.cs

@@ -803,40 +803,56 @@ namespace CyberX8_RT.Devices.SRD
         public void EnterErrorOperation()
         {
             //关闭风扇
-            if (CommonData.ExhaustOn)
+            if (CommonData.N2On)
             {
                 bool result = N2OffAction("", null);
                 if (!result)
                 {
-                    LOG.WriteLog(eEvent.ERR_SRD, Module, "EnterError: Exhaust Off is failed");
+                    LOG.WriteLog(eEvent.ERR_SRD, Module, "EnterError: N2 Off is failed");
                 }
             }
             //关闭WaterAbove
-            if (CommonData.WaterAbove)
+            if (CommonData.WaterOn)
             {
-                bool result = WaterAboveOff();
+                bool result = WaterOff();
                 if (!result)
                 {
-                    LOG.WriteLog(eEvent.INFO_SRD, Module, "EnterError: Water Above Off is failed");
-                }
-            }
-            //关闭WaterBelow
-            if (CommonData.WaterBelow)
-            {
-                bool result = WaterBelowOff();
-                if (!result)
-                {
-                    LOG.WriteLog(eEvent.INFO_SRD, Module, "EnterError: Water Below Off is failed");
+                    LOG.WriteLog(eEvent.INFO_SRD, Module, "EnterError: Water Off is failed");
                 }
             }
+            
             //停电机
-            JetAxisBase _armAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Arm");
-            if (_armAxis != null && _armAxis.IsRun) _armAxis.StopPositionOperation();
             JetAxisBase _rotationAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Rotation");
             if (_rotationAxis != null && _rotationAxis.IsRun) _rotationAxis.StopPositionOperation();
 
         }
         #endregion
+        /// <summary>
+        /// Rotation InterLock
+        /// </summary>
+        /// <returns></returns>
+        public bool RotationInterLock()
+        {
+            if (!CommonData.DoorClosed)
+            {
+                LOG.WriteLog(eEvent.ERR_SRD, Module, "Door is not closed. Rotation can not position");
+                return false;
+            }
+            //Check Flippers
+            if (CommonData.FlippersIn150 || CommonData.FlippersIn200) //|| _srdCommon.CommonData.FlippersIn100
+            {
+                LOG.WriteLog(eEvent.ERR_SRD, Module, "FlippersIn is on. Rotation can not position");
+                return false;
+            }
+            if (!CommonData.Flipper1Out150Status || !CommonData.Flipper2Out150Status || !CommonData.Flipper3Out150Status
+                || !CommonData.Flipper1Out200Status || !CommonData.Flipper2Out200Status || !CommonData.Flipper3Out200Status)
+            //|| !_srdCommon.CommonData.Flipper1Out100Status || !_srdCommon.CommonData.Flipper2Out100Status || !_srdCommon.CommonData.Flipper3Out100Status
+            {
+                LOG.WriteLog(eEvent.ERR_SRD, Module, "Flippers are at In position. Rotation can not position");
+                return false;
+            }
+            return true;
+        }
 
         /// <summary>
         /// 定时器

+ 13 - 0
CyberX8_RT/Devices/SRD/SrdRotationAxisInterLock.cs

@@ -52,6 +52,19 @@ namespace CyberX8_RT.Devices.SRD
                 LOG.WriteLog(eEvent.ERR_SRD, Module, "Door is not closed,Rotation can not position");
                 return false;
             }
+            //Check Flippers
+            if (common.CommonData.FlippersIn150 || common.CommonData.FlippersIn200) //|| _srdCommon.CommonData.FlippersIn100
+            {
+                LOG.WriteLog(eEvent.ERR_SRD, Module,"FlippersIn is on");
+                return false;
+            }
+            if (!common.CommonData.Flipper1Out150Status || !common.CommonData.Flipper2Out150Status || !common.CommonData.Flipper3Out150Status
+                || !common.CommonData.Flipper1Out200Status || !common.CommonData.Flipper2Out200Status || !common.CommonData.Flipper3Out200Status)
+            //|| !_srdCommon.CommonData.Flipper1Out100Status || !_srdCommon.CommonData.Flipper2Out100Status || !_srdCommon.CommonData.Flipper3Out100Status
+            {
+                LOG.WriteLog(eEvent.ERR_SRD, Module,"Flippers are at In position");
+                return false;
+            }
             return true;
         }
     }

+ 9 - 3
CyberX8_RT/Modules/SRD/SRDEntity.cs

@@ -395,6 +395,7 @@ namespace CyberX8_RT.Modules.SRD
             Transition(SRDState.ProcessReciping, SRDMSG.Abort, AbortProcessRecipe, SRDState.Abort);
             Transition(SRDState.PresenceTesting, SRDMSG.Abort, AbortPresenceTest, SRDState.Abort);
             Transition(SRDState.AWCCycling, SRDMSG.Abort, AbortAWCCycle, SRDState.Abort);
+            Transition(SRDState.ProcessError, SRDMSG.Abort, AbortProcessError, SRDState.Abort);
             //PresenceTestStart
             Transition(SRDState.Idle, SRDMSG.PresenceTestStart, PresenceTest, SRDState.PresenceTesting);
             Transition(SRDState.PresenceTesting, FSM_MSG.TIMER, PresenceTestTimeout, SRDState.Idle);
@@ -671,7 +672,8 @@ namespace CyberX8_RT.Modules.SRD
             RState ret = _processRecipeRoutine.Monitor();
             if (ret == RState.Failed || ret == RState.Timeout)
             {
-                PostMsg(SRDMSG.ProcessError);
+                //PostMsg(SRDMSG.ProcessError);
+                PostMsg(SRDMSG.Error);
                 //记录LotTrack
                 _runRecipeCompleteTime = DateTime.Now;
                 _processRecipeRoutine.SRDLotTrackHeaderDatas.ProcessTime = (_runRecipeCompleteTime - _runRecipeStartTime).TotalSeconds.ToString("F2");
@@ -763,7 +765,11 @@ namespace CyberX8_RT.Modules.SRD
             }
             return false;
         }
-
+        private bool AbortProcessError(object[] param)
+        {
+            _processErrorRoutine.Abort();      
+            return false;
+        }
         /// <summary>
         /// Retry RunRecipe
         /// </summary>
@@ -995,7 +1001,7 @@ namespace CyberX8_RT.Modules.SRD
         /// <returns></returns>
         private bool UnloaderWafer(object[] param)
         {
-            return _unloaderRoutine.Start(param) == RState.Running;
+            return _unloaderRoutine.Start(false) == RState.Running;
         }
         /// <summary>
         /// SRD Unloader Wafer Monitor

+ 5 - 20
CyberX8_RT/Modules/SRD/SRDHomeRoutine.cs

@@ -39,7 +39,6 @@ namespace CyberX8_RT.Modules.Transporter
             End
         }
         #region 内部变量
-        private JetAxisBase _armAxis;
         private JetAxisBase _rotationAxis;
         private SrdCommonDevice _common;
         private SrdCommonDoorCloseRoutine _doorCloseRoutine;
@@ -68,16 +67,12 @@ namespace CyberX8_RT.Modules.Transporter
 
         public RState Monitor()
         {
-            Runner.Run(HomeAllStep.CheckSafety,CheckSafety,_delay_1ms)
+            Runner//.Run(HomeAllStep.CheckSafety,CheckSafety,_delay_1ms)
                 .Run(HomeAllStep.CheckPreCondition, CheckPreCondition,NullFun,_delay_1ms)
                 .Run(HomeAllStep.CloseDoor, () => { return _doorCloseRoutine.Start(true) == RState.Running; }, NullFun, _delay_1ms)
-                .WaitWithStopCondition(HomeAllStep.CheckDoorClosed, () => CommonFunction.CheckRoutineEndState(_doorCloseRoutine), () => CommonFunction.CheckRoutineStopState(_doorCloseRoutine))
-                .Run(HomeAllStep.HomeSRDArm, ArmAxisHome, _delay_1ms)
-                .WaitWithStopCondition(HomeAllStep.CheckArmHome, () => { return _armAxis.IsHomed && _armAxis.Status == RState.End; }, () => { return _armAxis.Status == RState.Failed; })               
+                .WaitWithStopCondition(HomeAllStep.CheckDoorClosed, () => CommonFunction.CheckRoutineEndState(_doorCloseRoutine), () => CommonFunction.CheckRoutineStopState(_doorCloseRoutine))                
                 .Run(HomeAllStep.HomeSRDRotation, RotationAxisHome,_delay_1ms)
-                .WaitWithStopCondition(HomeAllStep.CheckRotationHome, () => { return _rotationAxis.IsHomed && _rotationAxis.Status == RState.End; }, () => { return _rotationAxis.Status == RState.Failed; })
-                .Run(HomeAllStep.ArmHome, () => { return _armAxis.PositionStation("Home", true); }, NullFun, 100)
-                .WaitWithStopCondition(HomeAllStep.ArmHomeWait, () => { return _armAxis.Status == RState.End; }, () => { return _armAxis.Status == RState.Failed; })
+                .WaitWithStopCondition(HomeAllStep.CheckRotationHome, () => { return _rotationAxis.IsHomed && _rotationAxis.Status == RState.End; }, () => { return _rotationAxis.Status == RState.Failed; })               
                 .Run(HomeAllStep.RotationHome, () => { return _rotationAxis.PositionStation("Home",true); }, NullFun, 100)
                 .WaitWithStopCondition(HomeAllStep.RotationHomeWait, () => { return _rotationAxis.Status == RState.End; }, () => { return _rotationAxis.Status == RState.Failed; })
                 .Run(HomeAllStep.OpenDoor, () => { return _doorCloseRoutine.Start(false) == RState.Running; },NullFun,_delay_1ms)
@@ -97,12 +92,7 @@ namespace CyberX8_RT.Modules.Transporter
             {
                 LOG.WriteLog(eEvent.ERR_SRD, Module.ToString(), "Safety device is null");
                 return false;
-            }
-            if (safetyDevice.SafetyData.TwincatState != 8)
-            {
-                LOG.WriteLog(eEvent.ERR_SRD, Module.ToString(), "Twincat Status is not OP status");
-                return false;
-            }
+            }           
             if (safetyDevice.SafetyData.SrdCommErr)
             {
                 LOG.WriteLog(eEvent.ERR_SRD, Module.ToString(), "Twincat SRD Communication status is error");
@@ -121,12 +111,7 @@ namespace CyberX8_RT.Modules.Transporter
         /// <returns></returns>
         private bool CheckPreCondition()
         {
-            //检查电机谁否开启
-            if(! _armAxis.IsSwitchOn)
-            {
-                LOG.WriteLog(eEvent.ERR_SRD, Module, $"{_module}.Arm is switchoff");
-                return false;
-            }
+            //检查电机谁否开启           
             if(!_rotationAxis.IsSwitchOn)
             {
                 LOG.WriteLog(eEvent.ERR_SRD, Module, $"{_module}.Rotation is switchoff");

+ 3 - 3
CyberX8_RT/Modules/SRD/SRDLoaderRoutine.cs

@@ -339,7 +339,7 @@ namespace CyberX8_RT.Modules.SRD
             return false;
         }
         /// <summary>
-        /// Flippers In
+        /// Flippers Out
         /// </summary>
         /// <param name="param"></param>
         /// <returns></returns>
@@ -358,7 +358,7 @@ namespace CyberX8_RT.Modules.SRD
             return true;
         }
         /// <summary>
-        /// 检验FlippersIn结束状态
+        /// 检验FlippersOut结束状态
         /// </summary>
         /// <param name="param"></param>
         /// <returns></returns>
@@ -367,7 +367,7 @@ namespace CyberX8_RT.Modules.SRD
             return _srdCommon.Status == RState.End;
         }
         /// <summary>
-        /// 检验FlippersIn结束状态
+        /// 检验FlippersOut结束状态
         /// </summary>
         /// <param name="param"></param>
         /// <returns></returns>

+ 7 - 32
CyberX8_RT/Modules/SRD/SRDProcessErrorRoutine.cs

@@ -15,11 +15,7 @@ namespace CyberX8_RT.Modules.SRD
     public class SRDProcessErrorRoutine : RoutineBase, IRoutine
     {
         private enum ProcessErrorStep
-        {
-            ArmStop,
-            ArmStopWait,
-            ArmHome,
-            ArmHomeWait,
+        {          
             RotationStop,
             RotationStopWait,
             RotationHome,
@@ -34,21 +30,9 @@ namespace CyberX8_RT.Modules.SRD
         /// </summary>
         private JetAxisBase _rotationAxis;
         /// <summary>
-        /// Arm Axis
-        /// </summary>
-        private JetAxisBase _armAxis;
-        /// <summary>
         /// unload routine
         /// </summary>
-        private SRDUnloadRoutine _unloadRoutine;
-        /// <summary>
-        /// Arm是否正在运动
-        /// </summary>
-        private bool _armIsRun;
-        /// <summary>
-        /// Arm是否Homed
-        /// </summary>
-        private bool _armIsHomed;
+        private SRDUnloaderRoutine _unloaderRoutine;
         /// <summary>
         /// Rotation是否正在运动
         /// </summary>
@@ -78,21 +62,15 @@ namespace CyberX8_RT.Modules.SRD
         /// <returns></returns>
         public RState Monitor()
         {
-            Runner.RunIf(ProcessErrorStep.ArmStop, _armIsRun, () => AxisStop(_armAxis), _delay_1ms)
-                .WaitWithStopConditionIf(ProcessErrorStep.ArmStopWait, _armIsRun, () => { return _armAxis.Status == RState.End; },
-                    () => { return _armAxis.Status == RState.Failed || _armAxis.Status == RState.Timeout; })
-                .RunIf(ProcessErrorStep.ArmHome, !_armIsHomed, () => AxisHome(_armAxis), _delay_1ms)
-                .WaitWithStopConditionIf(ProcessErrorStep.ArmHomeWait, !_armIsHomed, () => { return _armAxis.Status == RState.End; },
-                    () => { return _armAxis.Status == RState.Failed || _armAxis.Status == RState.Timeout; })
-                .RunIf(ProcessErrorStep.RotationStop, _rotationIsRun, () => AxisStop(_rotationAxis), _delay_1ms)
+            Runner.RunIf(ProcessErrorStep.RotationStop, _rotationIsRun, () => AxisStop(_rotationAxis), _delay_1ms)
                 .WaitWithStopConditionIf(ProcessErrorStep.RotationStopWait, _rotationIsRun, () => { return _rotationAxis.Status == RState.End; },
                     () => { return _rotationAxis.Status == RState.Failed || _rotationAxis.Status == RState.Timeout; })
                 .RunIf(ProcessErrorStep.RotationHome, !_rotationIsHomed, () => AxisHome(_rotationAxis), _delay_1ms)
                 .WaitWithStopConditionIf(ProcessErrorStep.RotationHomeWait, !_rotationIsHomed, () => { return _rotationAxis.Status == RState.End; },
                     () => { return _rotationAxis.Status == RState.Failed || _rotationAxis.Status == RState.Timeout; })
-                .Run(ProcessErrorStep.Unload, () => { return _unloadRoutine.Start() == RState.Running; }, _delay_1ms)
-                .WaitWithStopCondition(ProcessErrorStep.UnloadWait, () => CommonFunction.CheckRoutineEndState(_unloadRoutine),
-                    () => CommonFunction.CheckRoutineStopState(_unloadRoutine))
+                .Run(ProcessErrorStep.Unload, () => { return _unloaderRoutine.Start(true) == RState.Running; }, _delay_1ms)
+                .WaitWithStopCondition(ProcessErrorStep.UnloadWait, () => CommonFunction.CheckRoutineEndState(_unloaderRoutine),
+                    () => CommonFunction.CheckRoutineStopState(_unloaderRoutine))
                 .End(ProcessErrorStep.End, NullFun, _delay_1ms);
             return Runner.Status;
         }
@@ -121,13 +99,10 @@ namespace CyberX8_RT.Modules.SRD
         /// <returns></returns>
         public RState Start(params object[] objs)
         {
-            _armAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Arm");
             _rotationAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Rotation");
-            _armIsRun = _armAxis.IsRun;
-            _armIsHomed = _armAxis.IsHomed;
             _rotationIsRun= _rotationAxis.IsRun;
             _rotationIsHomed = _rotationAxis.IsHomed;
-            _unloadRoutine = new SRDUnloadRoutine(Module);
+            _unloaderRoutine = new SRDUnloaderRoutine(Module);
             return Runner.Start(Module, "start process error");
         }
     }

+ 9 - 5
CyberX8_RT/Modules/SRD/SRDProcessRecipeRoutine.cs

@@ -249,7 +249,11 @@ namespace CyberX8_RT.Modules.SRD
             bool result = CommonFunction.CheckRoutineStopState(_loaderRoutine);
             if (result)
             {
-                AddLotTrackData();
+                //AddLotTrackData();
+                if (_srdCommonDevice != null)
+                {
+                    _srdCommonDevice.EnterErrorOperation();
+                }
                 NotifyError(eEvent.ERR_SRD, _loaderRoutine.ErrorMsg, 0);
             }
             return result;
@@ -293,7 +297,7 @@ namespace CyberX8_RT.Modules.SRD
             bool result = CommonFunction.CheckRoutineStopState(_runRecipeRoutine);
             if (result)
             {
-                AddLotTrackData(); 
+                //AddLotTrackData(); 
                 if (_srdCommonDevice != null)
                 {
                     _srdCommonDevice.EnterErrorOperation();
@@ -313,7 +317,7 @@ namespace CyberX8_RT.Modules.SRD
         /// <returns></returns>
         private bool StartUnloader()
         {
-            bool result= _unloaderRoutine.Start() == RState.Running;
+            bool result= _unloaderRoutine.Start(false) == RState.Running;
             if (!result)
             {
                 NotifyError(eEvent.ERR_SRD,_unloaderRoutine.ErrorMsg, 0);
@@ -337,7 +341,7 @@ namespace CyberX8_RT.Modules.SRD
             bool result= CommonFunction.CheckRoutineStopState(_unloaderRoutine);
             if (result)
             {
-                AddLotTrackData();
+                //AddLotTrackData();
                 NotifyError(eEvent.ERR_SRD, _unloaderRoutine.ErrorMsg, 0);
             }
             return result;
@@ -377,7 +381,7 @@ namespace CyberX8_RT.Modules.SRD
             //记录Lottrack
             if (DateTime.Now.Subtract(_lotTackTime).TotalMilliseconds >= LOTTRACK_TIME)
             {
-                AddLotTrackData();
+                //AddLotTrackData();
                 _lotTackTime = DateTime.Now;
             }
         }

+ 5 - 5
CyberX8_RT/Modules/SRD/SRDRotationRoutine.cs

@@ -101,11 +101,7 @@ namespace CyberX8_RT.Modules.SRD
         /// <returns></returns>
         public bool StartRotation()
         {
-            if (_srdCommon.CommonData.DoorOpened)
-            {              
-                 LOG.WriteLog(eEvent.ERR_SRD, _module, "Door is not closed. Can't do rotation");
-                 return false;
-            }
+            
 
             if (!_rotationAxis.IsSwitchOn)
             {
@@ -123,6 +119,10 @@ namespace CyberX8_RT.Modules.SRD
                 LOG.WriteLog(eEvent.ERR_SRD, _module, $"{_module}.Rotation Provider is not exist");
                 return false;
             }
+            if (!_srdCommon.RotationInterLock())
+            {
+                return false;
+            }
             double _scale = _rotationProviderAxis.ScaleFactor;
             //获取当前Position
             double currentPosition = _rotationAxis.MotionData.MotorPosition;

+ 9 - 4
CyberX8_RT/Modules/SRD/SRDRunRecipeRoutine.cs

@@ -155,7 +155,12 @@ namespace CyberX8_RT.Modules.SRD
             _systemFacilities = DEVICE.GetDevice<SystemFacilities>("System.Facilities");
             string otherSRD = Module == "SRD1" ? "SRD2" : "SRD1";
             _otherSrdEntity = Singleton<RouteManager>.Instance.GetModule<SRDEntity>(otherSRD);
-
+            SRDEntity srdEntity = Singleton<RouteManager>.Instance.GetModule<SRDEntity>(Module);
+            if (srdEntity.IsManual && !srdEntity.IsLoaded)
+            {
+                NotifyError(eEvent.ERR_SRD, $"{Module} is not Loaded, can't run recipe", 0);
+                return RState.Failed;
+            }
             _rotationProviderAxis = BeckhoffAxisProviderManager.Instance.GetAxisProvider($"{Module}.Rotation");
             if (_rotationProviderAxis == null)
             {
@@ -389,9 +394,8 @@ namespace CyberX8_RT.Modules.SRD
         /// <returns></returns>
         private bool StartRotation()
         {
-            if (_srdCommon.CommonData.DoorOpened)
+            if (!_srdCommon.RotationInterLock())
             {
-                NotifyError(eEvent.ERR_SRD, "Door is not closed. Can't do rotation", 0);
                 return false;
             }
             double _scale = _rotationProviderAxis.ScaleFactor;
@@ -465,7 +469,7 @@ namespace CyberX8_RT.Modules.SRD
         private bool ChangeSpeed()
         {
             //调整速度为 drySpeed
-            bool result = _rotationAxis.ChangeSpeed(_drySpeed);
+            bool result = _rotationAxis.WriteSpeed(_drySpeed);
             if (!result)
             {
                 NotifyError(eEvent.ERR_SRD, "Change Speed to Dry Speed is failed", 0);
@@ -526,6 +530,7 @@ namespace CyberX8_RT.Modules.SRD
             }
             return false;
         }
+        
     }
     
 }

+ 10 - 11
CyberX8_RT/Modules/SRD/SRDSwitchOnRoutine.cs

@@ -16,7 +16,7 @@ namespace CyberX8_RT.Modules.Transporter
     {
         private enum SwitchOnStep
         {
-            Arm,
+            //Arm,
             Rotation,
             End
         }
@@ -46,21 +46,20 @@ namespace CyberX8_RT.Modules.Transporter
 
         public RState Monitor()
         {
-            Runner.Run(SwitchOnStep.Arm, ArmAxisSwitchOn, CheckArmSwitchOn, _timeOut)
-                .Run(SwitchOnStep.Rotation, RotationAxisSwitchOn, CheckRotationSwitchOn, _timeOut)
+            Runner.Run(SwitchOnStep.Rotation, RotationAxisSwitchOn, CheckRotationSwitchOn, _timeOut)
                 .End(SwitchOnStep.End,NullFun);
 
             return Runner.Status; 
         }
        
-        private bool ArmAxisSwitchOn()
-        {
-            return _armAxis.SwitchOn();
-        }
-        private bool CheckArmSwitchOn()
-        {
-            return _armAxis.IsSwitchOn&&_armAxis.Status==RState.End;
-        }
+        //private bool ArmAxisSwitchOn()
+        //{
+        //    return _armAxis.SwitchOn();
+        //}
+        //private bool CheckArmSwitchOn()
+        //{
+        //    return _armAxis.IsSwitchOn&&_armAxis.Status==RState.End;
+        //}
         private bool RotationAxisSwitchOn()
         {
             return _rotationAxis.SwitchOn();

+ 129 - 3
CyberX8_RT/Modules/SRD/SRDUnloaderRoutine.cs

@@ -1,4 +1,5 @@
-using Aitex.Core.RT.Device;
+using Aitex.Core.Common;
+using Aitex.Core.RT.Device;
 using Aitex.Core.RT.Log;
 using Aitex.Core.RT.Routine;
 using Aitex.Core.RT.SCCore;
@@ -6,7 +7,12 @@ using CyberX8_Core;
 using CyberX8_RT.Devices.AXIS;
 using CyberX8_RT.Devices.Facilities;
 using CyberX8_RT.Devices.SRD;
+using MECF.Framework.Common.Equipment;
+using MECF.Framework.Common.RecipeCenter;
 using MECF.Framework.Common.Routine;
+using MECF.Framework.Common.SubstrateTrackings;
+using System;
+using System.Windows.Input;
 
 namespace CyberX8_RT.Modules.SRD
 {
@@ -14,6 +20,7 @@ namespace CyberX8_RT.Modules.SRD
     {         
         private enum SRDUnloaderStep
         {
+            Unloader_FlippersOut,
             Unloader_ChuckVacuumOff,
             Unloader_ChuckATMOn,
             Unloader_CheckVacuum,
@@ -55,6 +62,10 @@ namespace CyberX8_RT.Modules.SRD
         /// 真空值
         /// </summary>
         private int _vacuumOffLimit = 0;
+        /// <summary>
+        /// Process Error状态
+        /// </summary>
+        private bool _isProcessError = false;
         #endregion
 
         #region 属性
@@ -80,7 +91,8 @@ namespace CyberX8_RT.Modules.SRD
         /// <returns></returns>
         public RState Monitor()
         {
-            Runner.Run(SRDUnloaderStep.Unloader_ChuckVacuumOff, ChuckVacuumOff, CheckChuckVacuumOffEndStatus, CheckChuckVacuumOffStopStatus)
+            Runner.RunIf(SRDUnloaderStep.Unloader_FlippersOut, _isProcessError, FlippersOut, CheckFlippersOutEndStatus, CheckFlippersOutStopStatus)
+                .Run(SRDUnloaderStep.Unloader_ChuckVacuumOff, ChuckVacuumOff, CheckChuckVacuumOffEndStatus, CheckChuckVacuumOffStopStatus)
                 .Run(SRDUnloaderStep.Unloader_ChuckATMOn, ChuckATMOn, CheckChuckATMEndStatus, CheckChuckATMStopStatus)
                 .WaitWithStopCondition(SRDUnloaderStep.Unloader_CheckVacuum, CheckVacuumEndStatus, CheckVacuumStopStatus)
                 .Run(SRDUnloaderStep.Unloader_LiftUpOn, LiftUpOn, CheckLiftUpOnEndStatus, CheckLiftUpOnStopStatus)
@@ -101,10 +113,19 @@ namespace CyberX8_RT.Modules.SRD
             _rotationAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Rotation");
             _systemFacilities = DEVICE.GetDevice<SystemFacilities>("System.Facilities");
             _vacuumOffLimit = SC.GetValue<int>("SRD.ChuckVacuumOffLimit");
-            if (!CheckPreCondition())
+            if (objs.Length >= 1)
+            {
+                _isProcessError = (bool)objs[0];
+            } 
+            if (!_isProcessError && !CheckPreCondition())
             {
                 return RState.Failed;
             }
+            if (!GetWaferSize())
+            {
+                NotifyError(eEvent.ERR_SRD, "Wafer Size is invalid", 0);
+                return RState.Failed;
+            }
             return Runner.Start(Module, "SRD Unloader Start");
         }
         /// <summary>
@@ -395,5 +416,110 @@ namespace CyberX8_RT.Modules.SRD
         {
             return _srdCommon.Status == RState.Failed || _srdCommon.Status == RState.Timeout;
         }
+        /// <summary>
+        /// Flippers Out
+        /// </summary>
+        /// <param name="param"></param>
+        /// <returns></returns>
+        private bool FlippersOut()
+        {
+            bool result = false;
+            object[] objects = new object[1];
+            objects[0] = _waferSize;
+            result = _srdCommon.FlipperOutAction("", objects);
+            if (!result)
+            {
+                NotifyError(eEvent.ERR_SRD, $"FlipperOut{_waferSize} Action is failed", 0);
+                return result;
+            }
+
+            return true;
+        }
+        /// <summary>
+        /// 检验FlippersOut结束状态
+        /// </summary>
+        /// <param name="param"></param>
+        /// <returns></returns>
+        private bool CheckFlippersOutEndStatus()
+        {
+            return _srdCommon.Status == RState.End;
+        }
+        /// <summary>
+        /// 检验FlippersOut结束状态
+        /// </summary>
+        /// <param name="param"></param>
+        /// <returns></returns>
+        private bool CheckFlippersOutStopStatus()
+        {
+            if (_srdCommon.Status == RState.Failed || _srdCommon.Status == RState.Timeout)
+            {
+                NotifyError(eEvent.ERR_SRD, $"Check FlipperOut{_waferSize} Action is failed", 0);
+                return true;
+            }
+            return false;
+        }
+        /// <summary>
+        /// Get current WaferSize
+        /// </summary>
+        /// <returns></returns>
+        private bool GetWaferSize()
+        {
+            WaferInfo waferInfo = WaferManager.Instance.GetWafer(ModuleNameString.ToEnum(Module), 0);
+            if (waferInfo == null)
+            {
+                return false;
+            }
+            switch (waferInfo.Size)
+            {
+
+                case WaferSize.WS4:
+                    _waferSize = 100;
+                    break;
+                case WaferSize.WS6:
+                case WaferSize.WS150:
+                case WaferSize.WS159:
+                    _waferSize = 150;
+                    break;
+                case WaferSize.WS0:
+                case WaferSize.WS8:
+                    _waferSize = 200;
+                    break;
+                default:
+                    return false;
+            }
+            return true;
+        }
+        /// <summary>
+        /// 关闭 Wafer N2
+        /// </summary>
+        /// <returns></returns>
+        private bool N2Off()
+        {
+            if(!_srdCommon.CommonData.N2On) return true;
+            bool result = _srdCommon.N2OffAction("", null);
+            if (!result)
+            {
+                NotifyError(eEvent.ERR_SRD, $"N2 Off Action is failed", 0);
+            }
+            return result;
+        }
+        /// <summary>
+        /// Water Off
+        /// </summary>
+        /// <param name="param"></param>
+        /// <returns></returns>
+        private bool WaterOff()
+        {
+            if (_srdCommon.CommonData.WaterOn)
+            {
+                bool result = _srdCommon.WaterOff();
+                if (!result)               
+                {
+                    NotifyError(eEvent.ERR_SRD, "Water On is failed", 0);
+                }
+                return result;
+            }
+            return true;
+        }
     }
 }

+ 1 - 0
CyberX8_Simulator/Config/UILayout.xml

@@ -26,6 +26,7 @@
 		<SubView Id="Galil2" Name="Loader1" ViewClass="CyberX8_Simulator.Views.GalilView" Assembly="CyberX8_Simulator" Port="58679"/>
 		<SubView Id="Galil3" Name="LoaderTransporter" ViewClass="CyberX8_Simulator.Views.GalilView" Assembly="CyberX8_Simulator" Port="58680"/>
 		<SubView Id="Galil4" Name="ProcessTransporter" ViewClass="CyberX8_Simulator.Views.GalilView" Assembly="CyberX8_Simulator" Port="58681"/>
+		<SubView Id="Galil5" Name="SRD1" ViewClass="CyberX8_Simulator.Views.GalilView" Assembly="CyberX8_Simulator" Port="58682"/>
 	</Navigation>
 	
 	<Navigation Id="Power" Name="Power" >		

+ 8 - 0
Framework/Common/Routine/RoutineRunner.cs

@@ -268,7 +268,15 @@ namespace MECF.Framework.Common.Routine
 
             return this;
         }
+        public RoutineRunner RunIf(Enum id, bool bRun, Func<bool> action, Func<bool> condition, Func<bool> failedCondition, int timeout = _defaultTimeout)
+        {
+            if (bRun)
+            {
+                return Run(id, action, condition, failedCondition,timeout);
+            }
 
+            return this;
+        }
         public RoutineRunner Run(Enum id, Func<bool> action, int delayMS = _defaultDelay)
         {
             if (bAllowSubStepStart(id))