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_DCM.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* DCM based AHRS (Attitude Heading Reference System) interface for19* ArduPilot20*21*/2223#include "AP_AHRS_config.h"2425#if AP_AHRS_DCM_ENABLED2627#include "AP_AHRS_Backend.h"2829class AP_AHRS_DCM : public AP_AHRS_Backend {30public:3132AP_AHRS_DCM(AP_Float &kp_yaw,33AP_Float &kp,34AP_Float &_gps_gain,35AP_Float &_beta,36AP_Enum<GPSUse> &gps_use,37AP_Int8 &gps_minsats)38: AP_AHRS_Backend(),39_kp_yaw(kp_yaw),40_kp(kp),41gps_gain(_gps_gain),42beta(_beta),43_gps_minsats(gps_minsats),44_gps_use(gps_use)45{46_dcm_matrix.identity();47}4849/* Do not allow copies */50CLASS_NO_COPY(AP_AHRS_DCM);5152// reset the current gyro drift estimate53// should be called if gyro offsets are recalculated54void reset_gyro_drift() override;5556// Methods57void update() override;58void get_results(Estimates &results) override;59void reset() override { reset(false); }6061// return true if yaw has been initialised62bool yaw_initialised(void) const {63return have_initial_yaw;64}6566// status reporting67float get_error_rp() const {68return _error_rp;69}70float get_error_yaw() const {71return _error_yaw;72}7374// return a wind estimation vector, in m/s75bool wind_estimate(Vector3f &wind) const override {76wind = _wind;77return true;78}7980void set_external_wind_estimate(float speed, float direction);8182// return an airspeed estimate if available. return true83// if we have an estimate84bool airspeed_EAS(float &airspeed_ret) const override;8586// return an airspeed estimate if available. return true87// if we have an estimate from a specific sensor index88bool airspeed_EAS(uint8_t airspeed_index, float &airspeed_ret) const override;8990// return a synthetic EAS estimate (one derived from sensors91// other than an actual airspeed sensor), if available. return92// true if we have a synthetic airspeed. ret will not be modified93// on failure.94bool synthetic_airspeed_EAS(float &ret) const WARN_IF_UNUSED {95ret = _last_airspeed_TAS;96return true;97}9899// return a ground vector estimate in meters/second, in North/East order100Vector2f groundspeed_vector() override;101102bool use_compass() override;103104// return the quaternion defining the rotation from NED to XYZ (body) axes105bool get_quaternion(Quaternion &quat) const override WARN_IF_UNUSED;106107void estimate_wind(void);108109// is the AHRS subsystem healthy?110bool healthy() const override;111112bool get_velocity_NED(Vector3f &vec) const override;113114// Get a derivative of the vertical position in m/s which is kinematically consistent with the vertical position is required by some control loops.115// 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.116bool get_vert_pos_rate_D(float &velocity) const override;117118// returns false if we fail arming checks, in which case the buffer will be populated with a failure message119// requires_position should be true if horizontal position configuration should be checked (not used)120bool pre_arm_check(bool requires_position, char *failure_msg, uint8_t failure_msg_len) const override;121122// relative-origin functions for fallback in AP_InertialNav123bool get_origin(Location &ret) const override;124bool get_relative_position_NED_origin(Vector3f &vec) const override;125bool get_relative_position_NE_origin(Vector2f &posNE) const override;126bool get_relative_position_D_origin(float &posD) const override;127128void send_ekf_status_report(class GCS_MAVLINK &link) const override;129130// return true if DCM has a yaw source131bool yaw_source_available(void) const;132133void get_control_limits(float &ekfGndSpdLimit, float &controlScaleXY) const override;134135private:136137// dead-reckoning support138bool get_location(Location &loc) const;139140// settable parameters141AP_Float &_kp_yaw;142AP_Float &_kp;143AP_Float &gps_gain;144145AP_Float β146147AP_Int8 &_gps_minsats;148149AP_Enum<GPSUse> &_gps_use;150151// these are experimentally derived from the simulator152// with large drift levels153static constexpr float _ki = 0.0087f;154static constexpr float _ki_yaw = 0.01f;155156// accelerometer values in the earth frame in m/s/s157Vector3f _accel_ef;158159// Methods160void matrix_update(void);161void normalize(void);162void check_matrix(void);163bool renorm(Vector3f const &a, Vector3f &result);164void drift_correction(float deltat);165void drift_correction_yaw(void);166float yaw_error_compass(class Compass &compass);167bool have_gps(void) const;168bool use_fast_gains(void) const;169void backup_attitude(void);170171// internal reset function. Called externally, we never reset the172// DCM matrix from the eulers. Called internally we may.173void reset(bool recover_eulers);174175// airspeed_ret: will always be filled-in by get_unconstrained_airspeed_EAS which fills in airspeed_ret in this order:176// airspeed as filled-in by an enabled airspeed sensor177// if no airspeed sensor: airspeed estimated using the GPS speed & wind_speed_estimation178// Or if none of the above, fills-in using the previous airspeed estimate179// Return false: if we are using the previous airspeed estimate180bool get_unconstrained_airspeed_EAS(uint8_t airspeed_index, float &airspeed_ret) const;181182// primary representation of attitude of board used for all inertial calculations183Matrix3f _dcm_matrix;184185// primary representation of attitude of flight vehicle body186Matrix3f _body_dcm_matrix;187188// euler angles - used for recovering if the DCM189// matrix becomes ill-conditioned and watchdog storage190float roll;191float pitch;192float yaw;193194Vector3f _omega_P; // accel Omega proportional correction195Vector3f _omega_yaw_P; // proportional yaw correction196Vector3f _omega_I; // Omega Integrator correction197Vector3f _omega_I_sum;198float _omega_I_sum_time;199Vector3f _omega; // Corrected Gyro_Vector data200201bool have_initial_yaw; // true if the yaw value has been initialised with a reference202203// variables to cope with delaying the GA sum to match GPS lag204Vector3f ra_delayed(uint8_t instance, const Vector3f &ra);205Vector3f _ra_delay_buffer[INS_MAX_INSTANCES];206207// P term gain based on spin rate208float _P_gain(float spin_rate);209210// P term yaw gain based on rate of change of horiz velocity211float _yaw_gain(void) const;212213/* returns true if attitude should be corrected from GPS-derived214* velocity-deltas. We turn this off for Copter and other similar215* vehicles while the vehicle is disarmed to avoid the HUD bobbing216* around while the vehicle is disarmed.217*/218bool should_correct_centrifugal() const;219220// state to support status reporting221float _renorm_val_sum;222uint16_t _renorm_val_count;223float _error_rp{1.0f};224float _error_yaw{1.0f};225226// time in microseconds of last compass update227uint32_t _compass_last_update;228229// time in millis when we last got a GPS heading230uint32_t _gps_last_update;231232// state of accel drift correction233Vector3f _ra_sum[INS_MAX_INSTANCES];234Vector3f _last_velocity;235float _ra_deltat;236uint32_t _ra_sum_start;237238// which accelerometer instance is active239uint8_t _active_accel_instance;240241// the earths magnetic field242float _last_declination;243Vector2f _mag_earth{1, 0};244245// whether we have GPS lock246bool _have_gps_lock;247248// the lat/lng where we last had GPS lock249int32_t _last_lat;250int32_t _last_lng;251uint32_t _last_pos_ms;252253// position offset from last GPS lock254float _position_offset_north;255float _position_offset_east;256257// whether we have a position estimate258bool _have_position;259260// support for wind estimation261Vector3f _last_fuse;262Vector3f _last_vel;263uint32_t _last_wind_time;264float _last_airspeed_TAS;265uint32_t _last_consistent_heading;266267// estimated wind in m/s268Vector3f _wind;269270// last time AHRS failed in milliseconds271uint32_t _last_failure_ms;272273// time when DCM was last reset274uint32_t _last_startup_ms;275276// last origin we returned, for DCM fallback from EKF277Location last_origin;278279// Declare filter states for HPF and LPF used by complementary280// filter in AP_AHRS::groundspeed_vector281Vector2f _lp; // ground vector low-pass filter282Vector2f _hp; // ground vector high-pass filter283Vector2f _lastGndVelADS; // previous HPF input284285// pre-calculated trig cache:286float _sin_yaw;287float _cos_yaw;288289uint32_t last_log_ms;290};291292#endif // AP_AHRS_DCM_ENABLED293294295