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

This commit is contained in:
Milan Hanajik 2023-08-09 09:25:31 +02:00
parent 8c30cb21e2
commit c5752f21a9
4 changed files with 51 additions and 38 deletions

View File

@ -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")]

View File

@ -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;
}

View File

@ -213,9 +213,11 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
/// <param name="nominalFlow">Nominal flow in m3/h</param>
/// <param name="currentFactor">0 or the current Q2 correction factor when updating the factor</param>
/// <returns>Calculated Q2 correction factor</returns>
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;

View File

@ -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;