LCOV - code coverage report
Current view: top level - AP_NavEKF3 - AP_NavEKF3.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 5 7 71.4 %
Date: 2026-09-09 11:02:08 Functions: 3 5 60.0 %

          Line data    Source code
       1             : /*
       2             :   24 state EKF based on the derivation in https://github.com/PX4/ecl/
       3             :   blob/master/matlab/scripts/Inertial%20Nav%20EKF/GenerateNavFilterEquations.m
       4             : 
       5             :   Converted from Matlab to C++ by Paul Riseborough
       6             : 
       7             :   This program is free software: you can redistribute it and/or modify
       8             :   it under the terms of the GNU General Public License as published by
       9             :   the Free Software Foundation, either version 3 of the License, or
      10             :   (at your option) any later version.
      11             : 
      12             :   This program is distributed in the hope that it will be useful,
      13             :   but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :   GNU General Public License for more details.
      16             : 
      17             :   You should have received a copy of the GNU General Public License
      18             :   along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             :  */
      20             : #pragma once
      21             : 
      22             : #include <AP_Common/Location.h>
      23             : #include <AP_Math/AP_Math.h>
      24             : #include <AP_Param/AP_Param.h>
      25             : #include <AP_NavEKF/AP_Nav_Common.h>
      26             : #include <AP_NavEKF/AP_NavEKF_Source.h>
      27             : 
      28             : class NavEKF3_core;
      29             : class EKFGSF_yaw;
      30             : 
      31             : class NavEKF3 {
      32             :     friend class NavEKF3_core;
      33             : 
      34             : public:
      35             :     NavEKF3();
      36             : 
      37             :     /* Do not allow copies */
      38             :     CLASS_NO_COPY(NavEKF3);
      39             : 
      40             :     static const struct AP_Param::GroupInfo var_info[];
      41             :     static const struct AP_Param::GroupInfo var_info2[];
      42             : 
      43             :     // allow logging to determine the number of active cores
      44     9752004 :     uint8_t activeCores(void) const {
      45     9752004 :         return num_cores;
      46             :     }
      47             : 
      48             :     // Initialise the filter
      49             :     bool InitialiseFilter(void);
      50             : 
      51             :     // Update Filter States - this should be called whenever new IMU data is available
      52             :     void UpdateFilter(void);
      53             : 
      54             :     // Check basic filter health metrics and return a consolidated health status
      55             :     bool healthy(void) const;
      56             : 
      57             :     // returns false if we fail arming checks, in which case the buffer will be populated with a failure message
      58             :     // requires_position should be true if horizontal position configuration should be checked
      59             :     bool pre_arm_check(bool requires_position, char *failure_msg, uint8_t failure_msg_len) const;
      60             : 
      61             :     // returns the index of the primary core
      62             :     // return -1 if no primary core selected
      63             :     int8_t getPrimaryCoreIndex(void) const;
      64             : 
      65             :     // returns the index of the IMU of the primary core
      66             :     // return -1 if no primary core selected
      67             :     int8_t getPrimaryCoreIMUIndex(void) const;
      68             : 
      69             :     // Write the last calculated NE position relative to the reference point (m)
      70             :     // If a calculated solution is not available, use the best available data and return false
      71             :     // If false returned, do not use for flight control
      72             :     bool getPosNE(Vector2p &posNE) const;
      73             : 
      74             :     // Write the last calculated D position relative to the reference point (m)
      75             :     // If a calculated solution is not available, use the best available data and return false
      76             :     // If false returned, do not use for flight control
      77             :     bool getPosD(postype_t &posD) const;
      78             : 
      79             :     // return NED velocity in m/s
      80             :     void getVelNED(Vector3f &vel) const;
      81             : 
      82             :     // return estimate of true airspeed vector in body frame in m/s
      83             :     // returns false if estimate is unavailable
      84             :     bool getAirSpdVec(Vector3f &vel) const;
      85             : 
      86             :     // return the innovation in m/s, innovation variance in (m/s)^2 and age in msec of the last TAS measurement processed for a given sensor instance
      87             :     // returns false if the data is unavailable
      88             :     bool getAirSpdHealthData(uint8_t instance, float &innovation, float &innovationVariance, uint32_t &age_ms) const;
      89             : 
      90             :     // Return the rate of change of vertical position in the down direction (dPosD/dt) in m/s
      91             :     // This can be different to the z component of the EKF velocity state because it will fluctuate with height errors and corrections in the EKF
      92             :     // but will always be kinematically consistent with the z component of the EKF position state
      93             :     float getPosDownDerivative() const;
      94             : 
      95             :     // return body axis gyro bias estimates in rad/sec for the specified instance
      96             :     // An out of range instance (eg -1) returns data for the primary instance
      97             :     void getGyroBias(int8_t instance, Vector3f &gyroBias) const;
      98             : 
      99             :     // return accelerometer bias estimate in m/s/s
     100             :     // An out of range instance (eg -1) returns data for the primary instance
     101             :     void getAccelBias(int8_t instance, Vector3f &accelBias) const;
     102             : 
     103             :     //returns index of the active source set used
     104             :     uint8_t get_active_source_set() const;
     105             : 
     106             :     // reset body axis gyro bias estimates
     107             :     void resetGyroBias(void);
     108             : 
     109             :     // Resets the baro so that it reads zero at the current height
     110             :     // Resets the EKF height to zero
     111             :     // Adjusts the EKF origin height so that the EKF height + origin height is the same as before
     112             :     // Returns true if the height datum reset has been performed
     113             :     // If using a range finder for height no reset is performed and it returns false
     114             :     bool resetHeightDatum(void);
     115             : 
     116             :     // return the horizontal speed limit in m/s set by optical flow sensor limits
     117             :     // return the scale factor to be applied to navigation velocity gains to compensate for increase in velocity noise with height when using optical flow
     118             :     void getEkfControlLimits(float &ekfGndSpdLimit, float &ekfNavVelGainScaler) const;
     119             : 
     120             :     // return the NED wind speed estimates in m/s (positive is air
     121             :     // moving in the direction of the axis) returns true if wind state
     122             :     // estimation is active
     123             :     bool getWind(Vector3f &wind) const;
     124             : 
     125             :     // return earth magnetic field estimates in measurement units / 1000
     126             :     void getMagNED(Vector3f &magNED) const;
     127             : 
     128             :     // return body magnetic field estimates in measurement units / 1000
     129             :     void getMagXYZ(Vector3f &magXYZ) const;
     130             : 
     131             :     // return the airspeed sensor in use
     132             :     uint8_t getActiveAirspeed() const;
     133             : 
     134             :     // Return estimated magnetometer offsets
     135             :     // Return true if magnetometer offsets are valid
     136             :     bool getMagOffsets(uint8_t mag_idx, Vector3f &magOffsets) const;
     137             : 
     138             :     // Return the last calculated latitude, longitude and height in WGS-84
     139             :     // If a calculated location isn't available, return a raw GPS measurement
     140             :     // The status will return true if a calculation or raw measurement is available
     141             :     // The getFilterStatus() function provides a more detailed description of data health and must be checked if data is to be used for flight control
     142             :     bool getLLH(Location &loc) const;
     143             : 
     144             :     // Return the latitude and longitude and height used to set the NED origin
     145             :     // All NED positions calculated by the filter are relative to this location
     146             :     // Returns false if the origin has not been set
     147             :     bool getOriginLLH(Location &loc) const;
     148             : 
     149             :     // set the latitude and longitude and height used to set the NED origin
     150             :     // All NED positions calculated by the filter will be relative to this location
     151             :     // The origin cannot be set if the filter is in a flight mode (eg vehicle armed)
     152             :     // Returns false if the filter has rejected the attempt to set the origin
     153             :     bool setOriginLLH(const Location &loc);
     154             : 
     155             :     // Set the EKF's NE horizontal position states and their corresponding variances from a supplied WGS-84 location and uncertainty
     156             :     // The altitude element of the location is not used.
     157             :     // Returns true if the set was successful
     158             :     bool setLatLng(const Location &loc, float posErr, uint32_t timestamp_ms);
     159             : 
     160             :     // return estimated height above ground level
     161             :     // return false if ground height is not being estimated.
     162             :     bool getHAGL(float &HAGL) const;
     163             : 
     164             :     // return the Euler roll, pitch and yaw angle in radians
     165             :     void getEulerAngles(Vector3f &eulers) const;
     166             : 
     167             :     // return the transformation matrix from XYZ (body) to NED axes
     168             :     void getRotationBodyToNED(Matrix3f &mat) const;
     169             : 
     170             :     // return the quaternions defining the rotation from XYZ (body) to NED axes
     171             :     void getQuaternionBodyToNED(int8_t instance, Quaternion &quat) const;
     172             : 
     173             :     // return the quaternions defining the rotation from NED to XYZ (autopilot) axes
     174             :     void getQuaternion(Quaternion &quat) const;
     175             : 
     176             :     // return the innovations
     177             :     bool getInnovations(Vector3f &velInnov, Vector3f &posInnov, Vector3f &magInnov, float &tasInnov, float &yawInnov) const;
     178             : 
     179             :     // return the innovation consistency test ratios
     180             :     bool getVariances(float &velVar, float &posVar, float &hgtVar, Vector3f &magVar, float &tasVar, Vector2f &offset) const;
     181             : 
     182             :     // return 1-sigma position and velocity uncertainty from the EKF state error covariance matrix P
     183             :     bool getPosVelUncertainty(float &pos_horiz_m, float &pos_vert_m, float &vel_m_s) const;
     184             : 
     185             :     // get a source's velocity innovations
     186             :     // returns true on success and results are placed in innovations and variances arguments
     187             :     bool getVelInnovationsAndVariancesForSource(AP_NavEKF_Source::SourceXY source, Vector3f &innovations, Vector3f &variances) const WARN_IF_UNUSED;
     188             : 
     189             :     // should we use the compass? This is public so it can be used for
     190             :     // reporting via ahrs.use_compass()
     191             :     bool use_compass(void) const;
     192             : 
     193             :     // write the raw optical flow measurements
     194             :     // rawFlowQuality is a measured of quality between 0 and 255, with 255 being the best quality
     195             :     // rawFlowRates are the optical flow rates in rad/sec about the X and Y sensor axes.
     196             :     // rawGyroRates are the sensor rotation rates in rad/sec measured by the sensors internal gyro
     197             :     // The sign convention is that a RH physical rotation of the sensor about an axis produces both a positive flow and gyro rate
     198             :     // msecFlowMeas is the scheduler time in msec when the optical flow data was received from the sensor.
     199             :     // posOffset is the XYZ flow sensor position in the body frame in m
     200             :     // heightOverride is the fixed height of the sensor above ground in m, when on rover vehicles. 0 if not used
     201             :     void writeOptFlowMeas(const uint8_t rawFlowQuality, const Vector2f &rawFlowRates, const Vector2f &rawGyroRates, const uint32_t msecFlowMeas, const Vector3f &posOffset, float heightOverride);
     202             : 
     203             :     // retrieve latest corrected optical flow samples (used for calibration)
     204             :     bool getOptFlowSample(uint32_t& timeStamp_ms, Vector2f& flowRate, Vector2f& bodyRate, Vector2f& losPred) const;
     205             : 
     206             :     /*
     207             :      * Write body frame linear and angular displacement measurements from a visual odometry sensor
     208             :      *
     209             :      * quality is a normalised confidence value from 0 to 100
     210             :      * delPos is the XYZ change in linear position measured in body frame and relative to the inertial reference at timeStamp_ms (m)
     211             :      * delAng is the XYZ angular rotation measured in body frame and relative to the inertial reference at timeStamp_ms (rad)
     212             :      * delTime is the time interval for the measurement of delPos and delAng (sec)
     213             :      * timeStamp_ms is the timestamp of the last image used to calculate delPos and delAng (msec)
     214             :      * delay_ms is the average delay of external nav system measurements relative to inertial measurements
     215             :      * posOffset is the XYZ body frame position of the camera focal point (m)
     216             :     */
     217             :     void writeBodyFrameOdom(float quality, const Vector3f &delPos, const Vector3f &delAng, float delTime, uint32_t timeStamp_ms, uint16_t delay_ms, const Vector3f &posOffset);
     218             : 
     219             :     /*
     220             :      * Write odometry data from a wheel encoder. The axis of rotation is assumed to be parallel to the vehicle body axis
     221             :      *
     222             :      * delAng is the measured change in angular position from the previous measurement where a positive rotation is produced by forward motion of the vehicle (rad)
     223             :      * delTime is the time interval for the measurement of delAng (sec)
     224             :      * timeStamp_ms is the time when the rotation was last measured (msec)
     225             :      * posOffset is the XYZ body frame position of the wheel hub (m)
     226             :      * radius is the effective rolling radius of the wheel (m)
     227             :      * this should not be called at more than the EKF's update rate (50hz or 100hz)
     228             :     */
     229             :     void writeWheelOdom(float delAng, float delTime, uint32_t timeStamp_ms, const Vector3f &posOffset, float radius);
     230             : 
     231             :     /*
     232             :      * Writes the measurement from a yaw angle sensor
     233             :      *
     234             :      * yawAngle: Yaw angle of the vehicle relative to true north in radians where a positive angle is
     235             :      * produced by a RH rotation about the Z body axis. The Yaw rotation is the first rotation in a
     236             :      * 321 (ZYX) or a 312 (ZXY) rotation sequence as specified by the 'type' argument.
     237             :      * yawAngleErr is the 1SD accuracy of the yaw angle measurement in radians.
     238             :      * timeStamp_ms: System time in msec when the yaw measurement was taken. This time stamp must include
     239             :      * all measurement lag and transmission delays.
     240             :      * type: An integer specifying Euler rotation order used to define the yaw angle.
     241             :      * type = 1 specifies a 312 (ZXY) rotation order, type = 2 specifies a 321 (ZYX) rotation order.
     242             :     */
     243             :     void writeEulerYawAngle(float yawAngle, float yawAngleErr, uint32_t timeStamp_ms, uint8_t type);
     244             : 
     245             :     /*
     246             :      * Write position and quaternion data from an external navigation system
     247             :      *
     248             :      * pos        : position in the RH navigation frame. Frame is assumed to be NED if frameIsNED is true. (m)
     249             :      * quat       : quaternion desribing the rotation from navigation frame to body frame
     250             :      * posErr     : 1-sigma spherical position error (m)
     251             :      * angErr     : 1-sigma spherical angle error (rad)
     252             :      * timeStamp_ms : system time the measurement was taken, not the time it was received (mSec)
     253             :      * delay_ms   : average delay of external nav system measurements relative to inertial measurements
     254             :      * resetTime_ms : system time of the last position reset request (mSec)
     255             :      *
     256             :     */
     257             :     void writeExtNavData(const Vector3f &pos, const Quaternion &quat, float posErr, float angErr, uint32_t timeStamp_ms, uint16_t delay_ms, uint32_t resetTime_ms);
     258             : 
     259             :     /*
     260             :      * Write velocity data from an external navigation system
     261             :      *
     262             :      * vel : velocity in NED (m)
     263             :      * err : velocity error (m/s)
     264             :      * timeStamp_ms : system time the measurement was taken, not the time it was received (mSec)
     265             :      * delay_ms   : average delay of external nav system measurements relative to inertial measurements
     266             :     */
     267             :     void writeExtNavVelData(const Vector3f &vel, float err, uint32_t timeStamp_ms, uint16_t delay_ms);
     268             : 
     269             :     /*
     270             :      * Write terrain altitude (derived from SRTM) in meters above the origin
     271             :      * only used by optical flow when out of rangefinder range
     272             :      */
     273             :     void writeTerrainData(float alt_m);
     274             : 
     275             :     // Set to true if the terrain underneath is stable enough to be used as a height reference
     276             :     // in combination with a range finder. Set to false if the terrain underneath the vehicle
     277             :     // cannot be used as a height reference. Use to prevent range finder operation otherwise
     278             :     // enabled by the combination of EK3_RNG_USE_HGT and EK3_RNG_USE_SPD parameters.
     279             :     void setTerrainHgtStable(bool val);
     280             : 
     281             :     /*
     282             :     return the filter fault status as a bitmasked integer
     283             :      0 = quaternions are NaN
     284             :      1 = velocities are NaN
     285             :      2 = badly conditioned X magnetometer fusion
     286             :      3 = badly conditioned Y magnetometer fusion
     287             :      4 = badly conditioned Z magnetometer fusion
     288             :      5 = badly conditioned airspeed fusion
     289             :      6 = badly conditioned synthetic sideslip fusion
     290             :      7 = filter is not initialised
     291             :     */
     292             :     void getFilterFaults(uint16_t &faults) const;
     293             : 
     294             :     /*
     295             :     return filter status flags
     296             :     */
     297             :     void getFilterStatus(nav_filter_status &status) const;
     298             : 
     299             :     // return a terrain altitude variance
     300             :     bool getTerrainAltVariance(float &terrain_alt_variance) const;
     301             : 
     302             :     // provides the height limit to be observed by the control loops
     303             :     // returns false if no height limiting is required
     304             :     // this is needed to ensure the vehicle does not fly too high when using optical flow navigation
     305             :     bool getHeightControlLimit(float &height) const;
     306             : 
     307             :     // return a count of yaw reset events; incremented when the
     308             :     // primary core changes and when the primary core resets its yaw
     309             :     uint16_t getYawResetCount(void);
     310             : 
     311             :     // return a count of NE position reset events; incremented when the
     312             :     // primary core changes and when the primary core resets its NE position
     313             :     uint16_t getPosNorthEastResetCount(void);
     314             : 
     315             :     // return a count of D position reset events; incremented when the
     316             :     // primary core changes and when the primary core resets its D position
     317             :     uint16_t getPosDownResetCount(void);
     318             : 
     319             :     // set and save the _baroAltNoise parameter
     320          82 :     void set_baro_alt_noise(float noise) { _baroAltNoise.set_and_save(noise); };
     321             : 
     322             :     // allow the enable flag to be set by Replay
     323           0 :     void set_enable(bool enable) { _enable.set_enable(enable); }
     324             : 
     325             :     // get the enable parameter
     326           0 :     bool get_enable(void) const { return bool(_enable.get()); }
     327             :     
     328             :     /*
     329             :       check if switching lanes will reduce the normalised
     330             :       innovations. This is called when the vehicle code is about to
     331             :       trigger an EKF failsafe, and it would like to avoid that by
     332             :       using a different EKF lane
     333             :      */
     334             :     void checkLaneSwitch(void);
     335             : 
     336             :     // switch to a new lane
     337             :     void switchLane(uint8_t new_lane_index);
     338             : 
     339             :     /*
     340             :       Request a reset of the EKF yaw. This is called when the vehicle code is about to
     341             :       trigger an EKF failsafe, and it would like to avoid that.
     342             :      */
     343             :     void requestYawReset(void);
     344             : 
     345             :     // set position, velocity and yaw sources to either 0=primary, 1=secondary, 2=tertiary
     346             :     void setPosVelYawSourceSet(uint8_t source_set_idx);
     347             : 
     348             :     // write EKF information to on-board logs
     349             :     void Log_Write();
     350             : 
     351             :     // are we using (aka fusing) a non-compass yaw?
     352             :     bool using_noncompass_for_yaw() const;
     353             : 
     354             :     // are we using (aka fusing) external nav for yaw?
     355             :     bool using_extnav_for_yaw() const;
     356             : 
     357             :     // are we using a gps
     358             :     bool using_gps() const;
     359             : 
     360             :     // check if configured to use GPS for horizontal position estimation
     361             :     bool configuredToUseGPSForPosXY(void) const;
     362             :     
     363             :     // check if configured to use GPS for position estimation
     364             :     bool configuredToUseGPSForPos(void) const;
     365             : 
     366             :     // Writes the default equivalent airspeed and 1-sigma uncertainty in m/s to be used in forward flight if a measured airspeed is required and not available.
     367             :     void writeDefaultAirSpeed(float airspeed, float uncertainty);
     368             : 
     369             :     // returns true when the yaw angle has been aligned
     370             :     bool yawAlignmentComplete(void) const;
     371             : 
     372             :     // returns true when the state estimates are significantly
     373             :     // degraded by vibration
     374             :     bool isVibrationAffected() const;
     375             : 
     376             :     // get a yaw estimator instance
     377             :     const EKFGSF_yaw *get_yawEstimator(void) const;
     378             : 
     379             :     // Do a reset and bootstrap alignment of all EKF cores
     380             :     // return true if successful for all cores
     381             :     bool InitialiseFilterBootstrap();
     382             : 
     383             : private:
     384             :     class AP_DAL &dal;
     385             : 
     386             :     uint8_t num_cores; // number of allocated cores
     387             :     uint8_t primary;   // current primary core
     388             :     NavEKF3_core *core = nullptr;
     389             : 
     390             :     uint32_t _frameTimeUsec;        // time per IMU frame
     391             :     uint8_t  _framesPerPrediction;  // expected number of IMU frames per prediction
     392             :   
     393             :     // values for EK3_LOG_LEVEL
     394             :     enum class LogLevel {
     395             :         ALL = 0,
     396             :         XKF4 = 1,
     397             :         XKF4_GSF = 2,
     398             :         NONE = 3
     399             :     };
     400             : 
     401             :     // EKF Mavlink Tuneable Parameters
     402             :     AP_Int8  _enable;               // zero to disable EKF3
     403             :     AP_Float _gpsHorizVelNoise;     // GPS horizontal velocity measurement noise : m/s
     404             :     AP_Float _gpsVertVelNoise;      // GPS vertical velocity measurement noise : m/s
     405             :     AP_Float _gpsHorizPosNoise;     // GPS horizontal position measurement noise m
     406             :     AP_Float _baroAltNoise;         // Baro height measurement noise : m
     407             :     AP_Float _magNoise;             // magnetometer measurement noise : gauss
     408             :     AP_Float _easNoise;             // equivalent airspeed measurement noise : m/s
     409             :     AP_Float _windVelProcessNoise;  // wind velocity state process noise : m/s^2
     410             :     AP_Float _wndVarHgtRateScale;   // scale factor applied to wind process noise due to height rate
     411             :     AP_Float _magEarthProcessNoise; // Earth magnetic field process noise : gauss/sec
     412             :     AP_Float _magBodyProcessNoise;  // Body magnetic field process noise : gauss/sec
     413             :     AP_Float _gyrNoise;             // gyro process noise : rad/s
     414             :     AP_Float _accNoise;             // accelerometer process noise : m/s^2
     415             :     AP_Float _gyroBiasProcessNoise; // gyro bias state process noise : rad/s
     416             :     AP_Float _accelBiasProcessNoise;// accel bias state process noise : m/s^2
     417             :     AP_Int16 _hgtDelay_ms;          // effective average delay of Height measurements relative to inertial measurements (msec)
     418             :     AP_Int16  _gpsVelInnovGate;     // Percentage number of standard deviations applied to GPS velocity innovation consistency check
     419             :     AP_Int16  _gpsPosInnovGate;     // Percentage number of standard deviations applied to GPS position innovation consistency check
     420             :     AP_Int16  _hgtInnovGate;        // Percentage number of standard deviations applied to height innovation consistency check
     421             :     AP_Int16  _magInnovGate;        // Percentage number of standard deviations applied to magnetometer innovation consistency check
     422             :     AP_Int16  _tasInnovGate;        // Percentage number of standard deviations applied to true airspeed innovation consistency check
     423             :     AP_Int8  _magCal;               // Sets activation condition for in-flight magnetometer calibration
     424             :     AP_Int8 _gpsGlitchRadiusMax;    // Maximum allowed discrepancy between inertial and GPS Horizontal position before GPS glitch is declared : m
     425             :     AP_Float _flowNoise;            // optical flow rate measurement noise
     426             :     AP_Int16  _flowInnovGate;       // Percentage number of standard deviations applied to optical flow innovation consistency check
     427             :     AP_Int8  _flowDelay_ms;         // effective average delay of optical flow measurements rel to IMU (msec)
     428             :     AP_Int16  _rngInnovGate;        // Percentage number of standard deviations applied to range finder innovation consistency check
     429             :     AP_Float _maxFlowRate;          // Maximum flow rate magnitude that will be accepted by the filter
     430             :     AP_Float _rngNoise;             // Range finder noise : m
     431             :     AP_Int8 _gpsCheck;              // Bitmask controlling which preflight GPS checks are bypassed
     432             :     AP_Int8 _imuMask;               // Bitmask of IMUs to instantiate EKF3 for
     433             :     AP_Int16 _gpsCheckScaler;       // Percentage increase to be applied to GPS pre-flight accuracy and drift thresholds
     434             :     AP_Float _noaidHorizNoise;      // horizontal position measurement noise assumed when synthesised zero position measurements are used to constrain attitude drift : m
     435             :     AP_Float _yawNoise;             // magnetic yaw measurement noise : rad
     436             :     AP_Int16 _yawInnovGate;         // Percentage number of standard deviations applied to magnetic yaw innovation consistency check
     437             :     AP_Int8 _tauVelPosOutput;       // Time constant of output complementary filter : csec (centi-seconds)
     438             :     AP_Int8 _useRngSwHgt;           // Maximum valid range of the range finder as a percentage of the maximum range specified by the sensor driver
     439             :     AP_Float _terrGradMax;          // Maximum terrain gradient below the vehicle
     440             :     AP_Float _rngBcnNoise;          // Range beacon measurement noise (m)
     441             :     AP_Int16 _rngBcnInnovGate;      // Percentage number of standard deviations applied to range beacon innovation consistency check
     442             :     AP_Int8  _rngBcnDelay_ms;       // effective average delay of range beacon measurements rel to IMU (msec)
     443             :     AP_Float _useRngSwSpd;          // Maximum horizontal ground speed to use range finder as the primary height source (m/s)
     444             :     AP_Float _accBiasLim;           // Accelerometer bias limit (m/s/s)
     445             :     AP_Int8 _magMask;               // Bitmask forcing specific EKF core instances to use simple heading magnetometer fusion.
     446             :     AP_Int8 _originHgtMode;         // Bitmask controlling post alignment correction and reporting of the EKF origin height.
     447             :     AP_Float _visOdmVelErrMax;      // Observation 1-STD velocity error assumed for visual odometry sensor at lowest reported quality (m/s)
     448             :     AP_Float _visOdmVelErrMin;      // Observation 1-STD velocity error assumed for visual odometry sensor at highest reported quality (m/s)
     449             :     AP_Float _wencOdmVelErr;        // Observation 1-STD velocity error assumed for wheel odometry sensor (m/s)
     450             :     AP_Int8  _flowUse;              // Controls if the optical flow data is fused into the main navigation estimator and/or the terrain estimator.
     451             :     AP_Float _hrt_filt_freq;        // frequency of output observer height rate complementary filter in Hz
     452             :     AP_Int16 _mag_ef_limit;         // limit on difference between WMM tables and learned earth field.
     453             :     AP_Int8 _gsfRunMask;            // mask controlling which EKF3 instances run a separate EKF-GSF yaw estimator
     454             :     AP_Int8 _gsfUseMask;            // mask controlling which EKF3 instances will use EKF-GSF yaw estimator data to assit with yaw resets
     455             :     AP_Int8 _gsfResetMaxCount;      // maximum number of times the EKF3 is allowed to reset it's yaw to the EKF-GSF estimate
     456             :     AP_Float _err_thresh;           // lanes have to be consistently better than the primary by at least this threshold to reduce their overall relativeCoreError
     457             :     AP_Int32 _affinity;             // bitmask of sensor affinity options
     458             :     AP_Float _dragObsNoise;         // drag specific force observatoin noise (m/s/s)**2
     459             :     AP_Float _ballisticCoef_x;      // ballistic coefficient measured for flow in X body frame directions
     460             :     AP_Float _ballisticCoef_y;      // ballistic coefficient measured for flow in Y body frame directions
     461             :     AP_Float _momentumDragCoef;     // lift rotor momentum drag coefficient
     462             :     AP_Int8 _betaMask;              // Bitmask controlling when sideslip angle fusion is used to estimate non wind states
     463             :     AP_Float _ognmTestScaleFactor;  // Scale factor applied to the thresholds used by the on ground not moving test
     464             :     AP_Float _baroGndEffectDeadZone;// Dead zone applied to positive baro height innovations when in ground effect (m)
     465             :     AP_Int8 _primary_core;          // initial core number
     466             :     AP_Enum<LogLevel> _log_level;   // log verbosity level
     467             :     AP_Float _gpsVAccThreshold;     // vertical accuracy threshold to use GPS as an altitude source
     468             :     AP_Int32 _options;              // bit mask of processing options
     469             : 
     470             :     // enum for processing options
     471             :     enum class Option {
     472             :         JammingExpected         = (1<<0),
     473             :         ManualLaneSwitch        = (1<<1),
     474             :         OptflowMayUseTerrainAlt = (1<<2),
     475             :         AglKfForOptflow         = (1<<3),  // Use IMU-aided 2-state AGL KF for optflow scaling
     476             :     };
     477   102936604 :     bool option_is_enabled(Option option) const {
     478   102936604 :         return (_options & (uint32_t)option) != 0;
     479             :     }
     480             : 
     481             : // Possible values for _flowUse
     482             : #define FLOW_USE_NONE    0
     483             : #define FLOW_USE_NAV     1
     484             : #define FLOW_USE_TERRAIN 2
     485             : 
     486             :     // Tuning parameters
     487             :     const float gpsNEVelVarAccScale = 0.05f;       // Scale factor applied to NE velocity measurement variance due to manoeuvre acceleration
     488             :     const float gpsDVelVarAccScale = 0.07f;        // Scale factor applied to vertical velocity measurement variance due to manoeuvre acceleration
     489             :     const float gpsPosVarAccScale = 0.05f;         // Scale factor applied to horizontal position measurement variance due to manoeuvre acceleration
     490             :     const float extNavVelVarAccScale = 0.05f;      // Scale factor applied to ext nav velocity measurement variance due to manoeuvre acceleration
     491             :     const uint16_t magDelay_ms = 60;               // Magnetometer measurement delay (msec)
     492             :     const uint16_t tasDelay_ms = 100;              // Airspeed measurement delay (msec)
     493             :     const uint16_t tiltDriftTimeMax_ms = 15000;    // Maximum number of ms allowed without any form of tilt aiding (GPS, flow, TAS, etc)
     494             :     const uint16_t posRetryTimeUseVel_ms = 10000;  // Position aiding retry time with velocity measurements (msec)
     495             :     const uint16_t posRetryTimeNoVel_ms = 7000;    // Position aiding retry time without velocity measurements (msec)
     496             :     const uint16_t hgtRetryTimeMode0_ms = 10000;   // Height retry time with vertical velocity measurement (msec)
     497             :     const uint16_t hgtRetryTimeMode12_ms = 5000;   // Height retry time without vertical velocity measurement (msec)
     498             :     const uint16_t tasRetryTime_ms = 5000;         // True airspeed timeout and retry interval (msec)
     499             :     const uint16_t dragFailTimeLimit_ms = 5000;    // Drag timeout (msec)
     500             :     const uint32_t magFailTimeLimit_ms = 10000;    // number of msec before a magnetometer failing innovation consistency checks is declared failed (msec)
     501             :     const float magVarRateScale = 0.005f;          // scale factor applied to magnetometer variance due to angular rate
     502             :     const float gyroBiasNoiseScaler = 2.0f;        // scale factor applied to gyro bias state process noise when on ground
     503             :     const uint16_t hgtAvg_ms = 100;                // average number of msec between height measurements
     504             :     const uint16_t betaAvg_ms = 100;               // average number of msec between synthetic sideslip measurements
     505             :     const float covTimeStepMax = 0.1f;             // maximum time (sec) between covariance prediction updates
     506             :     const float covDelAngMax = 0.05f;              // maximum delta angle between covariance prediction updates
     507             :     const float DCM33FlowMin = 0.71f;              // If Tbn(3,3) is less than this number, optical flow measurements will not be fused as tilt is too high.
     508             :     const float fScaleFactorPnoise = 1e-10f;       // Process noise added to focal length scale factor state variance at each time step
     509             :     const uint8_t flowTimeDeltaAvg_ms = 100;       // average interval between optical flow measurements (msec)
     510             :     const uint32_t flowIntervalMax_ms = 100;       // maximum allowable time between flow fusion events
     511             :     const float gndEffectBaroScaler = 4.0f;        // scaler applied to the barometer observation variance when ground effect mode is active
     512             :     const uint8_t gndGradientSigma = 50;           // RMS terrain gradient percentage assumed by the terrain height estimation
     513             :     const uint16_t fusionTimeStep_ms = 10;         // The minimum time interval between covariance predictions and measurement fusions in msec
     514             :     const uint8_t sensorIntervalMin_ms = 50;       // The minimum allowed time between measurements from any non-IMU sensor (msec)
     515             :     const uint8_t flowIntervalMin_ms = 20;         // The minimum allowed time between measurements from optical flow sensors (msec)
     516             :     const uint8_t extNavIntervalMin_ms = 20;       // The minimum allowed time between measurements from external navigation sensors (msec)
     517             :     const float maxYawEstVelInnov = 2.0f;          // Maximum acceptable length of the velocity innovation returned by the EKF-GSF yaw estimator (m/s)
     518             :     const uint16_t deadReckonDeclare_ms = 1000;    // Time without equivalent position or velocity observation to constrain drift before dead reckoning is declared (msec)
     519             :     const uint16_t gpsNoFixTimeout_ms = 2000;      // Time without a fix required to reset GPS alignment checks when EK3_OPTIONS bit 0 is set (msec)
     520             : 
     521             :     // time at start of current filter update
     522             :     uint64_t imuSampleTime_us;
     523             : 
     524             :     // time of last lane switch
     525             :     uint32_t lastLaneSwitch_ms;
     526             : 
     527             :     // last time of Log_Write
     528             :     uint64_t lastLogWrite_us;
     529             : 
     530             :     struct {
     531             :         uint16_t count;               // count of yaw reset events passed to consumers
     532             :         uint16_t last_core_count;     // primary core's yaw reset count when count last changed
     533             :     } yaw_reset_data;
     534             : 
     535             :     struct {
     536             :         uint16_t count;               // count of NE position reset events passed to consumers
     537             :         uint16_t last_core_count;     // primary core's NE position reset count when count last changed
     538             :     } pos_reset_data;
     539             : 
     540             :     struct {
     541             :         uint16_t count;               // count of D position reset events passed to consumers
     542             :         uint16_t last_core_count;     // primary core's D position reset count when count last changed
     543             :     } pos_down_reset_data;
     544             : 
     545             : #define CORE_ERR_LIM      1 // -LIM to LIM relative error range for a core
     546             : #define BETTER_THRESH   0.5 // a lane should have this much relative error difference to be considered for overriding a healthy primary core
     547             :     
     548             :     bool runCoreSelection;                          // true when the primary core has stabilised and the core selection logic can be started
     549             :     bool coreSetupRequired[MAX_EKF_CORES];          // true when this core index needs to be setup
     550             :     uint8_t coreImuIndex[MAX_EKF_CORES];            // IMU index used by this core
     551             :     float coreRelativeErrors[MAX_EKF_CORES];        // relative errors of cores with respect to primary
     552             :     float coreErrorScores[MAX_EKF_CORES];           // the instance error values used to update relative core error
     553             :     uint64_t coreLastTimePrimary_us[MAX_EKF_CORES]; // last time we were using this core as primary
     554             : 
     555             :     // origin set by one of the cores
     556             :     Location common_EKF_origin;
     557             :     bool common_origin_valid;
     558             :     
     559             :     // update the yaw reset data to capture changes due to a lane switch
     560             :     // new_primary - index of the ekf instance that we are about to switch to as the primary
     561             :     // old_primary - index of the ekf instance that we are currently using as the primary
     562             :     void updateLaneSwitchYawResetData(uint8_t new_primary);
     563             : 
     564             :     // update the position reset data to capture changes due to a lane switch
     565             :     // new_primary - index of the ekf instance that we are about to switch to as the primary
     566             :     // old_primary - index of the ekf instance that we are currently using as the primary
     567             :     void updateLaneSwitchPosResetData(uint8_t new_primary);
     568             : 
     569             :     // update the position down reset data to capture changes due to a lane switch
     570             :     // new_primary - index of the ekf instance that we are about to switch to as the primary
     571             :     // old_primary - index of the ekf instance that we are currently using as the primary
     572             :     void updateLaneSwitchPosDownResetData(uint8_t new_primary);
     573             : 
     574             :     // Update instance error scores for all available cores 
     575             :     float updateCoreErrorScores(void);
     576             : 
     577             :     // Update relative error scores for all alternate available cores
     578             :     void updateCoreRelativeErrors(void);
     579             : 
     580             :     // Reset error scores for all available cores
     581             :     void resetCoreErrors(void);
     582             : 
     583             :     // return true if a new core has a better score than an existing core, including
     584             :     // checks for alignment
     585             :     bool coreBetterScore(uint8_t new_core, uint8_t current_core) const;
     586             : 
     587             :     // position, velocity and yaw source control
     588             :     AP_NavEKF_Source sources;
     589             : };

Generated by: LCOV version 1.14