Path: blob/master/libraries/AC_AutoTune/AC_AutoTune.h
9685 views
/*1This program is free software: you can redistribute it and/or modify2it under the terms of the GNU General Public License as published by3the Free Software Foundation, either version 3 of the License, or4(at your option) any later version.56This program is distributed in the hope that it will be useful,7but WITHOUT ANY WARRANTY; without even the implied warranty of8MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the9GNU General Public License for more details.1011You should have received a copy of the GNU General Public License12along with this program. If not, see <http://www.gnu.org/licenses/>.13*/14/*15support for autotune of multirotors. Based on original autotune code from ArduCopter, written by Leonard Hall16Converted to a library by Andrew Tridgell17*/18#pragma once1920#include "AC_AutoTune_config.h"2122#if AC_AUTOTUNE_ENABLED2324#include <AC_AttitudeControl/AC_AttitudeControl.h>25#include <AC_AttitudeControl/AC_PosControl.h>26#include <AP_Math/AP_Math.h>27#include <RC_Channel/RC_Channel.h>28#include "AC_AutoTune_FreqResp.h"2930#define AUTOTUNE_AXIS_BITMASK_ROLL 131#define AUTOTUNE_AXIS_BITMASK_PITCH 232#define AUTOTUNE_AXIS_BITMASK_YAW 433#define AUTOTUNE_AXIS_BITMASK_YAW_D 83435#define AUTOTUNE_SUCCESS_COUNT 4 // The number of successful iterations we need to freeze at current gains3637// Auto Tune message ids for ground station38#define AUTOTUNE_MESSAGE_STARTED 039#define AUTOTUNE_MESSAGE_STOPPED 140#define AUTOTUNE_MESSAGE_SUCCESS 241#define AUTOTUNE_MESSAGE_FAILED 342#define AUTOTUNE_MESSAGE_SAVED_GAINS 443#define AUTOTUNE_MESSAGE_TESTING 544#define AUTOTUNE_MESSAGE_TESTING_END 64546#define AUTOTUNE_ANNOUNCE_INTERVAL_MS 20004748class AC_AutoTune49{50public:51// constructor52AC_AutoTune();5354// Main update loop for Autotune mode. Handles all states: tuning, testing, or idle.55// Should be called at >=100Hz for reliable performance.56virtual void run();5758// Possibly save gains, called on disarm59void disarmed(const bool in_autotune_mode);6061// stop tune, reverting gains62void stop();6364// Autotune aux function trigger65void do_aux_function(const RC_Channel::AuxSwitchPos ch_flag);6667protected:6869virtual void save_tuning_gains() = 0;707172// reset Autotune so that gains are not saved again and autotune can be run again.73void reset() {74mode = TuneMode::UNINITIALISED;75axes_completed = 0;76testing_switch_used = false;77}7879// axis that can be tuned80enum class AxisType {81ROLL = 0, // roll axis is being tuned (either angle or rate)82PITCH = 1, // pitch axis is being tuned (either angle or rate)83YAW = 2, // yaw axis is being tuned using FLTE (either angle or rate)84YAW_D = 3, // yaw axis is being tuned using D (either angle or rate)85};8687//88// methods that must be supplied by the vehicle specific subclass89//90virtual bool init(void) = 0;9192// get pilot input for desired climb rate93virtual float get_desired_climb_rate_ms(void) const = 0;9495// get pilot input for designed roll and pitch, and yaw rate96virtual void get_pilot_desired_rp_yrate_rad(float &roll_rad, float &pitch_rad, float &yaw_rate_rads) = 0;9798// init pos controller Z velocity and accel limits99virtual void init_z_limits() = 0;100101#if HAL_LOGGING_ENABLED102// log PIDs at full rate for during test103virtual void log_pids() = 0;104#endif105106//107// methods to load and save gains108//109110// backup original gains and prepare for start of tuning111virtual void backup_gains_and_initialise();112113// switch to use original gains114virtual void load_orig_gains() = 0;115116// switch to gains found by last successful autotune117virtual void load_tuned_gains() = 0;118119// load gains used between tests. called during testing mode's update-gains step to set gains ahead of return-to-level step120virtual void load_intra_test_gains() = 0;121122// load gains for next test. relies on axis variable being set123virtual void load_test_gains() = 0;124125// reset the test variables for each vehicle126virtual void reset_vehicle_test_variables() = 0;127128// reset the update gain variables for each vehicle129virtual void reset_update_gain_variables() = 0;130131// test initialization and run methods that should be overridden for each vehicle132virtual void test_init() = 0;133virtual void test_run(AxisType test_axis, const float dir_sign) = 0;134135// return true if user has enabled autotune for roll, pitch or yaw axis136bool roll_enabled() const;137bool pitch_enabled() const;138bool yaw_enabled() const;139bool yaw_d_enabled() const;140141// update gains for the rate p up tune type142virtual void updating_rate_p_up_all(AxisType test_axis)=0;143144// update gains for the rate d up tune type145virtual void updating_rate_d_up_all(AxisType test_axis)=0;146147// update gains for the rate d down tune type148virtual void updating_rate_d_down_all(AxisType test_axis)=0;149150// update gains for the angle p up tune type151virtual void updating_angle_p_up_all(AxisType test_axis)=0;152153// update gains for the angle p down tune type154virtual void updating_angle_p_down_all(AxisType test_axis)=0;155156// set gains post tune for the tune type157virtual void set_tuning_gains_with_backoff(AxisType test_axis)=0;158159// reverse the direction of the next test160virtual bool reverse_test_direction() = 0;161162163#if HAL_LOGGING_ENABLED164virtual void Log_AutoTune() = 0;165virtual void Log_AutoTuneDetails() = 0;166virtual void Log_AutoTuneSweep() = 0;167#endif168169// internal init function, should be called from init()170bool init_internals(bool use_poshold,171AC_AttitudeControl *attitude_control,172AC_PosControl *pos_control,173AP_AHRS_View *ahrs_view);174175// send intermittent updates to user on status of tune176virtual void do_gcs_announcements() = 0;177178// send post test updates to user179virtual void do_post_test_gcs_announcements() = 0;180181// send message with high level status (e.g. Started, Stopped)182void update_gcs(uint8_t message_id) const;183184// send lower level step status (e.g. Pilot overrides Active)185void send_step_string();186187// convert tune type to string for reporting188const char *get_tune_type_name() const;189190// return current axis string191const char *get_axis_name() const;192193// report final gains for a given axis to GCS194virtual void report_final_gains(AxisType test_axis) const = 0;195196// Functions added for heli autotune197198// Add additional updating gain functions specific to heli199// generic method used by subclasses to update gains for the rate ff up tune type200virtual void updating_rate_ff_up_all(AxisType test_axis)=0;201202// generic method used by subclasses to update gains for the max gain tune type203virtual void updating_max_gains_all(AxisType test_axis)=0;204205// steps performed while in the tuning mode206enum class Step {207WAITING_FOR_LEVEL = 0, // Waiting for the vehicle to stabilize at level before starting a test.208EXECUTING_TEST = 1, // Performing a test and monitoring the vehicle's response.209UPDATE_GAINS = 2, // Updating gains based on test results.210ABORT = 3 // Aborting the current test; revert to safe gains and return to WAITING_FOR_LEVEL.211};212Step step; // see StepType for what steps are performed213214// mini steps performed while in Tuning mode, Testing step215enum class TuneType {216RATE_D_UP = 0, // rate D is being tuned up217RATE_D_DOWN = 1, // rate D is being tuned down218RATE_P_UP = 2, // rate P is being tuned up219RATE_FF_UP = 3, // rate FF is being tuned up220ANGLE_P_DOWN = 4, // angle P is being tuned down221ANGLE_P_UP = 5, // angle P is being tuned up222MAX_GAINS = 6, // max allowable stable gains are determined223TUNE_CHECK = 7, // frequency sweep with tuned gains224TUNE_COMPLETE = 8 // Reached end of tuning225};226TuneType tune_type; // see TuneType227TuneType tune_seq[6]; // holds sequence of tune_types to be performed228uint8_t tune_seq_index; // current tune sequence step229230// get the next tune type231void next_tune_type(TuneType &curr_tune_type, bool reset);232233// Sets customizable tune sequence for the vehicle234virtual void set_tune_sequence() = 0;235236// get_axis_bitmask accessor237virtual uint8_t get_axis_bitmask() const = 0;238239// get_testing_step_timeout_ms accessor240virtual uint32_t get_testing_step_timeout_ms() const = 0;241242// get attitude for slow position hold in autotune mode243void get_poshold_attitude_rad(float &roll_rad, float &pitch_rad, float &yaw_rad);244245// type of gains to load246enum class GainType {247ORIGINAL = 0, // Gains as configured before autotune started248TEST = 1, // Gains applied during an active test249INTRA_TEST = 2, // Gains applied between tests to maintain safe control while returning to level, with slower I-term buildup250TUNED = 3, // Gains discovered by the autotune process, used for flight testing or final use251} loaded_gains;252void load_gains(enum GainType gain_type);253254// TuneMode defines the high-level state of the autotune process.255enum class TuneMode {256UNINITIALISED = 0, // Autotune has not yet been started.257TUNING = 1, // Autotune is actively running and tuning PID gains.258FINISHED = 2, // Tuning is complete, original (pre-tune) gains are restored.259FAILED = 3, // Tuning failed, vehicle is flying with original gains.260VALIDATING = 4, // Tuning complete, user is flight testing the newly tuned gains.261};262TuneMode mode; // see TuneMode for what modes are allowed263264// copies of object pointers to make code a bit clearer265AC_AttitudeControl *attitude_control;266AC_PosControl *pos_control;267AP_AHRS_View *ahrs_view;268AP_Motors *motors;269270AxisType axis; // current axis being tuned. see AxisType enum271bool positive_direction; // false = tuning in negative direction (i.e. left for roll), true = positive direction (i.e. right for roll)272bool angle_step_commanded; // true on first iteration of the tests (used to signal we must step the attitude or rate target)273uint8_t axes_completed; // bitmask of completed axes274uint32_t step_start_time_ms; // start time of current tuning step (used for timeout checks)275uint32_t step_timeout_ms; // time limit of current autotune process276uint32_t level_start_time_ms; // start time of waiting for level277int8_t success_counter; // counter for tuning gains278float start_angle; // start angle279float start_rate; // start rate - parent and multi280float test_accel_max_cdss; // maximum acceleration variable281float step_scaler; // scaler to reduce maximum target step - parent and multi282283LowPassFilterFloat rotation_rate_filt; // filtered rotation rate in radians/second284285// backup of currently being tuned parameter values286float orig_roll_rp, orig_roll_ri, orig_roll_rd, orig_roll_rff, orig_roll_dff, orig_roll_fltt, orig_roll_smax, orig_roll_sp, orig_roll_accel_radss, orig_roll_rate_rads;287float orig_pitch_rp, orig_pitch_ri, orig_pitch_rd, orig_pitch_rff, orig_pitch_dff, orig_pitch_fltt, orig_pitch_smax, orig_pitch_sp, orig_pitch_accel_radss, orig_pitch_rate_rads;288float orig_yaw_rp, orig_yaw_ri, orig_yaw_rd, orig_yaw_rff, orig_yaw_dff, orig_yaw_fltt, orig_yaw_smax, orig_yaw_rLPF, orig_yaw_sp, orig_yaw_accel_radss, orig_yaw_rate_rads;289bool orig_bf_feedforward;290291// currently being tuned parameter values292float tune_roll_rp, tune_roll_rd, tune_roll_sp, tune_roll_accel_radss;293float tune_pitch_rp, tune_pitch_rd, tune_pitch_sp, tune_pitch_accel_radss;294float tune_yaw_rp, tune_yaw_rLPF, tune_yaw_sp, tune_yaw_accel_radss;295float tune_roll_rff, tune_pitch_rff, tune_yaw_rd, tune_yaw_rff;296297uint32_t last_announce_ms;298float lean_angle;299float rotation_rate;300float desired_roll_rad, desired_pitch_rad, desired_yaw_rad; // desired attitude target setpoints and test origins301302// heli specific variables303float start_freq; //start freq for dwell test304float stop_freq; //ending freq for dwell test305306private:307// return true if we have a good position estimate308virtual bool position_ok();309310// methods subclasses must implement to specify max/min test angles:311virtual float target_angle_max_rp_cd() const = 0;312313// methods subclasses must implement to specify max/min test angles:314virtual float target_angle_max_y_cd() const = 0;315316// methods subclasses must implement to specify max/min test angles:317virtual float target_angle_min_rp_cd() const = 0;318319// methods subclasses must implement to specify max/min test angles:320virtual float target_angle_min_y_cd() const = 0;321322// methods subclasses must implement to specify max/min test angles:323virtual float angle_lim_max_rp_cd() const = 0;324325// methods subclasses must implement to specify max/min test angles:326virtual float angle_lim_neg_rpy_cd() const = 0;327328// initialise position controller329bool init_position_controller();330331// Main tuning state machine. Handles WAITING_FOR_LEVEL, EXECUTING_TEST, UPDATE_GAINS, ABORT.332// Updates attitude controller targets and evaluates test responses to tune gains.333void control_attitude();334335// returns true if vehicle is close to level336bool currently_level();337338bool pilot_override; // true = pilot is overriding controls so we suspend tuning temporarily339bool use_poshold; // true = enable position hold340bool have_position; // true = start_position is value341Vector3p start_position_ned_m; // target when holding position as an offset from EKF origin in meters in NED frame342343// variables344uint32_t override_time; // the last time the pilot overrode the controls345346// time in ms of last pilot override warning347uint32_t last_pilot_override_warning;348349// True if we ever got a pilot testing command of tuned gains.350// If true then disarming will save if the tuned gains are currently active.351bool testing_switch_used;352353};354355#endif // AC_AUTOTUNE_ENABLED356357358