mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-01-03 14:38:30 -04:00
770f697cfc
this allows the vehicle code to set the likely flying state, which can be used by EKF to trigger changes which should only happen when flying (such as mag alignment)
673 lines
21 KiB
C++
673 lines
21 KiB
C++
#pragma once
|
|
|
|
/*
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/*
|
|
* AHRS (Attitude Heading Reference System) interface for ArduPilot
|
|
*
|
|
*/
|
|
|
|
#include <AP_Math/AP_Math.h>
|
|
#include <inttypes.h>
|
|
#include <AP_Compass/AP_Compass.h>
|
|
#include <AP_Airspeed/AP_Airspeed.h>
|
|
#include <AP_Beacon/AP_Beacon.h>
|
|
#include <AP_GPS/AP_GPS.h>
|
|
#include <AP_InertialSensor/AP_InertialSensor.h>
|
|
#include <AP_Baro/AP_Baro.h>
|
|
#include <AP_Param/AP_Param.h>
|
|
|
|
class OpticalFlow;
|
|
#define AP_AHRS_TRIM_LIMIT 10.0f // maximum trim angle in degrees
|
|
#define AP_AHRS_RP_P_MIN 0.05f // minimum value for AHRS_RP_P parameter
|
|
#define AP_AHRS_YAW_P_MIN 0.05f // minimum value for AHRS_YAW_P parameter
|
|
|
|
enum AHRS_VehicleClass {
|
|
AHRS_VEHICLE_UNKNOWN,
|
|
AHRS_VEHICLE_GROUND,
|
|
AHRS_VEHICLE_COPTER,
|
|
AHRS_VEHICLE_FIXED_WING,
|
|
AHRS_VEHICLE_SUBMARINE,
|
|
};
|
|
|
|
|
|
// forward declare view class
|
|
class AP_AHRS_View;
|
|
|
|
class AP_AHRS
|
|
{
|
|
public:
|
|
friend class AP_AHRS_View;
|
|
|
|
// Constructor
|
|
AP_AHRS(AP_InertialSensor &ins, AP_Baro &baro, AP_GPS &gps) :
|
|
roll(0.0f),
|
|
pitch(0.0f),
|
|
yaw(0.0f),
|
|
roll_sensor(0),
|
|
pitch_sensor(0),
|
|
yaw_sensor(0),
|
|
_vehicle_class(AHRS_VEHICLE_UNKNOWN),
|
|
_compass(nullptr),
|
|
_optflow(nullptr),
|
|
_airspeed(nullptr),
|
|
_beacon(nullptr),
|
|
_compass_last_update(0),
|
|
_ins(ins),
|
|
_baro(baro),
|
|
_gps(gps),
|
|
_cos_roll(1.0f),
|
|
_cos_pitch(1.0f),
|
|
_cos_yaw(1.0f),
|
|
_sin_roll(0.0f),
|
|
_sin_pitch(0.0f),
|
|
_sin_yaw(0.0f),
|
|
_active_accel_instance(0)
|
|
{
|
|
// load default values from var_info table
|
|
AP_Param::setup_object_defaults(this, var_info);
|
|
|
|
// base the ki values by the sensors maximum drift
|
|
// rate.
|
|
_gyro_drift_limit = ins.get_gyro_drift_rate();
|
|
|
|
// enable centrifugal correction by default
|
|
_flags.correct_centrifugal = true;
|
|
|
|
// initialise _home
|
|
_home.options = 0;
|
|
_home.alt = 0;
|
|
_home.lng = 0;
|
|
_home.lat = 0;
|
|
|
|
_last_trim = _trim.get();
|
|
_rotation_autopilot_body_to_vehicle_body.from_euler(_last_trim.x, _last_trim.y, 0.0f);
|
|
_rotation_vehicle_body_to_autopilot_body = _rotation_autopilot_body_to_vehicle_body.transposed();
|
|
}
|
|
|
|
// empty virtual destructor
|
|
virtual ~AP_AHRS() {}
|
|
|
|
// init sets up INS board orientation
|
|
virtual void init() {
|
|
set_orientation();
|
|
};
|
|
|
|
// Accessors
|
|
void set_fly_forward(bool b) {
|
|
_flags.fly_forward = b;
|
|
}
|
|
|
|
bool get_fly_forward(void) const {
|
|
return _flags.fly_forward;
|
|
}
|
|
|
|
/*
|
|
set the "likely flying" flag. This is not guaranteed to be
|
|
accurate, but is the vehicle codes best guess as to the whether
|
|
the vehicle is currently flying
|
|
*/
|
|
void set_likely_flying(bool b) {
|
|
if (b && !_flags.likely_flying) {
|
|
_last_flying_ms = AP_HAL::millis();
|
|
}
|
|
_flags.likely_flying = b;
|
|
}
|
|
|
|
/*
|
|
get the likely flying status. Returns true if the vehicle code
|
|
thinks we are flying at the moment. Not guaranteed to be
|
|
accurate
|
|
*/
|
|
bool get_likely_flying(void) const {
|
|
return _flags.likely_flying;
|
|
}
|
|
|
|
/*
|
|
return time in milliseconds since likely_flying was set
|
|
true. Returns zero if likely_flying is currently false
|
|
*/
|
|
uint32_t get_time_flying_ms(void) const {
|
|
if (!_flags.likely_flying) {
|
|
return 0;
|
|
}
|
|
return AP_HAL::millis() - _last_flying_ms;
|
|
}
|
|
|
|
AHRS_VehicleClass get_vehicle_class(void) const {
|
|
return _vehicle_class;
|
|
}
|
|
|
|
void set_vehicle_class(AHRS_VehicleClass vclass) {
|
|
_vehicle_class = vclass;
|
|
}
|
|
|
|
void set_wind_estimation(bool b) {
|
|
_flags.wind_estimation = b;
|
|
}
|
|
|
|
void set_compass(Compass *compass) {
|
|
_compass = compass;
|
|
set_orientation();
|
|
}
|
|
|
|
const Compass* get_compass() const {
|
|
return _compass;
|
|
}
|
|
|
|
void set_optflow(const OpticalFlow *optflow) {
|
|
_optflow = optflow;
|
|
}
|
|
|
|
const OpticalFlow* get_optflow() const {
|
|
return _optflow;
|
|
}
|
|
|
|
// allow for runtime change of orientation
|
|
// this makes initial config easier
|
|
void set_orientation() {
|
|
_ins.set_board_orientation((enum Rotation)_board_orientation.get());
|
|
if (_compass != nullptr) {
|
|
_compass->set_board_orientation((enum Rotation)_board_orientation.get());
|
|
}
|
|
}
|
|
|
|
void set_airspeed(AP_Airspeed *airspeed) {
|
|
_airspeed = airspeed;
|
|
}
|
|
|
|
void set_beacon(AP_Beacon *beacon) {
|
|
_beacon = beacon;
|
|
}
|
|
|
|
const AP_Airspeed *get_airspeed(void) const {
|
|
return _airspeed;
|
|
}
|
|
|
|
const AP_Beacon *get_beacon(void) const {
|
|
return _beacon;
|
|
}
|
|
|
|
const AP_GPS &get_gps() const {
|
|
return _gps;
|
|
}
|
|
|
|
const AP_InertialSensor &get_ins() const {
|
|
return _ins;
|
|
}
|
|
|
|
const AP_Baro &get_baro() const {
|
|
return _baro;
|
|
}
|
|
|
|
// get the index of the current primary accelerometer sensor
|
|
virtual uint8_t get_primary_accel_index(void) const {
|
|
return _ins.get_primary_accel();
|
|
}
|
|
|
|
// get the index of the current primary gyro sensor
|
|
virtual uint8_t get_primary_gyro_index(void) const {
|
|
return _ins.get_primary_gyro();
|
|
}
|
|
|
|
// accelerometer values in the earth frame in m/s/s
|
|
virtual const Vector3f &get_accel_ef(uint8_t i) const {
|
|
return _accel_ef[i];
|
|
}
|
|
virtual const Vector3f &get_accel_ef(void) const {
|
|
return get_accel_ef(_ins.get_primary_accel());
|
|
}
|
|
|
|
// blended accelerometer values in the earth frame in m/s/s
|
|
virtual const Vector3f &get_accel_ef_blended(void) const {
|
|
return _accel_ef_blended;
|
|
}
|
|
|
|
// get yaw rate in earth frame in radians/sec
|
|
float get_yaw_rate_earth(void) const {
|
|
return get_gyro() * get_rotation_body_to_ned().c;
|
|
}
|
|
|
|
// Methods
|
|
virtual void update(bool skip_ins_update=false) = 0;
|
|
|
|
// report any reason for why the backend is refusing to initialise
|
|
virtual const char *prearm_failure_reason(void) const {
|
|
return nullptr;
|
|
}
|
|
|
|
// is the EKF backend doing its own sensor logging?
|
|
virtual bool have_ekf_logging(void) const {
|
|
return false;
|
|
}
|
|
|
|
// Euler angles (radians)
|
|
float roll;
|
|
float pitch;
|
|
float yaw;
|
|
|
|
// integer Euler angles (Degrees * 100)
|
|
int32_t roll_sensor;
|
|
int32_t pitch_sensor;
|
|
int32_t yaw_sensor;
|
|
|
|
// return a smoothed and corrected gyro vector
|
|
virtual const Vector3f &get_gyro(void) const = 0;
|
|
|
|
// return a smoothed and corrected gyro vector using the latest ins data (which may not have been consumed by the EKF yet)
|
|
Vector3f get_gyro_latest(void) const;
|
|
|
|
// return the current estimate of the gyro drift
|
|
virtual const Vector3f &get_gyro_drift(void) const = 0;
|
|
|
|
// reset the current gyro drift estimate
|
|
// should be called if gyro offsets are recalculated
|
|
virtual void reset_gyro_drift(void) = 0;
|
|
|
|
// reset the current attitude, used on new IMU calibration
|
|
virtual void reset(bool recover_eulers=false) = 0;
|
|
|
|
// reset the current attitude, used on new IMU calibration
|
|
virtual void reset_attitude(const float &roll, const float &pitch, const float &yaw) = 0;
|
|
|
|
// return the average size of the roll/pitch error estimate
|
|
// since last call
|
|
virtual float get_error_rp(void) const = 0;
|
|
|
|
// return the average size of the yaw error estimate
|
|
// since last call
|
|
virtual float get_error_yaw(void) const = 0;
|
|
|
|
// return a DCM rotation matrix representing our current
|
|
// attitude
|
|
virtual const Matrix3f &get_rotation_body_to_ned(void) const = 0;
|
|
const Matrix3f& get_rotation_autopilot_body_to_vehicle_body(void) const { return _rotation_autopilot_body_to_vehicle_body; }
|
|
const Matrix3f& get_rotation_vehicle_body_to_autopilot_body(void) const { return _rotation_vehicle_body_to_autopilot_body; }
|
|
|
|
// get our current position estimate. Return true if a position is available,
|
|
// otherwise false. This call fills in lat, lng and alt
|
|
virtual bool get_position(struct Location &loc) const = 0;
|
|
|
|
// return a wind estimation vector, in m/s
|
|
virtual Vector3f wind_estimate(void) = 0;
|
|
|
|
// return an airspeed estimate if available. return true
|
|
// if we have an estimate
|
|
virtual bool airspeed_estimate(float *airspeed_ret) const;
|
|
|
|
// return a true airspeed estimate (navigation airspeed) if
|
|
// available. return true if we have an estimate
|
|
bool airspeed_estimate_true(float *airspeed_ret) const {
|
|
if (!airspeed_estimate(airspeed_ret)) {
|
|
return false;
|
|
}
|
|
*airspeed_ret *= get_EAS2TAS();
|
|
return true;
|
|
}
|
|
|
|
// get apparent to true airspeed ratio
|
|
float get_EAS2TAS(void) const {
|
|
if (_airspeed) {
|
|
return _airspeed->get_EAS2TAS();
|
|
}
|
|
return 1.0f;
|
|
}
|
|
|
|
// return true if airspeed comes from an airspeed sensor, as
|
|
// opposed to an IMU estimate
|
|
bool airspeed_sensor_enabled(void) const {
|
|
return _airspeed != nullptr && _airspeed->use() && _airspeed->healthy();
|
|
}
|
|
|
|
// return a ground vector estimate in meters/second, in North/East order
|
|
virtual Vector2f groundspeed_vector(void);
|
|
|
|
// return a ground velocity in meters/second, North/East/Down
|
|
// order. This will only be accurate if have_inertial_nav() is
|
|
// true
|
|
virtual bool get_velocity_NED(Vector3f &vec) const {
|
|
return false;
|
|
}
|
|
|
|
// returns the expected NED magnetic field
|
|
virtual bool get_expected_mag_field_NED(Vector3f &ret) const {
|
|
return false;
|
|
}
|
|
|
|
// returns the estimated magnetic field offsets in body frame
|
|
virtual bool get_mag_field_correction(Vector3f &ret) const {
|
|
return false;
|
|
}
|
|
|
|
// return a position relative to home in meters, North/East/Down
|
|
// order. This will only be accurate if have_inertial_nav() is
|
|
// true
|
|
virtual bool get_relative_position_NED_home(Vector3f &vec) const {
|
|
return false;
|
|
}
|
|
|
|
// return a position relative to origin in meters, North/East/Down
|
|
// order. This will only be accurate if have_inertial_nav() is
|
|
// true
|
|
virtual bool get_relative_position_NED_origin(Vector3f &vec) const {
|
|
return false;
|
|
}
|
|
// return a position relative to home in meters, North/East
|
|
// order. Return true if estimate is valid
|
|
virtual bool get_relative_position_NE_home(Vector2f &vecNE) const {
|
|
return false;
|
|
}
|
|
|
|
// return a position relative to origin in meters, North/East
|
|
// order. Return true if estimate is valid
|
|
virtual bool get_relative_position_NE_origin(Vector2f &vecNE) const {
|
|
return false;
|
|
}
|
|
|
|
// return a Down position relative to home in meters
|
|
// if EKF is unavailable will return the baro altitude
|
|
virtual void get_relative_position_D_home(float &posD) const = 0;
|
|
|
|
// return a Down position relative to origin in meters
|
|
// Return true if estimate is valid
|
|
virtual bool get_relative_position_D_origin(float &posD) const {
|
|
return false;
|
|
}
|
|
|
|
// return ground speed estimate in meters/second. Used by ground vehicles.
|
|
float groundspeed(void) {
|
|
return groundspeed_vector().length();
|
|
}
|
|
|
|
// return true if we will use compass for yaw
|
|
virtual bool use_compass(void) {
|
|
return _compass && _compass->use_for_yaw();
|
|
}
|
|
|
|
// return true if yaw has been initialised
|
|
bool yaw_initialised(void) const {
|
|
return _flags.have_initial_yaw;
|
|
}
|
|
|
|
// set the correct centrifugal flag
|
|
// allows arducopter to disable corrections when disarmed
|
|
void set_correct_centrifugal(bool setting) {
|
|
_flags.correct_centrifugal = setting;
|
|
}
|
|
|
|
// get the correct centrifugal flag
|
|
bool get_correct_centrifugal(void) const {
|
|
return _flags.correct_centrifugal;
|
|
}
|
|
|
|
// get trim
|
|
const Vector3f &get_trim() const {
|
|
return _trim.get();
|
|
}
|
|
|
|
// set trim
|
|
virtual void set_trim(Vector3f new_trim);
|
|
|
|
// add_trim - adjust the roll and pitch trim up to a total of 10 degrees
|
|
virtual void add_trim(float roll_in_radians, float pitch_in_radians, bool save_to_eeprom = true);
|
|
|
|
// helper trig value accessors
|
|
float cos_roll() const {
|
|
return _cos_roll;
|
|
}
|
|
float cos_pitch() const {
|
|
return _cos_pitch;
|
|
}
|
|
float cos_yaw() const {
|
|
return _cos_yaw;
|
|
}
|
|
float sin_roll() const {
|
|
return _sin_roll;
|
|
}
|
|
float sin_pitch() const {
|
|
return _sin_pitch;
|
|
}
|
|
float sin_yaw() const {
|
|
return _sin_yaw;
|
|
}
|
|
|
|
// for holding parameters
|
|
static const struct AP_Param::GroupInfo var_info[];
|
|
|
|
// return secondary attitude solution if available, as eulers in radians
|
|
virtual bool get_secondary_attitude(Vector3f &eulers) {
|
|
return false;
|
|
}
|
|
|
|
// return secondary attitude solution if available, as quaternion
|
|
virtual bool get_secondary_quaternion(Quaternion &quat) {
|
|
return false;
|
|
}
|
|
|
|
// return secondary position solution if available
|
|
virtual bool get_secondary_position(struct Location &loc) {
|
|
return false;
|
|
}
|
|
|
|
// get the home location. This is const to prevent any changes to
|
|
// home without telling AHRS about the change
|
|
const struct Location &get_home(void) const {
|
|
return _home;
|
|
}
|
|
|
|
// set the home location in 10e7 degrees. This should be called
|
|
// when the vehicle is at this position. It is assumed that the
|
|
// current barometer and GPS altitudes correspond to this altitude
|
|
virtual void set_home(const Location &loc) = 0;
|
|
|
|
// set the EKF's origin location in 10e7 degrees. This should only
|
|
// be called when the EKF has no absolute position reference (i.e. GPS)
|
|
// from which to decide the origin on its own
|
|
virtual bool set_origin(const Location &loc) { return false; }
|
|
|
|
// return true if the AHRS object supports inertial navigation,
|
|
// with very accurate position and velocity
|
|
virtual bool have_inertial_nav(void) const {
|
|
return false;
|
|
}
|
|
|
|
// return the active accelerometer instance
|
|
uint8_t get_active_accel_instance(void) const {
|
|
return _active_accel_instance;
|
|
}
|
|
|
|
// is the AHRS subsystem healthy?
|
|
virtual bool healthy(void) const = 0;
|
|
|
|
// true if the AHRS has completed initialisation
|
|
virtual bool initialised(void) const {
|
|
return true;
|
|
};
|
|
|
|
// return the amount of yaw angle change due to the last yaw angle reset in radians
|
|
// returns the time of the last yaw angle reset or 0 if no reset has ever occurred
|
|
virtual uint32_t getLastYawResetAngle(float &yawAng) const {
|
|
return 0;
|
|
};
|
|
|
|
// return the amount of NE position change in metres due to the last reset
|
|
// returns the time of the last reset or 0 if no reset has ever occurred
|
|
virtual uint32_t getLastPosNorthEastReset(Vector2f &pos) const {
|
|
return 0;
|
|
};
|
|
|
|
// return the amount of NE velocity change in metres/sec due to the last reset
|
|
// returns the time of the last reset or 0 if no reset has ever occurred
|
|
virtual uint32_t getLastVelNorthEastReset(Vector2f &vel) const {
|
|
return 0;
|
|
};
|
|
|
|
// return the amount of vertical position change due to the last reset in meters
|
|
// returns the time of the last reset or 0 if no reset has ever occurred
|
|
virtual uint32_t getLastPosDownReset(float &posDelta) const {
|
|
return 0;
|
|
};
|
|
|
|
// Resets the baro so that it reads zero at the current height
|
|
// Resets the EKF height to zero
|
|
// Adjusts the EKf origin height so that the EKF height + origin height is the same as before
|
|
// Returns true if the height datum reset has been performed
|
|
// If using a range finder for height no reset is performed and it returns false
|
|
virtual bool resetHeightDatum(void) {
|
|
return false;
|
|
}
|
|
|
|
// get_variances - provides the innovations normalised using the innovation variance where a value of 0
|
|
// indicates prefect consistency between the measurement and the EKF solution and a value of of 1 is the maximum
|
|
// inconsistency that will be accpeted by the filter
|
|
// boolean false is returned if variances are not available
|
|
virtual bool get_variances(float &velVar, float &posVar, float &hgtVar, Vector3f &magVar, float &tasVar, Vector2f &offset) const {
|
|
return false;
|
|
}
|
|
|
|
// time that the AHRS has been up
|
|
virtual uint32_t uptime_ms(void) const = 0;
|
|
|
|
// get the selected ekf type, for allocation decisions
|
|
int8_t get_ekf_type(void) const {
|
|
return _ekf_type;
|
|
}
|
|
|
|
// Retrieves the corrected NED delta velocity in use by the inertial navigation
|
|
virtual void getCorrectedDeltaVelocityNED(Vector3f& ret, float& dt) const { ret.zero(); _ins.get_delta_velocity(ret); dt = _ins.get_delta_velocity_dt(); }
|
|
|
|
// create a view
|
|
AP_AHRS_View *create_view(enum Rotation rotation);
|
|
|
|
// return calculated AOA
|
|
float getAOA(void);
|
|
|
|
// return calculated SSA
|
|
float getSSA(void);
|
|
|
|
virtual void update_AOA_SSA(void);
|
|
|
|
protected:
|
|
AHRS_VehicleClass _vehicle_class;
|
|
|
|
// settable parameters
|
|
// these are public for ArduCopter
|
|
AP_Float _kp_yaw;
|
|
AP_Float _kp;
|
|
AP_Float gps_gain;
|
|
|
|
AP_Float beta;
|
|
AP_Int8 _gps_use;
|
|
AP_Int8 _wind_max;
|
|
AP_Int8 _board_orientation;
|
|
AP_Int8 _gps_minsats;
|
|
AP_Int8 _gps_delay;
|
|
AP_Int8 _ekf_type;
|
|
|
|
// flags structure
|
|
struct ahrs_flags {
|
|
uint8_t have_initial_yaw : 1; // whether the yaw value has been intialised with a reference
|
|
uint8_t fly_forward : 1; // 1 if we can assume the aircraft will be flying forward on its X axis
|
|
uint8_t correct_centrifugal : 1; // 1 if we should correct for centrifugal forces (allows arducopter to turn this off when motors are disarmed)
|
|
uint8_t wind_estimation : 1; // 1 if we should do wind estimation
|
|
uint8_t likely_flying : 1; // 1 if vehicle is probably flying
|
|
} _flags;
|
|
|
|
// time when likely_flying last went true
|
|
uint32_t _last_flying_ms;
|
|
|
|
// calculate sin/cos of roll/pitch/yaw from rotation
|
|
void calc_trig(const Matrix3f &rot,
|
|
float &cr, float &cp, float &cy,
|
|
float &sr, float &sp, float &sy) const;
|
|
|
|
// update_trig - recalculates _cos_roll, _cos_pitch, etc based on latest attitude
|
|
// should be called after _dcm_matrix is updated
|
|
void update_trig(void);
|
|
|
|
// update roll_sensor, pitch_sensor and yaw_sensor
|
|
void update_cd_values(void);
|
|
|
|
// pointer to compass object, if available
|
|
Compass * _compass;
|
|
|
|
// pointer to OpticalFlow object, if available
|
|
const OpticalFlow *_optflow;
|
|
|
|
// pointer to airspeed object, if available
|
|
AP_Airspeed * _airspeed;
|
|
|
|
// pointer to beacon object, if available
|
|
AP_Beacon * _beacon;
|
|
|
|
// time in microseconds of last compass update
|
|
uint32_t _compass_last_update;
|
|
|
|
// note: we use ref-to-pointer here so that our caller can change the GPS without our noticing
|
|
// IMU under us without our noticing.
|
|
AP_InertialSensor &_ins;
|
|
AP_Baro &_baro;
|
|
const AP_GPS &_gps;
|
|
|
|
// a vector to capture the difference between the controller and body frames
|
|
AP_Vector3f _trim;
|
|
|
|
// cached trim rotations
|
|
Vector3f _last_trim;
|
|
Matrix3f _rotation_autopilot_body_to_vehicle_body;
|
|
Matrix3f _rotation_vehicle_body_to_autopilot_body;
|
|
|
|
// the limit of the gyro drift claimed by the sensors, in
|
|
// radians/s/s
|
|
float _gyro_drift_limit;
|
|
|
|
// accelerometer values in the earth frame in m/s/s
|
|
Vector3f _accel_ef[INS_MAX_INSTANCES];
|
|
Vector3f _accel_ef_blended;
|
|
|
|
// Declare filter states for HPF and LPF used by complementary
|
|
// filter in AP_AHRS::groundspeed_vector
|
|
Vector2f _lp; // ground vector low-pass filter
|
|
Vector2f _hp; // ground vector high-pass filter
|
|
Vector2f _lastGndVelADS; // previous HPF input
|
|
|
|
// reference position for NED positions
|
|
struct Location _home;
|
|
|
|
// helper trig variables
|
|
float _cos_roll, _cos_pitch, _cos_yaw;
|
|
float _sin_roll, _sin_pitch, _sin_yaw;
|
|
|
|
// which accelerometer instance is active
|
|
uint8_t _active_accel_instance;
|
|
|
|
// optional view class
|
|
AP_AHRS_View *_view;
|
|
|
|
// AOA and SSA
|
|
float _AOA, _SSA;
|
|
uint32_t _last_AOA_update_ms;
|
|
};
|
|
|
|
#include "AP_AHRS_DCM.h"
|
|
#include "AP_AHRS_NavEKF.h"
|
|
|
|
#if AP_AHRS_NAVEKF_AVAILABLE
|
|
#define AP_AHRS_TYPE AP_AHRS_NavEKF
|
|
#else
|
|
#define AP_AHRS_TYPE AP_AHRS
|
|
#endif
|