StartMeasurementOp, ver. 3.1.1628

This commit is contained in:
Milan Hanajik
2021-03-11 17:57:19 +01:00
parent 768fb69653
commit 3e7ad6c06c
6 changed files with 311 additions and 75 deletions
+2 -2
View File
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
// Build Number
// Revision
//
[assembly: AssemblyVersion("3.1.1627.0")]
[assembly: AssemblyFileVersion("3.1.1627.0")]
[assembly: AssemblyVersion("3.1.1628.0")]
[assembly: AssemblyFileVersion("3.1.1628.0")]
@@ -0,0 +1,192 @@
///
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
///
using System;
using log4net;
using TBF.Rig.GenericDevices;
namespace TBF.Rig.ControlBoard.Uni
{
public class StartMeasurementOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(StartMeasurementOp));
public override string ToString() { return string.Format("StartMeasurementOp()"); }
/// Set by the constructor
readonly UniCB uniCB;
readonly TBF.Rig.Uni.RegValve.RegValve regValve;
readonly TBF.Rig.Uni.FlowMeter.FlowMeter flowMeter;
readonly TBF.Rig.Uni.Diverter.Diverter diverter;
readonly int regulValveStableTime;
readonly double maximalFlow;
readonly double qFrom;
readonly double qTo;
readonly int totalRefPulses; /// Number of reference pulses for a complete test
readonly int massRefPulses; /// Number of reference pulses for mass collection
readonly int delayBeforeFlowRegulation; /// Delay before flow control starts in seconds
readonly TestMethods testMethod;
///
/// Internal states of this operation
///
enum OpState
{
StartingTest,
ResendCommand,
WaitingBeforeValveMove,
StartingFlowRegulation,
OpCompleted,
}
OpState opState;
int delayStartTime; /// StateMachine.Time snapshot when delay before flow regulation starts
/// <summary>
/// Starts the measurement.
/// Events: MeasurementStarted
/// </summary>
/// <param name="cb">Control board component reference</param>
/// <param name="devices">Specifies used components</param>
/// <param name="method">Test method</param>
/// <param name="totalRefPulses">Test duration in number of reference flowmeter pulses</param>
/// <param name="filterConstant">Specifies filter for watermeter pulses</param>
public StartMeasurementOp(IControlBoard cb, OutputPath devices, TestMethods method, double qFrom, double qTo,
int refPulses, int delayBeforeFlowRegulation = 0)
: this(cb, devices, method, qFrom, qTo, refPulses, refPulses, delayBeforeFlowRegulation)
{
}
/// <summary>
/// Starts the measurement.
/// Events: MeasurementStarted
/// </summary>
/// <param name="cb">Control board component reference</param>
/// <param name="devices">Specifies used components</param>
/// <param name="method">Test method</param>
/// <param name="refPulses">Test duration in number of reference flowmeter pulses</param>
/// <param name="filterConstant">Specifies filter for watermeter pulses</param>
public StartMeasurementOp(IControlBoard cb, OutputPath devices, TestMethods method, double qFrom, double qTo,
int totalRefPulses, int massRefPulses, int delayBeforeFlowRegulation = 0)
{
this.uniCB = cb as UniCB;
if (uniCB == null) throw new ArgumentNullException("Invalid control board");
flowMeter = devices.FlowMeter as TBF.Rig.Uni.FlowMeter.FlowMeter;
if (flowMeter == null) throw new ArgumentNullException("Invalid flow meter");
regValve = devices.RegValve as TBF.Rig.Uni.RegValve.RegValve;
if (regValve == null) throw new ArgumentNullException("Invalid regulation");
diverter = devices.Diverter as TBF.Rig.Uni.Diverter.Diverter;
if (diverter == null) throw new ArgumentNullException("Invalid diverter");
this.testMethod = method;
this.qFrom = qFrom;
this.qTo = qTo;
this.totalRefPulses = totalRefPulses;
this.massRefPulses = massRefPulses;
this.delayBeforeFlowRegulation = delayBeforeFlowRegulation;
maximalFlow = 1.25 * flowMeter.NominalFlow;
log.Debug(this.ToString());
}
void SendStartCommand()
{
//uniCB.SyncRoute();
uniCB.StartTest(false, flowMeter.Idx1, diverter.DiverterNr, 20,
testMethod == TestMethods.Diverter || testMethod == TestMethods.MassAndContinue || testMethod == TestMethods.Synchro,
testMethod == TestMethods.Diverter || testMethod == TestMethods.MassAndContinue,
testMethod == TestMethods.FixedStart,
totalRefPulses, massRefPulses);
}
/// <summary>Start this operation</summary>
public void Start()
{
SendStartCommand();
opState = OpState.StartingTest;
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.FlowInDone or Event.FlowOutDone
/// </returns>
public Event Run()
{
if (opState == OpState.StartingTest)
{
ulong state = uniCB.State;
log.DebugFormat("state = {0} {1} {2} {3}",
(((ulong)state >> 48) & 0xFFFF).ToString("X4"),
(((ulong)state >> 32) & 0xFFFF).ToString("X4"),
(((ulong)state >> 16) & 0xFFFF).ToString("X4"),
((ulong)state & 0xFFFF).ToString("X4"));
if ((state & (ulong)StatusP.TestInProgress) != 0)
{
log.Info("Test started");
if (delayBeforeFlowRegulation > 0)
{
delayStartTime = StateMachine.Time;
opState = OpState.WaitingBeforeValveMove;
}
else
{
opState = OpState.StartingFlowRegulation;
}
}
else
{
//opState = OpState.ResendCommand;
}
return Event.None;
}
else if (opState == OpState.ResendCommand)
{
SendStartCommand();
opState = OpState.StartingTest;
return Event.None;
}
else if (opState == OpState.WaitingBeforeValveMove)
{
if (StateMachine.Time - delayStartTime >= delayBeforeFlowRegulation)
{
opState = OpState.StartingFlowRegulation;
}
return Event.None;
}
else if (opState == OpState.StartingFlowRegulation)
{
///
/// Done once, issues an appropriate ValveMove(...) command
///
if ((qFrom >= qTo) || (qFrom > maximalFlow) || (qTo <= 0))
{
return Event.OpArgumentError;
}
log.InfoFormat("Run(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}",
regValve.Idx1, flowMeter.Idx1, qFrom, qTo);
double freqLo = 2000 * qFrom / flowMeter.NominalFlow;
double freqHi = 2000 * qTo / flowMeter.NominalFlow;
uniCB.SetFlow(false, regValve.Idx1, 2000 * qFrom / flowMeter.NominalFlow, 2000 * qTo / flowMeter.NominalFlow);
opState = OpState.OpCompleted;
return Event.None;
}
else if (opState == OpState.OpCompleted)
{
return Event.MeasurementStarted;
}
return Event.None;
}
/// <summary>Stop this operation</summary>
public void Stop() { }
}
}
+88
View File
@@ -477,6 +477,7 @@ namespace TBF.Rig.ControlBoard.Uni
public IOperation StopFlowRegulationOp()
{
Stop(false);
//scheduledActionQueue.Enqueue(Action.Stop());
return null;
}
@@ -490,6 +491,93 @@ namespace TBF.Rig.ControlBoard.Uni
/// <returns>Operation</returns>
public IOperation StartTestOp(Test test, int iParam = 0, double dParam1 = 0, double dParam2 = 0)
{
/// Get total number of pulses
int totalPulses = Convert.ToInt32(Math.Round(test.Volume / devices.FlowMeter.LtrPerPulse));
/// Get method class string
string methodClass;
if (!StateMachine.TestMethod2Class.TryGetValue(test.Name, out methodClass)) return null;
if (methodClass.Contains("TestMethods.Adjustment."))
{
return new StartMeasurementOp(this, devices, TestMethods.Synchro, test.Qfrom, test.Qto, totalPulses);
}
if (methodClass.Contains("TestMethods.CombinedWithDetection."))
{
return new StartMeasurementOp(this, devices, (TestMethods.Diverter | TestMethods.Synchro), dParam1, dParam2, totalPulses);
}
if (methodClass == "TestMethods.DiverterTest")
{
if (iParam == 0) return null;
return new StartMeasurementOp(this, devices, (TestMethods.Diverter | TestMethods.Synchro), test.Qfrom, test.Qto, totalPulses / iParam);
}
if (methodClass == "TestMethods.Dummy")
{
}
if (methodClass == "TestMethods.Endurance")
{
return new StartMeasurementOp(this, devices, TestMethods.Synchro, test.Qfrom, test.Qto, totalPulses);
}
if (methodClass.Contains("TestMethods.FixedStart."))
{
return new StartMeasurementOp(this, devices, TestMethods.Synchro, test.Qfrom, test.Qto, 2 * totalPulses, 10);
}
if (methodClass.Contains("TestMethods.FixedStartAdvanced."))
{
return new StartMeasurementOp(this, devices, TestMethods.Synchro, test.Qfrom, test.Qto, 2 * totalPulses, 10);
}
if (methodClass.Contains("TestMethods.FixedStartDefferedEval."))
{
return new StartMeasurementOp(this, devices, TestMethods.Synchro, test.Qfrom, test.Qto, 2 * totalPulses, 10);
}
if (methodClass.Contains("TestMethods.FixedStartMassCollDeferredEval."))
{
return new StartMeasurementOp(this, devices, (TestMethods.Diverter | TestMethods.Synchro), test.Qfrom, test.Qto, 2 * totalPulses, 10);
}
if (methodClass.Contains("TestMethods.FixedStartMassCollection."))
{
return new StartMeasurementOp(this, devices, (TestMethods.Diverter | TestMethods.FixedStart), test.Qfrom, test.Qto, 2 * totalPulses, 10);
}
if (methodClass.Contains("TestMethods.FixedStartTankCollection."))
{
return new StartMeasurementOp(this, devices, (TestMethods.Diverter | TestMethods.Synchro), test.Qfrom, test.Qto, (totalPulses * 5 / 4), 10);
}
if (methodClass.Contains("TestMethods.FlyingStart."))
{
return new StartMeasurementOp(this, devices, TestMethods.Synchro, test.Qfrom, test.Qto, totalPulses);
}
if (methodClass.Contains("TestMethods.FlyingStartFirstRepetWithMassColl."))
{
TestMethods tm = (iParam == 1) ? (TestMethods.Diverter | TestMethods.Synchro) : TestMethods.Synchro;
return new StartMeasurementOp(this, devices, tm, test.Qfrom, test.Qto, totalPulses);
}
if (methodClass.Contains("TestMethods.FlyingStartMassCollComparative."))
{
return new StartMeasurementOp(this, devices, (TestMethods.Diverter | TestMethods.Synchro), test.Qfrom, test.Qto, totalPulses);
}
if (methodClass.Contains("TestMethods.FlyingStartMassCollection."))
{
return new StartMeasurementOp(this, devices, (TestMethods.Diverter | TestMethods.Synchro), test.Qfrom, test.Qto, totalPulses);
}
if (methodClass.Contains("TestMethods.FlyingStartMassCollProlonged."))
{
if (iParam == 0) return null;
return new StartMeasurementOp(this, devices, (TestMethods.Diverter | TestMethods.Synchro), test.Qfrom, test.Qto, totalPulses, iParam);
}
if (methodClass.Contains("TestMethods.FlyingStartTankCollection."))
{
return new StartMeasurementOp(this, devices, (TestMethods.Diverter | TestMethods.Synchro), test.Qfrom, test.Qto, totalPulses);
}
if (methodClass == "TestMethods.PulsesTest")
{
return new StartMeasurementOp(this, devices, TestMethods.Synchro, test.Qfrom, test.Qto, totalPulses);
}
if (methodClass == "TestMethods.PulsesTestManual")
{
return new StartMeasurementOp(this, devices, TestMethods.Synchro, test.Qfrom, test.Qto, totalPulses);
}
return null;
}
@@ -1,5 +1,5 @@
///
/// Copyright (c) 2013-2018 Sensus Slovensko a.s.
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
@@ -24,8 +24,7 @@ namespace TBF.Rig.TestMethods.FlyingStart
/// <returns>true when capabilities of devices are OK</returns>
public static bool CheckDeviceCaps(Config.Entities.Test test, OutputPath devices, out string message)
{
if (!(StateMachine.ControlBoard is ControlBoard.Legacy.CBoard) &&
!(StateMachine.ControlBoard is ControlBoard.Uni.UniCB))
if (!(StateMachine.ControlBoard is ControlBoard.Uni.UniCB))
{
/// Control board does not support this method
message = string.Format("{0}: {1}", test.Name, Strings.Test_bench_does_not_suport_selected_test_method);
@@ -70,7 +69,7 @@ namespace TBF.Rig.TestMethods.FlyingStart
return Simulate(test, repetitionNr, isLastRepetition, compoundTestParams, heatMetersTestParams, debugLevel);
}
ControlBoard.IControlBoard cBrd = StateMachine.ControlBoard;
ControlBoard.Uni.UniCB cBrd = StateMachine.ControlBoard as ControlBoard.Uni.UniCB;
int rangeIx = 0; /// Default range, used for non-Elde flowmeters
if (outPath.FlowMeter is Uni.FlowMeter.FlowMeter)
@@ -100,8 +99,6 @@ namespace TBF.Rig.TestMethods.FlyingStart
processDataLoggingOp = new TBF.Rig.Operations.ProcessDataLoggingOp(processDataLogger, this, heatMetersTestParams != null);
if (cBrd is ControlBoard.Legacy.CBoard)
{
int[] filters = new int[] { 0, 0, 0, 0, 0, 0, 0, 0 };
if (sensPath != null && sensPath.RegisterReaders != null)
@@ -115,9 +112,8 @@ namespace TBF.Rig.TestMethods.FlyingStart
}
}
}
//cBrd.SetFiltersPidShortPulses(filters, outPath.PidCoef, test.ShortPulses);
(cBrd as ControlBoard.Legacy.CBoard).SetFiltersPidShortPulses(filters, outPath.PidCoef, test.ShortPulses);
}
IList<IOperation> readTempPressOps = new List<IOperation>();
if (benchPath.TempMtrUp != null) readTempPressOps.Add(benchPath.TempMtrUp.ReadTempOp(ref TempUp));
@@ -754,17 +750,7 @@ namespace TBF.Rig.TestMethods.FlyingStart
StopRecordingStatistics();
State.Create(string.Format("{0}({1}) : Stopping flow regulation", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(cBrd.StopFlowRegulationOp())
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error)) { retVal = Event.Error; break; }
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; break; }
}
while (!e.Contains(Event.FlowRegulationStopped));
cBrd.Stop(false);
///
/// Quit this sequence
@@ -772,15 +758,7 @@ namespace TBF.Rig.TestMethods.FlyingStart
if (isLastRepetition || retVal == Event.UiCmdStop || retVal == Event.OpArgumentError
|| retVal == Event.Error || retVal == Event.ConfigurationError)
{
State.Create(string.Format("{0}({1}) : Stopping diverter, gate, etc.", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperation(cBrd.StopPreviousOp())
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
if (TestAndLogUiCmdStop(test, e)) { if (retVal == Event.Done) retVal = Event.UiCmdStop; break; }
}
while (!e.Contains(Event.PreviousStopped));
cBrd.Stop(false);
}
stopTestWOStoppingDivGateEtc:
@@ -1,5 +1,5 @@
///
/// Copyright (c) 2013-2020 Sensus Slovensko a.s.
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
@@ -24,8 +24,7 @@ namespace TBF.Rig.TestMethods.FlyingStartMassCollection
/// <returns>true when capabilities of devices are OK</returns>
public static bool CheckDeviceCaps(Config.Entities.Test test, OutputPath devices, out string message)
{
if (!(StateMachine.ControlBoard is ControlBoard.Legacy.CBoard) &&
!(StateMachine.ControlBoard is ControlBoard.Uni.UniCB))
if (!(StateMachine.ControlBoard is ControlBoard.Uni.UniCB))
{
/// Control board does not support this method
message = string.Format("{0}: {1}", test.Name, Strings.Test_bench_does_not_suport_selected_test_method);
@@ -95,7 +94,7 @@ namespace TBF.Rig.TestMethods.FlyingStartMassCollection
return Simulate2(test, repetitionNr, isLastRepetition, compoundTestParams, heatMetersTestParams);
}
ControlBoard.IControlBoard cBrd = StateMachine.ControlBoard;
ControlBoard.Uni.UniCB cBrd = StateMachine.ControlBoard as ControlBoard.Uni.UniCB;
IScale scale = cBrd.Devices.Scale as IScale;
int rangeIx = 0; /// Default range, used for non-Elde flowmeters
@@ -127,23 +126,20 @@ namespace TBF.Rig.TestMethods.FlyingStartMassCollection
processDataLoggingOp = new TBF.Rig.Operations.ProcessDataLoggingOp(processDataLogger, this, heatMetersTestParams != null);
if (cBrd is ControlBoard.Legacy.CBoard)
{
int[] filters = new int[] { 0, 0, 0, 0, 0, 0, 0, 0 };
if (sensPath != null && sensPath.RegisterReaders != null)
{
foreach (var rr in sensPath.RegisterReaders)
{
IRegReaderPulses eldeRR = rr as IRegReaderPulses;
if ((eldeRR != null) && (eldeRR.Position >= 1) && (eldeRR.Position <= 8))
IRegReaderPulses uniRR = rr as IRegReaderPulses;
if ((uniRR != null) && (uniRR.Position >= 1) && (uniRR.Position <= 8))
{
filters[eldeRR.Position - 1] = eldeRR.Filter;
filters[uniRR.Position - 1] = uniRR.Filter;
}
}
}
//cBrd.SetFiltersPidShortPulses(filters, outPath.PidCoef, test.ShortPulses);
(cBrd as ControlBoard.Legacy.CBoard).SetFiltersPidShortPulses(filters, outPath.PidCoef, test.ShortPulses);
}
IList<IOperation> readTempPressOps = new List<IOperation>();
if(benchPath.TempMtrUp != null) readTempPressOps.Add(benchPath.TempMtrUp.ReadTempOp(ref TempUp));
@@ -655,17 +651,7 @@ namespace TBF.Rig.TestMethods.FlyingStartMassCollection
StopRecordingStatistics();
State.Create(string.Format("{0}({1}) : Stopping flow regulation", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(cBrd.StopFlowRegulationOp())
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; }
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
}
while (!e.Contains(Event.FlowRegulationStopped));
cBrd.Stop(false);
///
/// (Berlin:) Water is stopped immediately after the test and before the 2nd mass measurement in case:
@@ -1102,16 +1088,7 @@ namespace TBF.Rig.TestMethods.FlyingStartMassCollection
if (isLastRepetition || retVal == Event.UiCmdStop || retVal == Event.OpArgumentError
|| retVal == Event.Error || retVal == Event.ConfigurationError)
{
State.Create(string.Format("{0}({1}) : Stopping diverter, gate, etc.", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperation(cBrd.StopPreviousOp())
.EnterState();
do
{
e = StateMachine.WaitRunDevsRunOps();
if (TestAndLogUiCmdStop(test, e)) break;
}
while (!e.Contains(Event.PreviousStopped));
cBrd.Stop(false);
}
stopTestWOStoppingDivGateEtc:
+1
View File
@@ -227,6 +227,7 @@
</Compile>
<Compile Include="Rig\ControlBoard\Papouch\Factory.cs" />
<Compile Include="Rig\ControlBoard\Uni\Action.cs" />
<Compile Include="Rig\ControlBoard\Uni\StartMeasurementOp.cs" />
<Compile Include="Rig\ControlBoard\Uni\UniCB.cs" />
<Compile Include="Rig\ControlBoard\Uni\UniCBCfg.cs" />
<Compile Include="Rig\ControlBoard\Uni\OutputMessage.cs" />