using System;
using System.IO.Ports;
using System.Text;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SWModules;
using HWModules;
namespace SensorModules
{
public sealed class BuoyancyEngine
{
private MotherBoard mb;
private ADC2485 bellowsPositionADC;
private ElmoTwitter pumpMotor;
private LheBoard lheBoard;
private BuoyancyEngine()
{
mb = MotherBoard.Instance;
bellowsPositionADC = new ADC2485(new I2CDevice.Configuration(0x26, 20), 6);
pumpMotor = new ElmoTwitter("PumpMotor", "COM2", 115200, Parity.None, 8, StopBits.One, 5000, 20, false, (byte)';', (byte)';');
emHotel = EnergyMonitorHotel.Instance;
emPump = EnergyMonitorPump.Instance;
lheBoard = LheBoard.Instance;
}
private static BuoyancyEngine instance;
public static BuoyancyEngine Instance
{
get
{
instance = instance ?? (new BuoyancyEngine());
return instance;
}
}
public static StringBuilder sbTemp = new StringBuilder(128);
public static double IB { get; private set; }
public static double OB { get; private set; }
public void initPumpMotor()
{
pumpMotor.init();
}
public void init()
{
EngrLogger.Comment("BE::init: Initializing Buoyancy Engine");
IB = 0.75;
OB = 2.0;
initPumpMotor();
mb.EnableChannelPower(MotherBoard.ChannelNames.MotorizedValve);
readyMV();
stopMotor();
closeMV();
bellowsPosition = double.NaN;
mb.EnableChannelPower((int)MotherBoard.ChannelNames.PositionSensorChannel);
EngrLogger.writeToColumns("BE::init: Getting bellows position 5X");
for (var i = 0; i < 5; i++)
{
bellowsPosition = getBellowsPositionStringPot();
sbTemp.Clear();
sbTemp.Append("Try ");
sbTemp.Append(i);
sbTemp.Append(" BP = ");
sbTemp.Append(bellowsPosition);
EngrLogger.writeToColumns(sbTemp);
Thread.Sleep(500);
}
}
public void EnableBEPumping()
{
lheBoard.EnablePumpPower(true);
mb.EnableChannelPower(MotherBoard.ChannelNames.MotorizedValve);
mb.EnableChannelPower(MotherBoard.ChannelNames.PositionSensorChannel);
mb.EnableChannelPower(MotherBoard.ChannelNames.PumpMotorControllerElexChannel);
//TODO might not have to do either or both these
mb.Enable12V();
mb.Enable5V();
}
public void DisableBEPumping()
{
lheBoard.EnablePumpPower(true);
mb.DisableChannelPower(MotherBoard.ChannelNames.MotorizedValve);
mb.DisableChannelPower(MotherBoard.ChannelNames.PositionSensorChannel);
mb.DisableChannelPower(MotherBoard.ChannelNames.PumpMotorControllerElexChannel);
}
public void getPumpMotorStats()
{
pumpMotor.getStats();
}
public void setPumpMotorAccDeacc1e9()
{
pumpMotor.setAccDeacc1e9();
}
//private const double sensorLength = 250.1;
private double bellowsPosition = double.NaN;
/*
public double getBellowsPositionMTS()
{
int value = 0;
double volts = double.NaN;
double voltage = double.NaN;
value = bellowsPositionADC.readValue();
if (value != int.MaxValue)
{
value = (int)(value ^ 0x80000000); //Need to invert the msb per 2485 data sheet
//Debug.Print("ADC Value = " + value.ToString());
volts = (float)value;
voltage = 2.5 + (5.0 * (double)volts / 2147483648.0);
//Debug.Print("Voltage = " + voltage.ToString() + "\r\n");
bellowsPosition = (voltage - 0.1) * (sensorLength / 4.8);
//Debug.Print("Position = " + position.ToString());
}
if (MissionConfig.EngrLoggerVerbosityLevel > 5)
EngrLogger.writeToColumns(EngrLiterals.ColumnNums.dateTime, DateTime.Now,
EngrLiterals.ColumnNums.state, SV.CurrentState,
EngrLiterals.ColumnNums.comment, "Bellows Position",
EngrLiterals.ColumnNums.bellowsPosition, bellowsPosition);
return (bellowsPosition);
}*/
public int getBellowsADCValue()
{
return bellowsPositionADC.readValue();
}
private static short _debugCounter = 1000;
public double getBellowsPositionStringPot(bool writeToLog = false)
{
//const double fullScaleStringOut = 500.0; //mm
//const double fullScaleVolts = 2.5;
//const double voltageOffset = -2.5;
//const double MMperVolt = fullScaleStringOut / (fullScaleVolts - voltageOffset);
bellowsPosition = double.NaN;
var value = getBellowsADCValue();
if (value != int.MaxValue)
{
//Convert ADC value to volts per 2485 data sheet
value = (int)(value ^ 0x80000000);
bellowsPosition = MissionConfig.StringPotSlope * value + MissionConfig.StringPotIntercept;
if ( (MissionConfig.EngrLoggerVerbosityLevel > 5) || writeToLog)
EngrLogger.writeToColumns(EngrLiterals.ColumnNums.dateTime, DateTime.Now,
EngrLiterals.ColumnNums.state, SV.CurrentState,
EngrLiterals.ColumnNums.comment, "Bellows Position",
EngrLiterals.ColumnNums.bellowsPosition, bellowsPosition);
if (MissionConfig.DebuggerVerbosityLevel > 2 && ++_debugCounter == 1000)
{
_debugCounter = 0;
sbTemp.Clear().Append(DateTime.Now.ToString());
sbTemp.Append(",Bellows Position,").Append(bellowsPosition.ToString("d2"));
sbTemp.Append(",ADC,").Append(value.ToString());
Debug.Print(sbTemp.ToString());
}
}
else
{
bellowsPosition = double.NaN;
sbTemp.Clear();
sbTemp.Append("[ERROR] converting ADC value, raw value = ");
sbTemp.Append(value);
EngrLogger.writeToColumns(sbTemp);
}
SV.BellowsPosition = bellowsPosition;
return (bellowsPosition);
}
public bool motorStopped;
public void stopMotor()
{
pumpMotor.stopMotor();
increasingBuoyancy = false;
decreasingBuoyancy = false;
motorStopped = true;
}
private static int exerciseBellowsJV = 100000;
EnergyMonitorHotel emHotel;
EnergyMonitorPump emPump;
public int exerciseBellows()
{
bellowsPosition = double.NaN;
stopMotor();
Thread.Sleep(2000);
sbTemp.Clear();
sbTemp.Append("Decreasing Buoyancy");
for (int i = 0; i < 10; i++)
{
//Debug.Print("Pump stats: ");
//Debug.Print(emPump.getVICE().ToString());
//Debug.Print("Hotel stats: ");
//Debug.Print(emHotel.getVICE().ToString());
decreaseBuoyancy(exerciseBellowsJV);
//CN0254Volts = CN0254.scanAll();
//bellowsPosition = (CN0254Volts[0] * configFile.cn0254CH0Scale) + configFile.cn0254CH0Offset;
bellowsPosition = getBellowsPositionStringPot();
EngrLogger.writeToColumns(1, EngrLiterals.ColumnNums.dateTime, DateTime.Now,
EngrLiterals.ColumnNums.state, SV.CurrentState,
EngrLiterals.ColumnNums.comment, sbTemp,
EngrLiterals.ColumnNums.bellowsPosition, bellowsPosition);
Thread.Sleep(2000);
}
stopMotor();
Thread.Sleep(2000);
sbTemp.Clear();
sbTemp.Append("Increasing Buoyancy");
for (int i = 0; i < 10; i++)
{
//Debug.Print("Pump stats: ");
//Debug.Print(emPump.getVICE().ToString());
//Debug.Print("Hotel stats: ");
//Debug.Print(emHotel.getVICE().ToString());
increaseBuoyancy(exerciseBellowsJV);
bellowsPosition = getBellowsPositionStringPot();
EngrLogger.writeToColumns(1, EngrLiterals.ColumnNums.dateTime, DateTime.Now,
EngrLiterals.ColumnNums.state, SV.CurrentState,
EngrLiterals.ColumnNums.comment, sbTemp,
EngrLiterals.ColumnNums.bellowsPosition, bellowsPosition);
Thread.Sleep(2000);
}
stopMotor();
return (1);
}
private static int moveBellowsInsideLimitsJV = 100000;
public int moveBellowsInsideLimits()
{
//Just in case the bellows was outside the limits, put it inside the limits
bellowsPosition = getBellowsPositionStringPot();
if (bellowsPosition > (MissionConfig.IBFillUpperLimit - 1.0))
{
sbTemp.Clear();
sbTemp.Append("Inner bellows exceeds upper limit, increasing buoyancy BP = ");
sbTemp.Append(bellowsPosition).Append(" limit: ").Append(MissionConfig.IBFillUpperLimit);
EngrLogger.writeToColumns(sbTemp);
increaseBuoyancy(moveBellowsInsideLimitsJV);
return (0); //action not complete, return 0
}
else if (bellowsPosition < (MissionConfig.IBFillLowerLimit + 1.0))
{
sbTemp.Clear();
sbTemp.Append("Inner bellows below lower limit, decreasing buoyancy BP = ");
sbTemp.Append(bellowsPosition).Append(" limit: ").Append(MissionConfig.IBFillLowerLimit);
EngrLogger.writeToColumns(sbTemp);
decreaseBuoyancy(moveBellowsInsideLimitsJV);
return (0); //action not complete, return 0
}
else
{
stopMotor();
sbTemp.Clear();
sbTemp.Append("Bellows inside limits: ").Append(bellowsPosition);
EngrLogger.writeToColumns(sbTemp);
sbTemp.Clear();
return (1);
}
}
public bool increasingBuoyancy;
public bool increaseBuoyancy(int jogVelocityCPS, bool checkBellowsPosition = true)
{
if (checkBellowsPosition)
{
bellowsPosition = getBellowsPositionStringPot();
if (bellowsPosition < MissionConfig.IBFillLowerLimit)
{
pumpMotor.stopMotor();
EngrLogger.writeToColumns("[ERROR] Elmo.increasingBuoyancy: Bellows at lower limit");
return false;
}
}
if (!isValveOpen()) {
EngrLogger.Comment("Increase Buoyancy is opening valve");
openMV();
Thread.Sleep(1500);
}
pumpMotor.sendJV(-1 * System.Math.Abs(jogVelocityCPS));
motorStopped = false;
increasingBuoyancy = true;
decreasingBuoyancy = false;
return true;
}
public bool decreasingBuoyancy;
public bool decreaseBuoyancy(int jogVelocityCPS)
{
bellowsPosition = getBellowsPositionStringPot();
if (bellowsPosition > MissionConfig.IBFillUpperLimit)
{
pumpMotor.stopMotor();
EngrLogger.writeToColumns("[ERROR] Elmo.decreaseBuoyancy: Bellows at upper limit");
return (false);
}
if (!isValveOpen()) {
EngrLogger.Comment("Decrease buoyancy is opening valve");
openMV();
Thread.Sleep(1500);
}
pumpMotor.sendJV((1 * System.Math.Abs(jogVelocityCPS)));
motorStopped = false;
decreasingBuoyancy = true;
increasingBuoyancy = false;
return (true);
}
///
/// Reads the digital input on the ready line from
/// the motorized valve controller.
///
/// True is the valve is ready for commands
public bool isValveReady()
{
return !mb.getMVReadyStatus();
}
///
/// Reads the digital input on the open line from
/// the motorized valve controller.
///
/// True if the motor is driven to the valve
/// open position.
public bool isValveOpen()
{
return !mb.getMVOpenedStatus();
}
public static bool valveOpen;
///
/// Waits for motorize valve control to read ready
///
/// The final state read from the motorized
/// valve controller.
public bool readyMV()
{
if (isValveReady()) return true;
var attempts = 10;
do
{
EngrLogger.Comment("BE::readyMV: Valve not ready, attempts remaining: "+attempts);
Thread.Sleep(3000);
if (isValveReady())
break;
} while (--attempts > 0);
if (attempts > 0)
return true;
EngrLogger.Comment("BE::readyMV: ERROR Valve not ready after 20 seconds");
return false;
}
///
/// Opens the motorized valve
///
public void openMV()
{
EngrLogger.Comment("BE::openMV: Starting valve open");
mb.openMV();
if (waitForOpen(true))
valveOpen = true;
else
{
EngrLogger.Comment("BE::openMV: ERROR valve not reading open");
valveOpen = false;
}
}
///
/// Waits up to 3 seconds for the valve to either open or close
///
/// boolean, true if you're waiting for
/// the valve to open, false if you're waiting for it to close
///
///
private bool waitForOpen(bool waitForOpen)
{
var attempts = 30;
do
{
if (isValveOpen() == waitForOpen)
break;
Thread.Sleep(100);
} while (--attempts > 0);
return attempts > 0;
}
///
/// Closes the motorized valve.
///
public void closeMV()
{
EngrLogger.writeToColumns("BE::closeMV: Starting valve close");
mb.closeMV();
if (waitForOpen(false))
valveOpen = true;
else
{
EngrLogger.Comment("BE::closeMV: ERROR valve not reading closed");
valveOpen = false;
}
}
///
/// Stops the motor and closes the motorized valve
///
public void stopMotorAndCloseValve()
{
stopMotor();
Thread.Sleep(500);
closeMV();
}
// Below is legacy CPF code
public struct PlatVel
{
//PID constants
//Constants based on Matlab analysis 2018 Aug 31 for 0.156 cm^3/rev pump
public const double K = 80.0, // Constant for P term of PID
Ti = 50000.0, // Time constant for I term of PID (in denominator, bigger values less I term in output
Td = 10.0, // Time constant for D term of PID
Tf = 10.0, // Derivative filter time constant
Tt = 100.0, // Anti-windup time constant
B = 1.0, // Setpoint weight
uLow = -3000.0 / 60.0, // minimum possible output (RPS)
uHigh = 3000.0 / 60.0; // maximum possible output (RPS)
public static double h = MissionConfig.SBE41CommandModeSamplePeriod / 1000.0; // Sample period (seconds)
//Precomputed constants
public static double den = (Tf * Tf) + (2 * h * Tf) + (2 * h * h), // denominator of measured signal filter terms
p1 = Tf * Tf / den, // first part of state variable x2 equation
p2 = 2 * h * h / den, // second part of state variable x1 equation
p3 = K * h / Ti, // integral gain
p4 = K * Td / h, // derivative gain
p5 = h / Tt; // anti-windup gain
//Loop variables
public static double I, // Integrator part of PID calculation
y1, // first state variable
y2, // second state variable
v, // unclipped PID output
u; // clipped PID output
public static int uCPS; // u value in counts per second
}
public struct PIDLogValues
{
public double setPoint;
public double PV;
public double y1;
public double y2;
public double I;
public double v;
public double u;
public double uCPS;
public double h;
public DateTime timeStamp;
}
private static PIDLogValues BCPIDLogValues;
public void resetPVPID()
{
PlatVel.I = 0;
PlatVel.y1 = 0;
PlatVel.y2 = 0;
PlatVel.v = 0.0;
PlatVel.u = 0.0;
PlatVel.uCPS = 0;
}
public void calcPIDConstants(int samplePeriod)
{
PlatVel.h = samplePeriod / 1000.0;
PlatVel.den = (PlatVel.Tf * PlatVel.Tf) + (2 * PlatVel.h * PlatVel.Tf) + (2 * PlatVel.h * PlatVel.h); // denominator of measured signal filter terms
PlatVel.p1 = PlatVel.Tf * PlatVel.Tf / PlatVel.den; // first part of state variable x2 equation
PlatVel.p2 = 2 * PlatVel.h * PlatVel.h / PlatVel.den; // second part of state variable x1 equation
PlatVel.p3 = PlatVel.K * PlatVel.h / PlatVel.Ti; // integral gain
PlatVel.p4 = PlatVel.K * PlatVel.Td / PlatVel.h; // derivative gain
PlatVel.p5 = PlatVel.h / PlatVel.Tt; // anti-windup gain
resetPVPID();
sbTemp.Clear();
sbTemp.Append("Calculated new PID Constant, h = ");
sbTemp.Append(PlatVel.h.ToString());
EngrLogger.writeToColumns(sbTemp);
}
//Pump motor encoder counts per revolution
public const int COUNTSperREV = 2048 * 4; //2048 Counts per Revolution Encoder *4 for quadrature interpolation
public PIDLogValues runPvPID(double velocitySetPoint, double currentPlatVel)
{
//sbTemp.Clear();
//sbTemp.Append("runPvPID got velocitySetPoint: ");
//sbTemp.Append(velocitySetPoint.ToString());
//sbTemp.Append(" and currentPlatVel: ");
//sbTemp.Append(currentPlatVel.ToString());
//Debug.Print(sbTemp.ToString());
//Astrom & Hagglund PID Algorithm
PlatVel.y2 = (PlatVel.p1 * PlatVel.y2) + (PlatVel.p2 * (currentPlatVel - PlatVel.y1)); // update filter state y2
PlatVel.y1 = PlatVel.y1 + PlatVel.y2; // update filter state y1
PlatVel.v = PlatVel.K * ((PlatVel.B * velocitySetPoint) - PlatVel.y1) - // compute nominal output
(PlatVel.p4 * PlatVel.y2) + PlatVel.I;
// limit the nominal output to desired range
if (PlatVel.v < PlatVel.uLow)
PlatVel.u = PlatVel.uLow;
else if (PlatVel.v > PlatVel.uHigh)
PlatVel.u = PlatVel.uHigh;
else
PlatVel.u = PlatVel.v;
// update the integral
PlatVel.I = PlatVel.I + (PlatVel.p3 * (velocitySetPoint - PlatVel.y1)) + (PlatVel.p5 * (PlatVel.u - PlatVel.v));
//Convert Rev per second to Counts per second
PlatVel.uCPS = (int)(PlatVel.u * COUNTSperREV);
if (PlatVel.uCPS >= 0)
{
increaseBuoyancy(PlatVel.uCPS);
}
else
{
decreaseBuoyancy(PlatVel.uCPS);
}
BCPIDLogValues.timeStamp = DateTime.Now;
BCPIDLogValues.I = PlatVel.I;
BCPIDLogValues.PV = currentPlatVel;
BCPIDLogValues.setPoint = velocitySetPoint;
BCPIDLogValues.u = PlatVel.u;
BCPIDLogValues.uCPS = PlatVel.uCPS;
BCPIDLogValues.v = PlatVel.v;
BCPIDLogValues.y1 = PlatVel.y1;
BCPIDLogValues.y2 = PlatVel.y2;
BCPIDLogValues.h = PlatVel.h;
return (BCPIDLogValues);
}
private const double currentErrorGain = 29.07;
private const double prevErrorGain = -56.78;
private const double prevPrevErrorGain = 27.71;
private const double prevPumpSpeedGain = 1.238;
private const double prevPrevPumpSpeedGain = -0.3829;
private const double pumpSpeedUpperLimit = 50.0; // [rev/sec]
private const double pumpSpeedLowerLimit = -50.0; // [rev/sec]
private static double currentPressureError = double.NaN;
private static double prevPressureError;
private static double prevPrevPressureError;
private static double nextPumpSpeedCmd = double.NaN;
private static double prevPumpSpeedCmd;
private static double prevPrevPumpSpeedCmd;
private const double maxSetPointIncrement = 1.2; // [decibar]
private const double maxSetPointDecrement = -1.2; // [decibar]
private static double governedPressureSetPoint = double.NaN; // [decibar]
///
/// Depth Controller using a dual lead model
///
///
/// pressure in dbar
/// pump speed in counts/second
///
public void InitializeReferenceGovernor(double desiredPressureSetPoint, double currentPlatformPressure)
{
//governedPressureSetPoint = (desiredPressureSetPoint - currentPlatformPressure);
//if (governedPressureSetPoint > maxSetPointIncrement)
// governedPressureSetPoint = maxSetPointIncrement;
//else if (governedPressureSetPoint < maxSetPointDecrement)
// governedPressureSetPoint = maxSetPointDecrement;
//governedPressureSetPoint = governedPressureSetPoint + currentPlatformPressure;
governedPressureSetPoint = currentPlatformPressure;
}
public double ReferenceGovernor(double desiredPressureSetPoint, double currentPlatformPressure)
{
// AUTHOR: Brian Ha (2018 Summer Intern)
//
double setPointDelta; // [decibar]
setPointDelta = desiredPressureSetPoint - governedPressureSetPoint;
//EngrLogger.writeToColumns("REF GOV: setPointDelta = " + setPointDelta.ToString());
//
if (setPointDelta > maxSetPointIncrement)
{
setPointDelta = maxSetPointIncrement;
}
else if (setPointDelta < maxSetPointDecrement)
{
setPointDelta = maxSetPointDecrement;
}
//
governedPressureSetPoint = governedPressureSetPoint + setPointDelta;
if (System.Math.Abs(desiredPressureSetPoint - governedPressureSetPoint) <= maxSetPointIncrement)
{
governedPressureSetPoint = desiredPressureSetPoint;
}
//EngrLogger.writeToColumns("governedPressureSetPoint = " + governedPressureSetPoint.ToString());
return governedPressureSetPoint;
}
public int DualLeadDepthController(double governedPressureSP, double currentPlatformPressure)
{
// AUTHOR: Brian Ha (2018 Summer Intern)
// Calculate current pressure error
currentPressureError = governedPressureSP - currentPlatformPressure;
//EngrLogger.writeToColumns("ERROR = " + currentPressureError.ToString());
// Calculate the next pump speed command.
nextPumpSpeedCmd = (currentErrorGain * currentPressureError) + (prevErrorGain * prevPressureError) + (prevPrevErrorGain * prevPrevPressureError) + (prevPumpSpeedGain * prevPumpSpeedCmd) + (prevPrevPumpSpeedGain * prevPrevPumpSpeedCmd);
//EngrLogger.writeToColumns("Pre threshold nextPumpSpeedCmd: " + nextPumpSpeedCmd.ToString());
// Limit pump speed command magnitude to 50 revs/sec.
if (nextPumpSpeedCmd > pumpSpeedUpperLimit)
{
nextPumpSpeedCmd = pumpSpeedUpperLimit;
}
else if (nextPumpSpeedCmd < pumpSpeedLowerLimit)
{
nextPumpSpeedCmd = pumpSpeedLowerLimit;
}
// Deadband
//if (nextPumpSpeedCmd < 0.05 && nextPumpSpeedCmd > -0.05)
//{
// nextPumpSpeedCmd = 0.0;
//}
// Set historical values for next function call
prevPrevPumpSpeedCmd = prevPumpSpeedCmd;
prevPrevPressureError = prevPressureError;
prevPumpSpeedCmd = nextPumpSpeedCmd;
prevPressureError = currentPressureError;
EngrLogger.writeToColumns("TARGET: " + governedPressureSP.ToString() + "; CURRENT DEPTH = " + currentPlatformPressure.ToString() + "; ERROR: " + currentPressureError.ToString() + "; CMD = " + nextPumpSpeedCmd.ToString() + " [revs/sec];");
// Convert from rev/sec to counts/sec
nextPumpSpeedCmd = nextPumpSpeedCmd * COUNTSperREV;
// Return next pump speed command [counts/sec].
//EngrLogger.writeToColumns("Final nextPumpSpeedCmd:" + ((int)nextPumpSpeedCmd).ToString());
return ((int)nextPumpSpeedCmd);
}
//public int DualLeadDepthController(double pressureSetPoint, double currentPlatformPressure)
//{
// // AUTHOR: Brian Ha (2018 Summer Intern)
// // Calculate current pressure error
// currentPressureError = pressureSetPoint - currentPlatformPressure;
// // Error Governor - This acts as a saturation on the error signal.
// if (currentPressureError > errorGovernorUpperLimit)
// {
// currentPressureError = errorGovernorUpperLimit;
// }
// else if (currentPressureError < errorGovernorLowerLimit)
// {
// currentPressureError = errorGovernorLowerLimit;
// }
// Debug.Print("Current Pressure Error: "+ currentPressureError);
// // Calculate the next pump speed command.
// nextPumpSpeedCmd = (currentErrorGain * currentPressureError) +
// (prevErrorGain * prevPressureError) + (prevPrevErrorGain * prevPrevPressureError) +
// (prevPumpSpeedGain * prevPumpSpeedCmd) + (prevPrevPumpSpeedGain * prevPrevPumpSpeedCmd);
// // Limit pump speed command magnitude to 50 revs/sec.
// if (nextPumpSpeedCmd > pumpSpeedUpperLimit)
// {
// nextPumpSpeedCmd = pumpSpeedUpperLimit;
// }
// else if(nextPumpSpeedCmd < pumpSpeedLowerLimit)
// {
// nextPumpSpeedCmd = pumpSpeedLowerLimit;
// }
// // Set values for next function call
// prevPrevPumpSpeedCmd = prevPumpSpeedCmd;
// prevPrevPressureError = prevPressureError;
// prevPumpSpeedCmd = nextPumpSpeedCmd;
// prevPressureError = currentPressureError;
// // Convert from rev/sec to counts/sec
// nextPumpSpeedCmd = nextPumpSpeedCmd * COUNTSperREV;
// // Return next pump speed command [counts/sec].
// return (int)(nextPumpSpeedCmd);
//}
}
}