Path: blob/master/libraries/AP_AHRS/AP_AHRS_Backend.h
9742 views
#pragma once12/*3This program is free software: you can redistribute it and/or modify4it under the terms of the GNU General Public License as published by5the Free Software Foundation, either version 3 of the License, or6(at your option) any later version.78This program is distributed in the hope that it will be useful,9but WITHOUT ANY WARRANTY; without even the implied warranty of10MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the11GNU General Public License for more details.1213You should have received a copy of the GNU General Public License14along with this program. If not, see <http://www.gnu.org/licenses/>.15*/1617/*18* AHRS (Attitude Heading Reference System) interface for ArduPilot19*20*/2122#include <AP_Math/AP_Math.h>23#include <inttypes.h>24#include <AP_Airspeed/AP_Airspeed.h>25#include <AP_InertialSensor/AP_InertialSensor.h>26#include <AP_Common/Location.h>27#include <AP_NavEKF/AP_NavEKF_Source.h>2829#define AP_AHRS_TRIM_LIMIT 10.0f // maximum trim angle in degrees30#define AP_AHRS_RP_P_MIN 0.05f // minimum value for AHRS_RP_P parameter31#define AP_AHRS_YAW_P_MIN 0.05f // minimum value for AHRS_YAW_P parameter3233enum class GPSUse : uint8_t {34Disable = 0,35Enable = 1,36EnableWithHeight = 2,37};3839class AP_AHRS_Backend40{41public:4243// Constructor44AP_AHRS_Backend() {}4546// empty virtual destructor47virtual ~AP_AHRS_Backend() {}4849CLASS_NO_COPY(AP_AHRS_Backend);5051// structure to retrieve results from backends:52struct Estimates {53// if attitude_valid is true then all of the54// eulers/quaternion/matrix must be valid:55bool attitude_valid;56float roll_rad;57float pitch_rad;58float yaw_rad;59Matrix3f dcm_matrix;60Quaternion quaternion;6162Vector3f gyro_estimate;63Vector3f gyro_drift;64Vector3f accel_ef;65Vector3f accel_bias;6667// a ground velocity in meters/second, North/East/Down68Vector3f velocity_NED;69bool velocity_NED_valid;70// return a ground velocity in meters/second, North/East/Down71bool get_velocity_NED(Vector3f &vel) const WARN_IF_UNUSED {72if (!velocity_NED_valid) {73return false;74}75vel = velocity_NED;76return true;77};7879// a derivative of the vertical position in m/s which is80// kinematically consistent with the vertical position is81// required by some control loops.82// This is different to the vertical velocity from the EKF83// which is not always consistent with the vertical position84// due to the various errors that are being corrected for.85float vert_pos_rate_D;86bool vert_pos_rate_D_valid;87// Get a derivative of the vertical position in m/s which is88// kinematically consistent with the vertical position is89// required by some control loops.90// This is different to the vertical velocity from the EKF91// which is not always consistent with the vertical position92// due to the various errors that are being corrected for.93bool get_vert_pos_rate_D(float &velocity) const {94if (!vert_pos_rate_D_valid) {95return false;96}97velocity = vert_pos_rate_D;98return true;99}100101Location location;102bool location_valid;103104bool get_location(Location &loc) const {105loc = location;106return location_valid;107};108};109110// init sets up INS board orientation111virtual void init();112113// get the index of the current primary gyro sensor114virtual uint8_t get_primary_gyro_index(void) const {115#if AP_INERTIALSENSOR_ENABLED116return AP::ins().get_first_usable_gyro();117#else118return 0;119#endif120}121122// Methods123virtual void update() = 0;124125virtual void get_results(Estimates &results) = 0;126127// returns false if we fail arming checks, in which case the buffer will be populated with a failure message128// requires_position should be true if horizontal position configuration should be checked129virtual bool pre_arm_check(bool requires_position, char *failure_msg, uint8_t failure_msg_len) const = 0;130131// see if EKF lane switching is possible to avoid EKF failsafe132virtual void check_lane_switch(void) {}133134// request EKF yaw reset to try and avoid the need for an EKF lane switch or failsafe135virtual void request_yaw_reset(void) {}136137// set position, velocity and yaw sources to either 0=primary, 1=secondary, 2=tertiary138virtual void set_posvelyaw_source_set(AP_NavEKF_Source::SourceSetSelection source_set_idx) {}139140// reset the current gyro drift estimate141// should be called if gyro offsets are recalculated142virtual void reset_gyro_drift(void) = 0;143144// reset the current attitude, used on new IMU calibration145virtual void reset() = 0;146147// get latest altitude estimate above ground level in meters and validity flag148virtual bool get_hagl(float &height) const WARN_IF_UNUSED { return false; }149150// return a wind estimation vector, in m/s151virtual bool wind_estimate(Vector3f &wind) const = 0;152153// return an airspeed estimate if available. return true154// if we have an estimate155virtual bool airspeed_EAS(float &airspeed_ret) const WARN_IF_UNUSED { return false; }156virtual bool airspeed_EAS(uint8_t airspeed_index, float &airspeed_ret) const { return false; }157158// return a true airspeed estimate (navigation airspeed) if159// available. return true if we have an estimate160bool airspeed_TAS(float &airspeed_ret) const WARN_IF_UNUSED {161if (!airspeed_EAS(airspeed_ret)) {162return false;163}164airspeed_ret *= get_EAS2TAS();165return true;166}167168// get apparent to true airspeed ratio169static float get_EAS2TAS(void);170static float get_TAS2EAS(void) { return 1.0/get_EAS2TAS(); }171172// return true if airspeed comes from an airspeed sensor, as173// opposed to an IMU estimate174static bool airspeed_sensor_enabled(void) {175#if AP_AIRSPEED_ENABLED176const AP_Airspeed *_airspeed = AP::airspeed();177return _airspeed != nullptr && _airspeed->use() && _airspeed->healthy();178#else179return false;180#endif181}182183// return true if airspeed comes from a specific airspeed sensor, as184// opposed to an IMU estimate185static bool airspeed_sensor_enabled(uint8_t airspeed_index) {186#if AP_AIRSPEED_ENABLED187const AP_Airspeed *_airspeed = AP::airspeed();188return _airspeed != nullptr && _airspeed->use(airspeed_index) && _airspeed->healthy(airspeed_index);189#else190return false;191#endif192}193194// return a ground vector estimate in meters/second, in North/East order195virtual Vector2f groundspeed_vector(void) = 0;196197virtual bool set_origin(const Location &loc) {198return false;199}200virtual bool get_origin(Location &ret) const = 0;201202// return a position relative to origin in meters, North/East/Down203// order. This will only be accurate if have_inertial_nav() is204// true205virtual bool get_relative_position_NED_origin(Vector3p &vec) const WARN_IF_UNUSED {206return false;207}208209// return a position relative to origin in meters, North/East210// order. Return true if estimate is valid211virtual bool get_relative_position_NE_origin(Vector2p &vecNE) const WARN_IF_UNUSED {212return false;213}214215// return a Down position relative to origin in meters216// Return true if estimate is valid217virtual bool get_relative_position_D_origin(postype_t &posD) const WARN_IF_UNUSED {218return false;219}220221// return true if we will use compass for yaw222virtual bool use_compass(void) = 0;223224// is the AHRS subsystem healthy?225virtual bool healthy(void) const = 0;226227// true if the AHRS has completed initialisation228virtual bool initialised(void) const {229return true;230};231virtual bool started(void) const {232return initialised();233};234235// return the amount of yaw angle change due to the last yaw angle reset in radians236// returns the time of the last yaw angle reset or 0 if no reset has ever occurred237virtual uint32_t getLastYawResetAngle(float &yawAng) {238return 0;239};240241// return the amount of NE position change in metres due to the last reset242// returns the time of the last reset or 0 if no reset has ever occurred243virtual uint32_t getLastPosNorthEastReset(Vector2f &pos) WARN_IF_UNUSED {244return 0;245};246247// return the amount of NE velocity change in metres/sec due to the last reset248// returns the time of the last reset or 0 if no reset has ever occurred249virtual uint32_t getLastVelNorthEastReset(Vector2f &vel) const WARN_IF_UNUSED {250return 0;251};252253// return the amount of vertical position change due to the last reset in meters254// returns the time of the last reset or 0 if no reset has ever occurred255virtual uint32_t getLastPosDownReset(float &posDelta) WARN_IF_UNUSED {256return 0;257};258259// Resets the baro so that it reads zero at the current height260// Resets the EKF height to zero261// Adjusts the EKf origin height so that the EKF height + origin height is the same as before262virtual void resetHeightDatum(void) { }263264// return the innovations for the specified instance265// An out of range instance (eg -1) returns data for the primary instance266virtual bool get_innovations(Vector3f &velInnov, Vector3f &posInnov, Vector3f &magInnov, float &tasInnov, float &yawInnov) const {267return false;268}269270virtual bool get_filter_status(union nav_filter_status &status) const {271return false;272}273274// get_variances - provides the innovations normalised using the innovation variance where a value of 0275// indicates perfect consistency between the measurement and the EKF solution and a value of 1 is the maximum276// inconsistency that will be accepted by the filter277// boolean false is returned if variances are not available278virtual bool get_variances(float &velVar, float &posVar, float &hgtVar, Vector3f &magVar, float &tasVar) const {279return false;280}281282virtual void send_ekf_status_report(class GCS_MAVLINK &link) const = 0;283284// Set to true if the terrain underneath is stable enough to be used as a height reference285// this is not related to terrain following286virtual void set_terrain_hgt_stable(bool stable) {}287288virtual void get_control_limits(float &ekfGndSpdLimit, float &controlScaleXY) const = 0;289};290291292