FlowStableSec parameter added to RegulValve

This commit is contained in:
Milan Hanajik 2014-09-08 20:24:46 +02:00
parent cc2a24cee5
commit d14cb175a6
8 changed files with 86 additions and 76 deletions

View File

@ -34,6 +34,7 @@ namespace TBF.BenchControl.Elde.RegulValve
public readonly int DacValueClosed; /// 0..1023
public readonly int DacValueOpen; /// 0..1023
public readonly int StableTime; /// 0=200ms, step=50ms, max. 1500ms (max.26)
public readonly int FlowStableSec; /// 0..60 sec
public RegulValve(RegulValveCfg cfg, IList<Generic.IComponent> components)
{
@ -47,6 +48,8 @@ namespace TBF.BenchControl.Elde.RegulValve
this.DacValueClosed = cfg.DacValueClosed;
this.DacValueOpen = cfg.DacValueOpen;
this.StableTime = cfg.StableTime;
this.FlowStableSec = cfg.FlowStableSec;
this.dict = new Dictionary<float, float>();
this.controlBoard.RegValveCalib[Position - 1, 0] = (uint)DacValueClosed;

View File

@ -16,6 +16,7 @@ namespace TBF.BenchControl.Elde.RegulValve
public int PidCoef; /// 1..100
public int StableTimeMs; /// 200..1500 ms
public bool StoredPositionReuse; /// true = store and re-use previous regulation valve positions
public int FlowStableSec; /// 0..60 sec
/// <summary>
/// Stabilization time when setting the flow: 0=200ms, step 50ms, max. 1.5 sec.
@ -26,6 +27,7 @@ namespace TBF.BenchControl.Elde.RegulValve
public RegulValveCfg()
{
StableTimeMs = 500;
FlowStableSec = 5;
}
/// <summary>
/// Regulation valve configuration parameters
@ -35,7 +37,7 @@ namespace TBF.BenchControl.Elde.RegulValve
/// <param name="dacValueClosed">0..1023</param>
/// <param name="dacValueOpen">0..1023</param>
/// <param name="pidCoef">1..100</param>
public RegulValveCfg(IComponentFactory factory, string name, string parentName, int position, int dacValueClosed, int dacValueOpen, int pidCoef, int stableTimeMs, bool storedPositionReuse)
public RegulValveCfg(IComponentFactory factory, string name, string parentName, int position, int dacValueClosed, int dacValueOpen, int pidCoef, int stableTimeMs, bool storedPositionReuse, int flowStableSec)
: base(factory, name, parentName)
{
if (position < 0 || position > 7) throw new ArgumentOutOfRangeException("position");
@ -49,17 +51,18 @@ namespace TBF.BenchControl.Elde.RegulValve
this.PidCoef = pidCoef;
this.StableTimeMs = stableTimeMs;
this.StoredPositionReuse = storedPositionReuse;
this.FlowStableSec = flowStableSec;
}
public IComponentCfg Clone()
{
return new RegulValveCfg(Factory, Name, ParentName, Position, DacValueClosed, DacValueOpen, PidCoef, StableTimeMs, StoredPositionReuse);
return new RegulValveCfg(Factory, Name, ParentName, Position, DacValueClosed, DacValueOpen, PidCoef, StableTimeMs, StoredPositionReuse, FlowStableSec);
}
public string ToString(int i)
{
return string.Format("position={0}, DAC-closed={1}, DAC-open={2}, PID={3}, posReuse={4}",
Position, DacValueClosed, DacValueOpen, PidCoef, StoredPositionReuse);
return string.Format("position={0}, DAC-closed={1}, DAC-open={2}, PID={3}, posReuse={4}, flowStableSec={5}",
Position, DacValueClosed, DacValueOpen, PidCoef, StoredPositionReuse, FlowStableSec);
}
public TBF.Entities.Component CreateDbEntity()

View File

@ -44,6 +44,8 @@
this.storedPosReuseCheckBox = new System.Windows.Forms.CheckBox();
this.stableTimeTextBox = new System.Windows.Forms.TextBox();
this.stableTimeLabel = new System.Windows.Forms.Label();
this.flowStableSecTextBox = new System.Windows.Forms.TextBox();
this.flowStableSecLabel = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// positionTextBox
@ -186,10 +188,29 @@
this.stableTimeLabel.TabIndex = 14;
this.stableTimeLabel.Text = "Stable time [ms]";
//
// flowStableSecTextBox
//
this.flowStableSecTextBox.Enabled = false;
this.flowStableSecTextBox.Location = new System.Drawing.Point(138, 219);
this.flowStableSecTextBox.Name = "flowStableSecTextBox";
this.flowStableSecTextBox.Size = new System.Drawing.Size(46, 20);
this.flowStableSecTextBox.TabIndex = 17;
//
// flowStableSecLabel
//
this.flowStableSecLabel.AutoSize = true;
this.flowStableSecLabel.Location = new System.Drawing.Point(28, 222);
this.flowStableSecLabel.Name = "flowStableSecLabel";
this.flowStableSecLabel.Size = new System.Drawing.Size(74, 13);
this.flowStableSecLabel.TabIndex = 16;
this.flowStableSecLabel.Text = "Flow stable [s]";
//
// RegulValveCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.flowStableSecTextBox);
this.Controls.Add(this.flowStableSecLabel);
this.Controls.Add(this.stableTimeTextBox);
this.Controls.Add(this.stableTimeLabel);
this.Controls.Add(this.storedPosReuseCheckBox);
@ -232,5 +253,7 @@
private System.Windows.Forms.CheckBox storedPosReuseCheckBox;
private System.Windows.Forms.TextBox stableTimeTextBox;
private System.Windows.Forms.Label stableTimeLabel;
private System.Windows.Forms.TextBox flowStableSecTextBox;
private System.Windows.Forms.Label flowStableSecLabel;
}
}

View File

@ -58,7 +58,8 @@ namespace TBF.BenchControl.Elde.RegulValve
pidCoefTextBox.Text = config.PidCoef.ToString();
stableTimeTextBox.Text = config.StableTimeMs.ToString();
storedPosReuseCheckBox.Checked = config.StoredPositionReuse;
}
flowStableSecTextBox.Text = config.FlowStableSec.ToString();
}
public void Unlock()
{
@ -70,7 +71,8 @@ namespace TBF.BenchControl.Elde.RegulValve
pidCoefTextBox.Enabled = true;
stableTimeTextBox.Enabled = true;
storedPosReuseCheckBox.Enabled = true;
}
flowStableSecTextBox.Enabled = true;
}
public CfgVerifyFlags VerifyCfg(ref string message)
{
@ -107,6 +109,11 @@ namespace TBF.BenchControl.Elde.RegulValve
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'Stable time' should be between 200 and 1500 ms in 50 ms steps";
}
if (!int.TryParse(flowStableSecTextBox.Text, out dummy) || dummy < 0 || dummy > 60)
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'Flow stable' should be between 0 and 60 sec";
}
return flags;
}
@ -123,6 +130,7 @@ namespace TBF.BenchControl.Elde.RegulValve
config.PidCoef = int.Parse(pidCoefTextBox.Text);
config.StableTimeMs = int.Parse(stableTimeTextBox.Text);
config.StoredPositionReuse = storedPosReuseCheckBox.Checked;
config.FlowStableSec = int.Parse(flowStableSecTextBox.Text);
}
}
}

View File

@ -16,7 +16,7 @@ namespace TBF.BenchControl.Elde.RegulValve
public IComponentCfg DefaultConfig(IList<Entities.Component> components)
{
return new RegulValveCfg(this, "RegulationValve", "CB", 1, 100, 500, 20, 500, false);
return new RegulValveCfg(this, "RegulationValve", "CB", 1, 100, 500, 20, 500, false, 5);
}
public IComponentCfgCtrl CreateCfgCtrl()

View File

@ -43,6 +43,7 @@ namespace TBF.BenchControl.Elde.RegulValve
int expireTime;
FloatBox measuredFlow;
int flowWithinBoundsTime;
/// <summary>
@ -139,6 +140,8 @@ namespace TBF.BenchControl.Elde.RegulValve
/// <summary>Start this operation</summary>
public void Start()
{
flowWithinBoundsTime = 0;
if (regulValve.RegulValveCfg.StoredPositionReuse && FetchTargetPosition(reqFlowAve, out targetPositionLo, out targetPositionHi))
{
log.InfoFormat("Start(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3} FETCHED: posLo={4} posHi={5}",
@ -218,27 +221,33 @@ namespace TBF.BenchControl.Elde.RegulValve
{
if ((reqFlowLo <= flow) && (flow <= reqFlowHi))
{
if (regulValve.RegulValveCfg.StoredPositionReuse)
if (flowWithinBoundsTime++ >= regulValve.FlowStableSec)
{
float storedPosition;
if (regulValve.Dict.TryGetValue(reqFlowAve, out storedPosition))
if (regulValve.RegulValveCfg.StoredPositionReuse)
{
/// update the stored valve position
StoreTargetPosition(reqFlowAve, (rvPosition + storedPosition) / 2.0f);
log.InfoFormat("Run(): rv#={0} reqFlow={1} pos={2}% stored={3} <--- Updating a stored position",
regulValveNr, reqFlowAve, rvPosition.ToString("F1"), storedPosition);
}
else
{
/// store the valve position
StoreTargetPosition(reqFlowAve, rvPosition);
log.InfoFormat("Run(): rv#={0} reqFlow={1} pos={2}% <--- Storing a new position",
regulValveNr, reqFlowAve, rvPosition.ToString("F1"));
float storedPosition;
if (regulValve.Dict.TryGetValue(reqFlowAve, out storedPosition))
{
/// update the stored valve position
StoreTargetPosition(reqFlowAve, (rvPosition + storedPosition) / 2.0f);
log.InfoFormat("Run(): rv#={0} reqFlow={1} pos={2}% stored={3} <--- Updating a stored position",
regulValveNr, reqFlowAve, rvPosition.ToString("F1"), storedPosition);
}
else
{
/// store the valve position
StoreTargetPosition(reqFlowAve, rvPosition);
log.InfoFormat("Run(): rv#={0} reqFlow={1} pos={2}% <--- Storing a new position",
regulValveNr, reqFlowAve, rvPosition.ToString("F1"));
}
}
opState = OpState.FlowReached;
return Event.FlowReached;
}
else
{
return Event.None;
}
opState = OpState.FlowReached;
return Event.FlowReached;
}
else if (StateMachine.Time > expireTime)
{
@ -246,6 +255,7 @@ namespace TBF.BenchControl.Elde.RegulValve
}
else
{
flowWithinBoundsTime = 0;
return Event.None;
}
}

View File

@ -151,25 +151,7 @@ namespace TBF.BenchControl.TestMethods.FlyingStart
if (cameraRoi != null) measureOperations.Add(cameraRoi.MeasureOp());
}
//------------------------------------------------
Bridge.OnActivity(this, Strings.Measuring_the_weight);
//------------------------------------------------
State.Create("FlyingStart : Measuring the start mass")
.AddOperation(checkUiOp)
.AddOperations(measureOperations)
.AddOperation(outPath.Balance.ReadStableMassOp(ref startMass, 5))
.EnterState();
do
{
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; }
if (e.Contains(Event.UiCmdStop)) { retVal = Event.UiCmdStop; goto stopTest; }
}
while (!e.Contains(Event.BalanceDone));
tstRslt.TimeStart = DateTime.Now;
tstRslt.MassStartRaw = startMass.Val;
mass.Val = startMass.Val;
//------------------------------------------------
Bridge.OnActivity(this, Strings.Test_in_progress);
@ -177,7 +159,7 @@ namespace TBF.BenchControl.TestMethods.FlyingStart
State.Create("FlyingStart : Starting the test")
.AddOperation(checkUiOp)
.AddOperations(measureOperations)
.AddOperation(cBrd.StartMeasurementOp(outPath.FlowMeter, totalPulses, Elde.TestMethods.Diverter | Elde.TestMethods.Synchro, (float)test.TolerRed))
.AddOperation(cBrd.StartMeasurementOp(outPath.FlowMeter, totalPulses, Elde.TestMethods.Synchro, (float)test.TolerRed))
.EnterState();
do
{
@ -248,25 +230,6 @@ namespace TBF.BenchControl.TestMethods.FlyingStart
test_completed:
//------------------------------------------------
Bridge.OnActivity(this, Strings.Measuring_the_weight);
//------------------------------------------------
State.Create("FlyingStart : Measuring the end mass")
.AddOperation(checkUiOp)
.AddOperation(outPath.Balance.ReadStableMassOp(ref endMass, 5))
.AddOperation(cBrd.UpdateTankWeightOp())
.EnterState();
do
{
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; }
if (e.Contains(Event.UiCmdStop)) { retVal = Event.UiCmdStop; goto stopTest; }
}
while (!e.Contains(Event.BalanceDone));
///
tstRslt.MassEndRaw = endMass.Val;
tstRslt.TimeEnd = DateTime.Now;
//------------------------------------------------
Bridge.OnActivity(this, Strings.Test_completed);
//------------------------------------------------
@ -276,19 +239,20 @@ namespace TBF.BenchControl.TestMethods.FlyingStart
///
tstRslt.TimeEnd = DateTime.Now;
UpdateTestRsltWithAveragedData(tstRslt);
tstRslt.MassStart = Formulas.CorrectedValue(tstRslt.MassStartRaw, outPath.Balance.Corrections);
tstRslt.MassEnd = Formulas.CorrectedValue(tstRslt.MassEndRaw, outPath.Balance.Corrections);
tstRslt.MassDiff = tstRslt.MassEnd - tstRslt.MassStart;
tstRslt.DensityIn = Formulas.WaterDensityFromTemp(tstRslt.TempInAvrg); /// [kg/m3]
tstRslt.DensityOut = Formulas.WaterDensityFromTemp(tstRslt.TempOutAvrg); /// [kg/m3]
tstRslt.DensityDiv = Formulas.WaterDensityFromTemp(tstRslt.TempDivAvrg); /// [kg/m3]
tstRslt.Time = cBrd.TTime; /// [s] measurement time
tstRslt.FlowMass = 3600.0f * tstRslt.MassDiff / tstRslt.Time; /// [kg/h]
tstRslt.FlowVolume = 3600.0f * ltrPerRefPulse * cBrd.EtPulses(0) / tstRslt.Time; /// [l/h]
tstRslt.VolumeCTV = 1.00103f * 1000.0f * tstRslt.MassDiff / tstRslt.DensityOut; /// [l] 1000.0f is because density is in [kg/m3]
tstRslt.VolumeMaster = ltrPerRefPulse * cBrd.EtPulses(0); /// [l] volume from the master flow meter
tstRslt.PulsesMaster = cBrd.EtPulses(0); /// Pulses of the master flow meter (test total)
tstRslt.ConstMaster = ltrPerRefPulse * tstRslt.VolumeCTV / tstRslt.VolumeMaster;
tstRslt.MassStart = 0;
tstRslt.MassEnd = 0;
tstRslt.MassDiff = 0;
tstRslt.DensityIn = Formulas.WaterDensityFromTemp(tstRslt.TempInAvrg); /// [kg/m3]
tstRslt.DensityOut = Formulas.WaterDensityFromTemp(tstRslt.TempOutAvrg); /// [kg/m3]
tstRslt.DensityDiv = Formulas.WaterDensityFromTemp(tstRslt.TempDivAvrg); /// [kg/m3]
tstRslt.Time = cBrd.TTime; /// [s] measurement time
tstRslt.FlowMass = 0; /// [kg/h]
tstRslt.FlowVolume = 3600.0f * ltrPerRefPulse * cBrd.EtPulses(0) / tstRslt.Time; /// [l/h]
tstRslt.PulsesMaster = cBrd.EtPulses(0); /// Pulses of the master flow meter (test total)
/// TODO: tuto pokracovat
tstRslt.VolumeMaster = ltrPerRefPulse * tstRslt.PulsesMaster; /// [l] volume from the master flow meter
tstRslt.VolumeCTV = 1.00103f * 1000.0f * tstRslt.MassDiff / tstRslt.DensityOut; /// [l] 1000.0f is because density is in [kg/m3]
tstRslt.ConstMaster = ltrPerRefPulse * tstRslt.VolumeCTV / tstRslt.VolumeMaster;
/// Corrected master pulses per liter
if (tstRslt.VolumeCTV <= float.Epsilon)
{

View File

@ -353,7 +353,6 @@ namespace TBF.BenchControl.TestMethods.FlyingStartCollectionMethod
goto loop;
}
stopTest:
///----------------------///