#ifndef __PID_H_INCLUDED__
#define __PID_H_INCLUDED__

#include <stdint.h>

class PID {
public:

struct PIDConstants
{
	double			m_Ti;					//Integral time constant
	double			m_Td;					//Derivative time constant
	double			m_K;					//Controller gain
	double			m_N;					//Derivative smoothing factor
	double			m_B;					//Setpoint weight
	double			m_Umax;				//Maximum output value
	double			m_Umin;				//Minimum output value
};

    PID ( double kP, double kI, double kD, double lI, uint32_t cD );
    PID() {}

   void ahSetConstants( uint32_t tv_sec, uint32_t tv_usec, PIDConstants PVC);

   double ahCalcCV( double setPoint, double PV, PIDConstants PVC);

    double CalculateGain( double position );

    // virtual void Set_Setpoint( double setpoint );

    double GetProportionalGain(void)
		{ return m_ProportionalGain; }

    double GetIntegralGain(void)
		{ return m_IntegralGain; }

    double GetDifferentialGain(void)
		{ return m_DifferentialGain; }

    void SetProportionalConstant( double kP )
        { m_KProportional = kP; };

    void SetIntegralConstant( double kI )
        { m_KIntegral = kI; }

    void SetDifferentialConstant( double kD )
        { m_KDifferential = kD; }

    void SetDifferentialCycle( uint32_t Dc )
        { m_DifferentialCycle = Dc; }

    double GetProportionalConstant(void)
		{ return m_KProportional; }

    double GetIntegralConstant(void)
		{ return m_KIntegral; }

    double GetDifferentialConstant(void)
		{ return m_KDifferential; }

    double GetIntegralLimit(void)
		{ return m_IntegralLimit; }

    double GetSetpoint(void)
		{ return m_Setpoint; }

private:
    double		m_KProportional;
    double		m_KIntegral;
    double		m_KDifferential;
    double		m_IntegralLimit;
    double		m_ProportionalGain;
    double		m_IntegralGain;
    double		m_DifferentialGain;
    double		m_Setpoint;
    double		m_Gain;
    uint32_t	m_DifferentialCycle;
    uint32_t	m_DifferentialCycleCount;
    double		m_ErrorSum;
    double      m_LastError;


  //GM
	double				m_h;						//cycle time
	double				m_Y;
	double				m_Ysetpoint;
	double				m_Tt;
	double				m_V;
	double				m_U;
	double				m_bi;
	double				m_ad;
	double				m_bd;
	double				m_a0;
	double				m_P;
	double				m_D;
	double				m_Yold;
	double				m_Iold;
	double				m_Dold;
	double				m_I;

};

#endif
/* End of File */
