From c5752f21a9db450376d6827325cdf9f994e8db69 Mon Sep 17 00:00:00 2001 From: Milan Hanajik Date: Wed, 9 Aug 2023 09:25:31 +0200 Subject: [PATCH] Q2 correction factor calculation bug fix, case when the original factor was not zero and the error target is not zero, ver. 2.33.2084 --- TBF/Properties/AssemblyInfo.cs | 4 +- .../iPerlCommunicationForm.cs | 64 ++++++++++--------- .../iPerlCommunication/iPerlHead/IperlHead.cs | 19 ++++-- .../iPerlHead/ProcParams.cs | 2 +- 4 files changed, 51 insertions(+), 38 deletions(-) diff --git a/TBF/Properties/AssemblyInfo.cs b/TBF/Properties/AssemblyInfo.cs index 1803f048f..aea8b281f 100644 --- a/TBF/Properties/AssemblyInfo.cs +++ b/TBF/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("2.33.2081.0")] -[assembly: AssemblyFileVersion("2.33.2081.0")] +[assembly: AssemblyVersion("2.33.2084.0")] +[assembly: AssemblyFileVersion("2.33.2084.0")] diff --git a/TBF/Rig/TestMethods/iPerlCommunication/iPerlCommunicationForm.cs b/TBF/Rig/TestMethods/iPerlCommunication/iPerlCommunicationForm.cs index d2859aa31..c07f88687 100644 --- a/TBF/Rig/TestMethods/iPerlCommunication/iPerlCommunicationForm.cs +++ b/TBF/Rig/TestMethods/iPerlCommunication/iPerlCommunicationForm.cs @@ -2060,30 +2060,33 @@ namespace TBF.Rig.TestMethods.iPerlCommunication return CommErr.None; /// No Q2 correction when doing conditional update and WM passed } + if (q2adjResult.Error < -50 || +50 < q2adjResult.Error || + (q2adjResult2 != null && (q2adjResult2.Error < -50 || +50 < q2adjResult2.Error))) + { + resultStr = string.Format("Measurement error => no Q2 correction"); - double errLimitLo = test.ErrLimLo + test.Uncertainty; + /// At least one of Q2 errors is out of range for Q2 correction + log.WarnFormat("OoR => anyhow Q2 correction was done: Pos={0}, PCB#={1}, ***Q2_RL err={2}%***, ***Q2_LR err={3}%***", + ihead.Name, + ihead.SerialNr, + q2adjResult.Error.ToString("F2"), + q2adjResult2 != null ? q2adjResult2.Error.ToString("F2") : string.Empty); + + rfidDataLogger.InfoFormat("{0}({1}): Q2 error ({2},{3}) is out of range => Failed", + ihead.Name, + ihead.SerialNr, + q2adjResult.Error.ToString("F2"), + q2adjResult2 != null ? q2adjResult2.Error.ToString("F2") : string.Empty); + + return CommErr.Q2OutOfRange; + } + + double errLimitLo = test.ErrLimLo + test.Uncertainty; double errLimitHi = test.ErrLimHi - test.Uncertainty; /// - /// Calculate Q2 correction factor(s) from an error measured at Q2 + /// Calculate Q2 correction factor(s) /// - double q2Correction = 0; - double q2Correction2 = 0; /// L-R direction in case of Q2CorrType.Update and Q2CorrType.ConditionalUpdate - - if (q2CorrType == Q2CorrType.Update || q2CorrType == Q2CorrType.ConditionalUpdate) - { - /// Calculate two Q2 correction factors from two tests done in both directions - q2Correction = ihead.CalculateQ2CorrectionFactor(q2adjResult, q2adjTestData.Qfrom, q2adjResult.Q2CorrRL); - q2Correction2 = ihead.CalculateQ2CorrectionFactor(q2adjResult2, q2adjTestData2.Qfrom, q2adjResult2.Q2CorrLR); - } - else - { - /// Calculate Q2 correction factors from a single test - q2Correction = ihead.CalculateQ2CorrectionFactor(q2adjResult, q2adjTestData.Qfrom, q2adjResult.Q2CorrRL); - q2Correction2 = ihead.CalculateQ2CorrectionFactor(q2adjResult, q2adjTestData.Qfrom, q2adjResult.Q2CorrLR); - } - - int q2CorrRL = 0; int q2CorrLR = 0; /// @@ -2096,7 +2099,8 @@ namespace TBF.Rig.TestMethods.iPerlCommunication /// No 2nd Q2 test, MakeQ2CorrectedFrom(...) is used to calculate Q2 error /// Do not forget to modify iPerlCommunicationSeq.MakeQ2CorrectedFrom(...) /// - q2CorrRL = (q3error * q2adjResult.Error < 0) ? Convert.ToInt32(0.9 * q2Correction) : Convert.ToInt32(1.1 * q2Correction); + double errorTarget = (q3error * q2adjResult.Error < 0) ? (0.1 * q2adjResult.Error) : (-0.1 * q2adjResult.Error); + q2CorrRL = Convert.ToInt32(ihead.CalculateQ2CorrectionFactor(q2adjResult, errorTarget, q2adjTestData.Qfrom, q2adjResult.Q2CorrRL)); } else if (q2CorrType == Q2CorrType.Dewa || q2CorrType == Q2CorrType.Dewa_incl_05 || @@ -2107,7 +2111,8 @@ namespace TBF.Rig.TestMethods.iPerlCommunication /// No 2nd Q2 test, MakeQ2CorrectedFrom(...) is used to calculate Q2 error /// Do not forget to modify iPerlCommunicationSeq.MakeQ2CorrectedFrom(...) /// - q2CorrLR = (q3error * q2adjResult.Error < 0) ? Convert.ToInt32(0.9 * q2Correction) : Convert.ToInt32(1.1 * q2Correction); + double errorTarget = (q3error * q2adjResult.Error < 0) ? (0.1 * q2adjResult.Error) : (-0.1 * q2adjResult.Error); + q2CorrLR = Convert.ToInt32(ihead.CalculateQ2CorrectionFactor(q2adjResult, errorTarget, q2adjTestData.Qfrom, q2adjResult.Q2CorrLR)); } else if (q2CorrType == Q2CorrType.RL || q2CorrType == Q2CorrType.RL_incl_05 || @@ -2124,7 +2129,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication return CommErr.None; } - q2CorrRL = Convert.ToInt32(q2Correction); + q2CorrRL = Convert.ToInt32(ihead.CalculateQ2CorrectionFactor(q2adjResult, 0, q2adjTestData.Qfrom, q2adjResult.Q2CorrRL)); } else if (q2CorrType == Q2CorrType.LR || q2CorrType == Q2CorrType.LR_incl_05 || @@ -2141,7 +2146,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication return CommErr.None; } - q2CorrLR = Convert.ToInt32(q2Correction2); + q2CorrLR = Convert.ToInt32(ihead.CalculateQ2CorrectionFactor(q2adjResult, 0, q2adjTestData.Qfrom, q2adjResult.Q2CorrLR)); } else if (q2CorrType == Q2CorrType.Update || q2CorrType == Q2CorrType.ConditionalUpdate) { @@ -2150,8 +2155,8 @@ namespace TBF.Rig.TestMethods.iPerlCommunication /// Assuming the 2nd Q2 tests are done afterwards /// MakeQ2CorrectedFrom(...) is not used /// - q2CorrRL = Convert.ToInt32(q2Correction); - q2CorrLR = Convert.ToInt32(q2Correction2); + q2CorrRL = Convert.ToInt32(ihead.CalculateQ2CorrectionFactor(q2adjResult, 0, q2adjTestData.Qfrom, q2adjResult.Q2CorrRL)); + q2CorrLR = Convert.ToInt32(ihead.CalculateQ2CorrectionFactor(q2adjResult2, 0, q2adjTestData2.Qfrom, q2adjResult2.Q2CorrLR)); } else if (q2CorrType == Q2CorrType.Greece || q2CorrType == Q2CorrType.Greece_incl_05 || q2CorrType == Q2CorrType.UpdateBothQ2FactorsTestLRDir) { @@ -2164,15 +2169,16 @@ namespace TBF.Rig.TestMethods.iPerlCommunication return CommErr.None; } - q2CorrRL = Convert.ToInt32(2.0 * q2Correction2); - q2CorrLR = Convert.ToInt32(1.0 * q2Correction2); - } + q2CorrLR = Convert.ToInt32(ihead.CalculateQ2CorrectionFactor(q2adjResult, 0, q2adjTestData.Qfrom, q2adjResult.Q2CorrLR)); + q2CorrRL = q2CorrLR; + } else if (q2CorrType == Q2CorrType.UpdateBothQ2FactorsTestRLDir) { /// /// Another strange process /// - q2CorrRL = (q3error * q2adjResult.Error < 0) ? Convert.ToInt32(0.9 * q2Correction) : Convert.ToInt32(1.1 * q2Correction); + double errorTarget = (q3error * q2adjResult.Error < 0) ? (0.1 * q2adjResult.Error) : (-0.1 * q2adjResult.Error); + q2CorrRL = Convert.ToInt32(ihead.CalculateQ2CorrectionFactor(q2adjResult, errorTarget, q2adjTestData.Qfrom, q2adjResult.Q2CorrRL)); q2CorrLR = q2CorrRL; } diff --git a/TBF/Rig/TestMethods/iPerlCommunication/iPerlHead/IperlHead.cs b/TBF/Rig/TestMethods/iPerlCommunication/iPerlHead/IperlHead.cs index 52ac1f662..2236e9d32 100644 --- a/TBF/Rig/TestMethods/iPerlCommunication/iPerlHead/IperlHead.cs +++ b/TBF/Rig/TestMethods/iPerlCommunication/iPerlHead/IperlHead.cs @@ -213,9 +213,11 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead /// Nominal flow in m3/h /// 0 or the current Q2 correction factor when updating the factor /// Calculated Q2 correction factor - public double CalculateQ2CorrectionFactor(Results.Entities.MeterTestRslt q2adjResult, double nominalFlow, int currentFactor = 0) + public double CalculateQ2CorrectionFactor(Results.Entities.MeterTestRslt currentQ2Result, double errorTarget, double nominalFlow, int currentFactor = 0) { double nominalTestFlowLph = Units.ConvertTo(Unit.lph, nominalFlow); + double volumeRefShiftedToTarget = currentQ2Result.VolumeRef * (1.0 + errorTarget / 100.0); + double q2adjErrorShiftedToTarget = Config.Formulas.ErrorFromVolumes(currentQ2Result.VolumeMeter, volumeRefShiftedToTarget); double A = 16.0 / ScalingFactor(); /// Raw units per ml: DN15=16, DN20=8, DN25=4, DN32=2, DN40=1 const double B = 8.0; /// Raw units per minute, 8 @@ -224,14 +226,19 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead double F = D / (nominalTestFlowLph * 10.0); /// Error corrected with 8 Raw Units per minute [%] double G = F / B; /// Error corrected with 1 Raw Unit per minute [%] - /// Do not change the factor for an invalid measurement (q2adjResult.VolumeMeter == 0) - double q2CorrectionFactor = (Math.Abs(q2adjResult.VolumeMeter) <= float.Epsilon) ? Convert.ToDouble(currentFactor) : - Convert.ToDouble(currentFactor) - (q2adjResult.Error / G) * (q2adjResult.VolumeRef / q2adjResult.VolumeMeter); + double q2CorrectionFactor = Convert.ToDouble(currentFactor) + - (q2adjErrorShiftedToTarget / G) * (volumeRefShiftedToTarget / currentQ2Result.VolumeMeter); - log.WarnFormat("CalculateQ2CorrectionFactor() : Pos={0}, PCB#={1}, Error={2}%, Q2CorrFactor={3}", + ///// Do not change the factor for an invalid measurement (q2adjResult.VolumeMeter == 0) + //double q2CorrectionFactor = (Math.Abs(q2adjResult.VolumeMeter) <= float.Epsilon) ? Convert.ToDouble(currentFactor) : + // Convert.ToDouble(currentFactor) - (q2adjResult.Error / G) * (q2adjResult.VolumeRef / q2adjResult.VolumeMeter); + + log.WarnFormat("CalculateQ2CorrectionFactor() : Pos={0}, PCB#={1}, Error={2}%, Target={3}%, Current factor={4} New factor={5}", Name, SerialNr, - q2adjResult.Error.ToString("F2"), + currentQ2Result.Error.ToString("F2"), + errorTarget.ToString("F3"), + currentFactor.ToString("F1"), q2CorrectionFactor.ToString("F1")); return q2CorrectionFactor; diff --git a/TBF/Rig/TestMethods/iPerlCommunication/iPerlHead/ProcParams.cs b/TBF/Rig/TestMethods/iPerlCommunication/iPerlHead/ProcParams.cs index 446898dd5..b716a79a3 100644 --- a/TBF/Rig/TestMethods/iPerlCommunication/iPerlHead/ProcParams.cs +++ b/TBF/Rig/TestMethods/iPerlCommunication/iPerlHead/ProcParams.cs @@ -1,5 +1,5 @@ /// -/// Copyright (c) 2015-2019 Sensus Slovensko a.s. +/// Copyright (c) 2015-2023 Sensus Slovensko a.s. /// using System; using System.IO;