#include <cmath>
// Select 'double' or 'float' here:
typedef double real;
class PID_Controller
{
public:
void Initialize(real kp, real ki, real kd,
real error_thresh, real step_time);
real Update(real error);
private:
bool m_started;
real m_kp, m_ki, m_kd, m_h, m_inv_h, m_prev_error,
m_error_thresh, m_integral;
};
void PID_Controller::Initialize(real kp, real ki,
real kd, real error_thresh, real step_time)
{
// Initialize controller parameters
m_kp = kp;
m_ki = ki;
m_kd = kd;
m_error_thresh = error_thresh;
// Controller step time and its inverse
m_h = step_time;
m_inv_h = 1 / step_time;
// Initialize integral and derivative calculations
m_integral = 0;
m_started = false;
}
real PID_Controller::Update(real error)
{
// Set q to 1 if the error magnitude is below
// the threshold and 0 otherwise
real q;
if (fabs(error) < m_error_thresh)
q = 1;
else
q = 0;
// Update the error integral
m_integral += m_h*q*error;
// Compute the error derivative
real deriv;
if (!m_started)
{
m_started = true;
deriv = 0;
}
else
deriv = (error - m_prev_error) * m_inv_h;
m_prev_error = error;
// Return the PID controller actuator command
return m_kp*(error + m_ki*m_integral + m_kd*deriv);
} |
|