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/AP_AHRS/AP_AHRS_Backend.h
Views: 1798
#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 {53float roll_rad;54float pitch_rad;55float yaw_rad;56Matrix3f dcm_matrix;57Vector3f gyro_estimate;58Vector3f gyro_drift;59Vector3f accel_ef;60Vector3f accel_bias;6162Location location;63bool location_valid;6465bool get_location(Location &loc) const {66loc = location;67return location_valid;68};69};7071// init sets up INS board orientation72virtual void init();7374// get the index of the current primary gyro sensor75virtual uint8_t get_primary_gyro_index(void) const {76#if AP_INERTIALSENSOR_ENABLED77return AP::ins().get_first_usable_gyro();78#else79return 0;80#endif81}8283// Methods84virtual void update() = 0;8586virtual void get_results(Estimates &results) = 0;8788// returns false if we fail arming checks, in which case the buffer will be populated with a failure message89// requires_position should be true if horizontal position configuration should be checked90virtual bool pre_arm_check(bool requires_position, char *failure_msg, uint8_t failure_msg_len) const = 0;9192// check all cores providing consistent attitudes for prearm checks93virtual bool attitudes_consistent(char *failure_msg, const uint8_t failure_msg_len) const { return true; }9495// see if EKF lane switching is possible to avoid EKF failsafe96virtual void check_lane_switch(void) {}9798// check if non-compass sensor is providing yaw. Allows compass pre-arm checks to be bypassed99virtual bool using_noncompass_for_yaw(void) const { return false; }100101// check if external nav is providing yaw102virtual bool using_extnav_for_yaw(void) const { return false; }103104// request EKF yaw reset to try and avoid the need for an EKF lane switch or failsafe105virtual void request_yaw_reset(void) {}106107// set position, velocity and yaw sources to either 0=primary, 1=secondary, 2=tertiary108virtual void set_posvelyaw_source_set(AP_NavEKF_Source::SourceSetSelection source_set_idx) {}109110// reset the current gyro drift estimate111// should be called if gyro offsets are recalculated112virtual void reset_gyro_drift(void) = 0;113114// reset the current attitude, used on new IMU calibration115virtual void reset() = 0;116117// get latest altitude estimate above ground level in meters and validity flag118virtual bool get_hagl(float &height) const WARN_IF_UNUSED { return false; }119120// return a wind estimation vector, in m/s121virtual bool wind_estimate(Vector3f &wind) const = 0;122123// return an airspeed estimate if available. return true124// if we have an estimate125virtual bool airspeed_EAS(float &airspeed_ret) const WARN_IF_UNUSED { return false; }126virtual bool airspeed_EAS(uint8_t airspeed_index, float &airspeed_ret) const { return false; }127128// return a true airspeed estimate (navigation airspeed) if129// available. return true if we have an estimate130bool airspeed_TAS(float &airspeed_ret) const WARN_IF_UNUSED {131if (!airspeed_EAS(airspeed_ret)) {132return false;133}134airspeed_ret *= get_EAS2TAS();135return true;136}137138// get apparent to true airspeed ratio139static float get_EAS2TAS(void);140static float get_TAS2EAS(void) { return 1.0/get_EAS2TAS(); }141142// return true if airspeed comes from an airspeed sensor, as143// opposed to an IMU estimate144static bool airspeed_sensor_enabled(void) {145#if AP_AIRSPEED_ENABLED146const AP_Airspeed *_airspeed = AP::airspeed();147return _airspeed != nullptr && _airspeed->use() && _airspeed->healthy();148#else149return false;150#endif151}152153// return true if airspeed comes from a specific airspeed sensor, as154// opposed to an IMU estimate155static bool airspeed_sensor_enabled(uint8_t airspeed_index) {156#if AP_AIRSPEED_ENABLED157const AP_Airspeed *_airspeed = AP::airspeed();158return _airspeed != nullptr && _airspeed->use(airspeed_index) && _airspeed->healthy(airspeed_index);159#else160return false;161#endif162}163164// return a ground vector estimate in meters/second, in North/East order165virtual Vector2f groundspeed_vector(void) = 0;166167// return a ground velocity in meters/second, North/East/Down168// order. This will only be accurate if have_inertial_nav() is169// true170virtual bool get_velocity_NED(Vector3f &vec) const WARN_IF_UNUSED {171return false;172}173174// Get a derivative of the vertical position in m/s which is kinematically consistent with the vertical position is required by some control loops.175// This is different to the vertical velocity from the EKF which is not always consistent with the vertical position due to the various errors that are being corrected for.176virtual bool get_vert_pos_rate_D(float &velocity) const = 0;177178//179virtual bool set_origin(const Location &loc) {180return false;181}182virtual bool get_origin(Location &ret) const = 0;183184// return a position relative to origin in meters, North/East/Down185// order. This will only be accurate if have_inertial_nav() is186// true187virtual bool get_relative_position_NED_origin(Vector3f &vec) const WARN_IF_UNUSED {188return false;189}190191// return a position relative to origin in meters, North/East192// order. Return true if estimate is valid193virtual bool get_relative_position_NE_origin(Vector2f &vecNE) const WARN_IF_UNUSED {194return false;195}196197// return a Down position relative to origin in meters198// Return true if estimate is valid199virtual bool get_relative_position_D_origin(float &posD) const WARN_IF_UNUSED {200return false;201}202203// return ground speed estimate in meters/second. Used by ground vehicles.204float groundspeed(void) {205return groundspeed_vector().length();206}207208// return true if we will use compass for yaw209virtual bool use_compass(void) = 0;210211// return the quaternion defining the rotation from NED to XYZ (body) axes212virtual bool get_quaternion(Quaternion &quat) const WARN_IF_UNUSED = 0;213214// is the AHRS subsystem healthy?215virtual bool healthy(void) const = 0;216217// true if the AHRS has completed initialisation218virtual bool initialised(void) const {219return true;220};221virtual bool started(void) const {222return initialised();223};224225// return the amount of yaw angle change due to the last yaw angle reset in radians226// returns the time of the last yaw angle reset or 0 if no reset has ever occurred227virtual uint32_t getLastYawResetAngle(float &yawAng) {228return 0;229};230231// return the amount of NE position change in metres due to the last reset232// returns the time of the last reset or 0 if no reset has ever occurred233virtual uint32_t getLastPosNorthEastReset(Vector2f &pos) WARN_IF_UNUSED {234return 0;235};236237// return the amount of NE velocity change in metres/sec due to the last reset238// returns the time of the last reset or 0 if no reset has ever occurred239virtual uint32_t getLastVelNorthEastReset(Vector2f &vel) const WARN_IF_UNUSED {240return 0;241};242243// return the amount of vertical position change due to the last reset in meters244// returns the time of the last reset or 0 if no reset has ever occurred245virtual uint32_t getLastPosDownReset(float &posDelta) WARN_IF_UNUSED {246return 0;247};248249// Resets the baro so that it reads zero at the current height250// Resets the EKF height to zero251// Adjusts the EKf origin height so that the EKF height + origin height is the same as before252// Returns true if the height datum reset has been performed253// If using a range finder for height no reset is performed and it returns false254virtual bool resetHeightDatum(void) WARN_IF_UNUSED {255return false;256}257258// return the innovations for the specified instance259// An out of range instance (eg -1) returns data for the primary instance260virtual bool get_innovations(Vector3f &velInnov, Vector3f &posInnov, Vector3f &magInnov, float &tasInnov, float &yawInnov) const {261return false;262}263264virtual bool get_filter_status(union nav_filter_status &status) const {265return false;266}267268// get_variances - provides the innovations normalised using the innovation variance where a value of 0269// indicates perfect consistency between the measurement and the EKF solution and a value of 1 is the maximum270// inconsistency that will be accepted by the filter271// boolean false is returned if variances are not available272virtual bool get_variances(float &velVar, float &posVar, float &hgtVar, Vector3f &magVar, float &tasVar) const {273return false;274}275276// get a source's velocity innovations. source should be from 0 to 7 (see AP_NavEKF_Source::SourceXY)277// returns true on success and results are placed in innovations and variances arguments278virtual bool get_vel_innovations_and_variances_for_source(uint8_t source, Vector3f &innovations, Vector3f &variances) const WARN_IF_UNUSED {279return false;280}281282virtual void send_ekf_status_report(class GCS_MAVLINK &link) const = 0;283284// get_hgt_ctrl_limit - get maximum height to be observed by the285// control loops in meters and a validity flag. It will return286// false when no limiting is required287virtual bool get_hgt_ctrl_limit(float &limit) const WARN_IF_UNUSED { return false; };288289// Set to true if the terrain underneath is stable enough to be used as a height reference290// this is not related to terrain following291virtual void set_terrain_hgt_stable(bool stable) {}292293virtual void get_control_limits(float &ekfGndSpdLimit, float &controlScaleXY) const = 0;294};295296297