gov.sandia.cognition.math.signals.PIDController Maven / Gradle / Ivy
/*
* File: PIDController.java
* Authors: Kevin R. Dixon
* Company: Sandia National Laboratories
* Project: Cognitive Foundry
*
* Copyright Apr 4, 2009, Sandia Corporation.
* Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
* license for use of this work by or on behalf of the U.S. Government.
* Export of this program may require a license from the United States
* Government. See CopyrightHistory.txt for complete details.
*
*/
package gov.sandia.cognition.math.signals;
import gov.sandia.cognition.annotation.PublicationReference;
import gov.sandia.cognition.annotation.PublicationReferences;
import gov.sandia.cognition.annotation.PublicationType;
import gov.sandia.cognition.evaluator.AbstractStatefulEvaluator;
import gov.sandia.cognition.util.AbstractCloneableSerializable;
/**
* This class defines a Proportional-plus-Integral-plus-Derivative set-point
* controller. The goal of this PID controller is to minimize the difference
* between its target-value input and a given input by changing a control
* variable to implicitly change its given input at the next time step.
* @author Kevin R. Dixon
* @since 3.0
*/
@PublicationReferences(
references={
@PublicationReference(
author="Control Tutorial for MATLAB",
title="PID Tutorial",
type=PublicationType.WebPage,
year=1997,
url="http://www.engin.umich.edu/group/ctm/PID/PID.html"
),
@PublicationReference(
author="Wikipedia",
title="PID Controller",
type=PublicationType.WebPage,
year=2009,
url="http://en.wikipedia.org/wiki/PID_controller",
notes="This article pretty much sucks"
)
}
)
public class PIDController
extends AbstractStatefulEvaluator
{
/**
* Set point target to achieve at steady-state.
*/
private double targetInput;
/**
* Proportional-error gain.
*/
private double proportionalGain;
/**
* Integral-error gain.
*/
private double integralGain;
/**
* Derivative-error gain.
*/
private double derivativeGain;
/**
* Default proportional-error gain, {@value}.
*/
public static final double DEFAULT_PROPORTIONAL_GAIN = 0.5;
/**
* Default integral-error gain, {@value}.
*/
public static final double DEFAULT_INTEGRAL_GAIN = 0.0;
/**
* Default derivative-error gain, {@value}.
*/
public static final double DEFAULT_DERIVATIVE_GAIN = 0.25;
/**
* Creates a new instance of PIDController
*/
public PIDController()
{
this( DEFAULT_PROPORTIONAL_GAIN, DEFAULT_INTEGRAL_GAIN, DEFAULT_DERIVATIVE_GAIN );
}
/**
* Creates a new instance of PIDController.
* @param proportionalGain
* Proportional-error gain.
* @param integralGain
* Integral-error gain.
* @param derivativeGain
* Derivative-error gain.
*/
public PIDController(
double proportionalGain,
double integralGain,
double derivativeGain )
{
this( proportionalGain, integralGain, derivativeGain, 0.0 );
}
/**
* Creates a new instance of PIDController.
* @param proportionalGain
* Proportional-error gain.
* @param integralGain
* Integral-error gain.
* @param derivativeGain
* Derivative-error gain.
* @param targetInput
* Set point target to achieve at steady-state.
*/
public PIDController(
double proportionalGain,
double integralGain,
double derivativeGain,
double targetInput )
{
super();
this.setProportionalGain( proportionalGain );
this.setIntegralGain( integralGain );
this.setDerivativeGain( derivativeGain );
this.setTargetInput( targetInput );
}
/**
* Getter for targetInput.
* @return
* Set point target to achieve at steady-state.
*/
public double getTargetInput()
{
return this.targetInput;
}
/**
* Setter for targetInput
* @param targetInput
* Set point target to achieve at steady-state.
*/
public void setTargetInput(
double targetInput )
{
this.targetInput = targetInput;
}
/**
* Getter for proportionalGain
* @return
* Proportional-error gain.
*/
public double getProportionalGain()
{
return this.proportionalGain;
}
/**
* Setter for proportionalGain
* @param proportionalGain
* Proportional-error gain.
*/
public void setProportionalGain(
double proportionalGain )
{
this.proportionalGain = proportionalGain;
}
/**
* Getter for integralGain.
* @return
* Integral-error gain.
*/
public double getIntegralGain()
{
return this.integralGain;
}
/**
* Setter for integralGain
* @param integralGain
* Integral-error gain.
*/
public void setIntegralGain(
double integralGain )
{
this.integralGain = integralGain;
}
/**
* Getter for derivativeGain
* @return
* Derivative-error gain.
*/
public double getDerivativeGain()
{
return this.derivativeGain;
}
/**
* Setter for derivativeGain
* @param derivativeGain
* Derivative-error gain.
*/
public void setDerivativeGain(
double derivativeGain )
{
this.derivativeGain = derivativeGain;
}
public Double evaluate(
Double input )
{
double err = this.targetInput - input;
double errSum = err + this.getState().getErrSum();
double diffErr = err - this.getState().getLastErr();
this.getState().setErrSum( errSum );
this.getState().setLastErr( err );
double pid = this.proportionalGain * err
+ this.integralGain * errSum
+ this.derivativeGain * diffErr;
return pid;
}
public State createDefaultState()
{
return new State();
}
/**
* State of a PIDController
*/
public static class State
extends AbstractCloneableSerializable
{
/**
* Last error.
*/
private double lastErr;
/**
* Sum of all errors.
*/
private double errSum;
/**
* Default constructor.
*/
public State()
{
this( 0.0, 0.0 );
}
/**
* Creates a new instance of State
* @param lastErr
* Last error.
* @param errSum
* Sum of all errors.
*/
public State(
double lastErr,
double errSum )
{
this.setLastErr( lastErr );
this.setErrSum( errSum );
}
/**
* Getter for lastErr
* @return
* Last error.
*/
public double getLastErr()
{
return this.lastErr;
}
/**
* Setter for lastErr
* @param lastErr
* Last error.
*/
public void setLastErr(
double lastErr )
{
this.lastErr = lastErr;
}
/**
* Getter for errSum
* @return
* Sum of all errors.
*/
public double getErrSum()
{
return this.errSum;
}
/**
* Setter for errSum
* @param errSum
* Sum of all errors.
*/
public void setErrSum(
double errSum )
{
this.errSum = errSum;
}
}
}