#pragma once
#include <AP_Common/AP_Common.h>
#include <AP_Param/AP_Param.h>
#include <stdlib.h>
#include <cmath>
#define AC_PI_2D_FILT_HZ_MIN 0.01f
class AC_PI_2D {
public:
AC_PI_2D(float initial_p, float initial_i, float initial_imax, float initial_filt_hz, float dt);
CLASS_NO_COPY(AC_PI_2D);
void set_dt(float dt);
void set_input(const Vector2f &input);
void set_input(const Vector3f &input) { set_input(Vector2f{input.x, input.y}); }
Vector2f get_pi();
Vector2f get_p() const;
Vector2f get_i();
Vector2f get_i_shrink();
void reset_I();
void reset_filter();
void load_gains();
void save_gains();
AP_Float &kP() { return _kp; }
AP_Float &kI() { return _ki; }
float imax() const { return _imax.get(); }
float filt_hz() const { return _filt_hz.get(); }
float get_filt_alpha() const { return _filt_alpha; }
void kP(float v) { _kp.set(v); }
void kI(float v) { _ki.set(v); }
void imax(float v) { _imax.set(fabsf(v)); }
void filt_hz(float hz);
Vector2f get_integrator() const { return _integrator; }
void set_integrator(const Vector2f &i) { _integrator = i; }
void set_integrator(const Vector3f &i) { _integrator.x = i.x; _integrator.y = i.y; }
static const struct AP_Param::GroupInfo var_info[];
private:
void calc_filt_alpha();
AP_Float _kp;
AP_Float _ki;
AP_Float _imax;
AP_Float _filt_hz;
struct ac_pid_flags {
bool _reset_filter;
} _flags;
float _dt;
Vector2f _integrator;
Vector2f _input;
float _filt_alpha;
const float default_kp;
const float default_ki;
const float default_imax;
const float default_filt_hz;
};