Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/libraries/AC_PID/AC_PID.h
Views: 1798
#pragma once12/// @file AC_PID.h3/// @brief Generic PID algorithm, with EEPROM-backed storage of constants.45#include <AP_Common/AP_Common.h>6#include <AP_Param/AP_Param.h>7#include <stdlib.h>8#include <cmath>9#include <Filter/SlewLimiter.h>10#include <Filter/NotchFilter.h>11#include <Filter/AP_Filter.h>1213#define AC_PID_TFILT_HZ_DEFAULT 0.0f // default input filter frequency14#define AC_PID_EFILT_HZ_DEFAULT 0.0f // default input filter frequency15#define AC_PID_DFILT_HZ_DEFAULT 20.0f // default input filter frequency16#define AC_PID_RESET_TC 0.16f // Time constant for integrator reset decay to zero1718#include "AP_PIDInfo.h"1920/// @class AC_PID21/// @brief Copter PID control class22class AC_PID {23public:2425struct Defaults {26float p;27float i;28float d;29float ff;30float imax;31float filt_T_hz;32float filt_E_hz;33float filt_D_hz;34float srmax;35float srtau;36float dff;37};3839// Constructor for PID40AC_PID(float initial_p, float initial_i, float initial_d, float initial_ff, float initial_imax, float initial_filt_T_hz, float initial_filt_E_hz, float initial_filt_D_hz,41float initial_srmax=0, float initial_srtau=1.0, float initial_dff=0);42AC_PID(const AC_PID::Defaults &defaults) :43AC_PID(44defaults.p,45defaults.i,46defaults.d,47defaults.ff,48defaults.imax,49defaults.filt_T_hz,50defaults.filt_E_hz,51defaults.filt_D_hz,52defaults.srmax,53defaults.srtau,54defaults.dff55)56{ }5758CLASS_NO_COPY(AC_PID);5960// update_all - set target and measured inputs to PID controller and calculate outputs61// target and error are filtered62// the derivative is then calculated and filtered63// the integral is then updated based on the setting of the limit flag64float update_all(float target, float measurement, float dt, bool limit = false, float boost = 1.0f);6566// update_error - set error input to PID controller and calculate outputs67// target is set to zero and error is set and filtered68// the derivative then is calculated and filtered69// the integral is then updated based on the setting of the limit flag70// Target and Measured must be set manually for logging purposes.71// todo: remove function when it is no longer used.72float update_error(float error, float dt, bool limit = false);7374// get_pid - get results from pid controller75float get_p() const;76float get_i() const;77float get_d() const;78float get_ff() const;7980// reset_I - reset the integrator81void reset_I();8283// reset_filter - input filter will be reset to the next value provided to set_input()84void reset_filter() {85_flags._reset_filter = true;86}8788// load gain from eeprom89void load_gains();9091// save gain to eeprom92void save_gains();9394// get accessors95const AP_Float &kP() const { return _kp; }96AP_Float &kP() { return _kp; }97AP_Float &kI() { return _ki; }98AP_Float &kD() { return _kd; }99AP_Float &kIMAX() { return _kimax; }100AP_Float &kPDMAX() { return _kpdmax; }101AP_Float &ff() { return _kff;}102AP_Float &filt_T_hz() { return _filt_T_hz; }103AP_Float &filt_E_hz() { return _filt_E_hz; }104AP_Float &filt_D_hz() { return _filt_D_hz; }105AP_Float &slew_limit() { return _slew_rate_max; }106AP_Float &kDff() { return _kdff; }107108float imax() const { return _kimax.get(); }109float pdmax() const { return _kpdmax.get(); }110111float get_filt_T_alpha(float dt) const;112float get_filt_E_alpha(float dt) const;113float get_filt_D_alpha(float dt) const;114115// set accessors116void set_kP(const float v) { _kp.set(v); }117void set_kI(const float v) { _ki.set(v); }118void set_kD(const float v) { _kd.set(v); }119void set_ff(const float v) { _kff.set(v); }120void set_imax(const float v) { _kimax.set(fabsf(v)); }121void set_pdmax(const float v) { _kpdmax.set(fabsf(v)); }122void set_filt_T_hz(const float v);123void set_filt_E_hz(const float v);124void set_filt_D_hz(const float v);125void set_slew_limit(const float v);126void set_kDff(const float v) { _kdff.set(v); }127128// set the desired and actual rates (for logging purposes)129void set_target_rate(float target) { _pid_info.target = target; }130void set_actual_rate(float actual) { _pid_info.actual = actual; }131132// integrator setting functions133void set_integrator(float i);134void relax_integrator(float integrator, float dt, float time_constant);135136// set slew limiter scale factor137void set_slew_limit_scale(int8_t scale) { _slew_limit_scale = scale; }138139// return current slew rate of slew limiter. Will return 0 if SMAX is zero140float get_slew_rate(void) const { return _slew_limiter.get_slew_rate(); }141142const AP_PIDInfo& get_pid_info(void) const { return _pid_info; }143144void set_notch_sample_rate(float);145146// parameter var table147static const struct AP_Param::GroupInfo var_info[];148149protected:150151// update_i - update the integral152// if the limit flag is set the integral is only allowed to shrink153void update_i(float dt, bool limit);154155// parameters156AP_Float _kp;157AP_Float _ki;158AP_Float _kd;159AP_Float _kff;160AP_Float _kimax;161AP_Float _kpdmax;162AP_Float _filt_T_hz; // PID target filter frequency in Hz163AP_Float _filt_E_hz; // PID error filter frequency in Hz164AP_Float _filt_D_hz; // PID derivative filter frequency in Hz165AP_Float _slew_rate_max;166AP_Float _kdff;167#if AP_FILTER_ENABLED168AP_Int8 _notch_T_filter;169AP_Int8 _notch_E_filter;170#endif171172// the time constant tau is not currently configurable, but is set173// as an AP_Float to make it easy to make it configurable for a174// single user of AC_PID by adding the parameter in the param175// table of the parent class. It is made public for this reason176AP_Float _slew_rate_tau;177178SlewLimiter _slew_limiter{_slew_rate_max, _slew_rate_tau};179180// flags181struct ac_pid_flags {182bool _reset_filter :1; // true when input filter should be reset during next call to set_input183bool _I_set :1; // true if if the I terms has been set externally including zeroing184} _flags;185186// internal variables187float _integrator; // integrator value188float _target; // target value to enable filtering189float _error; // error value to enable filtering190float _derivative; // derivative value to enable filtering191int8_t _slew_limit_scale;192float _target_derivative; // target derivative value to enable dff193#if AP_FILTER_ENABLED194NotchFilterFloat* _target_notch;195NotchFilterFloat* _error_notch;196#endif197198AP_PIDInfo _pid_info;199200private:201const float default_kp;202const float default_ki;203const float default_kd;204const float default_kff;205const float default_kdff;206const float default_kimax;207const float default_filt_T_hz;208const float default_filt_E_hz;209const float default_filt_D_hz;210const float default_slew_rate_max;211};212213214