Browse Source

add platingcell interval rinse/entry/ deposition routine

chenzk 1 week ago
parent
commit
28830d558c

+ 2 - 2
Framework/Common/RecipeCenter/CurrentRampProfile.cs

@@ -14,7 +14,7 @@ namespace MECF.Framework.Common.RecipeCenter
         private int _durartionSeconds;
         private double _currentValue;
         private double _PlatingZoffset;
-        private double _PlatingSpeed;
+        private int _PlatingSpeed;
         private bool _biDireaction;
         private int _biDFrequency;
         #endregion
@@ -27,7 +27,7 @@ namespace MECF.Framework.Common.RecipeCenter
         [JsonProperty]
         public double PlatingZoffset { get { return _PlatingZoffset; } set { _PlatingZoffset = value; InvokePropertyChanged(nameof(PlatingZoffset)); } }
         [JsonProperty]
-        public double PlatingSpeed { get { return _PlatingSpeed; } set { _PlatingSpeed = value; InvokePropertyChanged(nameof(PlatingSpeed)); } }
+        public int PlatingSpeed { get { return _PlatingSpeed; } set { _PlatingSpeed = value; InvokePropertyChanged(nameof(PlatingSpeed)); } }
         [JsonProperty]
         public bool BiDireaction { get { return _biDireaction; } set { _biDireaction = value; InvokePropertyChanged(nameof(BiDireaction)); } }
         [JsonProperty]

+ 6 - 6
PunkHPX8_MainPages/Views/VpwRecipeView.xaml

@@ -119,8 +119,8 @@
                     <Button Grid.Row="6" Style="{StaticResource SysBtnStyle}"  IsEnabled="{Binding Enable}" Content="Move Down" Height="26" Width="80" FontSize="10" Command="{Binding MoveDownCommand}" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,165,-20,-50" ></Button>
                     <Button Grid.Row="6" Style="{StaticResource SysBtnStyle}"  IsEnabled="{Binding Enable}" Content="Delete" Height="26" Width="80" FontSize="10" Command="{Binding DeleteCommand}" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,210,-20,-80"/>
 
-                    <UserControls:GroupDigitalBoxControl Grid.Row="6" Title="Flow Set Point" Unit="L/min" MinValue="0" MaxValue="10" Width="120" Margin="0,0,200,119"
-                                       DigitalValue="{Binding Recipe.VacuumPrewetFlowSetPoint,Mode=TwoWay}" 
+                    <UserControls:GroupTextBoxControlDouble Grid.Row="6" Title="Flow Set Point" Unit="L/min" MinValue="0" MaxValue="10.0" Width="120" Margin="0,0,200,119"
+                                       DoubleValue="{Binding Recipe.VacuumPrewetFlowSetPoint,Mode=TwoWay}" 
                                        ValidResult="{Binding PropertyValidResultDic[VacuumPrewetFlowSetPoint],Mode=TwoWay}"  />
                     <UserControls:GroupTextBoxControl Grid.Row="6" Title="Flow Warning" Unit="%" MinValue="0" MaxValue="100" Margin="97,0,105,118" Width="120"
                         IntValue="{Binding Recipe.VacuumPrewetFlowWarningPercent,Mode=TwoWay}" 
@@ -249,8 +249,8 @@ Command="{Binding AutoCurrentBasedFalseCommand}"  IsChecked="{Binding Recipe.Vac
                     <Button Grid.Row="6" Style="{StaticResource SysBtnStyle}"  IsEnabled="{Binding Enable}" Content="Move Down" Height="25" Width="80" FontSize="10" Command="{Binding VentPrewetMoveDownCommand}" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,110,-20,0"></Button>
                     <Button Grid.Row="6" Style="{StaticResource SysBtnStyle}"  IsEnabled="{Binding Enable}" Content="Delete" Height="25" Width="80" FontSize="10" Command="{Binding VentPrewetDeleteCommand}" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,180,-20,0"></Button>
 
-                    <UserControls:GroupDigitalBoxControl Grid.Row="3" Title="Flow Set Point" Unit="L/min" MinValue="0" MaxValue="10" Width="120" Margin="-1,2,201,220"
-                                                          DigitalValue="{Binding Recipe.VentPrewetFlowSetPoint,Mode=TwoWay}" 
+                    <UserControls:GroupTextBoxControlDouble Grid.Row="3" Title="Flow Set Point" Unit="L/min" MinValue="0" MaxValue="10.0" Width="120" Margin="-1,2,201,220"
+                                                          DoubleValue="{Binding Recipe.VentPrewetFlowSetPoint,Mode=TwoWay}" 
                                                           ValidResult="{Binding PropertyValidResultDic[VentPrewetFlowSetPoint],Mode=TwoWay}"  />
                     <UserControls:GroupTextBoxControl Grid.Row="3" Title="Flow Warning" Unit="%" MinValue="0" MaxValue="100" Margin="96,2,84,220" Width="120"
                                            IntValue="{Binding Recipe.VentPrewetFlowWarningPercent,Mode=TwoWay}" 
@@ -319,8 +319,8 @@ Command="{Binding AutoCurrentBasedFalseCommand}"  IsChecked="{Binding Recipe.Ven
                     <Button Grid.Row="6" Style="{StaticResource SysBtnStyle}"  IsEnabled="{Binding Enable}" Content="Move Up" Height="25" Width="80" FontSize="10" Command="{Binding ExtendCleanMoveUpCommand}" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,150,-20,0"></Button>
                     <Button Grid.Row="3" Style="{StaticResource SysBtnStyle}"  IsEnabled="{Binding Enable}" Content="Move Down" FontSize="10" Height="26" Width="80" Command="{Binding ExtendCleanMoveDownCommand}" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,-20,-23"/>
                     <Button Grid.Row="3" Style="{StaticResource SysBtnStyle}"  IsEnabled="{Binding Enable}" Content="Delete" Height="24" Width="80" FontSize="10" Command="{Binding ExtendCleanDeleteCommand}" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,-20,-57"></Button>
-                    <UserControls:GroupDigitalBoxControl Grid.Row="3" Title="Flow Set Point" Unit="L/min" MinValue="0" MaxValue="10" Width="120" Margin="1,3,199,123"
-                                       DigitalValue="{Binding Recipe.ExtendCleanFlowSetPoint,Mode=TwoWay}" 
+                    <UserControls:GroupTextBoxControlDouble Grid.Row="3" Title="Flow Set Point" Unit="L/min" MinValue="0" MaxValue="10.0" Width="120" Margin="1,3,199,123"
+                                       DoubleValue="{Binding Recipe.ExtendCleanFlowSetPoint,Mode=TwoWay}" 
                                        ValidResult="{Binding PropertyValidResultDic[ExtendCleanFlowSetPoint],Mode=TwoWay}"  />
                     <UserControls:GroupTextBoxControl Grid.Row="3" Title="Flow Warning" Unit="%" MinValue="0" MaxValue="100" Margin="100,2,105,122" Width="120"
                         IntValue="{Binding Recipe.ExtendCleanFlowWarningPercent,Mode=TwoWay}" 

+ 19 - 1
PunkHPX8_RT/Devices/AXIS/JetAxisBase.cs

@@ -1137,7 +1137,25 @@ namespace PunkHPX8_RT.Devices.AXIS
             }
             return true;
         }
-
+        /// <summary>
+        /// 计算电机从一个位置移动到另一个位置用时  vercial/rotation 类型都能用
+        /// </summary>
+        /// <param name="sourceLocation"></param>
+        /// <param name="destinationLocation"></param>
+        /// <returns>返回值单位毫秒</returns>
+        public int CalculateVerticaMoveTime(string AxisName,string sourceLocation, string destinationLocation)
+        {
+            Station sourceStation = _stationAxis.Stations.FirstOrDefault(p => p.Name == $"{AxisName}.{sourceLocation}");
+            Station destinationStation = _stationAxis.Stations.FirstOrDefault(p => p.Name == $"{AxisName}.{destinationLocation}");
+            Double.TryParse(sourceStation.Position, out double sourcePosition);
+            Double.TryParse(destinationStation.Position, out double destinationPosition);
+            double time = Math.Abs(destinationPosition - sourcePosition) / MotionData.ProfileVelocity * 1000;
+            if (time <= 0)
+            {
+                return 0;
+            }
+            return (int)time;
+        }
         /// <summary>
         /// 开始运动
         /// </summary>

+ 7 - 2
PunkHPX8_RT/Devices/VpwCell/VpwCellDevice.cs

@@ -99,6 +99,10 @@ namespace PunkHPX8_RT.Devices.VpwCell
         /// 是否在检测totalflow的周期中
         /// </summary>
         private bool _isIntotalFlowCheck=false;
+        /// <summary>
+        /// 检查cellflow的时机flag
+        /// </summary>
+        private bool _cellFlowCheckFlag = false;
         #endregion
 
         #region 属性
@@ -679,7 +683,7 @@ namespace PunkHPX8_RT.Devices.VpwCell
             return true;
         }
 
-        //cell flow满足条件过一段时间自动打开drip阀
+        //total flow满足条件过一段时间自动打开drip阀
         private void CellFlowMonitor()
         {
             _cellFlowSetValue = SC.GetValue<double>("VPWMain.Plumbing.CellFlowStartLowLimit");
@@ -697,8 +701,9 @@ namespace PunkHPX8_RT.Devices.VpwCell
                     _isIntotalFlowCheck = false;//重置监控周期
                     LOG.WriteLog(eEvent.INFO_VPW, Module, $"total flow is large than start limit more than {_dripValveOpenIdlePeriod} min,Drip valve on!");
                     FlowDripOn();
-                    if(_commonData.DiwFlow <= 0)
+                    if (_commonData.DiwFlow <= 0)
                     {
+                        _cellFlowCheckFlag = false;
                         LOG.WriteLog(eEvent.WARN_VPW, Module, $"Drip valve open failed!");
                     }
                 }

+ 305 - 0
PunkHPX8_RT/Modules/PlatingCell/PlatingCellDepositionRoutine.cs

@@ -0,0 +1,305 @@
+using Aitex.Core.RT.Device;
+using Aitex.Core.RT.Log;
+using Aitex.Core.RT.Routine;
+using Aitex.Core.Util;
+using MECF.Framework.Common.Beckhoff.Station;
+using MECF.Framework.Common.CommonData.PowerSupplier;
+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.Text;
+using System.Threading.Tasks;
+
+namespace PunkHPX8_RT.Modules.PlatingCell
+{
+    public class PlatingCellDepositionRoutine : RoutineBase, IRoutine
+    {
+        private enum RunRecipeStep
+        {
+            RunPowerStep,
+            RunPowerStepWait,
+            LoopRotationStart,
+            LoopVerticalGotoOffSet,
+            LoopVerticalGotoOffSetCheck,
+
+            LoopRotationStartIfCurrentIsStoped,//如果当前电机是停止状态,启动起来
+            LoopRotationChangeSpeed,
+            LoopRotationDelay,
+
+            LoopRotationStopIfCurrentIsRuning, //如果当前电机是启动状态,则停止
+            LoopROtationStopCheck,
+            LoopRotationBiRotation,
+            LoopRotationBiRotationCheck,
+
+            LoopUpdateDepositionIndex,
+            LoopEnd,
+            RotationStartIfCurrentIsStoped,
+            End
+        }
+        #region 常量
+        /// <summary>
+        /// ROTATION电机转速比例
+        /// </summary>
+        private const int SPEED_RATIO = 1;
+        private const int ROTATION_FAR_POSITION = 12 * 60 * 60 * 500 * 6; //以500rmp 运行12个小时的位置
+        #endregion
+
+        /// <summary>
+        /// recipe
+        /// </summary>
+        private DepRecipe _recipe;
+        /// <summary>
+        /// Rotation axis
+        /// </summary>
+        private JetAxisBase _rotationAxis;
+        /// <summary>
+        /// Platingcell device
+        /// </summary>
+        private PlatingCellDevice _device;
+        /// <summary>
+        /// vertical axis entity
+        /// </summary>
+        private PlatingCellVerticalEntity _verticalEntity;
+        /// <summary>
+        /// vertical 轴的位置数据
+        /// </summary>
+        private BeckhoffStationAxis _verticalBeckhoffStation;
+        /// <summary>
+        /// 不通电
+        /// </summary>
+        private bool _isZeroCurrent = false;
+        /// <summary>
+        /// 是否双有双向旋转
+        /// </summary>
+        private bool _isBiRotation = false;
+        /// <summary>
+        /// 是否启动smart spin
+        /// </summary>
+        private bool _isSmartSpin = false;
+        /// <summary>
+        /// Power step集合
+        /// </summary>
+        List<PowerSupplierStepPeriodData> _powerSupplierStepPeriodDatas = new List<PowerSupplierStepPeriodData>();
+        /// <summary>
+        /// 双向旋转routine
+        /// </summary>
+        private RotationBiDirectionRoutine _rotationBiDirectionRoutine;
+        /// <summary>
+        /// Plating启动时间
+        /// </summary>
+        private DateTime _platingStartTime;
+        /// <summary>
+        /// 当前执行到电镀步骤的索引
+        /// </summary>
+        private int _depositionStepIndex = 0;
+        /// <summary>
+        /// 构造函数
+        /// </summary>
+        /// <param name="module"></param>
+        public PlatingCellDepositionRoutine(string module) : base(module)
+        {
+            _rotationBiDirectionRoutine = new RotationBiDirectionRoutine(module);
+        }
+        /// <summary>
+        /// 中止
+        /// </summary>
+        public void Abort()
+        {
+            Runner.Stop("Manual Abort");
+        }
+        /// <summary>
+        /// 监控
+        /// </summary>
+        /// <returns></returns>
+        public RState Monitor()
+        {
+            Runner //没有上电保护,此刻给电
+                .RunIf(RunRecipeStep.RunPowerStep, _recipe.IsEntryTypeCold, StartPowerStep, _delay_1ms)
+                .LoopStart(RunRecipeStep.LoopRotationStart, "Start rotation cycle",_recipe.DepStepCount,NullFun)
+                //vertical 调整位置
+                .LoopRunIf(RunRecipeStep.LoopVerticalGotoOffSet, _recipe.DepSteps[_depositionStepIndex].PlatingZoffset!=0, () => StartVertical("Plate", _recipe.DepSteps[_depositionStepIndex].PlatingZoffset),_delay_1ms)
+                .LoopRunIf(RunRecipeStep.LoopVerticalGotoOffSetCheck, _recipe.DepSteps[_depositionStepIndex].PlatingZoffset!=0, CheckVerticalEnd, CheckVerticalError)
+                
+                //不带双向旋转,时间到了直接变速(如果当前电机是停止状态,启动起来)
+                .LoopRunIf(RunRecipeStep.LoopRotationStartIfCurrentIsStoped, CheckRotationIsIdle() && !_recipe.DepSteps[_depositionStepIndex].BiDireaction,
+                   () => { return StartRotation(ROTATION_FAR_POSITION); }, _delay_1ms)
+                .LoopRunIf(RunRecipeStep.LoopRotationChangeSpeed, !_recipe.DepSteps[_depositionStepIndex].BiDireaction,() => ChangeRotationSpeed(_recipe.DepSteps[_depositionStepIndex].PlatingSpeed),_delay_1ms)
+                .LoopDelayIf(RunRecipeStep.LoopRotationDelay, !_recipe.DepSteps[_depositionStepIndex].BiDireaction, _recipe.DepSteps[_depositionStepIndex].DurartionSeconds *1000)
+                
+                //带双向旋转,启动双向旋转的routine(如果当前电机是启动状态,则停止)
+                .LoopRunIf(RunRecipeStep.LoopRotationStopIfCurrentIsRuning, checkRotationIsRunning() && _recipe.DepSteps[_depositionStepIndex].BiDireaction,
+                    _rotationAxis.StopPositionOperation, _delay_1ms)
+                .LoopRunIfWithStopStatus(RunRecipeStep.LoopROtationStopCheck, checkRotationIsRunning() && _recipe.DepSteps[_depositionStepIndex].BiDireaction,
+                    CheckRotationIsIdle, CheckRotationPositionRunStop)
+                .LoopRunIf(RunRecipeStep.LoopRotationBiRotation, _recipe.DepSteps[_depositionStepIndex].BiDireaction, 
+                    () => _rotationBiDirectionRoutine.Start(_recipe.DepSteps[_depositionStepIndex].DurartionSeconds, _recipe.DepSteps[_depositionStepIndex].BiDFrequency, _recipe.DepSteps[_depositionStepIndex].PlatingSpeed) == RState.Running,_delay_1ms)
+                .LoopRunIfWithStopStatus(RunRecipeStep.LoopRotationBiRotationCheck, _recipe.DepSteps[_depositionStepIndex].BiDireaction, 
+                        () => CommonFunction.CheckRoutineEndState(_rotationBiDirectionRoutine), 
+                        () => CommonFunction.CheckRoutineStopState(_rotationBiDirectionRoutine))
+                
+                .LoopRun(RunRecipeStep.LoopUpdateDepositionIndex, UpdateDepositionIndex, _delay_1ms)
+                .LoopEnd(RunRecipeStep.LoopEnd,NullFun,_delay_1ms)
+                //检验步阶电流是否完成
+                .WaitWithStopCondition(RunRecipeStep.RunPowerStepWait, CheckRecipeStepEndStatus, CheckRecipeStepStopStatus, _delay_1ms)
+                
+                //如果电镀最后一步带双向旋转,后续电机会停止,需要再把电机启动起来
+                .RunIf(RunRecipeStep.RotationStartIfCurrentIsStoped, CheckRotationIsIdle(), () => { return StartRotation(ROTATION_FAR_POSITION); }, _delay_1ms)
+                .End(RunRecipeStep.End, NullFun);
+            return Runner.Status;
+        }
+        /// <summary>
+        /// 判断当前电机是否在转
+        /// </summary>
+        /// <returns></returns>
+        private bool checkRotationIsRunning()
+        {
+            return _rotationAxis.Status == RState.Running;
+        }
+        /// <summary>
+        /// 判断电机当前状态是否停止
+        /// </summary>
+        /// <returns></returns>
+        private bool CheckRotationIsIdle()
+        {
+            return _rotationAxis.Status == RState.End;
+        }
+        /// <summary>
+        /// 检验Rotation是否运动失败
+        /// </summary>
+        /// <returns></returns>
+        private bool CheckRotationPositionRunStop()
+        {
+            return _rotationAxis.Status == RState.Failed || _rotationAxis.Status == RState.Timeout;
+        }
+        /// <summary>
+        /// 更新电镀步骤索引
+        /// </summary>
+        /// <returns></returns>
+        private bool UpdateDepositionIndex()
+        {
+            _depositionStepIndex++;
+            return true;
+        }
+        /// <summary>
+        /// 启动PowerSupplier
+        /// </summary>
+        /// <returns></returns>
+        private bool StartPowerStep()
+        {
+            bool result = _device.PowerSupplier.StartSetStepPeriodNoWaitEnd(_powerSupplierStepPeriodDatas);
+            if (!result)
+            {
+                _device.PowerSupplier.DisableOperation("", null);
+                return false;
+            }
+            _platingStartTime = DateTime.Now;
+            return true;
+        }
+        /// <summary>
+        /// 检验Powerstep是否启动完成
+        /// </summary>
+        /// <returns></returns>
+        private bool CheckRecipeStepEndStatus()
+        {
+            if (_isZeroCurrent)
+            {
+                return true;
+            }
+            return _device.PowerSupplier.Status == RState.End;
+
+        }
+        /// <summary>
+        /// 检验Powerstep是否启动失败
+        /// </summary>
+        /// <returns></returns>
+        private bool CheckRecipeStepStopStatus()
+        {
+            if (_isZeroCurrent)
+            {
+                return false;
+            }
+            return _device.PowerSupplier.Status == RState.Failed || _device.PowerSupplier.Status == RState.Timeout;
+        }
+        /// <summary>
+        /// rotation开始旋转
+        /// </summary>
+        /// <param name="param"></param>
+        /// <returns></returns>
+        private bool StartRotation(int targetPosition)
+        {
+            bool result = _rotationAxis.ProfilePosition(targetPosition, _recipe.IntervalRinseSpeed * SPEED_RATIO * 6, 0, 0); //rpm->deg/s
+            if (!result)
+            {
+                NotifyError(eEvent.ERR_PLATINGCELL, "Start Rotation is failed", 0);
+                return false;
+            }
+            return true;
+        }
+        /// <summary>
+        /// rotation改变速度
+        /// </summary>
+        /// <param name="speed"></param>
+        /// <returns></returns>
+        private bool ChangeRotationSpeed(int speed)
+        {
+            double _scale = _rotationAxis.ScaleFactor;
+            speed = (int)Math.Round(_scale * BeckhoffVelocityUtil.ConvertVelocityToDegPerSecondByRPM(speed), 0);
+            return _rotationAxis.ChangeSpeed(speed);
+        }
+        /// <summary>
+        /// vertical 运行
+        /// </summary>
+        /// <param name="positionName"></param> 目标位置名称
+        /// <param name="offset"></param> 偏移量
+        /// <returns></returns>
+        private bool StartVertical(string positionName, double offset)
+        {
+            return _verticalEntity.CheckToPostMessage<PlatingCellVerticalState, PlatingCellVerticalEntity.VerticalMsg>(Aitex.Core.RT.Log.eEvent.INFO_PLATINGCELL,
+                    Module, (int)PlatingCellVerticalEntity.VerticalMsg.Position, positionName, offset);
+        }
+        /// <summary>
+        /// 检验垂直电机是否运动完成
+        /// </summary>
+        /// <returns></returns>
+        private bool CheckVerticalEnd()
+        {
+            return _verticalEntity.IsIdle;
+        }
+        /// <summary>
+        /// 检验垂直是否出现错误
+        /// </summary>
+        /// <returns></returns>
+        private bool CheckVerticalError()
+        {
+            return _verticalEntity.IsError;
+        }
+        /// <summary>
+        /// 启动
+        /// </summary>
+        /// <param name="objs"></param>
+        /// <returns></returns>
+        public RState Start(params object[] objs)
+        {
+            _recipe = (DepRecipe)objs[0];
+            _isZeroCurrent = (bool)objs[1];
+            _isBiRotation = (bool)objs[2];
+            _powerSupplierStepPeriodDatas = (List<PowerSupplierStepPeriodData>)objs[3];
+            _platingStartTime = (DateTime)objs[4];
+            _rotationAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Rotation");
+            _device = DEVICE.GetDevice<PlatingCellDevice>(Module);
+            _depositionStepIndex = 0;
+            //获取vertical entity
+            string vertical = ModuleMatcherManager.Instance.GetPlatingVerticalByCell(Module);
+            _verticalEntity = Singleton<RouteManager>.Instance.GetModule<PlatingCellVerticalEntity>(vertical);
+            //获取vertical station信息对象
+            _verticalBeckhoffStation = BeckhoffStationLocationManager.Instance.GetStationAxis($"{_verticalEntity.Module}", "Vertical");
+            return Runner.Start(Module, "start intervale rinse");
+        }
+    }
+}

+ 227 - 0
PunkHPX8_RT/Modules/PlatingCell/PlatingCellEntryRoutine.cs

@@ -0,0 +1,227 @@
+using Aitex.Core.RT.Device;
+using Aitex.Core.RT.Log;
+using Aitex.Core.RT.Routine;
+using Aitex.Core.Util;
+using MECF.Framework.Common.Beckhoff.Station;
+using MECF.Framework.Common.CommonData.PowerSupplier;
+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.Text;
+using System.Threading.Tasks;
+
+namespace PunkHPX8_RT.Modules.PlatingCell
+{
+    public class PlatingCellEntryRoutine : RoutineBase, IRoutine
+    {
+        private enum RunRecipeStep
+        {
+            RotationStartEntry,
+            RotationChangeToEntrySpeed,
+            AngleTilt,
+            VerticalGotoPlate,
+            WaitEntryCurrentProtectedFromRinse,
+            WaitEntryCurrentProtectedFromHome,
+            RunPowerStepWithEntryProtect,
+            CheckVerticalGotoPlate,
+            AngleVertical,
+            WaitPlatingDelay,
+            End
+        }
+        #region 常量
+        /// <summary>
+        /// ROTATION电机转速比例
+        /// </summary>
+        private const int SPEED_RATIO = 1;
+        #endregion
+
+        /// <summary>
+        /// recipe
+        /// </summary>
+        private DepRecipe _recipe;
+        /// <summary>
+        /// Rotation axis
+        /// </summary>
+        private JetAxisBase _rotationAxis;
+        /// <summary>
+        /// Vertical axis
+        /// </summary>
+        private JetAxisBase _verticalAxis;
+        /// <summary>
+        /// Platingcell device
+        /// </summary>
+        private PlatingCellDevice _device;
+        /// <summary>
+        /// rotation运动的目的地
+        /// </summary>
+        private int _rotationgTargetPosition;
+        /// <summary>
+        /// vertical axis entity
+        /// </summary>
+        private PlatingCellVerticalEntity _verticalEntity;
+        /// <summary>
+        /// Power step集合
+        /// </summary>
+        List<PowerSupplierStepPeriodData> _powerSupplierStepPeriodDatas = new List<PowerSupplierStepPeriodData>();
+        /// <summary>
+        /// Plating启动时间
+        /// </summary>
+        private DateTime _platingStartTime;
+        /// <summary>
+        /// 构造函数
+        /// </summary>
+        /// <param name="module"></param>
+        public PlatingCellEntryRoutine(string module) : base(module)
+        {
+
+        }
+        /// <summary>
+        /// 中止
+        /// </summary>
+        public void Abort()
+        {
+            Runner.Stop("Manual Abort");
+        }
+        /// <summary>
+        /// 监控
+        /// </summary>
+        /// <returns></returns>
+        public RState Monitor()
+        {        //启动Rotation/Rotation 设置为entry 转速 (没有intercal rinse 在entry开始的时候启动rotation)
+            Runner.RunIf(RunRecipeStep.RotationStartEntry, !_recipe.RinseBeforeEntryEnable, RotationStartEntry, _delay_1ms)
+                //有intercal rinse 直接变速 (rotation在interval rinse的时候已经启动了)
+                .RunIf(RunRecipeStep.RotationChangeToEntrySpeed, _recipe.RinseBeforeEntryEnable, () => { return ChangeSpeed(_recipe.EntrySpinSpeed); }, _delay_1ms)
+                //Angle tilt 操作
+                .Run(RunRecipeStep.AngleTilt, _device.HeadtTiltAction, () => { return _device.PlatingCellDeviceData.IsHeadTilt; }, _delay_1s)
+                //vertical goto plate
+                .Run(RunRecipeStep.VerticalGotoPlate, () => { return StartVertical("Plate", _recipe.EntryZoffset); }, _delay_1ms)
+                //vertical 到达entry位置前110ms (多10ms)
+                .Delay(RunRecipeStep.WaitEntryCurrentProtectedFromRinse, CalculatePowerDelayTime())
+                //有上电保护,此刻给电
+                .RunIf(RunRecipeStep.RunPowerStepWithEntryProtect, !_recipe.IsEntryTypeCold, StartPowerStep, _delay_1ms)
+                //检查vertical到达plate位置
+                .WaitWithStopCondition(RunRecipeStep.CheckVerticalGotoPlate, CheckVerticalEnd, CheckVerticalError)
+                //Angle vertical操作
+                .Run(RunRecipeStep.AngleVertical, _device.HeadtVerticalAction, () => { return _device.PlatingCellDeviceData.IsHeadVertical; }, _delay_1s)
+                //如果不需要上电保护,执行plating delay
+                .RunIf(RunRecipeStep.WaitPlatingDelay, _recipe.IsEntryTypeCold, NullFun, _recipe.PlatingDelay)
+                .End(RunRecipeStep.End, NullFun);
+            return Runner.Status;
+        }
+        /// <summary>
+        /// 计算出上电前需要delay的时间 
+        /// </summary>
+        /// <returns> 返回值单位ms</returns>
+        private int CalculatePowerDelayTime()
+        {
+            int delayTime = 0;
+            if (!_recipe.RinseBeforeEntryEnable)
+            {
+                delayTime = _verticalAxis.CalculateVerticaMoveTime(_verticalAxis.Name, "Rinse", "Entry") - 110;
+            }
+            else
+            {
+                delayTime = _verticalAxis.CalculateVerticaMoveTime(_verticalAxis.Name, "Home", "Entry") - 110;
+
+            }
+            return delayTime;
+        }
+        /// <summary>
+        /// 启动PowerSupplier
+        /// </summary>
+        /// <returns></returns>
+        private bool StartPowerStep()
+        {
+            bool result = _device.PowerSupplier.StartSetStepPeriodNoWaitEnd(_powerSupplierStepPeriodDatas);
+            if (!result)
+            {
+                _device.PowerSupplier.DisableOperation("", null);
+                return false;
+            }
+            _platingStartTime = DateTime.Now;
+            return true;
+        }
+        /// <summary>
+        /// rotation 从entry步骤开始旋转
+        /// </summary>
+        /// <returns></returns>
+        private bool RotationStartEntry()
+        {
+            bool result = _rotationAxis.ProfilePosition(_rotationgTargetPosition, _recipe.EntrySpinSpeed * SPEED_RATIO, 0, 0);
+            if (!result)
+            {
+                NotifyError(eEvent.ERR_PLATINGCELL, "Start Rotation is failed", 0);
+                return false;
+            }
+            return true;
+        }
+        /// <summary>
+        /// change speed
+        /// </summary>
+        /// <returns></returns>
+        private bool ChangeSpeed(int speed)  //参数speed单位是rmp
+        {
+            double realSpeed = BeckhoffVelocityUtil.ConvertVelocityToDegPerSecondByRPM(speed);
+            bool result = _rotationAxis.ChangeSpeed((int)realSpeed);
+            if (!result)
+            {
+                NotifyError(eEvent.ERR_PLATINGCELL, "Change Speed failed", 0);
+                return false;
+            }
+            return true;
+        }
+        /// <summary>
+        /// vertical 运行
+        /// </summary>
+        /// <param name="positionName"></param> 目标位置名称
+        /// <param name="offset"></param> 偏移量
+        /// <returns></returns>
+        private bool StartVertical(string positionName, double offset)
+        {
+            return _verticalEntity.CheckToPostMessage<PlatingCellVerticalState, PlatingCellVerticalEntity.VerticalMsg>(Aitex.Core.RT.Log.eEvent.INFO_PLATINGCELL,
+                    Module, (int)PlatingCellVerticalEntity.VerticalMsg.Position, positionName, offset);
+        }
+        
+        /// <summary>
+        /// 检验垂直电机是否运动完成
+        /// </summary>
+        /// <returns></returns>
+        private bool CheckVerticalEnd()
+        {
+            return _verticalEntity.IsIdle;
+        }
+        /// <summary>
+        /// 检验垂直是否出现错误
+        /// </summary>
+        /// <returns></returns>
+        private bool CheckVerticalError()
+        {
+            return _verticalEntity.IsError;
+        }
+        /// <summary>
+        /// 启动
+        /// </summary>
+        /// <param name="objs"></param>
+        /// <returns></returns>
+        public RState Start(params object[] objs)
+        {
+            _recipe = (DepRecipe)objs[0];
+            _rotationgTargetPosition = (int)objs[1];
+            _powerSupplierStepPeriodDatas = (List<PowerSupplierStepPeriodData>)objs[2];
+            _platingStartTime = (DateTime)objs[3];
+            _rotationAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Rotation");
+            _device = DEVICE.GetDevice<PlatingCellDevice>(Module);
+            //获取vertical entity
+            string vertical = ModuleMatcherManager.Instance.GetPlatingVerticalByCell(Module);
+            _verticalEntity = Singleton<RouteManager>.Instance.GetModule<PlatingCellVerticalEntity>(vertical);
+            _verticalAxis = DEVICE.GetDevice<JetAxisBase>($"{vertical}.Vertical");//不能用来移动
+            return Runner.Start(Module, "start intervale rinse");
+        }
+    }
+}

+ 50 - 14
PunkHPX8_RT/Modules/PlatingCell/PlatingCellInterRinseRoutine.cs

@@ -1,12 +1,17 @@
-using Aitex.Core.RT.Log;
+using Aitex.Core.RT.Device;
+using Aitex.Core.RT.Log;
 using Aitex.Core.RT.Routine;
+using Aitex.Core.Util;
 using MECF.Framework.Common.Beckhoff.AxisProvider;
+using MECF.Framework.Common.Beckhoff.Station;
 using MECF.Framework.Common.RecipeCenter;
 using MECF.Framework.Common.Routine;
+using MECF.Framework.Common.ToolLayout;
 using MECF.Framework.Common.Utilities;
 using PunkHPX8_Core;
 using PunkHPX8_RT.Devices.AXIS;
 using PunkHPX8_RT.Devices.PlatingCell;
+using PunkHPX8_RT.Modules.Reservoir;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -19,6 +24,8 @@ namespace PunkHPX8_RT.Modules.PlatingCell
     {
         private enum RunRecipeStep
         {
+            VerticalGotoRinse,
+            CheckVerticalGotoRinse,
             OpenRinseValve,
             StartRotation,
             WaitRotation,
@@ -45,14 +52,13 @@ namespace PunkHPX8_RT.Modules.PlatingCell
         /// </summary>
         private PlatingCellDevice _device;
         /// <summary>
-        ///rotation Provider对象
+        /// rotation运动的目的地
         /// </summary>
-        private BeckhoffProviderAxis _rotationProviderAxis;
+        private int _rotationgTargetPosition;
         /// <summary>
-        /// rotation运动的目的地
+        /// vertical axis entity
         /// </summary>
-        private int _targetPosition;
-
+        private PlatingCellVerticalEntity _verticalEntity;
         /// <summary>
         /// 构造函数
         /// </summary>
@@ -73,9 +79,11 @@ namespace PunkHPX8_RT.Modules.PlatingCell
         /// </summary>
         /// <returns></returns>
         public RState Monitor()
-        {
-            Runner.Run(RunRecipeStep.OpenRinseValve, _device.RinseEnableAction, _delay_1ms)
-                .Run(RunRecipeStep.StartRotation, () => { return StartRotation(_targetPosition); }, _delay_1ms)
+        {          
+            Runner.Run(RunRecipeStep.VerticalGotoRinse,  () => { return StartVertical("Rinse", _recipe.IntervalRinseZoffset); }, _delay_1ms)
+                .WaitWithStopCondition(RunRecipeStep.CheckVerticalGotoRinse, CheckVerticalEnd, CheckVerticalError)
+                .Run(RunRecipeStep.OpenRinseValve, _device.RinseEnableAction, _delay_1ms)
+                .Run(RunRecipeStep.StartRotation, () => { return StartRotation(_rotationgTargetPosition); }, _delay_1ms)
                 .Delay(RunRecipeStep.WaitRotation, _recipe.IntervalRinseTime*1000)
                 .Run(RunRecipeStep.CloseRinseValve, _device.RinseDisableAction, _delay_1ms)
                 .End(RunRecipeStep.End, NullFun);
@@ -97,7 +105,33 @@ namespace PunkHPX8_RT.Modules.PlatingCell
             }
             return true;
         }
-
+        /// <summary>
+        /// vertical 运行
+        /// </summary>
+        /// <param name="positionName"></param> 目标位置名称
+        /// <param name="offset"></param> 偏移量
+        /// <returns></returns>
+        private bool StartVertical(string positionName, double offset)
+        {
+            return _verticalEntity.CheckToPostMessage<PlatingCellVerticalState, PlatingCellVerticalEntity.VerticalMsg>(Aitex.Core.RT.Log.eEvent.INFO_PLATINGCELL,
+                    Module, (int)PlatingCellVerticalEntity.VerticalMsg.Position, positionName,  offset);
+        }
+        /// <summary>
+        /// 检验垂直电机是否运动完成
+        /// </summary>
+        /// <returns></returns>
+        private bool CheckVerticalEnd()
+        {
+            return _verticalEntity.IsIdle;
+        }
+        /// <summary>
+        /// 检验垂直是否出现错误
+        /// </summary>
+        /// <returns></returns>
+        private bool CheckVerticalError()
+        {
+            return _verticalEntity.IsError;
+        }
         /// <summary>
         /// 启动
         /// </summary>
@@ -106,10 +140,12 @@ namespace PunkHPX8_RT.Modules.PlatingCell
         public RState Start(params object[] objs)
         {
             _recipe = (DepRecipe)objs[0];
-            _rotationAxis = (JetAxisBase)objs[1];
-            _device = (PlatingCellDevice)objs[2];
-            _rotationProviderAxis = (BeckhoffProviderAxis)objs[3];
-            _targetPosition = (int)objs[4];
+            _rotationgTargetPosition = (int)objs[1];
+            _rotationAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Rotation");
+            _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 intervale rinse");
         }
     }

+ 46 - 185
PunkHPX8_RT/Modules/PlatingCell/PlatingCellRunRecipeRoutine.cs

@@ -31,23 +31,12 @@ namespace PunkHPX8_RT.Modules.PlatingCell
     {
         private enum RunRecipeStep
         {
-            Delay,
-            VerticalGotoRinse,
-            CheckVerticalGotoRinse,
             InterRinse,
             CheckInterRinse,
-            RotationStartEntry,
-            RotationChangeToEntrySpeed,
-            AngleTilt,
-            VerticalGotoPlate,
-            WaitEntryCurrentProtectedFromRinse,
-            WaitEntryCurrentProtectedFromHome,
-            RunPowerStepWithEntryProtect,
-            CheckVerticalGotoPlate,
-            AngleVertical,
-            WaitPlatingDelay,
-            RunPowerStep,
-            RunPowerStepWait,
+            Entry,
+            CheckEntry,
+            Deposition,
+            CheckDeposition,
             End
         }
         #region 常量 
@@ -94,10 +83,6 @@ namespace PunkHPX8_RT.Modules.PlatingCell
         /// </summary>
         private ReservoirEntity _reservoirEntity;
         /// <summary>
-        /// interbal rinse routien
-        /// </summary>
-        private PlatingCellInterRinseRoutine _interRinseRoutine;
-        /// <summary>
         /// vertical axis entity
         /// </summary>
         private PlatingCellVerticalEntity _verticalEntity;
@@ -117,27 +102,44 @@ namespace PunkHPX8_RT.Modules.PlatingCell
 
         #region 电镀通电相关
         /// <summary>
-        /// PlatingDelay计时
-        /// </summary>
-        private DateTime _hotPlatingRunTime;
-        /// <summary>
         /// 不通电
         /// </summary>
         private bool _isZeroCurrent = false;
         /// <summary>
-        /// 通电时长
-        /// </summary>
-        private int _totalMicrosecond = 0;
-        /// <summary>
-        /// Power 集合
+        /// Power step集合
         /// </summary>
         List<PowerSupplierStepPeriodData> _powerSupplierStepPeriodDatas = new List<PowerSupplierStepPeriodData>();
         /// <summary>
         /// 记录dep recipe中出现的最大电流,用于启动电源前切换挡位
         /// </summary>
         private double _maxCurrent = 0;
+        /// <summary>
+        /// 通电总时长
+        /// </summary>
+        private int _totalMicrosecond = 0;
+        /// <summary>
+        /// Plating启动时间
+        /// </summary>
+        private DateTime _platingStartTime;
+        #endregion
+
+        #region routine
+        /// <summary>
+        /// interbal rinse routien
+        /// </summary>
+        private PlatingCellInterRinseRoutine _interRinseRoutine;
+        /// <summary>
+        /// entry routien
+        /// </summary>
+        private PlatingCellEntryRoutine _entryRoutine;
+        /// <summary>
+        /// entry routien
+        /// </summary>
+        private PlatingCellDepositionRoutine _depositionRoutine;
         #endregion
 
+        #region 属性
+        #endregion
 
         #endregion
         /// <summary>
@@ -147,6 +149,8 @@ namespace PunkHPX8_RT.Modules.PlatingCell
         public PlatingCellRunRecipeRoutine(string module) : base(module)
         {
             _interRinseRoutine = new PlatingCellInterRinseRoutine(module);
+            _entryRoutine = new PlatingCellEntryRoutine(module);
+            _depositionRoutine = new PlatingCellDepositionRoutine(module);
         }
         /// <summary>
         /// 中止
@@ -160,112 +164,25 @@ namespace PunkHPX8_RT.Modules.PlatingCell
         /// </summary>
         /// <returns></returns>
         public RState Monitor()
-        {        //vertical去rinse位置
-            Runner.RunIf(RunRecipeStep.VerticalGotoRinse, _recipe.RinseBeforeEntryEnable, () => { return StartVertical("Rinse", _recipe.IntervalRinseZoffset); }, _delay_1ms)
-                .WaitWithStopConditionIf(RunRecipeStep.CheckVerticalGotoRinse, _recipe.RinseBeforeEntryEnable, CheckVerticalEnd, CheckVerticalError)
-                //执行interval rinse
-                .RunIf(RunRecipeStep.InterRinse, _recipe.RinseBeforeEntryEnable, () => { return _interRinseRoutine.Start(_recipe, _rotationAxis, _device, _rotationProviderAxis, _targetPositionList[0]) == RState.Running; })
+        {         //interval rinse
+            Runner.RunIf(RunRecipeStep.InterRinse, _recipe.RinseBeforeEntryEnable, () => { return _interRinseRoutine.Start(_recipe, _targetPositionList[0]) == RState.Running; })
                 .WaitWithStopConditionIf(RunRecipeStep.CheckInterRinse, _recipe.RinseBeforeEntryEnable, CheckInterRinseEndStatus,
                         () => CommonFunction.CheckRoutineStopState(_interRinseRoutine))
-                //启动Rotation/Rotation 设置为entry 转速 (没有intercal rinse 在entry开始的时候启动rotation)
-                .RunIf(RunRecipeStep.RotationStartEntry, !_recipe.RinseBeforeEntryEnable, RotationStartEntry, _delay_1ms)
-                //有intercal rinse 直接变速 (rotation在interval rinse的时候已经启动了)
-                .RunIf(RunRecipeStep.RotationChangeToEntrySpeed, _recipe.RinseBeforeEntryEnable, () => { return ChangeSpeed(_recipe.EntrySpinSpeed); }, _delay_1ms) 
-                //Angle tilt 操作
-                .Run(RunRecipeStep.AngleTilt, _device.HeadtTiltAction, () => { return _device.PlatingCellDeviceData.IsHeadTilt; }, _delay_1s)
-                //vertical goto plate
-                .Run(RunRecipeStep.VerticalGotoPlate, () => { return StartVertical("Plate", _recipe.EntryZoffset); }, _delay_1ms)
-                //vertical 到达entry位置前110ms (多10ms)
-                .DelayIf(RunRecipeStep.WaitEntryCurrentProtectedFromRinse, !_recipe.RinseBeforeEntryEnable, CalculateVerticaMoveTime("Rinse", "Entry") - 110 > 0 ? CalculateVerticaMoveTime("Rinse", "Entry") : 0) 
-                .DelayIf(RunRecipeStep.WaitEntryCurrentProtectedFromHome, _recipe.RinseBeforeEntryEnable, CalculateVerticaMoveTime("Home", "Entry") - 110 > 0 ? CalculateVerticaMoveTime("Home", "Entry") : 0)
-                //有上电保护,此刻给电
-                .RunIf(RunRecipeStep.RunPowerStepWithEntryProtect, !_recipe.IsEntryTypeCold,StartPowerStep, _delay_1ms)
-                //检查vertical到达plate位置
-                .WaitWithStopCondition(RunRecipeStep.CheckVerticalGotoPlate, CheckVerticalEnd, CheckVerticalError)
-                //Angle vertical操作
-                .Run(RunRecipeStep.AngleVertical, _device.HeadtVerticalAction, () => { return _device.PlatingCellDeviceData.IsHeadVertical; }, _delay_1s)
-                //如果不需要上电保护,执行plating delay
-                .RunIf(RunRecipeStep.WaitPlatingDelay, _recipe.IsEntryTypeCold, NullFun, _recipe.PlatingDelay)
-                //没有上电保护,此刻给电
-                .RunIf(RunRecipeStep.RunPowerStep, _recipe.IsEntryTypeCold, StartPowerStep, _delay_1ms)
-                .WaitWithStopCondition(RunRecipeStep.RunPowerStepWait, CheckRecipeStepEndStatus, CheckRecipeStepStopStatus, _delay_1ms)
+                //entry
+                .Run(RunRecipeStep.Entry,  () => { return _entryRoutine.Start(_recipe, _targetPositionList[0], _powerSupplierStepPeriodDatas,_platingStartTime) == RState.Running; })
+                .WaitWithStopCondition(RunRecipeStep.CheckEntry, CheckInterRinseEndStatus,
+                        () => CommonFunction.CheckRoutineStopState(_entryRoutine))
+
+                //Deposition
+                .Run(RunRecipeStep.Deposition, () => { return _depositionRoutine.Start(_recipe, _isZeroCurrent, _isRecipeContainsRevserseRotation,_powerSupplierStepPeriodDatas, _platingStartTime) == RState.Running; })
+                .WaitWithStopCondition(RunRecipeStep.CheckDeposition, CheckInterRinseEndStatus,
+                        () => CommonFunction.CheckRoutineStopState(_depositionRoutine))
+
                 .End(RunRecipeStep.End, NullFun);
             return Runner.Status;
         }
-        /// <summary>
-        /// 启动PowerSupplier
-        /// </summary>
-        /// <returns></returns>
-        private bool StartPowerStep()
-        {
-            bool result = _device.PowerSupplier.StartSetStepPeriodNoWaitEnd(_powerSupplierStepPeriodDatas);
-            if (!result)
-            {
-                _device.PowerSupplier.DisableOperation("", null);
-                return false;
-            }
-            return true;
-        }
-        /// <summary>
-        /// 检验Powerstep是否启动完成
-        /// </summary>
-        /// <returns></returns>
-        private bool CheckRecipeStepEndStatus()
-        {
-            if (_isZeroCurrent)
-            {
-                return true;
-            }
-            return _device.PowerSupplier.Status == RState.End;
-       
-        }
-        /// <summary>
-        /// 检验Powerstep是否启动失败
-        /// </summary>
-        /// <returns></returns>
-        private bool CheckRecipeStepStopStatus()
-        {
-            if (_isZeroCurrent)
-            {
-                return false;
-            }
-            return _device.PowerSupplier.Status == RState.Failed || _device.PowerSupplier.Status == RState.Timeout;
-        }
-        /// <summary>
-        /// 计算vertical 从一个位置移动到另一个位置用时
-        /// </summary>
-        /// <param name="sourceLocation"></param>
-        /// <param name="destinationLocation"></param>
-        /// <returns>返回值单位毫秒</returns>
-        private int CalculateVerticaMoveTime(string sourceLocation,string destinationLocation) 
-        {
-            Station sourceStation = _verticalBeckhoffStation.Stations.FirstOrDefault(p => p.Name == $"{_verticalEntity.Module}.{sourceLocation}");
-            Station destinationStation = _verticalBeckhoffStation.Stations.FirstOrDefault(p => p.Name == $"{_verticalEntity.Module}.{destinationLocation}");
-            Double.TryParse(sourceStation.Position, out double sourcePosition);
-            Double.TryParse(destinationStation.Position, out double destinationPosition);
-            double time = Math.Abs(destinationPosition - sourcePosition) / _verticalEntity.MotionData.ProfileVelocity * 10;
-            if (time <= 0)
-            {
-                NotifyError(eEvent.WARN_PLATINGCELL, "Calculate Vertica Move Time is 0", 0);
-                return 0;
-            }
-            return (int)time;
-        }
-        /// <summary>
-        /// change speed
-        /// </summary>
-        /// <returns></returns>
-        private bool ChangeSpeed(int speed)  //参数speed单位是rmp
-        {
-            double realSpeed = BeckhoffVelocityUtil.ConvertVelocityToDegPerSecondByRPM(speed);
-            bool result = _rotationAxis.ChangeSpeed((int)realSpeed);
-            if (!result)
-            {
-                NotifyError(eEvent.ERR_PLATINGCELL, "Change Speed failed", 0);
-                return false;
-            }
-            return true;
-        }
+
+
         private bool CheckInterRinseEndStatus()
         {
             bool result = CommonFunction.CheckRoutineEndState(_interRinseRoutine);
@@ -273,62 +190,6 @@ namespace PunkHPX8_RT.Modules.PlatingCell
             return result;
         }
         /// <summary>
-        /// rotation 从entry步骤开始旋转
-        /// </summary>
-        /// <returns></returns>
-        private bool RotationStartEntry()
-        {
-            bool result = _rotationAxis.ProfilePosition(_targetPositionList[0], _recipe.IntervalRinseSpeed * SPEED_RATIO, 0, 0);
-            if (!result)
-            {
-                NotifyError(eEvent.ERR_PLATINGCELL, "Start Rotation is failed", 0);
-                return false;
-            }
-            return true;
-        }
-        /// <summary>
-        /// vertical 运行
-        /// </summary>
-        /// <param name="positionName"></param> 目标位置名称
-        /// <param name="offset"></param> 偏移量
-        /// <returns></returns>
-        private bool StartVertical(string positionName,double offset) 
-        {
-            double position = 0;
-            Station station = _verticalBeckhoffStation.Stations.FirstOrDefault(p => p.Name == $"{_verticalEntity.Module}.{positionName}");
-            if (station != null)
-            {
-                if(!Double.TryParse(station.Position, out position))
-                {
-                    LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, "vertical station position is error");
-                    return false;
-                }
-            }
-            else
-            {
-                LOG.WriteLog(eEvent.ERR_PLATINGCELL, Module, $"vertical station {_verticalEntity.Module}.{positionName} is null");
-                return false;
-            }
-            return _verticalEntity.CheckToPostMessage<PlatingCellVerticalState, PlatingCellVerticalEntity.VerticalMsg>(Aitex.Core.RT.Log.eEvent.INFO_PLATINGCELL,
-                    Module, (int)PlatingCellVerticalEntity.VerticalMsg.Position, position + offset);
-        }
-        /// <summary>
-        /// 检验垂直电机是否运动完成
-        /// </summary>
-        /// <returns></returns>
-        private bool CheckVerticalEnd()
-        {
-            return _verticalEntity.IsIdle;
-        }
-        /// <summary>
-        /// 检验垂直是否出现错误
-        /// </summary>
-        /// <returns></returns>
-        private bool CheckVerticalError()
-        {
-            return _verticalEntity.IsError;
-        }
-        /// <summary>
         /// 启动
         /// </summary>
         /// <param name="objs"></param>

+ 4 - 4
PunkHPX8_RT/Modules/PlatingCell/RotationBiDirectionRoutine.cs

@@ -170,7 +170,7 @@ namespace PunkHPX8_RT.Modules.PlatingCell
             return result;
         }
         /// <summary>
-        /// 检验Rotation是否还在运动
+        /// 检验Rotation是否运动失败
         /// </summary>
         /// <returns></returns>
         private bool CheckRotationPositionRunStop()
@@ -184,9 +184,9 @@ namespace PunkHPX8_RT.Modules.PlatingCell
         /// <returns></returns>
         public RState Start(params object[] objs)
         {
-            _rotationTime = (int)objs[0];
-            _frequency = (int)objs[1];
-            _speed = (int)objs[2];
+            _rotationTime = (int)objs[0]; //单位s
+            _frequency = (int)objs[1]; //单位s
+            _speed = (int)objs[2]; //单位rmp
             if(_frequency > _rotationTime)
             {
                 NotifyError(eEvent.ERR_PLATINGCELL, "frequency can not large than rotation time", 0);

+ 2 - 0
PunkHPX8_RT/PunkHPX8_RT.csproj

@@ -300,7 +300,9 @@
     <Compile Include="Devices\Reservoir\CAPumpOnRoutine.cs" />
     <Compile Include="Modules\ModuleMatcherManager.cs" />
     <Compile Include="Modules\PlatingCell\PlatingCellCCRRoutine.cs" />
+    <Compile Include="Modules\PlatingCell\PlatingCellDepositionRoutine.cs" />
     <Compile Include="Modules\PlatingCell\PlatingCellEntity.cs" />
+    <Compile Include="Modules\PlatingCell\PlatingCellEntryRoutine.cs" />
     <Compile Include="Modules\PlatingCell\PlatingCellInterRinseRoutine.cs" />
     <Compile Include="Modules\PlatingCell\PlatingCellVerticalPositionRoutine.cs" />
     <Compile Include="Modules\PlatingCell\PlatingCellVerticalInitializeRoutine.cs" />

+ 1 - 1
PunkHPX8_Themes/UserControls/GroupTextBoxControlDouble.xaml

@@ -15,7 +15,7 @@
                 <Control:DoubleTextBox Name="txtValue" Value="{Binding ElementName=self,Path=DoubleValue,Mode=TwoWay}" Height="30" VerticalAlignment="Top"  Margin="18,3,55,0"/>
                 <Label Content="{Binding ElementName=self,Path=Unit}" HorizontalAlignment="Right" VerticalAlignment="Top" Height="30" Width="55" Margin="0,3,0,0"></Label>
                 <Label Content="{Binding ElementName=self,Path=MinValue}" HorizontalAlignment="Left" Width="40" Margin="17,31,0,-9"/>
-                <Label Content="{Binding ElementName=self,Path=MaxValue}" HorizontalAlignment="Right" Width="40" Margin="0,31,30,-9"/>
+                <TextBlock Text="{Binding ElementName=self,Path=MaxValue,StringFormat={}{0:F1}}" HorizontalAlignment="Right" Width="40" Margin="0,36,30,-9"/>
             </Grid>
         </GroupBox>
     </Grid>