tbf/TestBenchFramework/BenchControl/Elde/ControlComSim.cs
Milan Hanajik 94de991bf6 Everything works OK after serious changes:
- all components, componentCfg-s and parameter providers use base classes
 - less boilerplate code, simpler access to test/procedure parameters from code
 - CreateTestParams(test), CreateProcedureParams(procedure) methods added
 - TestBenchSim class is made static, it is not inheritted by any device anymore
2015-01-02 12:51:27 +01:00

297 lines
9.4 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
using log4net;
namespace TBF.BenchControl.Elde
{
public class ControlComSim : IControlCom
{
private static readonly ILog log = LogManager.GetLogger(typeof(ControlComSim));
public override string ToString() { return string.Format("ControlComSim"); }
StatusP statusP;
public StatusP StatusP { get { return statusP; } }
float referenceFreq = 650.0f;
public float ReferenceFreq { get { return referenceFreq; } }
int[] etPulses = new int[Program.WMsCount + 1];
public int EtPulses(int wmNr1and0)
{
return etPulses[wmNr1and0];
}
float[] errFactor = new float[Program.WMsCount + 1]; /// Internal
float[] wMeterPulsesF = new float[Program.WMsCount + 1]; /// Internal
int[] wMeterPulses = new int[Program.WMsCount + 1]; /// Rounded from wMeterPulsesF
public int WMeterPulses(int wmNr1)
{
return wMeterPulses[wmNr1];
}
int[] wMeterReference = new int[Program.WMsCount + 1];
public int WMeterReference(int wmNr1)
{
return wMeterReference[wmNr1];
}
public uint RegulValveDAC { get { return 0; } }
public float Pressure(int prsNr0) { return 0; }
public float Temperature(int tmpNr0) { return (float)(20 + tmpNr0); }
public RegulValveState RegulValveState(int rvNr1) { return 0; }
public ulong RRoute { get { return route; } }
public uint DivTime { get { return 0; } }
float tTime = 0;
public float TTime { get { return tTime; } }
public uint FmState { get { return 0; } }
public uint BeginState(int wmNr0) { return 0; }
float referenceFlow;
public float ReferenceFlow { get { return referenceFlow; } }
public float RValvePosition(int rvNr1) { return 0; }
public float DivSamples(int ms) { return 0; }
public int ScopeSamples(int i, int j, int k) { return 0; }
public uint DigitalInputs { get { return 0; } }
public float AnalogInput(int adcNr0) { return 0; }
public uint AnalogInputRaw(int adcNr0, int bank) { return 0; } /// bank0=RV, bank1=Temp
public float ReferenceVolume { get { return 0; } }
public float VyslExt(int wmNr0, int what) { return 0; }
public void SetWeight(int pos, float mass) { return; } /// not available in sim. mode
///
/// Private initialization data updated by contructors of children components
/// and sent to 'controlCom2panel' by SendCalibData() method.
///
uint[,] regValveCalib;
byte[] meretRS485Address;
float[,] tempCalibData;
float[] etCalib;
uint[] diverterEdge;
uint[] balanceRange;
///
/// Private values set by SendCommand()
///
Command cmd;
int refFlowmtrNr;
ulong route;
public ulong Route { get { return route; } }
int totalRefPulses;
TestMethods testMethods;
float filterConstant;
float[] FMFreq;
int regConst;
int shortImp;
StopDevs stopDevs;
///
/// Private values set by ValveMove()
///
int regulValveNo;
RegulValveMode regulValveMode;
float[] regulValveValue;
Random rand;
/// <summary>
/// Constructor
/// </summary>
public ControlComSim()
{
rand = new Random();
}
/// <summary>
/// Sends calibration and configuration data to the control board.
/// </summary>
/// <param name="rvCalib">Regulating valves calib.coefs, ix1 = valve nr. (1..5), ix2 = coef.nr. (0..1), values typ. c0 = 0, c1 = 0.2</param>
/// <param name="meretA">Meret address, index = 0..1, value typ. 99 and 100</param>
/// <param name="usedCom">COM port number of the control board (typ. 1)</param>
/// <param name="tempCalib">Temp.calc.coefs, ix1 = temp.sens.nr. (0..7 ???), ix2 = coef.nr</param>
/// <param name="etCalib">Etalon nominal values</param>
/// <param name="divEdge">Percentages for switching of diverters, ix = diverter nr.(0,1), typ.value 50 (%)</param>
public void SendCalibData(uint[,] rvCalib, byte[] meretA, int usedCom, float[,] tempCalib, float[] etCalib, uint[] divEdge, uint[] balanceRange)
{
this.regValveCalib = rvCalib;
this.meretRS485Address = meretA;
this.tempCalibData = tempCalib;
this.etCalib = etCalib;
this.diverterEdge = divEdge;
this.balanceRange = balanceRange;
}
/// <summary>
/// Sends a command to the control board.
/// </summary>
/// <param name="cmd">See ControlBoard.Command enum</param>
/// <param name="refFlowmtrNr">Number of the etalon/reference (1..5)</param>
/// <param name="route">Route: 64-bit installation specific number</param>
/// <param name="refPulses">kolko impulzov ma trvat skuska</param>
/// <param name="testMethods">See ControlBoard.TestMethods enum</param>
/// <param name="filterConstant">0 = No filtering (0..255)</param>
/// <param name="FMFreq">Freq.inverter control (not applicable in DT100, Munich)</param>
/// <param name="regConst">Coefficient used to control reg. valves (1..100)</param>
/// <param name="shortImp">0 = default value, 1 = spec. processing of very short pulses</param>
/// <param name="stopDevs">What to stop</param>
public void SendCommand(Command cmd, int refFlowmtrNr, ulong route, int totalRefPulses, TestMethods testMethods,
float filterConstant, float[] FMFreq, int regConst, int shortImp, StopDevs stopDevs)
{
Command lastCmd = this.cmd;
this.cmd = cmd;
this.refFlowmtrNr = refFlowmtrNr;
this.route = route;
TestBenchSim.RouteSim = route;
this.totalRefPulses = totalRefPulses;
this.testMethods = testMethods;
this.filterConstant = filterConstant;
this.FMFreq = FMFreq;
this.regConst = regConst;
this.shortImp = shortImp;
this.stopDevs = stopDevs;
#pragma warning disable
statusP = (StatusP)(((ulong)statusP & (ulong)0xFFFFFFFFFFFFFFF8L) | (ulong)refFlowmtrNr);
#pragma warning restore
if (cmd == Command.Start && lastCmd != Command.Start )
{
statusP |= StatusP.TestInProgress;
///
/// Clear all counters
///
if (etPulses != null) { for (int i = 0; i < etPulses.Length; i++) etPulses[i] = 0; }
if (wMeterPulses != null) { for (int i = 0; i < wMeterPulses.Length; i++) wMeterPulses[i] = 0; }
if (wMeterPulsesF != null) { for (int i = 0; i < wMeterPulsesF.Length; i++) wMeterPulsesF[i] = 0; }
if (wMeterReference != null) { for (int i = 0; i < wMeterReference.Length; i++) wMeterReference[i] = 0; }
if (errFactor != null)
{
for (int i = 0; i < errFactor.Length; i++) errFactor[i] = ((float)rand.Next(100) + 950.0f) / 1000.0f;
}
tTime = 0;
}
else if (cmd == Command.Stop)
{
statusP = 0;
//statusP &= ~StatusP.Running;
}
}
/// <summary>
/// Control of regulating valves.
/// </summary>
/// <param name="regulValveNo">Regulating valve nr. (1..5)</param>
/// <param name="regulValveMode">???</param>
/// <param name="regulValveValue">???</param>
/// <param name="stableTime">Stabilization time when setting the flow: 0=200ms, step 50ms, max. 1.5 sec.</param>
public void ValveMove(int regulValveNo, RegulValveMode regulValveMode, float[] regulValveValue, int stableTime)
{
this.regulValveNo = regulValveNo;
this.regulValveMode = regulValveMode;
this.regulValveValue = regulValveValue;
}
public void RunDeviceBefore()
{
TestBenchSim.RunDevice(regulValveNo, refFlowmtrNr, statusP);
log.DebugFormat("refFreq=", referenceFreq);
tTime += 1.0f;
float Qnom = (regulValveNo > 0) ? etCalib[regulValveNo] : 0;
switch (cmd)
{
case Command.None:
break;
case Command.Start:
if ((testMethods & TestMethods.Diverter) == TestMethods.Diverter)
{
TestBenchSim.SetSimDiverter(true);
}
break;
case Command.Stop:
if ((testMethods & TestMethods.Diverter) == TestMethods.Diverter)
{
TestBenchSim.SetSimDiverter(false);
}
break;
}
switch (regulValveMode)
{
case RegulValveMode.TargetFrequency:
float targetFlow = ((regulValveValue[0] + regulValveValue[1]) / 2.0f) * (Qnom / 2000.0f);
TestBenchSim.UpdateSimFlow(targetFlow);
//if (referenceFreq < valveValue[0]) referenceFreq += ((float)rand.Next(20) + 10.0f) / 2.0f;
//else if (referenceFreq > valveValue[1]) referenceFreq -= ((float)rand.Next(20) + 10.0f) / 2.0f;
//else referenceFreq += ((float)rand.Next(10) - 5.0f) / 2.0f;
referenceFreq = TestBenchSim.GetSimFlow() * 2000.0f / Qnom;
if (referenceFreq < 0) referenceFreq = 0;
if (referenceFreq > 2500) referenceFreq = 2500;
break;
default:
break;
}
referenceFlow = referenceFreq / 2000;
bool stopTest = false;
if (cmd == Command.Start)
{
float pwFactor = 1.0f;
/// Increment reference flow meters
for (int i = 0; i < Program.WMsCount; i++)
{
etPulses[i] += (int)referenceFreq;
if (etPulses[i] > totalRefPulses)
{
pwFactor = 1.0f - (float)(etPulses[i] - totalRefPulses) / referenceFreq;
etPulses[i] = totalRefPulses;
stopTest = true;
}
}
/// Increment water meters
for (int i = 1; i < Program.WMsCount; i++)
{
const float wmPulsesPerLiter = 10.0f;
wMeterPulsesF[i] += errFactor[i] * pwFactor * ((float)rand.Next(100) + 450.0f) * wmPulsesPerLiter * TestBenchSim.GetSimFlow() / 1800.0f;
wMeterPulses[i] = (int)wMeterPulsesF[i];
}
if (etPulses[0] > totalRefPulses)
{
statusP |= StatusP.TestCompleted;
statusP &= ~StatusP.TestInProgress;
}
}
if (stopTest)
{
TestBenchSim.SetSimDiverter(false);
statusP = (statusP | StatusP.TestCompleted);
statusP = (statusP & ~StatusP.TestInProgress);
}
}
public void RunDeviceAfter()
{
}
}
}