Advanced flow setting algorithm with adaptive behavior, ver. 2.17.709

This commit is contained in:
Milan Hanajik
2017-10-19 10:34:10 +02:00
parent 38d7562bb3
commit 32fbb2964e
4 changed files with 135 additions and 69 deletions
@@ -14,7 +14,7 @@ namespace TBF.BenchControl.Elde.RegulValve
private static readonly ILog log = LogManager.GetLogger(typeof(SetFlowOp)); private static readonly ILog log = LogManager.GetLogger(typeof(SetFlowOp));
public override string ToString() public override string ToString()
{ {
return string.Format("SetFlowOp({0}, Qfrom={1}, Qto={2}, PID={3})", regulValve.Name, reqFlowLo, reqFlowHi, pidCoef); return string.Format("SetFlowOp({0}, Qfrom={1}, Qto={2}, PID={3})", regulValve.Name, finalReqFlowLo, finalReqFlowHi, pidCoef);
} }
const int CoaxValveNr = 7; /// Coax. valve has number 7 const int CoaxValveNr = 7; /// Coax. valve has number 7
@@ -25,17 +25,17 @@ namespace TBF.BenchControl.Elde.RegulValve
readonly Elde.RegulValve.RegulValve regulValve; readonly Elde.RegulValve.RegulValve regulValve;
readonly int regulValveNr; readonly int regulValveNr;
readonly int flowMeterNr; readonly int flowMeterNr;
readonly float reqFlowLo; readonly float finalReqFlowLo;
readonly float reqFlowHi; readonly float finalReqFlowHi;
readonly float reqFlowAve; readonly float reqFlowAve;
readonly float pidCoef; readonly float pidCoef;
readonly int timeout; readonly int timeout;
readonly bool leaveMeasurementRunning; readonly bool leaveMeasurementRunning;
readonly bool reTryCommands; readonly bool reTryCommands;
readonly float nominalFlow; readonly float nominalFlow;
/// ///
/// Internal states of this operation /// Internal states of this operation
/// ///
enum OpState enum OpState
@@ -56,6 +56,8 @@ namespace TBF.BenchControl.Elde.RegulValve
} }
OpState opState; OpState opState;
float currentReqFlowLo;
float currentReqFlowHi;
float targetPositionLo; float targetPositionLo;
float targetPositionHi; float targetPositionHi;
@@ -103,10 +105,10 @@ namespace TBF.BenchControl.Elde.RegulValve
nominalFlow = flowMeter.NominalFlow; nominalFlow = flowMeter.NominalFlow;
this.reqFlowLo = (3.0f * requiredFlowLo + requiredFlowHi) / 4.0f; this.finalReqFlowLo = requiredFlowLo;
this.reqFlowHi = (3.0f * requiredFlowHi + requiredFlowLo) / 4.0f; this.finalReqFlowHi = requiredFlowHi;
this.reqFlowAve = (reqFlowLo + reqFlowHi) / 2.0f; this.reqFlowAve = (requiredFlowLo + requiredFlowHi) / 2.0f;
this.pidCoef = pidCoef; this.pidCoef = pidCoef;
this.measuredFlow = measuredFlow; this.measuredFlow = measuredFlow;
this.reTryCommands = reTryCmds; this.reTryCommands = reTryCmds;
@@ -173,19 +175,36 @@ namespace TBF.BenchControl.Elde.RegulValve
/// <summary>Start this operation</summary> /// <summary>Start this operation</summary>
public void Start() public void Start()
{ {
double flowMtrFreq = controlBoard.ReferenceFreq;
currentReqFlowLo = reqFlowAve;
currentReqFlowHi = reqFlowAve;
///
if (flowMtrFreq != 0)
{
double flow = flowMtrFreq * nominalFlow / 2000.0;
if (measuredFlow != null) measuredFlow.Val = flow;
if (flow >= reqFlowAve) currentReqFlowLo = finalReqFlowLo;
if (flow <= reqFlowAve) currentReqFlowHi = finalReqFlowHi;
}
else
{
currentReqFlowLo = finalReqFlowLo; /// Unexpected case when flowMtrFreq==0
currentReqFlowHi = finalReqFlowHi;
}
flowWithinBoundsTime = 0; flowWithinBoundsTime = 0;
if (regulValve.RegulValveCfg.StoredPositionReuse && FetchTargetPosition(reqFlowAve, out targetPositionLo, out targetPositionHi)) if (regulValve.RegulValveCfg.StoredPositionReuse && FetchTargetPosition(reqFlowAve, out targetPositionLo, out targetPositionHi))
{ {
log.InfoFormat("SetFlowOp:Start() rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3} FETCHED: posLo={4} posHi={5}", log.InfoFormat("SetFlowOp:Start() rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3} FETCHED: posLo={4} posHi={5}",
regulValveNr, flowMeterNr, reqFlowLo, reqFlowHi, targetPositionLo, targetPositionHi); regulValveNr, flowMeterNr, currentReqFlowLo, currentReqFlowHi, targetPositionLo, targetPositionHi);
opState = OpState.ValveMoveToPosition1; opState = OpState.ValveMoveToPosition1;
} }
else else
{ {
log.InfoFormat("SetFlowOp:Start() rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}", log.InfoFormat("SetFlowOp:Start() rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}",
regulValveNr, flowMeterNr, reqFlowLo, reqFlowHi); regulValveNr, flowMeterNr, currentReqFlowLo, currentReqFlowHi);
opState = OpState.ValveMoveToFlow1; opState = OpState.ValveMoveToFlow1;
} }
@@ -214,6 +233,8 @@ namespace TBF.BenchControl.Elde.RegulValve
if (flowMtrFreq != 0) if (flowMtrFreq != 0)
{ {
if (measuredFlow != null) measuredFlow.Val = flow; if (measuredFlow != null) measuredFlow.Val = flow;
if (flow >= reqFlowAve) currentReqFlowLo = finalReqFlowLo;
if (flow <= reqFlowAve) currentReqFlowHi = finalReqFlowHi;
} }
log.InfoFormat("SetFlowOp:Run() rv#={0} pos={1}% freq={2} flow={3} opState={4}", log.InfoFormat("SetFlowOp:Run() rv#={0} pos={1}% freq={2} flow={3} opState={4}",
@@ -227,14 +248,14 @@ namespace TBF.BenchControl.Elde.RegulValve
if (regulValve.RegulValveCfg.StoredPositionReuse && FetchTargetPosition(reqFlowAve, out targetPositionLo, out targetPositionHi)) if (regulValve.RegulValveCfg.StoredPositionReuse && FetchTargetPosition(reqFlowAve, out targetPositionLo, out targetPositionHi))
{ {
log.InfoFormat("Run(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3} FETCHED: posLo={4} posHi={5}", log.InfoFormat("Run(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3} FETCHED: posLo={4} posHi={5}",
regulValveNr, flowMeterNr, reqFlowLo, reqFlowHi, targetPositionLo, targetPositionHi); regulValveNr, flowMeterNr, currentReqFlowLo, currentReqFlowHi, targetPositionLo, targetPositionHi);
opState = OpState.ValveMoveToPosition1; opState = OpState.ValveMoveToPosition1;
} }
else else
{ {
log.InfoFormat("Run(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}", log.InfoFormat("Run(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}",
regulValveNr, flowMeterNr, reqFlowLo, reqFlowHi); regulValveNr, flowMeterNr, currentReqFlowLo, currentReqFlowHi);
opState = OpState.ValveMoveToFlow1; opState = OpState.ValveMoveToFlow1;
} }
@@ -335,16 +356,16 @@ namespace TBF.BenchControl.Elde.RegulValve
/// ///
/// Done once, issues an appropriate ValveMove(...) command /// Done once, issues an appropriate ValveMove(...) command
/// ///
if (reqFlowLo >= reqFlowHi || reqFlowLo > nominalFlow || reqFlowHi <= 0) if (currentReqFlowLo >= currentReqFlowHi || currentReqFlowLo > nominalFlow || currentReqFlowHi <= 0)
{ {
return Event.OpArgumentError; return Event.OpArgumentError;
} }
log.InfoFormat("Run(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}", log.InfoFormat("Run(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}",
regulValveNr, flowMeterNr, reqFlowLo, reqFlowHi); regulValveNr, flowMeterNr, currentReqFlowLo, currentReqFlowHi);
float freqLo = 2000.0f * reqFlowLo / nominalFlow; float freqLo = 2000.0f * currentReqFlowLo / nominalFlow;
float freqHi = 2000.0f * reqFlowHi / nominalFlow; float freqHi = 2000.0f * currentReqFlowHi / nominalFlow;
controlBoard.ValveMove(regulValveNr, RegulValveMode.TargetFrequency, controlBoard.ValveMove(regulValveNr, RegulValveMode.TargetFrequency,
new float[2] { freqLo, freqHi }, new float[2] { freqLo, freqHi },
regulValve.StableTime); regulValve.StableTime);
@@ -375,8 +396,8 @@ namespace TBF.BenchControl.Elde.RegulValve
else if (regulValveNr == CoaxValveNr && ((ulong)controlBoard.StatusP & (ulong)StatusP.CoaxRegValveBusy) == 0) else if (regulValveNr == CoaxValveNr && ((ulong)controlBoard.StatusP & (ulong)StatusP.CoaxRegValveBusy) == 0)
{ {
/// Done once, issues an appropriate ValveMove(...) command /// Done once, issues an appropriate ValveMove(...) command
float freqLo = 2000.0f * reqFlowLo / nominalFlow; float freqLo = 2000.0f * currentReqFlowLo / nominalFlow;
float freqHi = 2000.0f * reqFlowHi / nominalFlow; float freqHi = 2000.0f * currentReqFlowHi / nominalFlow;
controlBoard.ValveMove(regulValveNr, RegulValveMode.TargetFrequency, controlBoard.ValveMove(regulValveNr, RegulValveMode.TargetFrequency,
new float[2] { (freqLo + freqHi) / 2.0f, (freqLo + freqHi) / 2.0f }, new float[2] { (freqLo + freqHi) / 2.0f, (freqLo + freqHi) / 2.0f },
regulValve.StableTime); regulValve.StableTime);
@@ -390,8 +411,8 @@ namespace TBF.BenchControl.Elde.RegulValve
else if (regulValveNr < 6 && controlBoard.RegulValveState(regulValveNr) != RegulValveState.PwOrFreqRegul) else if (regulValveNr < 6 && controlBoard.RegulValveState(regulValveNr) != RegulValveState.PwOrFreqRegul)
{ {
/// Done once, issues an appropriate ValveMove(...) command /// Done once, issues an appropriate ValveMove(...) command
float freqLo = 2000.0f * reqFlowLo / nominalFlow; float freqLo = 2000.0f * currentReqFlowLo / nominalFlow;
float freqHi = 2000.0f * reqFlowHi / nominalFlow; float freqHi = 2000.0f * currentReqFlowHi / nominalFlow;
controlBoard.ValveMove(regulValveNr, RegulValveMode.TargetFrequency, controlBoard.ValveMove(regulValveNr, RegulValveMode.TargetFrequency,
new float[2] { freqLo, freqHi }, new float[2] { freqLo, freqHi },
regulValve.StableTime); regulValve.StableTime);
@@ -413,7 +434,7 @@ namespace TBF.BenchControl.Elde.RegulValve
/// ///
/// Repeated untill the required flow is reached /// Repeated untill the required flow is reached
/// ///
if ((reqFlowLo <= flow) && (flow <= reqFlowHi)) if ((currentReqFlowLo <= flow) && (flow <= currentReqFlowHi))
{ {
if (flowWithinBoundsTime++ >= regulValve.FlowStableSec) if (flowWithinBoundsTime++ >= regulValve.FlowStableSec)
{ {
@@ -436,14 +457,14 @@ namespace TBF.BenchControl.Elde.RegulValve
} }
} }
log.InfoFormat("flow = {0} m3/h (lo={1}, hi={2}, REACHED)", flow, reqFlowLo, reqFlowHi); log.InfoFormat("flow = {0} m3/h (lo={1}, hi={2}, REACHED)", flow, currentReqFlowLo, currentReqFlowHi);
opState = OpState.FlowReached; opState = OpState.FlowReached;
return Event.FlowReached; return Event.FlowReached;
} }
else else
{ {
log.InfoFormat("flow = {0} m3/h (lo={1}, hi={2}, FLOW_OK_TIMER={3}s)", flow, reqFlowLo, reqFlowHi, flowWithinBoundsTime); log.InfoFormat("flow = {0} m3/h (lo={1}, hi={2}, FLOW_OK_TIMER={3}s)", flow, currentReqFlowLo, currentReqFlowHi, flowWithinBoundsTime);
return Event.None; return Event.None;
} }
} }
@@ -453,14 +474,14 @@ namespace TBF.BenchControl.Elde.RegulValve
} }
else else
{ {
log.InfoFormat("flow = {0} m3/h (lo={1}, hi={2})", flow, reqFlowLo, reqFlowHi); log.InfoFormat("flow = {0} m3/h (lo={1}, hi={2})", flow, currentReqFlowLo, currentReqFlowHi);
flowWithinBoundsTime = 0; flowWithinBoundsTime = 0;
return Event.None; return Event.None;
} }
} }
else /// opState == OpState.FlowReached else /// opState == OpState.FlowReached
{ {
log.InfoFormat("flow = {0} m3/h (lo={1}, hi={2}, REACHED)", flow, reqFlowLo, reqFlowHi); log.InfoFormat("flow = {0} m3/h (lo={1}, hi={2}, REACHED)", flow, currentReqFlowLo, currentReqFlowHi);
return Event.FlowReached; return Event.FlowReached;
} }
} }
@@ -14,7 +14,7 @@ namespace TBF.BenchControl.Elde.RegulValveCoax
private static readonly ILog log = LogManager.GetLogger(typeof(SetFlowOp)); private static readonly ILog log = LogManager.GetLogger(typeof(SetFlowOp));
public override string ToString() public override string ToString()
{ {
return string.Format("SetFlowOp({0}, Qfrom={1}, Qto={2}, PID={3})", regulValve.Name, reqFlowLo, reqFlowHi, pidCoef); return string.Format("SetFlowOp({0}, Qfrom={1}, Qto={2}, PID={3})", regulValve.Name, finalReqFlowLo, finalReqFlowHi, pidCoef);
} }
const int CoaxValveNr = 7; /// Coax. valve has number 7 const int CoaxValveNr = 7; /// Coax. valve has number 7
@@ -25,8 +25,8 @@ namespace TBF.BenchControl.Elde.RegulValveCoax
readonly Elde.RegulValve.RegulValve regulValve; readonly Elde.RegulValve.RegulValve regulValve;
readonly int regulValveNr; readonly int regulValveNr;
readonly int flowMeterNr; readonly int flowMeterNr;
readonly float reqFlowLo; readonly float finalReqFlowLo;
readonly float reqFlowHi; readonly float finalReqFlowHi;
readonly float reqFlowAve; readonly float reqFlowAve;
readonly float pidCoef; readonly float pidCoef;
readonly int timeout; readonly int timeout;
@@ -56,7 +56,9 @@ namespace TBF.BenchControl.Elde.RegulValveCoax
} }
OpState opState; OpState opState;
float targetPositionLo; float currentReqFlowLo;
float currentReqFlowHi;
float targetPositionLo;
float targetPositionHi; float targetPositionHi;
int expireTime; int expireTime;
@@ -103,10 +105,10 @@ namespace TBF.BenchControl.Elde.RegulValveCoax
nominalFlow = flowMeter.NominalFlow; nominalFlow = flowMeter.NominalFlow;
this.reqFlowLo = (3.0f * requiredFlowLo + requiredFlowHi) / 4.0f; this.finalReqFlowLo = requiredFlowLo;
this.reqFlowHi = (3.0f * requiredFlowHi + requiredFlowLo) / 4.0f; this.finalReqFlowHi = requiredFlowHi;
this.reqFlowAve = (reqFlowLo + reqFlowHi) / 2.0f; this.reqFlowAve = (requiredFlowLo + requiredFlowHi) / 2.0f;
this.pidCoef = pidCoef; this.pidCoef = pidCoef;
this.measuredFlow = measuredFlow; this.measuredFlow = measuredFlow;
this.reTryCommands = reTryCmds; this.reTryCommands = reTryCmds;
@@ -173,19 +175,36 @@ namespace TBF.BenchControl.Elde.RegulValveCoax
/// <summary>Start this operation</summary> /// <summary>Start this operation</summary>
public void Start() public void Start()
{ {
double flowMtrFreq = controlBoard.ReferenceFreq;
currentReqFlowLo = reqFlowAve;
currentReqFlowHi = reqFlowAve;
///
if (flowMtrFreq != 0)
{
double flow = flowMtrFreq * nominalFlow / 2000.0;
if (measuredFlow != null) measuredFlow.Val = flow;
if (flow >= reqFlowAve) currentReqFlowLo = finalReqFlowLo;
if (flow <= reqFlowAve) currentReqFlowHi = finalReqFlowHi;
}
else
{
currentReqFlowLo = finalReqFlowLo; /// Unexpected case when flowMtrFreq==0
currentReqFlowHi = finalReqFlowHi;
}
flowWithinBoundsTime = 0; flowWithinBoundsTime = 0;
if (regulValve.RegulValveCfg.StoredPositionReuse && FetchTargetPosition(reqFlowAve, out targetPositionLo, out targetPositionHi)) if (regulValve.RegulValveCfg.StoredPositionReuse && FetchTargetPosition(reqFlowAve, out targetPositionLo, out targetPositionHi))
{ {
log.InfoFormat("SetFlowOp:Start() rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3} FETCHED: posLo={4} posHi={5}", log.InfoFormat("SetFlowOp:Start() rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3} FETCHED: posLo={4} posHi={5}",
regulValveNr, flowMeterNr, reqFlowLo, reqFlowHi, targetPositionLo, targetPositionHi); regulValveNr, flowMeterNr, currentReqFlowLo, currentReqFlowHi, targetPositionLo, targetPositionHi);
opState = OpState.ValveMoveToPosition1; opState = OpState.ValveMoveToPosition1;
} }
else else
{ {
log.InfoFormat("SetFlowOp:Start() rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}", log.InfoFormat("SetFlowOp:Start() rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}",
regulValveNr, flowMeterNr, reqFlowLo, reqFlowHi); regulValveNr, flowMeterNr, currentReqFlowLo, currentReqFlowHi);
opState = OpState.ValveMoveToFlow1; opState = OpState.ValveMoveToFlow1;
} }
@@ -214,6 +233,8 @@ namespace TBF.BenchControl.Elde.RegulValveCoax
if (flowMtrFreq != 0) if (flowMtrFreq != 0)
{ {
if (measuredFlow != null) measuredFlow.Val = flow; if (measuredFlow != null) measuredFlow.Val = flow;
if (flow >= reqFlowAve) currentReqFlowLo = finalReqFlowLo;
if (flow <= reqFlowAve) currentReqFlowHi = finalReqFlowHi;
} }
log.InfoFormat("SetFlowOp:Run() rv#={0} pos={1}% freq={2} flow={3} opState={4}", log.InfoFormat("SetFlowOp:Run() rv#={0} pos={1}% freq={2} flow={3} opState={4}",
@@ -227,14 +248,14 @@ namespace TBF.BenchControl.Elde.RegulValveCoax
if (regulValve.RegulValveCfg.StoredPositionReuse && FetchTargetPosition(reqFlowAve, out targetPositionLo, out targetPositionHi)) if (regulValve.RegulValveCfg.StoredPositionReuse && FetchTargetPosition(reqFlowAve, out targetPositionLo, out targetPositionHi))
{ {
log.InfoFormat("Run(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3} FETCHED: posLo={4} posHi={5}", log.InfoFormat("Run(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3} FETCHED: posLo={4} posHi={5}",
regulValveNr, flowMeterNr, reqFlowLo, reqFlowHi, targetPositionLo, targetPositionHi); regulValveNr, flowMeterNr, currentReqFlowLo, currentReqFlowHi, targetPositionLo, targetPositionHi);
opState = OpState.ValveMoveToPosition1; opState = OpState.ValveMoveToPosition1;
} }
else else
{ {
log.InfoFormat("Run(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}", log.InfoFormat("Run(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}",
regulValveNr, flowMeterNr, reqFlowLo, reqFlowHi); regulValveNr, flowMeterNr, currentReqFlowLo, currentReqFlowHi);
opState = OpState.ValveMoveToFlow1; opState = OpState.ValveMoveToFlow1;
} }
@@ -335,16 +356,16 @@ namespace TBF.BenchControl.Elde.RegulValveCoax
/// ///
/// Done once, issues an appropriate ValveMove(...) command /// Done once, issues an appropriate ValveMove(...) command
/// ///
if (reqFlowLo >= reqFlowHi || reqFlowLo > nominalFlow || reqFlowHi <= 0) if (currentReqFlowLo >= currentReqFlowHi || currentReqFlowLo > nominalFlow || currentReqFlowHi <= 0)
{ {
return Event.OpArgumentError; return Event.OpArgumentError;
} }
log.InfoFormat("Run(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}", log.InfoFormat("Run(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}",
regulValveNr, flowMeterNr, reqFlowLo, reqFlowHi); regulValveNr, flowMeterNr, currentReqFlowLo, currentReqFlowHi);
float freqLo = 2000.0f * reqFlowLo / nominalFlow; float freqLo = 2000.0f * currentReqFlowLo / nominalFlow;
float freqHi = 2000.0f * reqFlowHi / nominalFlow; float freqHi = 2000.0f * currentReqFlowHi / nominalFlow;
controlBoard.ValveMove(regulValveNr, RegulValveMode.TargetFrequency, controlBoard.ValveMove(regulValveNr, RegulValveMode.TargetFrequency,
new float[2] { freqLo, freqHi }, new float[2] { freqLo, freqHi },
regulValve.StableTime); regulValve.StableTime);
@@ -375,8 +396,8 @@ namespace TBF.BenchControl.Elde.RegulValveCoax
else if (regulValveNr == CoaxValveNr && ((ulong)controlBoard.StatusP & (ulong)StatusP.CoaxRegValveBusy) == 0) else if (regulValveNr == CoaxValveNr && ((ulong)controlBoard.StatusP & (ulong)StatusP.CoaxRegValveBusy) == 0)
{ {
/// Done once, issues an appropriate ValveMove(...) command /// Done once, issues an appropriate ValveMove(...) command
float freqLo = 2000.0f * reqFlowLo / nominalFlow; float freqLo = 2000.0f * currentReqFlowLo / nominalFlow;
float freqHi = 2000.0f * reqFlowHi / nominalFlow; float freqHi = 2000.0f * currentReqFlowHi / nominalFlow;
controlBoard.ValveMove(regulValveNr, RegulValveMode.TargetFrequency, controlBoard.ValveMove(regulValveNr, RegulValveMode.TargetFrequency,
new float[2] { (freqLo + freqHi) / 2.0f, (freqLo + freqHi) / 2.0f }, new float[2] { (freqLo + freqHi) / 2.0f, (freqLo + freqHi) / 2.0f },
regulValve.StableTime); regulValve.StableTime);
@@ -390,8 +411,8 @@ namespace TBF.BenchControl.Elde.RegulValveCoax
else if (regulValveNr < 6 && controlBoard.RegulValveState(regulValveNr) != RegulValveState.PwOrFreqRegul) else if (regulValveNr < 6 && controlBoard.RegulValveState(regulValveNr) != RegulValveState.PwOrFreqRegul)
{ {
/// Done once, issues an appropriate ValveMove(...) command /// Done once, issues an appropriate ValveMove(...) command
float freqLo = 2000.0f * reqFlowLo / nominalFlow; float freqLo = 2000.0f * currentReqFlowLo / nominalFlow;
float freqHi = 2000.0f * reqFlowHi / nominalFlow; float freqHi = 2000.0f * currentReqFlowHi / nominalFlow;
controlBoard.ValveMove(regulValveNr, RegulValveMode.TargetFrequency, controlBoard.ValveMove(regulValveNr, RegulValveMode.TargetFrequency,
new float[2] { freqLo, freqHi }, new float[2] { freqLo, freqHi },
regulValve.StableTime); regulValve.StableTime);
@@ -413,7 +434,7 @@ namespace TBF.BenchControl.Elde.RegulValveCoax
/// ///
/// Repeated untill the required flow is reached /// Repeated untill the required flow is reached
/// ///
if ((reqFlowLo <= flow) && (flow <= reqFlowHi)) if ((currentReqFlowLo <= flow) && (flow <= currentReqFlowHi))
{ {
if (flowWithinBoundsTime++ >= regulValve.FlowStableSec) if (flowWithinBoundsTime++ >= regulValve.FlowStableSec)
{ {
@@ -436,14 +457,14 @@ namespace TBF.BenchControl.Elde.RegulValveCoax
} }
} }
log.InfoFormat("flow = {0} m3/h (lo={1}, hi={2}, REACHED)", flow, reqFlowLo, reqFlowHi); log.InfoFormat("flow = {0} m3/h (lo={1}, hi={2}, REACHED)", flow, currentReqFlowLo, currentReqFlowHi);
opState = OpState.FlowReached; opState = OpState.FlowReached;
return Event.FlowReached; return Event.FlowReached;
} }
else else
{ {
log.InfoFormat("flow = {0} m3/h (lo={1}, hi={2}, FLOW_OK_TIMER={3}s)", flow, reqFlowLo, reqFlowHi, flowWithinBoundsTime); log.InfoFormat("flow = {0} m3/h (lo={1}, hi={2}, FLOW_OK_TIMER={3}s)", flow, currentReqFlowLo, currentReqFlowHi, flowWithinBoundsTime);
return Event.None; return Event.None;
} }
} }
@@ -453,14 +474,14 @@ namespace TBF.BenchControl.Elde.RegulValveCoax
} }
else else
{ {
log.InfoFormat("flow = {0} m3/h (lo={1}, hi={2})", flow, reqFlowLo, reqFlowHi); log.InfoFormat("flow = {0} m3/h (lo={1}, hi={2})", flow, currentReqFlowLo, currentReqFlowHi);
flowWithinBoundsTime = 0; flowWithinBoundsTime = 0;
return Event.None; return Event.None;
} }
} }
else /// opState == OpState.FlowReached else /// opState == OpState.FlowReached
{ {
log.InfoFormat("flow = {0} m3/h (lo={1}, hi={2}, REACHED)", flow, reqFlowLo, reqFlowHi); log.InfoFormat("flow = {0} m3/h (lo={1}, hi={2}, REACHED)", flow, currentReqFlowLo, currentReqFlowHi);
return Event.FlowReached; return Event.FlowReached;
} }
} }
@@ -14,7 +14,7 @@ namespace TBF.BenchControl.Elde.RegulValveTandem
private static readonly ILog log = LogManager.GetLogger(typeof(SetFlowOp)); private static readonly ILog log = LogManager.GetLogger(typeof(SetFlowOp));
public override string ToString() public override string ToString()
{ {
return string.Format("SetFlowOp({0}, Qfrom={1}, Qto={2}, PID={3})", regulValve.Name, reqFlowLo, reqFlowHi, pidCoef); return string.Format("SetFlowOp({0}, Qfrom={1}, Qto={2}, PID={3})", regulValve.Name, finalReqFlowLo, finalReqFlowHi, pidCoef);
} }
/// Set by the constructor /// Set by the constructor
@@ -26,8 +26,8 @@ namespace TBF.BenchControl.Elde.RegulValveTandem
readonly float fixedPctLo; readonly float fixedPctLo;
readonly float fixedPctHi; readonly float fixedPctHi;
readonly int flowMeterNr; readonly int flowMeterNr;
readonly float reqFlowLo; readonly float finalReqFlowLo;
readonly float reqFlowHi; readonly float finalReqFlowHi;
readonly float reqFlowAve; readonly float reqFlowAve;
readonly float pidCoef; readonly float pidCoef;
readonly int timeout; readonly int timeout;
@@ -49,7 +49,9 @@ namespace TBF.BenchControl.Elde.RegulValveTandem
} }
OpState opState; OpState opState;
float targetPositionLo; float currentReqFlowLo;
float currentReqFlowHi;
float targetPositionLo;
float targetPositionHi; float targetPositionHi;
int expireTime; int expireTime;
@@ -106,9 +108,9 @@ namespace TBF.BenchControl.Elde.RegulValveTandem
nominalFlow = flowMeter.NominalFlow; nominalFlow = flowMeter.NominalFlow;
this.reqFlowLo = (3.0f * requiredFlowLo + requiredFlowHi) / 4.0f; this.finalReqFlowLo = requiredFlowLo;
this.reqFlowHi = (3.0f * requiredFlowHi + requiredFlowLo) / 4.0f; this.finalReqFlowHi = requiredFlowHi;
this.reqFlowAve = (reqFlowLo + reqFlowHi) / 2.0f; this.reqFlowAve = (requiredFlowLo + requiredFlowHi) / 2.0f;
this.pidCoef = pidCoef; this.pidCoef = pidCoef;
this.measuredFlow = measuredFlow; this.measuredFlow = measuredFlow;
@@ -175,19 +177,36 @@ namespace TBF.BenchControl.Elde.RegulValveTandem
/// <summary>Start this operation</summary> /// <summary>Start this operation</summary>
public void Start() public void Start()
{ {
double flowMtrFreq = controlBoard.ReferenceFreq;
currentReqFlowLo = reqFlowAve;
currentReqFlowHi = reqFlowAve;
///
if (flowMtrFreq != 0)
{
double flow = flowMtrFreq * nominalFlow / 2000.0;
if (measuredFlow != null) measuredFlow.Val = flow;
if (flow >= reqFlowAve) currentReqFlowLo = finalReqFlowLo;
if (flow <= reqFlowAve) currentReqFlowHi = finalReqFlowHi;
}
else
{
currentReqFlowLo = finalReqFlowLo; /// Unexpected case when flowMtrFreq==0
currentReqFlowHi = finalReqFlowHi;
}
flowWithinBoundsTime = 0; flowWithinBoundsTime = 0;
if (regulValve.RegulValveCfg.StoredPositionReuse && FetchTargetPosition(reqFlowAve, out targetPositionLo, out targetPositionHi)) 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}", log.InfoFormat("Start(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3} FETCHED: posLo={4} posHi={5}",
regulValveNr, flowMeterNr, reqFlowLo, reqFlowHi, targetPositionLo, targetPositionHi); regulValveNr, flowMeterNr, currentReqFlowLo, currentReqFlowHi, targetPositionLo, targetPositionHi);
opState = OpState.IssueSetPositionCommand; opState = OpState.IssueSetPositionCommand;
} }
else else
{ {
log.InfoFormat("Start(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}", log.InfoFormat("Start(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}",
regulValveNr, flowMeterNr, reqFlowLo, reqFlowHi); regulValveNr, flowMeterNr, currentReqFlowLo, currentReqFlowHi);
opState = OpState.IssueSetPositionCommand_FixedRV; opState = OpState.IssueSetPositionCommand_FixedRV;
} }
@@ -214,7 +233,12 @@ namespace TBF.BenchControl.Elde.RegulValveTandem
double flowMtrFreq = controlBoard.ReferenceFreq; double flowMtrFreq = controlBoard.ReferenceFreq;
double flow = flowMtrFreq * nominalFlow / 2000.0; double flow = flowMtrFreq * nominalFlow / 2000.0;
if (measuredFlow != null) measuredFlow.Val = flow; if (flowMtrFreq != 0)
{
if (measuredFlow != null) measuredFlow.Val = flow;
if (flow >= reqFlowAve) currentReqFlowLo = finalReqFlowLo;
if (flow <= reqFlowAve) currentReqFlowHi = finalReqFlowHi;
}
log.InfoFormat("Run(): rv#={0} pos={1}% freq={2} flow={3} opState={4}", log.InfoFormat("Run(): rv#={0} pos={1}% freq={2} flow={3} opState={4}",
regulValveNr, rvPosition.ToString("F1"), flowMtrFreq, flow, opState); regulValveNr, rvPosition.ToString("F1"), flowMtrFreq, flow, opState);
@@ -270,16 +294,16 @@ namespace TBF.BenchControl.Elde.RegulValveTandem
/// ///
/// Done once, issues an appropriate ValveMove(...) command /// Done once, issues an appropriate ValveMove(...) command
/// ///
if (reqFlowLo >= reqFlowHi || reqFlowLo > nominalFlow || reqFlowHi <= 0) if (currentReqFlowLo >= currentReqFlowHi || currentReqFlowLo > nominalFlow || currentReqFlowHi <= 0)
{ {
return Event.OpArgumentError; return Event.OpArgumentError;
} }
log.InfoFormat("Run(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}", log.InfoFormat("Run(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}",
regulValveNr, flowMeterNr, reqFlowLo, reqFlowHi); regulValveNr, flowMeterNr, currentReqFlowLo, currentReqFlowHi);
float freqLo = 2000.0f * reqFlowLo / nominalFlow; float freqLo = 2000.0f * currentReqFlowLo / nominalFlow;
float freqHi = 2000.0f * reqFlowHi / nominalFlow; float freqHi = 2000.0f * currentReqFlowHi / nominalFlow;
controlBoard.ValveMove(regulValveNr, RegulValveMode.TargetFrequency, controlBoard.ValveMove(regulValveNr, RegulValveMode.TargetFrequency,
new float[2] { freqLo, freqHi }, new float[2] { freqLo, freqHi },
regulValve.StableTime); regulValve.StableTime);
@@ -292,7 +316,7 @@ namespace TBF.BenchControl.Elde.RegulValveTandem
/// ///
/// Repeated untill the required flow is reached /// Repeated untill the required flow is reached
/// ///
if ((reqFlowLo <= flow) && (flow <= reqFlowHi)) if ((currentReqFlowLo <= flow) && (flow <= currentReqFlowHi))
{ {
if (flowWithinBoundsTime++ >= regulValve.FlowStableSec) if (flowWithinBoundsTime++ >= regulValve.FlowStableSec)
{ {
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
// Build Number // Build Number
// Revision // Revision
// //
[assembly: AssemblyVersion("2.17.708.1")] [assembly: AssemblyVersion("2.17.709.1")]
[assembly: AssemblyFileVersion("2.17.708.1")] [assembly: AssemblyFileVersion("2.17.709.1")]