CombinedWithDetTestParams.OffsetPulsesFreq parameter introduced, use in Qfall detection, ver. 2.18.968
This commit is contained in:
parent
1d8728c7ce
commit
9ba1b58d2e
@ -1,5 +1,5 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2015 Sensus Metering Systems
|
||||
/// Copyright (c) 2013-2018 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.IO;
|
||||
@ -21,7 +21,8 @@ namespace TBF.BenchControl.TestMethods.CombinedWithDetection
|
||||
public float RelativeQto; /// Tested flow high range related to the detected flow
|
||||
public float RateOfChange; /// Each step is calculated as (TargetQfrom - Qfrom) * RateOfChange, text form is displayed in % (*100)
|
||||
public float DetectionThreshold; /// Drop of frequency for the detection, text form is displayed in % (*100)
|
||||
public bool SupressTrills; /// Main meter readings are ignored during test (suitable for small flows)
|
||||
public float OffsetPulsesFreq; /// Offset frequency of pulses of the small WM for the detection in Hz
|
||||
public bool SupressTrills; /// Main meter readings are ignored during test (suitable for small flows)
|
||||
|
||||
public override void InitializeAll()
|
||||
{
|
||||
@ -30,6 +31,7 @@ namespace TBF.BenchControl.TestMethods.CombinedWithDetection
|
||||
RelativeQto = -0.2f;
|
||||
RateOfChange = 0.05f;
|
||||
DetectionThreshold = 0.25f;
|
||||
OffsetPulsesFreq = 1.0f;
|
||||
SupressTrills = false;
|
||||
}
|
||||
|
||||
@ -41,6 +43,7 @@ namespace TBF.BenchControl.TestMethods.CombinedWithDetection
|
||||
Strings.RelativeQto,
|
||||
Strings.RateOfChangePct,
|
||||
Strings.DetectionThresholdPct,
|
||||
"Offset pulses freq.",
|
||||
Strings.SupressWMTrills,
|
||||
};
|
||||
public override string ParamName(int i) { return paramNames[i]; }
|
||||
@ -55,7 +58,8 @@ namespace TBF.BenchControl.TestMethods.CombinedWithDetection
|
||||
case 2: return RelativeQto.ToString();
|
||||
case 3: return (100.0f * RateOfChange).ToString();
|
||||
case 4: return (100.0f * DetectionThreshold).ToString();
|
||||
case 5: return (SupressTrills ? Strings.yes : Strings.no);
|
||||
case 5: return OffsetPulsesFreq.ToString();
|
||||
case 6: return (SupressTrills ? Strings.yes : Strings.no);
|
||||
default: return string.Empty;
|
||||
}
|
||||
}
|
||||
@ -64,13 +68,14 @@ namespace TBF.BenchControl.TestMethods.CombinedWithDetection
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0: TargetQ = Utils.ParseUFloat(strValue); return CfgUpdateFlags.None;
|
||||
case 1: RelativeQfrom = Utils.ParseSFloat(strValue); return CfgUpdateFlags.None;
|
||||
case 2: RelativeQto = Utils.ParseSFloat(strValue); return CfgUpdateFlags.None;
|
||||
case 3: RateOfChange = Utils.ParseUFloat(strValue) / 100.0f; return CfgUpdateFlags.None;
|
||||
case 4: DetectionThreshold = Utils.ParseUFloat(strValue) / 100.0f; return CfgUpdateFlags.None;
|
||||
case 5: SupressTrills = strValue.Equals(Strings.yes); return CfgUpdateFlags.None;
|
||||
default: return CfgUpdateFlags.None;
|
||||
case 0: TargetQ = Utils.ParseUFloat(strValue); return CfgUpdateFlags.None;
|
||||
case 1: RelativeQfrom = Utils.ParseSFloat(strValue); return CfgUpdateFlags.None;
|
||||
case 2: RelativeQto = Utils.ParseSFloat(strValue); return CfgUpdateFlags.None;
|
||||
case 3: RateOfChange = Utils.ParseUFloat(strValue) / 100.0f; return CfgUpdateFlags.None;
|
||||
case 4: DetectionThreshold = Utils.ParseUFloat(strValue) / 100.0f; return CfgUpdateFlags.None;
|
||||
case 5: OffsetPulsesFreq = Utils.ParseUFloat(strValue); return CfgUpdateFlags.None;
|
||||
case 6: SupressTrills = strValue.Equals(Strings.yes); return CfgUpdateFlags.None;
|
||||
default: return CfgUpdateFlags.None;
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,13 +89,14 @@ namespace TBF.BenchControl.TestMethods.CombinedWithDetection
|
||||
case 0:
|
||||
case 3:
|
||||
case 4:
|
||||
if (Utils.TryParseUFloat(strValue, out dummy)) return true;
|
||||
case 5:
|
||||
if (Utils.TryParseUFloat(strValue, out dummy)) return true;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
if (Utils.TryParseSFloat(strValue, out dummy)) return true;
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
if (strValue.Equals(Strings.yes) || strValue.Equals(Strings.no)) return true;
|
||||
break;
|
||||
default:
|
||||
@ -109,7 +115,8 @@ namespace TBF.BenchControl.TestMethods.CombinedWithDetection
|
||||
prms.RelativeQto = this.RelativeQto;
|
||||
prms.RateOfChange = this.RateOfChange;
|
||||
prms.DetectionThreshold = this.DetectionThreshold;
|
||||
prms.SupressTrills = this.SupressTrills;
|
||||
prms.OffsetPulsesFreq = this.OffsetPulsesFreq;
|
||||
prms.SupressTrills = this.SupressTrills;
|
||||
}
|
||||
|
||||
public IParamsProvider Clone()
|
||||
|
||||
@ -91,7 +91,7 @@ namespace TBF.BenchControl.TestMethods.CombinedWithDetection
|
||||
int[] lastWMPulses = new int[2 * Config.Data.CompoundWMsCount];
|
||||
|
||||
//--------------------------------
|
||||
State.Create(string.Format("{0}({1}) : stopTest diverter gate etc", test.Method, test.Name))
|
||||
State.Create(string.Format("{0}({1}) : Stop diverter gate etc", test.Method, test.Name))
|
||||
.AddOperation(checkUiOp)
|
||||
.AddOperation(cBrd.StopPreviousOp())
|
||||
.EnterState();
|
||||
@ -131,9 +131,9 @@ namespace TBF.BenchControl.TestMethods.CombinedWithDetection
|
||||
goto stopTest;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
processDataLoggingOp = new TBF.BenchControl.Operations.ProcessDataLoggingOp(processDataLogger, this, false);
|
||||
|
||||
|
||||
/// Meters path is required for the following:
|
||||
readRegistersOp = new Operations.ReadMoreRegistersOp(sensPath.RegisterReaders);
|
||||
|
||||
@ -170,7 +170,7 @@ namespace TBF.BenchControl.TestMethods.CombinedWithDetection
|
||||
}
|
||||
}
|
||||
|
||||
// Empty the water tank
|
||||
/// Empty the water tank
|
||||
switch (DrainTheTank(outPath.Scale.DrainValve, outPath.Scale))
|
||||
{
|
||||
case Event.Error: goto error;
|
||||
@ -218,7 +218,6 @@ namespace TBF.BenchControl.TestMethods.CombinedWithDetection
|
||||
foreach (var camera in cameras) measureOperations.Add(camera.MeasurementOp());
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------
|
||||
Bridge.OnActivity(this, Strings.Switching_flow_detection);
|
||||
//------------------------------------------------
|
||||
@ -237,7 +236,7 @@ namespace TBF.BenchControl.TestMethods.CombinedWithDetection
|
||||
}
|
||||
while (!e.Contains(Event.ValvesSet));
|
||||
|
||||
//--------------------------------
|
||||
|
||||
State.Create(string.Format("{0}({1}) : Set the initial flow", test.Method, test.Name))
|
||||
.AddOperation(checkUiOp)
|
||||
.AddOperations(measureOperations)
|
||||
@ -257,7 +256,7 @@ namespace TBF.BenchControl.TestMethods.CombinedWithDetection
|
||||
}
|
||||
while (!e.Contains(Event.FlowReached));
|
||||
|
||||
//--------------------------------
|
||||
|
||||
switch (ReadRegistersTempPressAmbient(measureOperations, false))
|
||||
{
|
||||
case Event.Error: goto error;
|
||||
@ -269,7 +268,7 @@ namespace TBF.BenchControl.TestMethods.CombinedWithDetection
|
||||
//====================================
|
||||
|
||||
/// Allocate detection buffers
|
||||
double[] flowsForDetection = new double[DetectionBufferSize];
|
||||
double[] flowsForDetection = new double[DetectionBufferSize]; /// in [m3/h]
|
||||
double[] pulseFreqsForDetection = new double[DetectionBufferSize];
|
||||
|
||||
/// Current values
|
||||
@ -279,9 +278,9 @@ namespace TBF.BenchControl.TestMethods.CombinedWithDetection
|
||||
int lastTime = StateMachine.Time;
|
||||
|
||||
/// Detection parameters
|
||||
float rvPulse = (testParams.TargetQ > (test.Qfrom + test.Qto) / 2.0f) ? 0.05f : -0.05f; // rise or fall?
|
||||
float rvPulse = (testParams.TargetQ > (test.Qfrom + test.Qto) / 2.0f) ? 0.05f : -0.05f; /// rise(+) or fall(-)
|
||||
rvPulse *= (100.0f * testParams.RateOfChange);
|
||||
|
||||
|
||||
bool detected = false;
|
||||
bool targetReached = false;
|
||||
double detectedFlow = 0;
|
||||
@ -290,109 +289,124 @@ namespace TBF.BenchControl.TestMethods.CombinedWithDetection
|
||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Config.Entities.Progress.SwitchingFlowDetection));
|
||||
|
||||
do
|
||||
{
|
||||
//--------------------------------
|
||||
{
|
||||
State.Create(string.Format("{0}({1}) : Change the RV position", test.Method, test.Name))
|
||||
.AddOperation(checkUiOp)
|
||||
.AddOperations(measureOperations)
|
||||
.AddOperation(outPath.RegulValve.ChangeRegulValvePositionOp(rvPulse))
|
||||
.EnterState();
|
||||
do
|
||||
{
|
||||
e = StateMachine.WaitRunDevsRunOps();
|
||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Config.Entities.Progress.SwitchingFlowDetection));
|
||||
.AddOperation(checkUiOp)
|
||||
.AddOperations(measureOperations)
|
||||
.AddOperation(outPath.RegulValve.ChangeRegulValvePositionOp(rvPulse))
|
||||
.EnterState();
|
||||
do
|
||||
{
|
||||
e = StateMachine.WaitRunDevsRunOps();
|
||||
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetitionNr, Config.Entities.Progress.SwitchingFlowDetection));
|
||||
|
||||
if (TestAndLogUiCmdStop(test,e)) goto stopTest;
|
||||
}
|
||||
if (TestAndLogUiCmdStop(test, e)) goto stopTest;
|
||||
}
|
||||
while (!e.Contains(Event.PositionReached));
|
||||
|
||||
// Last pulses are kept to calculate differences
|
||||
for (int i = 0; i < 2 * Config.Data.CompoundWMsCount; i++) lastWMPulses[i] = RegisterReaders[i].WMPulses;
|
||||
|
||||
// Shift data in the detection buffers
|
||||
for (int i = DetectionBufferSize - 2; i >= 0; i--)
|
||||
{
|
||||
flowsForDetection[i+1] = flowsForDetection[i];
|
||||
pulseFreqsForDetection[i+1] = pulseFreqsForDetection[i];
|
||||
///
|
||||
/// Update FIFO buffers for the reference flow and the frequency of pulses
|
||||
///
|
||||
|
||||
/// Last pulses are kept to calculate differences
|
||||
for (int i = 0; i < 2 * Config.Data.CompoundWMsCount; i++) lastWMPulses[i] = RegisterReaders[i].WMPulses;
|
||||
|
||||
/// Shift data in the detection buffers
|
||||
for (int i = DetectionBufferSize - 2; i >= 0; i--)
|
||||
{
|
||||
flowsForDetection[i + 1] = flowsForDetection[i];
|
||||
pulseFreqsForDetection[i + 1] = pulseFreqsForDetection[i];
|
||||
}
|
||||
|
||||
switch (ReadRegistersTempPressAmbient(measureOperations, false))
|
||||
{
|
||||
case Event.Error: goto error;
|
||||
case Event.UiCmdStop: goto stopTest;
|
||||
}
|
||||
|
||||
int diff = RegisterReaders[(test.Part - 1) * 2 + 1].WMPulses - lastWMPulses[(test.Part - 1) * 2 + 1];
|
||||
flowsForDetection[0] = cBrd.ReferenceFreq * outPath.FlowMeter.NominalFlow / 2000.0;
|
||||
pulseFreqsForDetection[0] = (double)diff / (double)(StateMachine.Time - lastTime);
|
||||
lastTime = StateMachine.Time;
|
||||
}
|
||||
|
||||
switch (ReadRegistersTempPressAmbient(measureOperations, false))
|
||||
{
|
||||
case Event.Error: goto error;
|
||||
case Event.UiCmdStop: goto stopTest;
|
||||
}
|
||||
if ((StateMachine.Time - detectionStartTime > 15) && (flowsForDetection[0] > 0) && (flowsForDetection[DetectionBufferSize - 1] > 0))
|
||||
{
|
||||
///
|
||||
/// Evaluate ref. flow and WM pulses frequency data in FIFO buffers.
|
||||
/// Updpate 'detected' and 'targetReached' flags.
|
||||
///
|
||||
double[] flowBefore = new double[DetectionKernelSize];
|
||||
double[] flowAfter = new double[DetectionKernelSize];
|
||||
double[] freqBefore = new double[DetectionKernelSize];
|
||||
double[] freqAfter = new double[DetectionKernelSize];
|
||||
for (int i = 0; i < DetectionKernelSize; i++)
|
||||
{
|
||||
flowBefore[i] = flowsForDetection[DetectionBufferSize - DetectionKernelSize + i]; /// The oldest DetectionKernelSize samples
|
||||
freqBefore[i] = pulseFreqsForDetection[DetectionBufferSize - DetectionKernelSize + i];
|
||||
|
||||
int time = StateMachine.Time;
|
||||
int diff = RegisterReaders[(test.Part - 1) * 2 + 1].WMPulses - lastWMPulses[(test.Part - 1) * 2 + 1];
|
||||
flowsForDetection[0] = cBrd.ReferenceFreq * outPath.FlowMeter.NominalFlow / 2000.0f;
|
||||
pulseFreqsForDetection[0] = (float)diff / (float)(time - lastTime);
|
||||
lastTime = StateMachine.Time;
|
||||
flowAfter[i] = flowsForDetection[i]; /// The newest DetectionKernelSize samples
|
||||
freqAfter[i] = pulseFreqsForDetection[i];
|
||||
}
|
||||
|
||||
if (StateMachine.Time - detectionStartTime > 15)
|
||||
{
|
||||
if ((flowsForDetection[0] > 0) && (flowsForDetection[DetectionBufferSize - 1] > 0))
|
||||
{
|
||||
double[] flowBefore = new double[DetectionKernelSize];
|
||||
double[] flowAfter = new double[DetectionKernelSize];
|
||||
double[] freqBefore = new double[DetectionKernelSize];
|
||||
double[] freqAfter = new double[DetectionKernelSize];
|
||||
for (int i = 0; i < DetectionKernelSize; i++)
|
||||
{
|
||||
flowBefore[i] = flowsForDetection[DetectionBufferSize - DetectionKernelSize + i];
|
||||
freqBefore[i] = pulseFreqsForDetection[DetectionBufferSize - DetectionKernelSize + i];
|
||||
flowAfter[i] = flowsForDetection[i];
|
||||
freqAfter[i] = pulseFreqsForDetection[i];
|
||||
}
|
||||
Array.Sort(flowBefore);
|
||||
Array.Sort(flowAfter);
|
||||
Array.Sort(freqBefore);
|
||||
Array.Sort(freqAfter);
|
||||
flowBefore[0] = 0;
|
||||
flowAfter[0] = 0;
|
||||
//freqBefore[0] = 0;
|
||||
//freqAfter[0] = 0;
|
||||
flowBefore[DetectionKernelSize - 1] = 0;
|
||||
flowAfter[DetectionKernelSize - 1] = 0;
|
||||
//freqBefore[DetectionKernelSize - 1] = 0;
|
||||
//freqAfter[DetectionKernelSize - 1] = 0;
|
||||
double aveFlowBefore = 0;
|
||||
double aveFlowAfter = 0;
|
||||
double aveFreqBefore = 0;
|
||||
double aveFreqAfter = 0;
|
||||
foreach (var f in flowBefore) aveFlowBefore += f;
|
||||
foreach (var f in flowAfter) aveFlowAfter += f;
|
||||
foreach (var f in freqBefore) aveFreqBefore += f;
|
||||
foreach (var f in freqAfter) aveFreqAfter += f;
|
||||
aveFlowBefore /= (double)(DetectionKernelSize - 2);
|
||||
aveFlowAfter /= (double)(DetectionKernelSize - 2);
|
||||
aveFreqBefore /= (double)(DetectionKernelSize);
|
||||
aveFreqAfter /= (double)(DetectionKernelSize);
|
||||
/// Skip the smallest and the largest flow
|
||||
Array.Sort(flowBefore);
|
||||
Array.Sort(flowAfter);
|
||||
flowBefore[0] = 0;
|
||||
flowAfter[0] = 0;
|
||||
flowBefore[DetectionKernelSize - 1] = 0;
|
||||
flowAfter[DetectionKernelSize - 1] = 0;
|
||||
///
|
||||
double aveFlowBefore = 0;
|
||||
double aveFlowAfter = 0;
|
||||
foreach (var f in flowBefore) aveFlowBefore += f;
|
||||
foreach (var f in flowAfter) aveFlowAfter += f;
|
||||
aveFlowBefore /= (double)(DetectionKernelSize - 2);
|
||||
aveFlowAfter /= (double)(DetectionKernelSize - 2);
|
||||
|
||||
UiBridge.Bridge.OnLog(this, string.Format("time={0}, flow{1}, aveFlowB={2}, aveFlowA={3}, pulseFreq={4}, aveFreqB={5}, aveFreqA={6}\r\n",
|
||||
time - startTime,
|
||||
flowsForDetection[0].ToString("F2"),
|
||||
aveFlowBefore.ToString("F2"),
|
||||
aveFlowAfter.ToString("F2"),
|
||||
pulseFreqsForDetection[0].ToString("F2"),
|
||||
aveFreqBefore.ToString("F2"),
|
||||
aveFreqAfter.ToString("F2")));
|
||||
/// Do NOT skip the smallest and the largest flow
|
||||
//Array.Sort(freqBefore);
|
||||
//Array.Sort(freqAfter);
|
||||
//freqBefore[0] = 0;
|
||||
//freqAfter[0] = 0;
|
||||
//freqBefore[DetectionKernelSize - 1] = 0;
|
||||
//freqAfter[DetectionKernelSize - 1] = 0;
|
||||
///
|
||||
double aveFreqBefore = 0;
|
||||
double aveFreqAfter = 0;
|
||||
foreach (var f in freqBefore) aveFreqBefore += f;
|
||||
foreach (var f in freqAfter) aveFreqAfter += f;
|
||||
aveFreqBefore /= (double)DetectionKernelSize;
|
||||
aveFreqAfter /= (double)DetectionKernelSize;
|
||||
|
||||
//detectedFlow = (aveFlowBefore + aveFlowAfter) / 2.0f;
|
||||
detectedFlow = aveFlowBefore;
|
||||
UiBridge.Bridge.OnLog(this, string.Format("time={0}, flow{1}, aveFlowB={2}, aveFlowA={3}, pulseFreq={4}, aveFreqB={5}, aveFreqA={6}\r\n",
|
||||
StateMachine.Time - startTime,
|
||||
flowsForDetection[0].ToString("F2"),
|
||||
aveFlowBefore.ToString("F2"),
|
||||
aveFlowAfter.ToString("F2"),
|
||||
pulseFreqsForDetection[0].ToString("F2"),
|
||||
aveFreqBefore.ToString("F2"),
|
||||
aveFreqAfter.ToString("F2")));
|
||||
|
||||
if (rvPulse > 0)
|
||||
{
|
||||
detected = (aveFreqAfter < aveFreqBefore * (1.0f - testParams.DetectionThreshold));
|
||||
targetReached = ((aveFlowAfter + aveFlowBefore) / 2.0f) > testParams.TargetQ;
|
||||
}
|
||||
else
|
||||
{
|
||||
detected = (aveFreqAfter > aveFreqBefore * (1.0f + testParams.DetectionThreshold));
|
||||
targetReached = ((aveFlowAfter + aveFlowBefore) / 2.0f) < testParams.TargetQ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//detectedFlow = (aveFlowBefore + aveFlowAfter) / 2.0f;
|
||||
detectedFlow = aveFlowBefore;
|
||||
|
||||
if (rvPulse > 0)
|
||||
{
|
||||
/// rise
|
||||
detected = (aveFreqAfter < aveFreqBefore * (1.0f - testParams.DetectionThreshold));
|
||||
targetReached = ((aveFlowAfter + aveFlowBefore) / 2.0f) > testParams.TargetQ;
|
||||
}
|
||||
else
|
||||
{
|
||||
/// fall
|
||||
detected = (aveFreqAfter > (aveFreqBefore + testParams.OffsetPulsesFreq) * (1.0f + testParams.DetectionThreshold));
|
||||
targetReached = ((aveFlowAfter + aveFlowBefore) / 2.0f) < testParams.TargetQ;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
while (!detected && !targetReached);
|
||||
|
||||
if (rvPulse > 0)
|
||||
|
||||
@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("2.18.967.0")]
|
||||
[assembly: AssemblyFileVersion("2.18.967.0")]
|
||||
[assembly: AssemblyVersion("2.18.968.0")]
|
||||
[assembly: AssemblyFileVersion("2.18.968.0")]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user