Browse Source

add Booster Pump speed adjust;

chenkui 2 weeks ago
parent
commit
8405df311e

+ 82 - 13
Framework/Common/Algorithm/PdiAlgorithm.cs

@@ -10,6 +10,9 @@ namespace MECF.Framework.Common.Algorithm
 {
     public class PdiAlgorithm : Singleton<PdiAlgorithm>
     {
+        #region 常量
+        private const double RANGE_PRESSURE = 2;
+        #endregion
         #region 内部变量
         /// <summary>
         /// 差额系数
@@ -46,7 +49,8 @@ namespace MECF.Framework.Common.Algorithm
         /// <param name="pressure"></param>
         /// <param name="speed"></param>
         /// <returns></returns>
-        public short CalculateSpeed(double kp,double ki,double kd,double targetPressure,double pressure,short speed,double targetLimit)
+        public short CalculateSpeed(double kp, double ki, double kd, double targetPressure, double pressure, short speed, double targetLimit,
+            double downTargetLimit, double minSpeedDelta)
         {
             _kp = kp;
             _ki = ki;
@@ -54,39 +58,104 @@ namespace MECF.Framework.Common.Algorithm
             _targetPressure = targetPressure;
             _maxBias = 0.5 * targetPressure;
             double index = 0;
-            double bias=_targetPressure - pressure;
-            if(Math.Abs(bias)<=targetLimit)
+            double bias = _targetPressure - pressure;
+            if (bias >= 0 && bias <= targetLimit)
+            {
+                return speed;
+            }
+            if (bias >= -downTargetLimit && bias < 0)
             {
                 return speed;
             }
+
             _integral += bias;
-            if(Math.Abs(bias)>_maxBias)
+            if (Math.Abs(bias) > _maxBias)
             {
                 index = 0;
             }
-            else if(Math.Abs(bias)<0.9*_maxBias)
+            else if (Math.Abs(bias) < 0.9 * _maxBias)
             {
-                 index = 1;
+                index = 1;
                 _integral += bias;
             }
             else
             {
-                index=(_maxBias-Math.Abs(bias))/(0.9*_maxBias);
+                index = (_maxBias - Math.Abs(bias)) / (0.9 * _maxBias);
                 _integral += bias;
             }
 
-            double pressureBias=_kp*bias+index*_ki*_integral+_kd*(bias-_lastBias);
-            //根据伯努利一般形态P+1/2V^2=C
-            double speedBias =Math.Round(Math.Sqrt(2 * pressureBias),2);
-            _lastBias=bias;
-            short finalSpeed= (short)Math.Round(speed+pressureBias,0);
+            double pressureBias = _kp * bias + index * _ki * _integral + _kd * (bias - _lastBias);
+            double range = SC.GetValue<double>("VPWMain.RangePressure");
+            if (Math.Abs(bias) >= range)
+            {
+                if (bias < 0)
+                {
+                    pressureBias = -minSpeedDelta;
+                }
+                else
+                {
+                    pressureBias = minSpeedDelta;
+                }
+            }
+            _lastBias = bias;
+            short finalSpeed = (short)Math.Round(speed + pressureBias, 0);
+            int maxPumpSpeed = SC.GetValue<int>("VPWMain.MaxPumpSpeed");
+            int minPumpSpeed = SC.GetValue<int>("VPWMain.MinPumpSpeed");
+            if (finalSpeed >= maxPumpSpeed)
+            {
+                finalSpeed = (short)maxPumpSpeed;
+            }
+            else if (finalSpeed <= minPumpSpeed)
+            {
+                finalSpeed = (short)minPumpSpeed;
+            }
+            return finalSpeed;
+        }
+
+        public short CalculateSpeed(double targetPressure, double pressure, short speed, double targetLimit,
+            double downTargetLimit)
+        {
+            //根据现场手动调速得到的3次拟合多项式拟合系统 y=k3x^3+K2x^2+k2x+offset(y=0.8641x^3-131.23x^2+6750.4x-113116) 拟合r2为0.9929
+            //Pressure	Pre-wet Pump Speed
+            //37.9    1000
+            //38  1300
+            //38.6    1600
+            //38.9    1900
+            //39.3    2200
+            //40.6    2500
+            //41.6    2800
+            //42.5    3100
+            //44.3    3400
+            //45.2    3700
+            //47.9    4000
+            //50.4    4300
+            //51.5    4600
+            //54.04   4900
+            //56.13   5200
+            //58.12   5500
+
+            double k3 = 0.8641;
+            double k2 = -131.23;
+            double k1 = 6750.4;
+            double bias = _targetPressure - pressure;
+            if (bias >= 0 && bias <= targetLimit)
+            {
+                return speed;
+            }
+            if (bias >= -downTargetLimit && bias < 0)
+            {
+                return speed;
+            }
+            double speedDelta = k3 * Math.Pow(targetPressure, 3) + k2 * Math.Pow(targetPressure, 2) + k1 * targetPressure -
+                k3 * Math.Pow(pressure, 3) - k2 * Math.Pow(pressure, 2) - k1 * pressure;
+            short finalSpeed = (short)Math.Round(speed + speedDelta, 0);
             int maxPumpSpeed = SC.GetValue<int>("Prewet.MaxPumpSpeed");
             int minPumpSpeed = SC.GetValue<int>("Prewet.MinPumpSpeed");
             if (finalSpeed >= maxPumpSpeed)
             {
                 finalSpeed = (short)maxPumpSpeed;
             }
-            else if(finalSpeed<=minPumpSpeed)
+            else if (finalSpeed <= minPumpSpeed)
             {
                 finalSpeed = (short)minPumpSpeed;
             }

+ 1 - 1
Framework/Common/Persistent/VpwMain/VpwMainPersistentManager.cs

@@ -29,7 +29,7 @@ namespace MECF.Framework.Common.Persistent.VpwMain
                 List<string> lst = VpwMainItemManager.Instance.InstalledModules;
                 foreach (string item in lst)
                 {
-                    string foldStr = PathManager.GetCfgDir() + $"Persistent\\VpwMain";
+                    string foldStr = PathManager.GetCfgDir() + "Persistent\\VpwMain";
                     if (!Directory.Exists(foldStr))
                     {
                         Directory.CreateDirectory(foldStr);

+ 12 - 13
PunkHPX8_MainPages/ViewModels/VPWMotionViewModel.cs

@@ -16,7 +16,6 @@ namespace PunkHPX8_MainPages.ViewModels
     {
         #region 常量
         private const string MOTION_DATA = "MotionData";
-        private const int ACCEL_FACTOR = 10;
         #endregion
 
         #region 内部变量
@@ -159,24 +158,24 @@ namespace PunkHPX8_MainPages.ViewModels
                     CommandMotionData tmp1 = CommonFunction.GetValue<CommandMotionData>(_rtDataValueDic, $"{VPW1RotationModuleName}.{MOTION_DATA}");
                     if (tmp1 != null)
                     {
-                        tmp1.ActualVelocity = Math.Round(tmp1.ActualVelocity / 6, 2);
-                        tmp1.ProfileVelocity = Math.Round(tmp1.ProfileVelocity / 6, 2);
-                        tmp1.HomingVelocity = Math.Round(tmp1.HomingVelocity / 6, 2);
-                        tmp1.HomingVelocitySlow = Math.Round(tmp1.HomingVelocitySlow / 6, 2);
-                        tmp1.ProfileDecel = tmp1.ProfileDecel * ACCEL_FACTOR;
-                        tmp1.ProfileAccel = tmp1.ProfileAccel * ACCEL_FACTOR;
+                        tmp1.ActualVelocity = Math.Round(tmp1.ActualVelocity , 2);
+                        tmp1.ProfileVelocity = Math.Round(tmp1.ProfileVelocity, 2);
+                        tmp1.HomingVelocity = Math.Round(tmp1.HomingVelocity, 2);
+                        tmp1.HomingVelocitySlow = Math.Round(tmp1.HomingVelocitySlow, 2);
+                        tmp1.ProfileDecel = tmp1.ProfileDecel;
+                        tmp1.ProfileAccel = tmp1.ProfileAccel;
                     }
                     VPW1RotationMotionData = tmp1;
 
                     CommandMotionData tmp2 = CommonFunction.GetValue<CommandMotionData>(_rtDataValueDic, $"{VPW2RotationModuleName}.{MOTION_DATA}");
                     if (tmp2 != null)
                     {
-                        tmp2.ActualVelocity = Math.Round(tmp1.ActualVelocity / 6, 2);
-                        tmp2.ProfileVelocity = Math.Round(tmp1.ProfileVelocity / 6, 2);
-                        tmp2.HomingVelocity = Math.Round(tmp1.HomingVelocity / 6, 2);
-                        tmp2.HomingVelocitySlow = Math.Round(tmp1.HomingVelocitySlow / 6, 2);
-                        tmp2.ProfileDecel = tmp1.ProfileDecel * ACCEL_FACTOR;
-                        tmp2.ProfileAccel = tmp1.ProfileAccel * ACCEL_FACTOR;
+                        tmp2.ActualVelocity = Math.Round(tmp1.ActualVelocity, 2);
+                        tmp2.ProfileVelocity = Math.Round(tmp1.ProfileVelocity, 2);
+                        tmp2.HomingVelocity = Math.Round(tmp1.HomingVelocity, 2);
+                        tmp2.HomingVelocitySlow = Math.Round(tmp1.HomingVelocitySlow, 2);
+                        tmp2.ProfileDecel = tmp1.ProfileDecel;
+                        tmp2.ProfileAccel = tmp1.ProfileAccel;
                     }
                     VPW2RotationMotionData = tmp2;
                 }

+ 42 - 42
PunkHPX8_RT/Config/Devices/Beckhoffcfg.xml

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <BeckhoffCfg>
-	<Controller Name="MASTER" IPAddress="192.168.0.14.1.1" PortAddress="301">
+	<Controller Name="MASTER" IPAddress="192.168.0.200.1.1" PortAddress="301">
 
 		<!-- Need to have at least one input and one output before Axis stuff -->
 
@@ -74,14 +74,14 @@
 
 		<!--////////////////////////////////////////////////// ALL AXIS BEGIN //////////////////////////////////////////////////-->		
 		
-		<Axis Name="VPW1.Rotation" MotorType="Yaskawa" COEAddress="192.168.0.14.4.1" COEPort="1016" DebugLogging="false">
-			<Input Address="Task 2.Inputs.r_Loader1Rotation_StatusWord" Type="StatusWord" DataType="uint"/>
-			<Input Address="Task 2.Inputs.Loader1Rotation_DigitalInputs" Type="DigitalInputs" DataType="udint"/>
-			<Input Address="Task 2.Inputs.r_Loader1Rotation_ActualMotorPosition" Type="MotorPosition" DataType="dint"/>
-			<Input Address="Task 2.Inputs.Loader1Rotation_FollowingError" Type="PositionError" DataType="dint"/>
-			<Input Address="Task 2.Inputs.Loader1Rotation_ActualVelocity" Type="ActualVelocity" DataType="dint"/>
-			<Input Address="Task 2.Inputs.Loader1Rotation_ActualTorque" Type="ActualTorque" DataType="int"/>
-			<!-- Input Address="Task 2.Outputs.Loader1Rotation_DigitalOutputs" Type="DigitalOutputs" DataType="dint"/ -->
+		<Axis Name="VPW1.Rotation" MotorType="Kollmorgen" COEAddress="192.168.0.14.4.1" COEPort="1016" DebugLogging="false">
+			<Input Address="Task 2.Inputs.VPW1RotationStatusWord" Type="StatusWord" DataType="uint"/>
+			<Input Address="Task 2.Inputs.VPW1RotationDigitalInputs" Type="DigitalInputs" DataType="udint"/>
+			<Input Address="Task 2.Inputs.VPW1RotationMotorPosition" Type="MotorPosition" DataType="dint"/>
+			<Input Address="Task 2.Inputs.VPW1RotationPositionError" Type="PositionError" DataType="dint"/>
+			<Input Address="Task 2.Inputs.VPW1RotationActualVelocity" Type="ActualVelocity" DataType="dint"/>
+			<Input Address="Task 2.Inputs.VPW1RotationActualTorque" Type="ActualTorque" DataType="int"/>
+			<!-- Input Address="MAIN.Loader1Rotation_DigitalOutputs" Type="DigitalOutputs" DataType="dint"/ -->
 			<Input Address="0x607D:01" Type="SoftwareLimitMinus" DataType="dint"/>
 			<Input Address="0x607D:02" Type="SoftwareLimitPlus" DataType="dint"/>
 			<Input Address="0x6098:00" Type="HomingMethod" DataType="byte"/>
@@ -98,13 +98,13 @@
 			<Input Address="0x2520:00" Type="FollowingErrorWindow" DataType="udint"/>
 			<Input Address="0x603F:00" Type="ErrorCode" DataType="uint"/>
 
-			<Output Address="Task 2.Outputs.Loader1Rotation_ControlWord" Type="ControlWord" DataType="uint"/>
-			<Output Address="Task 2.Outputs.Loader1Rotation_ModeOfOperation" Type="ModeOfOperation" DataType="byte"/>
-			<Output Address="Task 2.Outputs.Loader1Rotation_TargetPosition" Type="TargetPosition" DataType="dint"/>
-			<Output Address="Task 2.Outputs.Loader1Rotation_ProfileVelocity" Type="ProfileVelocity" DataType="dint"/>
-			<Output Address="Task 2.Outputs.Loader1Rotation_ProfileAccel" Type="ProfileAccel" DataType="dint"/>
-			<Output Address="Task 2.Outputs.Loader1Rotation_ProfileDecel" Type="ProfileDecel" DataType="dint"/>
-			<!-- Output Address="Task 2.Outputs.Loader1Rotation_DigitalOutputs" Type="DigitalOutputs" DataType="dint"/ -->
+			<Output Address="Task 2.Outputs.VPW1RotationControlWord" Type="ControlWord" DataType="uint"/>
+			<Output Address="Task 2.Outputs.VPW1RotationModeOfOperation" Type="ModeOfOperation" DataType="byte"/>
+			<Output Address="Task 2.Outputs.VPW1RotationTargetPosition" Type="TargetPosition" DataType="dint"/>
+			<Output Address="Task 2.Outputs.VPW1RotationProfileVelocity" Type="ProfileVelocity" DataType="dint"/>
+			<Output Address="Task 2.Outputs.VPW1RotationProfileAccel" Type="ProfileAccel" DataType="dint"/>
+			<Output Address="Task 2.Outputs.VPW1RotationProfileDecel" Type="ProfileDecel" DataType="dint"/>
+			<!-- Output Address="MAIN.Loader1Rotation_DigitalOutputs" Type="DigitalOutputs" DataType="dint"/ -->
 			<Output Address="0x607D:01" Type="SoftwareLimitMinus" DataType="dint"/>
 			<Output Address="0x607D:02" Type="SoftwareLimitPlus" DataType="dint"/>
 			<Output Address="0x607C:00" Type="HomeOffset" DataType="dint"/>
@@ -133,28 +133,28 @@
 			<IntegralGain>0</IntegralGain>
 			<DerivativeGain>0</DerivativeGain>
 			<IntegralLimit>0</IntegralLimit>
-			<ErrorLimit>6766</ErrorLimit>
+			<ErrorLimit>0</ErrorLimit>
 			<VoltageOffset>0</VoltageOffset>
 			<!-- -193 degrees * 169161 = -32648073 -->
-			<ReverseSoftwareLimit>-46180953</ReverseSoftwareLimit>
+			<ReverseSoftwareLimit>0</ReverseSoftwareLimit>
 			<!-- 13 degrees * 169161 = 2199093 -->
-			<ForwardSoftwareLimit>2706576</ForwardSoftwareLimit>
-			<Speed>15000000</Speed>
-			<Acceleration>10000000</Acceleration>
-			<Deceleration>10000000</Deceleration>
+			<ForwardSoftwareLimit>0</ForwardSoftwareLimit>
+			<Speed>360</Speed>
+			<Acceleration>1000</Acceleration>
+			<Deceleration>1000</Deceleration>
 			<Jerk>0</Jerk>
 			<FeedforwardVelocity>0</FeedforwardVelocity>
 			<FeedforwardAcceleration>0</FeedforwardAcceleration>
 			<OffOnError>0</OffOnError>
 		</Axis>
 		<Axis Name="VPW2.Rotation" MotorType="Yaskawa" COEAddress="192.168.0.14.4.1" COEPort="1016" DebugLogging="false">
-			<Input Address="Task 2.Inputs.r_Loader1Rotation_StatusWord" Type="StatusWord" DataType="uint"/>
-			<Input Address="Task 2.Inputs.Loader1Rotation_DigitalInputs" Type="DigitalInputs" DataType="udint"/>
-			<Input Address="Task 2.Inputs.r_Loader1Rotation_ActualMotorPosition" Type="MotorPosition" DataType="dint"/>
-			<Input Address="Task 2.Inputs.Loader1Rotation_FollowingError" Type="PositionError" DataType="dint"/>
-			<Input Address="Task 2.Inputs.Loader1Rotation_ActualVelocity" Type="ActualVelocity" DataType="dint"/>
-			<Input Address="Task 2.Inputs.Loader1Rotation_ActualTorque" Type="ActualTorque" DataType="int"/>
-			<!-- Input Address="Task 2.Outputs.Loader1Rotation_DigitalOutputs" Type="DigitalOutputs" DataType="dint"/ -->
+			<Input Address="Task 2.Inputs.VPW2RotationStatusWord" Type="StatusWord" DataType="uint"/>
+			<Input Address="Task 2.Inputs.VPW2RotationDigitalInputs" Type="DigitalInputs" DataType="udint"/>
+			<Input Address="Task 2.Inputs.VPW2RotationMotorPosition" Type="MotorPosition" DataType="dint"/>
+			<Input Address="Task 2.Inputs.VPW2RotationPositionError" Type="PositionError" DataType="dint"/>
+			<Input Address="Task 2.Inputs.VPW2RotationActualVelocity" Type="ActualVelocity" DataType="dint"/>
+			<Input Address="Task 2.Inputs.VPW2RotationActualTorque" Type="ActualTorque" DataType="int"/>
+			<!-- Input Address="MAIN.Loader1Rotation_DigitalOutputs" Type="DigitalOutputs" DataType="dint"/ -->
 			<Input Address="0x607D:01" Type="SoftwareLimitMinus" DataType="dint"/>
 			<Input Address="0x607D:02" Type="SoftwareLimitPlus" DataType="dint"/>
 			<Input Address="0x6098:00" Type="HomingMethod" DataType="byte"/>
@@ -171,13 +171,13 @@
 			<Input Address="0x2520:00" Type="FollowingErrorWindow" DataType="udint"/>
 			<Input Address="0x603F:00" Type="ErrorCode" DataType="uint"/>
 
-			<Output Address="Task 2.Outputs.Loader1Rotation_ControlWord" Type="ControlWord" DataType="uint"/>
-			<Output Address="Task 2.Outputs.Loader1Rotation_ModeOfOperation" Type="ModeOfOperation" DataType="byte"/>
-			<Output Address="Task 2.Outputs.Loader1Rotation_TargetPosition" Type="TargetPosition" DataType="dint"/>
-			<Output Address="Task 2.Outputs.Loader1Rotation_ProfileVelocity" Type="ProfileVelocity" DataType="dint"/>
-			<Output Address="Task 2.Outputs.Loader1Rotation_ProfileAccel" Type="ProfileAccel" DataType="dint"/>
-			<Output Address="Task 2.Outputs.Loader1Rotation_ProfileDecel" Type="ProfileDecel" DataType="dint"/>
-			<!-- Output Address="Task 2.Outputs.Loader1Rotation_DigitalOutputs" Type="DigitalOutputs" DataType="dint"/ -->
+			<Output Address="Task 2.Outputs.VPW2RotationControlWord" Type="ControlWord" DataType="uint"/>
+			<Output Address="Task 2.Outputs.VPW2RotationModeOfOperation" Type="ModeOfOperation" DataType="byte"/>
+			<Output Address="Task 2.Outputs.VPW2RotationTargetPosition" Type="TargetPosition" DataType="dint"/>
+			<Output Address="Task 2.Outputs.VPW2RotationProfileVelocity" Type="ProfileVelocity" DataType="dint"/>
+			<Output Address="Task 2.Outputs.VPW2RotationProfileAccel" Type="ProfileAccel" DataType="dint"/>
+			<Output Address="Task 2.Outputs.VPW2RotationProfileDecel" Type="ProfileDecel" DataType="dint"/>
+			<!-- Output Address="MAIN.Loader1Rotation_DigitalOutputs" Type="DigitalOutputs" DataType="dint"/ -->
 			<Output Address="0x607D:01" Type="SoftwareLimitMinus" DataType="dint"/>
 			<Output Address="0x607D:02" Type="SoftwareLimitPlus" DataType="dint"/>
 			<Output Address="0x607C:00" Type="HomeOffset" DataType="dint"/>
@@ -206,15 +206,15 @@
 			<IntegralGain>0</IntegralGain>
 			<DerivativeGain>0</DerivativeGain>
 			<IntegralLimit>0</IntegralLimit>
-			<ErrorLimit>6766</ErrorLimit>
+			<ErrorLimit>0</ErrorLimit>
 			<VoltageOffset>0</VoltageOffset>
 			<!-- -193 degrees * 169161 = -32648073 -->
-			<ReverseSoftwareLimit>-46180953</ReverseSoftwareLimit>
+			<ReverseSoftwareLimit>0</ReverseSoftwareLimit>
 			<!-- 13 degrees * 169161 = 2199093 -->
-			<ForwardSoftwareLimit>2706576</ForwardSoftwareLimit>
-			<Speed>15000000</Speed>
-			<Acceleration>10000000</Acceleration>
-			<Deceleration>10000000</Deceleration>
+			<ForwardSoftwareLimit>0</ForwardSoftwareLimit>
+			<Speed>360</Speed>
+			<Acceleration>1000</Acceleration>
+			<Deceleration>1000</Deceleration>
 			<Jerk>0</Jerk>
 			<FeedforwardVelocity>0</FeedforwardVelocity>
 			<FeedforwardAcceleration>0</FeedforwardAcceleration>

+ 2 - 2
PunkHPX8_RT/Config/Station/StationPositionsCfg.xml

@@ -35,7 +35,7 @@
 			<ToleranceDefault>0.5</ToleranceDefault>
 			<Stations>
 				<Station Name="VPW1.Rotation.Home" Position="0" />
-				<Station Name="VPW1.Rotation.Center" Position="50" />
+				<Station Name="VPW1.Rotation.Center" Position="14400" />
 			</Stations>
 		</Axis>
 	</Module>
@@ -44,7 +44,7 @@
 			<ToleranceDefault>0.5</ToleranceDefault>
 			<Stations>
 				<Station Name="VPW2.Rotation.Home" Position="0" />
-				<Station Name="VPW2.Rotation.Center" Position="50" />
+				<Station Name="VPW2.Rotation.Center" Position="14400" />
 			</Stations>
 		</Axis>
 	</Module>

+ 3 - 0
PunkHPX8_RT/Config/System.sccfg

@@ -236,6 +236,9 @@
 		<config default="7300" name="MaxPumpSpeed" nameView="MaxPumpSpeed" description="Max Pump Speed" max="32768" min="0" paramter="" tag="" unit="" type="Integer"/>
 		<config default="300" name="MinPumpSpeed" nameView="MinPumpSpeed" description="Min Pump Speed" max="32768" min="0" paramter="" tag="" unit="" type="Integer"/>
 		<config default="0.5" name="PrewetTargetLimit" nameView="PrewetTargetLimit" description="Prewet pressure in PrewetTarget Limit,device stop adjust speed" max="60" min="0" paramter="" tag="" unit="" type="Double"/>
+		<config default="0.1" name="PrewetDownTargetLimit" nameView="PrewetDownTargetLimit" description="Prewet pressure in down PrewetTarget Limit,device stop adjust speed" max="60" min="0" paramter="" tag="" unit="" type="Double"/>
+		<config default="20" name="MinSpeedDelta" nameView="MinSpeedDelta" description="min speed delta while presure is over range pressure" max="60" min="0" paramter="" tag="" unit="" type="Double"/>
+		<config default="2" name="RangePressure" nameView="RangePressure" description="pressure delta range" max="60" min="0" paramter="" tag="" unit="" type="Double"/>
 		<configs name="PumpPressure" nameView="PumpPressure">
 			<config default="50.0" name="Error_Max" nameView="Error_Max" max="100.0" min="0" paramter="" tag="" unit="" type="Double"  description="This value defines the maximum flow, in liters per minute, above which this interlock will transition to an Error state."/>
 			<config default="40.0" name="Warning_Max" nameView="Warning_Max" max="100.0" min="0" paramter="" tag="" unit="" type="Double"  description="This value defines the maximum flow, in liters per minute, above which this interlock will transition to an Warning state.  Note corresponding Error_Min/Error_Max testing supersedes this test."/>

+ 1 - 1
PunkHPX8_RT/Devices/AXIS/CanOpen/CanOpenStopPositionRoutine.cs

@@ -49,7 +49,7 @@ namespace PunkHPX8_RT.Devices.AXIS.CanOpen
 
         public RState Monitor()
         {
-            Runner.Run(StopPositionStep.SetHaltControlWord, () => { return _beckhoffCommonAxis.WriteControlWord(0X8F); }, () => { return CheckControlWord(0X8F); }, 1000)               
+            Runner.Run(StopPositionStep.SetHaltControlWord, () => { return _beckhoffCommonAxis.WriteControlWord(0X12F); }, () => { return CheckControlWord(0X12F); }, 1000)               
                 .WaitWithStopCondition(StopPositionStep.CheckStop, CheckStop, CheckErrorOrWarning, _timeout)
                 .Run(StopPositionStep.WriteTargePosition, () => { return WriteTargetPosition(); }, NullFun, 100)
                 .Run(StopPositionStep.ResetHaltControlWord, () => { return _beckhoffCommonAxis.WriteControlWord(0x3F); }, () => { return CheckControlWord(0x3F); }, 1000)

+ 2 - 2
PunkHPX8_RT/Devices/AXIS/Kollmorgen/KollmorgenAxis.cs

@@ -290,14 +290,14 @@ namespace PunkHPX8_RT.Devices.AXIS.Kollmorgen
         /// </summary>
         public override void FirstStartUpWriteCOE(string variable)
         {
-            _beckhoffCommonAxis.FirstStartUpWriteCOE(variable);
+            //_beckhoffCommonAxis.FirstStartUpWriteCOE(variable);
         }
         /// <summary>
         /// 启动写入COE线程
         /// </summary>
         public override void StartUpWriteCoeThread()
         {
-            _beckhoffCommonAxis.StartUpWriteCoeThread();
+            //_beckhoffCommonAxis.StartUpWriteCoeThread();
         }
         /// <summary>
         /// OnTimer 定时器执行

+ 1 - 1
PunkHPX8_RT/Devices/AXIS/Kollmorgen/KollmorgenStopPositionRoutine.cs

@@ -48,7 +48,7 @@ namespace PunkHPX8_RT.Devices.AXIS.Kollmorgen
 
         public RState Monitor()
         {
-            Runner.Run(StopPositionStep.SetHaltControlWord, () => { return _beckhoffCommonAxis.WriteControlWord(0X10F); }, () => { return CheckControlWord(0X10F); }, 1000)
+            Runner.Run(StopPositionStep.SetHaltControlWord, () => { return _beckhoffCommonAxis.WriteControlWord(0X12F); }, () => { return CheckControlWord(0X12F); }, 1000)
                 .WaitWithStopCondition(StopPositionStep.CheckStop, CheckStop, CheckErrorOrWarning, _timeout)
                 .Delay(StopPositionStep.Delay,_delay_1s)
                 .Run(StopPositionStep.WriteTargePosition, () => { return WriteTargetPosition(); }, NullFun, 100)

+ 1 - 1
PunkHPX8_RT/Devices/AXIS/Maxon/MaxonStopPositionRoutine.cs

@@ -49,7 +49,7 @@ namespace PunkHPX8_RT.Devices.AXIS.Maxon
 
         public RState Monitor()
         {
-            Runner.Run(StopPositionStep.SetHaltControlWord, () => { return _beckhoffCommonAxis.WriteControlWord(0X8F); }, () => { return CheckControlWord(0X8F); }, 1000)
+            Runner.Run(StopPositionStep.SetHaltControlWord, () => { return _beckhoffCommonAxis.WriteControlWord(0X12F); }, () => { return CheckControlWord(0X12F); }, 1000)
                 .WaitWithStopCondition(StopPositionStep.CheckStop, CheckStop, CheckErrorOrWarning, _timeout)
                 .Run(StopPositionStep.WriteTargePosition, () => { return WriteTargetPosition(); }, NullFun, 100)
                 .Run(StopPositionStep.ResetHaltControlWord, () => { return _beckhoffCommonAxis.WriteControlWord(0x3F); }, () => { return CheckControlWord(0x3F); }, 1000)

+ 1 - 1
PunkHPX8_RT/Devices/AXIS/Yaskawa/YaskawaStopPositionRoutine.cs

@@ -54,7 +54,7 @@ namespace PunkHPX8_RT.Devices.AXIS.Yaskawa
 
         public RState Monitor()
         {
-            Runner.Run(StopPositionStep.SetHaltControlWord, () => { return _beckhoffCommonAxis.WriteControlWord(0X8F); }, () => { return CheckControlWord(0X8F); }, 1000)
+            Runner.Run(StopPositionStep.SetHaltControlWord, () => { return _beckhoffCommonAxis.WriteControlWord(0X12F); }, () => { return CheckControlWord(0X12F); }, 1000)
                 .WaitWithStopCondition(StopPositionStep.CheckStop, CheckStop, CheckErrorOrWarning, _timeout)
                 .Run(StopPositionStep.WriteTargePosition, () => { return WriteTargetPosition(); }, NullFun, 100)
                 .Run(StopPositionStep.ResetHaltControlWord, () => { return _beckhoffCommonAxis.WriteControlWord(0x3F); }, () => { return CheckControlWord(0x3F); }, 1000)

+ 64 - 0
PunkHPX8_RT/Devices/VpwMain/BoosterPumpDisableRoutine.cs

@@ -0,0 +1,64 @@
+using Aitex.Core.RT.Routine;
+using MECF.Framework.Common.Routine;
+using PunkHPX8_Core;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PunkHPX8_RT.Devices.VpwMain
+{
+    public class BoosterPumpDisableRoutine : RoutineBase, IRoutine
+    {
+        private enum PumpDisableStep
+        {
+            PumpDisable,
+            Delay,
+            PumpValveClose,
+            End
+        }
+
+        #region 内部变量
+        VpwMainDevice _device;
+        #endregion
+
+        /// <summary>
+        /// 构造函数
+        /// </summary>
+        /// <param name="module"></param>
+        public BoosterPumpDisableRoutine(string module, VpwMainDevice device) : base(module)
+        {
+            _device = device;
+        }
+        /// <summary>
+        /// 中止
+        /// </summary>
+        public void Abort()
+        {
+            Runner.Stop("Manual Abort");
+        }
+        /// <summary>
+        /// 监控
+        /// </summary>
+        /// <returns></returns>
+        public RState Monitor()
+        {
+            Runner.Run(PumpDisableStep.PumpDisable, _device.BoosterPumpDisable, 500)
+                .Delay(PumpDisableStep.Delay, 500)
+                .Run(PumpDisableStep.PumpValveClose, _device.DiwProcessOff, 500)
+                .End(PumpDisableStep.End, NullFun, _delay_1ms);
+            return Runner.Status;
+        }
+        /// <summary>
+        /// 启动
+        /// </summary>
+        /// <param name="objs"></param>
+        /// <returns></returns>
+        public RState Start(params object[] objs)
+        {
+            return Runner.Start(Module, "Pump Disable");
+        }
+
+    }
+}

+ 68 - 0
PunkHPX8_RT/Devices/VpwMain/BoosterPumpEnableRoutine.cs

@@ -0,0 +1,68 @@
+using Aitex.Core.RT.Routine;
+using MECF.Framework.Common.Persistent.Prewet;
+using MECF.Framework.Common.Routine;
+using PunkHPX8_Core;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PunkHPX8_RT.Devices.VpwMain
+{
+    public class BoosterPumpEnableRoutine : RoutineBase, IRoutine
+    {
+        private enum PumpEnableStep
+        {
+            PumpValve,
+            Delay,
+            PumpEnable,
+            WritePumpSpeed,
+            LastDelay,
+            End
+        }
+        #region 内部变量
+        VpwMainDevice _device;
+        #endregion
+
+        /// <summary>
+        /// 构造函数
+        /// </summary>
+        /// <param name="module"></param>
+        public BoosterPumpEnableRoutine(string module,VpwMainDevice device) : base(module)
+        {
+            _device = device;
+        }
+
+        /// <summary>
+        /// 中止
+        /// </summary>
+        public void Abort()
+        {
+            Runner.Stop("Manual Abort");
+        }
+        /// <summary>
+        /// 监控
+        /// </summary>
+        /// <returns></returns>
+        public RState Monitor()
+        {
+            Runner.Run(PumpEnableStep.PumpValve, _device.DiwProcessOn, () => { return _device.CommonData.DiwProcess; }, _delay_1s)
+                .Delay(PumpEnableStep.Delay, 200)
+                .Run(PumpEnableStep.PumpEnable, _device.BoosterPumpEnable, () => { return _device.CommonData.BoosterPumpEnable; }, _delay_1s)
+                .Run(PumpEnableStep.WritePumpSpeed, () => { return _device.BoosterPumpSpeed(); }, _delay_1ms)
+                .Delay(PumpEnableStep.LastDelay, 500)
+                .End(PumpEnableStep.End, NullFun, _delay_1ms);
+            return Runner.Status;
+        }
+        /// <summary>
+        /// 启动
+        /// </summary>
+        /// <param name="objs"></param>
+        /// <returns></returns>
+        public RState Start(params object[] objs)
+        {
+            return Runner.Start(Module, "Pump Enable");
+        }
+    }
+}

+ 222 - 12
PunkHPX8_RT/Devices/VpwMain/VpwMainDevice.cs

@@ -2,19 +2,23 @@
 using Aitex.Core.RT.Device;
 using Aitex.Core.RT.Log;
 using Aitex.Core.RT.OperationCenter;
+using Aitex.Core.RT.Routine;
 using Aitex.Core.RT.SCCore;
 using Aitex.Core.Util;
+using MECF.Framework.Common.Algorithm;
 using MECF.Framework.Common.Beckhoff.ModuleIO;
 using MECF.Framework.Common.CommonData.Prewet;
 using MECF.Framework.Common.CommonData.Vpw;
 using MECF.Framework.Common.IOCore;
 using MECF.Framework.Common.Persistent.Prewet;
 using MECF.Framework.Common.Persistent.VpwMain;
+using PunkHPX8_Core;
 using PunkHPX8_RT.Modules;
 using PunkHPX8_RT.Modules.VpwMain;
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Net.NetworkInformation;
 using System.Reflection;
 using System.Text;
 using System.Threading.Tasks;
@@ -50,6 +54,13 @@ namespace PunkHPX8_RT.Devices.VpwMain
         private const string DEGAS_PUMP_PRESSURE = "DegasPumpPressure";
         #endregion
 
+        private enum VPWOperation
+        {
+            None,
+            PumpEnable,
+            PumpDisable
+        }
+
         #region 内部变量
         /// <summary>
         /// 变量是否初始化字典
@@ -63,6 +74,15 @@ namespace PunkHPX8_RT.Devices.VpwMain
         /// 持久性数值
         /// </summary>
         private VpwMainPersistentValue _vpwMainPersistentValue;
+
+        /// <summary>
+        /// Pump Enable routine
+        /// </summary>
+        private BoosterPumpEnableRoutine _boosterPumpEnableRoutine;
+        /// <summary>
+        /// Pump Disable routine
+        /// </summary>
+        private BoosterPumpDisableRoutine _boosterPumpDisableRoutine;
         /// <summary>
         /// 上一次Booster泵速
         /// </summary>
@@ -71,8 +91,34 @@ namespace PunkHPX8_RT.Devices.VpwMain
         /// 定时器任务
         /// </summary>
         private PeriodicJob _periodicJob;
-        
+        /// <summary>
+        /// 是否数据完成初台化
+        /// </summary>
         private bool _isDataInitialized;
+        /// <summary>
+        /// pdi控制中的p
+        /// </summary>
+        private double _pumpKp;
+        /// <summary>
+        /// pdi控制中的i
+        /// </summary>
+        private double _pumpKi;
+        /// <summary>
+        /// pdi控制中的d
+        /// </summary>
+        private double _pumpKd;
+        /// <summary>
+        /// 操作当前状态
+        /// </summary>
+        private RState _status;
+        /// <summary>
+        /// 当前操作
+        /// </summary>
+        private VPWOperation _currentOperation;
+        /// <summary>
+        /// 启动自动调泵速
+        /// </summary>
+        private bool _isStartAutoSpeed;
         #endregion
 
         #region 属性
@@ -124,7 +170,8 @@ namespace PunkHPX8_RT.Devices.VpwMain
         /// </summary>
         private void InitializeRoutine()
         {
-
+            _boosterPumpEnableRoutine = new BoosterPumpEnableRoutine(Module, this);
+            _boosterPumpDisableRoutine = new BoosterPumpDisableRoutine(Module, this);
         }
         /// <summary>
         /// 订阅
@@ -218,19 +265,20 @@ namespace PunkHPX8_RT.Devices.VpwMain
             OP.Subscribe($"{Module}.VacuumPumpDisable", (cmd, para) => { return VacuumPumpDisable(); });
             OP.Subscribe($"{Module}.VacuumPumpSpeedEnable", (cmd, para) => { return VacuumSpeedEnable(); });
             OP.Subscribe($"{Module}.VacuumPumpSpeedDisable", (cmd, para) => { return VacuumSpeedDisable(); });
-            OP.Subscribe($"{Module}.VacuumPumpSpeed", (cmd, para) => { return BoosterPumpSpeedKeyDownOperation(cmd, para); });
+            OP.Subscribe($"{Module}.VacuumPumpSpeed", (cmd, para) => { return WriteVacuumSpeedOperation(cmd, para); });
             OP.Subscribe($"{Module}.DegasPumpEnable", (cmd, para) => { return DegasPumpEnable(); });
             OP.Subscribe($"{Module}.DegasPumpDisable", (cmd, para) => { return DegasPumpDisable(); });
             OP.Subscribe($"{Module}.DegasAdjustOn", (cmd, para) => { return DegasAdjustOn(); });
             OP.Subscribe($"{Module}.DegasAdjustOff", (cmd, para) => { return DegasAdjustOff(); });
             OP.Subscribe($"{Module}.DiwDegasValveOn", (cmd, para) => { return DiwDegasValveOn(); });
             OP.Subscribe($"{Module}.DiwDegasValveOff", (cmd, para) => { return DiwDegasValveOff(); });
-            OP.Subscribe($"{Module}.BoosterPumpEnable", (cmd, para) => { return BoosterPumpEnable(); });
-            OP.Subscribe($"{Module}.BoosterPumpDisable", (cmd, para) => { return BoosterPumpDisable(); });
-            OP.Subscribe($"{Module}.BoosterPumpSpeed", (cmd, para) => {
-                short speed = short.Parse(para[0].ToString());
-                return BoosterPumpSpeed(speed);
-            });
+            OP.Subscribe($"{Module}.DiwEnable", (cmd, para) => { return DiwEnable(); });
+            OP.Subscribe($"{Module}.DiwDisable", (cmd, para) => { return DiwDisable(); });
+            OP.Subscribe($"{Module}.DiwProcessOn", (cmd, para) => { return DiwProcessOn(); });
+            OP.Subscribe($"{Module}.DiwProcessOff", (cmd, para) => { return DiwProcessOff(); });
+            OP.Subscribe($"{Module}.BoosterPumpEnable", BoosterPumpEnableOperation);
+            OP.Subscribe($"{Module}.BoosterPumpDisable", BoosterPumpDisableOperation);
+            OP.Subscribe($"{Module}.BoosterPumpSpeed", BoosterPumpSpeedKeyDownOperation);
 
             OP.Subscribe($"{Module}.ChamberUp", (cmd, para) => { return ChamberUp(); });
             OP.Subscribe($"{Module}.ChamberDown", (cmd, para) => { return ChamberDown(); });
@@ -298,6 +346,24 @@ namespace PunkHPX8_RT.Devices.VpwMain
         {
             return WriteVariableValue(VACUUM_PUMP_SPEED_ENABLE, false);
         }
+
+        /// <summary>
+        /// 写入Vacuum速度
+        /// </summary>
+        /// <param name="speed"></param>
+        /// <returns></returns>
+        private bool WriteVacuumSpeedOperation(string cmd, object[] param)
+        {
+            if (short.TryParse(param[0].ToString(), out var speed))
+            {
+                return WriteVariableValue(VACUUM_PUMP_SPEED, speed);
+            }
+            else
+            {
+                LOG.WriteLog(eEvent.ERR_VPWMAIN, Module, $"Write VacuumSpeed {param[0]} is not short");
+                return false;
+            }
+        }
         /// <summary>
         /// 写入速度
         /// </summary>
@@ -362,6 +428,41 @@ namespace PunkHPX8_RT.Devices.VpwMain
 
         #region Booster Pump
         /// <summary>
+        /// Pump Enable操作
+        /// </summary>
+        /// <param name="cmd"></param>
+        /// <param name="param"></param>
+        /// <returns></returns>
+        public bool BoosterPumpEnableOperation(string cmd, object[] param)
+        {
+            if (_status == RState.Running)
+            {
+                LOG.WriteLog(eEvent.ERR_PREWET, Module.ToString(), $"{Module} current execute {_currentOperation},cannot Pump enable");
+                return false;
+            }
+            _status = _boosterPumpEnableRoutine.Start();
+            _currentOperation = VPWOperation.PumpEnable;
+            return _status == RState.Running;
+        }
+        /// <summary> 
+        /// pump disable 操作
+        /// </summary>
+        /// <param name="cmd"></param>
+        /// <param name="param"></param>
+        /// <returns></returns>
+        public bool BoosterPumpDisableOperation(string cmd, object[] param)
+        {
+            if (_status == RState.Running)
+            {
+                LOG.WriteLog(eEvent.ERR_PREWET, Module.ToString(), $"{Module} current execute {_currentOperation},cannot Pump disable");
+                return false;
+            }
+            _status = _boosterPumpDisableRoutine.Start();
+            _currentOperation = VPWOperation.PumpDisable;
+            return _status == RState.Running;
+            //return PumpDisable();
+        }
+        /// <summary>
         /// Booster Pump enable
         /// </summary>
         /// <returns></returns>
@@ -382,9 +483,9 @@ namespace PunkHPX8_RT.Devices.VpwMain
         /// </summary>
         /// <param name="speed"></param>
         /// <returns></returns>
-        public bool BoosterPumpSpeed(short speed)
+        public bool BoosterPumpSpeed(short speed=0)
         {
-            return WriteVariableValue(BOOSTER_PUMP_SPEED, speed);
+            return WriteVariableValue(BOOSTER_PUMP_SPEED, speed == 0 ? _lastBoosterPumpSpeed : speed);
         }
 
 
@@ -407,7 +508,7 @@ namespace PunkHPX8_RT.Devices.VpwMain
             {
                 _vpwMainPersistentValue.Speed = speed;
                 _lastBoosterPumpSpeed = speed;
-                PrewetPersistentManager.Instance.UpdatePersistentValue(Module);
+                VpwMainPersistentManager.Instance.UpdatePersistentValue(Module);
             }
             return true;
         }
@@ -575,6 +676,42 @@ namespace PunkHPX8_RT.Devices.VpwMain
 
         #endregion
 
+        #region DIW
+        /// <summary>
+        /// DIW Enable
+        /// </summary>
+        /// <returns></returns>
+        public bool DiwEnable()
+        {
+            return WriteVariableValue(DIW_ENABLE, true);
+        }
+        /// <summary>
+        /// DIW Disable
+        /// </summary>
+        /// <returns></returns>
+        public bool DiwDisable()
+        {
+            return WriteVariableValue(DIW_ENABLE, false);
+        }
+        /// <summary>
+        /// DIW Process On
+        /// </summary>
+        /// <returns></returns>
+        public bool DiwProcessOn()
+        {
+            return WriteVariableValue(DIW_PROCESS, true);
+        }
+
+        /// <summary>
+        /// DIW Process On
+        /// </summary>
+        /// <returns></returns>
+        public bool DiwProcessOff()
+        {
+            return WriteVariableValue(DIW_PROCESS, false);
+        }
+        #endregion
+
         /// <summary>
         /// 写变量
         /// </summary>
@@ -600,8 +737,81 @@ namespace PunkHPX8_RT.Devices.VpwMain
             _commonData.BoosterPumpPressureData.MaxError = SC.GetValue<double>($"VPWMain.PumpPressure.Error_Max");
             _commonData.BoosterPumpPressureData.MaxWarning = SC.GetValue<double>($"VPWMain.PumpPressure.Warning_Max");
             _commonData.PressureTarget = SC.GetValue<double>($"VPWMain.PressureTarget");
+            if (_status == RState.Running)
+            {
+                IRoutine routine = GetCurrentRoutine();
+                if (routine != null)
+                {
+                    RState rsState = routine.Monitor();
+                    if (rsState == RState.Failed || rsState == RState.Timeout)
+                    {
+                        _status = RState.Failed;
+                        _currentOperation = VPWOperation.None;
+                        LOG.WriteLog(eEvent.ERR_VPWMAIN, Module.ToString(), $"{_currentOperation} error");
+                        _isStartAutoSpeed = false;
+                    }
+                    else if (rsState == RState.End)
+                    {
+                        if (_currentOperation == VPWOperation.PumpEnable)
+                        {
+                            _isStartAutoSpeed = true;
+                        }
+                        else if (_currentOperation == VPWOperation.PumpDisable)
+                        {
+                            _isStartAutoSpeed = false;
+                        }
+                        _status = RState.End;
+                        _currentOperation = VPWOperation.None;
+                    }
+                }
+            }
+            if (_isStartAutoSpeed)
+            {
+                AdjustPumpSpeed();
+            }
             return true;
         }
+        /// <summary>
+        /// 调速
+        /// </summary>
+        public void AdjustPumpSpeed()
+        {
+            //Speed Auto模式同时pump enbled,根据kdi调整泵速
+            if (_commonData.BoosterPumpSpeedAuto && _commonData.BoosterPumpEnable)
+            {
+                _pumpKp = SC.GetValue<double>($"VPWMain.PumpKp");
+                _pumpKd = SC.GetValue<double>($"VPWMain.PumpKd");
+                _pumpKi = SC.GetValue<double>($"VPWMain.PumpKi");
+                double limit = SC.GetValue<double>("VPWMain.PrewetTargetLimit");
+                double downLimit = SC.GetValue<double>("VPWMain.PrewetDownTargetLimit");
+                double minSpeedDelta = SC.GetValue<double>("VPWMain.MinSpeedDelta");
+                short speed = PdiAlgorithm.Instance.CalculateSpeed(_pumpKp, _pumpKi, _pumpKd, _commonData.PressureTarget,
+                    _commonData.BoosterPumpPressureData.Value, _lastBoosterPumpSpeed, limit, downLimit, minSpeedDelta);
+                //short speed = PdiAlgorithm.Instance.CalculateSpeed(PrewetPumpData.PressureTarget, PrewetPumpData.PumpPressureData.Value,
+                //    _lastPumpSpeed, limit, downLimit);
+                if (Math.Abs(speed - _lastBoosterPumpSpeed) >= 1)
+                {
+                    _lastBoosterPumpSpeed = speed;
+                    BoosterPumpSpeed(speed);
+                }
+            }
+        }
+        /// <summary>
+        /// 当前Routine;
+        /// </summary>
+        /// <returns></returns>
+        private IRoutine GetCurrentRoutine()
+        {
+            switch (_currentOperation)
+            {
+                case VPWOperation.PumpEnable:
+                    return _boosterPumpEnableRoutine;
+                case VPWOperation.PumpDisable:
+                    return _boosterPumpDisableRoutine;
+                default:
+                    return null;
+            }
+        }
 
         /// <summary>
         /// 监控

+ 2 - 0
PunkHPX8_RT/PunkHPX8_RT.csproj

@@ -243,6 +243,8 @@
     <Compile Include="Devices\SRD\TotalSRDDevice.cs" />
     <Compile Include="Devices\VpwCell\VpwCellDevice.cs" />
     <Compile Include="Devices\VpwCell\VpwRotationAxisInterLock.cs" />
+    <Compile Include="Devices\VpwMain\BoosterPumpDisableRoutine.cs" />
+    <Compile Include="Devices\VpwMain\BoosterPumpEnableRoutine.cs" />
     <Compile Include="Devices\VpwMain\VpwDeviceTimer.cs" />
     <Compile Include="Devices\VpwMain\VpwMainDevice.cs" />
     <Compile Include="Modules\EFEM\CycleRobotCycleNewRoutine.cs" />