diff options
| author | Roy Ben-Shabat <Roy@Twine-s.com> | 2018-10-10 16:55:44 +0300 |
|---|---|---|
| committer | Roy Ben-Shabat <Roy@Twine-s.com> | 2018-10-10 16:55:44 +0300 |
| commit | 79eb19cbd10785a7dbc972bc0b26817932237419 (patch) | |
| tree | e36176fc94ce6f26efc89b006d7e6faf7e4398cb /Software/Visual_Studio/Tango.Core/Components | |
| parent | df9197240ba5a643ce1599f36b7e3dd34aad6a60 (diff) | |
| download | Tango-79eb19cbd10785a7dbc972bc0b26817932237419.tar.gz Tango-79eb19cbd10785a7dbc972bc0b26817932237419.zip | |
Sign-out works !
Fixed issue where color conversion was busy while not in research module but research module in job view.
Added new RealTimeGraphX !
Diffstat (limited to 'Software/Visual_Studio/Tango.Core/Components')
| -rw-r--r-- | Software/Visual_Studio/Tango.Core/Components/PidController.cs | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/Software/Visual_Studio/Tango.Core/Components/PidController.cs b/Software/Visual_Studio/Tango.Core/Components/PidController.cs new file mode 100644 index 000000000..0545ec98d --- /dev/null +++ b/Software/Visual_Studio/Tango.Core/Components/PidController.cs @@ -0,0 +1,141 @@ +using System; + +namespace Tango.Core.Components +{ + /// <summary> + /// A (P)roportional, (I)ntegral, (D)erivative Controller + /// </summary> + /// <remarks> + /// The controller should be able to control any process with a + /// measureable value, a known ideal value and an input to the + /// process that will affect the measured value. + /// </remarks> + /// <see cref="https://en.wikipedia.org/wiki/PID_controller"/> + public sealed class PidController + { + private double processVariable = 0; + + public PidController(double setPoint, double OutputMax, double OutputMin) : this(1.2, 0.5, 1, OutputMax, OutputMin) + { + SetPoint = setPoint; + } + + public PidController(double GainProportional, double GainIntegral, double GainDerivative, double OutputMax, double OutputMin) + { + this.GainDerivative = GainDerivative; + this.GainIntegral = GainIntegral; + this.GainProportional = GainProportional; + this.OutputMax = OutputMax; + this.OutputMin = OutputMin; + } + + /// <summary> + /// The controller output + /// </summary> + /// <param name="timeSinceLastUpdate">timespan of the elapsed time + /// since the previous time that ControlVariable was called</param> + /// <returns>Value of the variable that needs to be controlled</returns> + public double ControlVariable(TimeSpan timeSinceLastUpdate) + { + double error = SetPoint - ProcessVariable; + + // integral term calculation + IntegralTerm += (GainIntegral * error * timeSinceLastUpdate.TotalSeconds); + IntegralTerm = Clamp(IntegralTerm); + + // derivative term calculation + double dInput = processVariable - ProcessVariableLast; + double derivativeTerm = GainDerivative * (dInput / timeSinceLastUpdate.TotalSeconds); + + // proportional term calcullation + double proportionalTerm = GainProportional * error; + + double output = proportionalTerm + IntegralTerm - derivativeTerm; + + output = Clamp(output); + + return output; + } + + /// <summary> + /// The derivative term is proportional to the rate of + /// change of the error + /// </summary> + public double GainDerivative { get; set; } = 0; + + /// <summary> + /// The integral term is proportional to both the magnitude + /// of the error and the duration of the error + /// </summary> + public double GainIntegral { get; set; } = 0; + + /// <summary> + /// The proportional term produces an output value that + /// is proportional to the current error value + /// </summary> + /// <remarks> + /// Tuning theory and industrial practice indicate that the + /// proportional term should contribute the bulk of the output change. + /// </remarks> + public double GainProportional { get; set; } = 0; + + /// <summary> + /// The max output value the control device can accept. + /// </summary> + public double OutputMax { get; private set; } = 0; + + /// <summary> + /// The minimum ouput value the control device can accept. + /// </summary> + public double OutputMin { get; private set; } = 0; + + /// <summary> + /// Adjustment made by considering the accumulated error over time + /// </summary> + /// <remarks> + /// An alternative formulation of the integral action, is the + /// proportional-summation-difference used in discrete-time systems + /// </remarks> + public double IntegralTerm { get; private set; } = 0; + + + /// <summary> + /// The current value + /// </summary> + public double ProcessVariable + { + get { return processVariable; } + set + { + ProcessVariableLast = processVariable; + processVariable = value; + } + } + + /// <summary> + /// The last reported value (used to calculate the rate of change) + /// </summary> + public double ProcessVariableLast { get; private set; } = 0; + + /// <summary> + /// The desired value + /// </summary> + public double SetPoint { get; set; } = 0; + + /// <summary> + /// Limit a variable to the set OutputMax and OutputMin properties + /// </summary> + /// <returns> + /// A value that is between the OutputMax and OutputMin properties + /// </returns> + /// <remarks> + /// Inspiration from http://stackoverflow.com/questions/3176602/how-to-force-a-number-to-be-in-a-range-in-c + /// </remarks> + private double Clamp(double variableToClamp) + { + if (variableToClamp <= OutputMin) { return OutputMin; } + if (variableToClamp >= OutputMax) { return OutputMax; } + return variableToClamp; + } + } +}
\ No newline at end of file |
