Line data Source code
1 : /* 2 : 24 state EKF based on the derivation in https://github.com/priseborough/ 3 : InertialNav/blob/master/derivations/RotationVectorAttitudeParameterisation/ 4 : GenerateNavFilterEquations.m 5 : 6 : Converted from Matlab to C++ by Paul Riseborough 7 : 8 : EKF Tuning parameters refactored by Tom Cauchois 9 : 10 : This program is free software: you can redistribute it and/or modify 11 : it under the terms of the GNU General Public License as published by 12 : the Free Software Foundation, either version 3 of the License, or 13 : (at your option) any later version. 14 : 15 : This program is distributed in the hope that it will be useful, 16 : but WITHOUT ANY WARRANTY; without even the implied warranty of 17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 : GNU General Public License for more details. 19 : 20 : You should have received a copy of the GNU General Public License 21 : along with this program. If not, see <http://www.gnu.org/licenses/>. 22 : */ 23 : #pragma once 24 : 25 : #include <AP_Common/Location.h> 26 : #include <AP_Math/AP_Math.h> 27 : #include <AP_Param/AP_Param.h> 28 : #include <AP_NavEKF/AP_Nav_Common.h> 29 : 30 : class NavEKF2_core; 31 : class EKFGSF_yaw; 32 : 33 : class NavEKF2 { 34 : friend class NavEKF2_core; 35 : 36 : public: 37 : NavEKF2(); 38 : 39 : /* Do not allow copies */ 40 : CLASS_NO_COPY(NavEKF2); 41 : 42 : static const struct AP_Param::GroupInfo var_info[]; 43 : 44 : // allow logging to determine the number of active cores 45 4812879 : uint8_t activeCores(void) const { 46 4812879 : return num_cores; 47 : } 48 : 49 : // Initialise the filter 50 : bool InitialiseFilter(void); 51 : 52 : // Update Filter States - this should be called whenever new IMU data is available 53 : void UpdateFilter(void); 54 : 55 : // Check basic filter health metrics and return a consolidated health status 56 : bool healthy(void) const; 57 : 58 : // returns false if we fail arming checks, in which case the buffer will be populated with a failure message 59 : bool pre_arm_check(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 rate of change of vertical position in the down direction (dPosD/dt) in m/s 87 : // 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 88 : // but will always be kinematically consistent with the z component of the EKF position state 89 : float getPosDownDerivative() const; 90 : 91 : // return body axis gyro bias estimates in rad/sec 92 : void getGyroBias(Vector3f &gyroBias) const; 93 : 94 : // reset body axis gyro bias estimates 95 : void resetGyroBias(void); 96 : 97 : // Resets the baro so that it reads zero at the current height 98 : // Resets the EKF height to zero 99 : // Adjusts the EKf origin height so that the EKF height + origin height is the same as before 100 : // Returns true if the height datum reset has been performed 101 : // If using a range finder for height no reset is performed and it returns false 102 : bool resetHeightDatum(void); 103 : 104 : // return the horizontal speed limit in m/s set by optical flow sensor limits 105 : // return the scale factor to be applied to navigation velocity gains to compensate for increase in velocity noise with height when using optical flow 106 : void getEkfControlLimits(float &ekfGndSpdLimit, float &ekfNavVelGainScaler) const; 107 : 108 : // return the Z-accel bias estimate in m/s^2 for the specified instance 109 : // An out of range instance (eg -1) returns data for the primary instance 110 : void getAccelZBias(float &zbias) const; 111 : 112 : // return the NED wind speed estimates in m/s (positive is air moving in the direction of the axis) 113 : // An out of range instance (eg -1) returns data for the primary instance 114 : void getWind(Vector3f &wind) const; 115 : 116 : // return earth magnetic field estimates in measurement units / 1000 for the specified instance 117 : // An out of range instance (eg -1) returns data for the primary instance 118 : void getMagNED(Vector3f &magNED) const; 119 : 120 : // return body magnetic field estimates in measurement units / 1000 for the specified instance 121 : // An out of range instance (eg -1) returns data for the primary instance 122 : void getMagXYZ(Vector3f &magXYZ) const; 123 : 124 : // Return estimated magnetometer offsets 125 : // Return true if magnetometer offsets are valid 126 : bool getMagOffsets(uint8_t mag_idx, Vector3f &magOffsets) const; 127 : 128 : // Return the last calculated latitude, longitude and height in WGS-84 129 : // If a calculated location isn't available, return a raw GPS measurement 130 : // The status will return true if a calculation or raw measurement is available 131 : // The getFilterStatus() function provides a more detailed description of data health and must be checked if data is to be used for flight control 132 : bool getLLH(Location &loc) const; 133 : 134 : // Return the latitude and longitude and height used to set the NED origin for the specified instance 135 : // An out of range instance (eg -1) returns data for the primary instance 136 : // All NED positions calculated by the filter are relative to this location 137 : // Returns false if the origin has not been set 138 : bool getOriginLLH(Location &loc) const; 139 : 140 : // set the latitude and longitude and height used to set the NED origin 141 : // All NED positions calculated by the filter will be relative to this location 142 : // The origin cannot be set if the filter is in a flight mode (eg vehicle armed) 143 : // Returns false if the filter has rejected the attempt to set the origin 144 : bool setOriginLLH(const Location &loc); 145 : 146 : // return estimated height above ground level 147 : // return false if ground height is not being estimated. 148 : bool getHAGL(float &HAGL) const; 149 : 150 : // return the Euler roll, pitch and yaw angle in radians for the specified instance 151 : // An out of range instance (eg -1) returns data for the primary instance 152 : void getEulerAngles(Vector3f &eulers) const; 153 : 154 : // return the transformation matrix from XYZ (body) to NED axes 155 : void getRotationBodyToNED(Matrix3f &mat) const; 156 : 157 : // return the transformation matrix from XYZ (body) to NED axes 158 : void getQuaternionBodyToNED(int8_t instance, Quaternion &quat) const; 159 : 160 : // return the quaternions defining the rotation from NED to autopilot axes 161 : void getQuaternion(Quaternion &quat) const; 162 : 163 : // return the innovations for the specified instance 164 : // An out of range instance (eg -1) returns data for the primary instance 165 : bool getInnovations(Vector3f &velInnov, Vector3f &posInnov, Vector3f &magInnov, float &tasInnov, float &yawInnov) const; 166 : 167 : // return the innovation consistency test ratios for the specified instance 168 : // An out of range instance (eg -1) returns data for the primary instance 169 : bool getVariances(float &velVar, float &posVar, float &hgtVar, Vector3f &magVar, float &tasVar, Vector2f &offset) const; 170 : 171 : // should we use the compass? This is public so it can be used for 172 : // reporting via ahrs.use_compass() 173 : bool use_compass(void) const; 174 : 175 : // are we using a gps? 176 : bool using_gps(void) const; 177 : 178 : // write the raw optical flow measurements 179 : // rawFlowQuality is a measured of quality between 0 and 255, with 255 being the best quality 180 : // rawFlowRates are the optical flow rates in rad/sec about the X and Y sensor axes. 181 : // rawGyroRates are the sensor rotation rates in rad/sec measured by the sensors internal gyro 182 : // The sign convention is that a RH physical rotation of the sensor about an axis produces both a positive flow and gyro rate 183 : // msecFlowMeas is the scheduler time in msec when the optical flow data was received from the sensor. 184 : // posOffset is the XYZ flow sensor position in the body frame in m 185 : // heightOverride is the fixed height of the sensor above ground in m, when on rover vehicles. 0 if not used 186 : void writeOptFlowMeas(const uint8_t rawFlowQuality, const Vector2f &rawFlowRates, const Vector2f &rawGyroRates, const uint32_t msecFlowMeas, const Vector3f &posOffset, float heightOverride); 187 : 188 : // Set to true if the terrain underneath is stable enough to be used as a height reference 189 : // in combination with a range finder. Set to false if the terrain underneath the vehicle 190 : // cannot be used as a height reference. Use to prevent range finder operation otherwise 191 : // enabled by the combination of EK2_RNG_AID_HGT and EK2_RNG_USE_SPD parameters. 192 : void setTerrainHgtStable(bool val); 193 : 194 : /* 195 : return the filter fault status as a bitmasked integer for the specified instance 196 : An out of range instance (eg -1) returns data for the primary instance 197 : 0 = quaternions are NaN 198 : 1 = velocities are NaN 199 : 2 = badly conditioned X magnetometer fusion 200 : 3 = badly conditioned Y magnetometer fusion 201 : 4 = badly conditioned Z magnetometer fusion 202 : 5 = badly conditioned airspeed fusion 203 : 6 = badly conditioned synthetic sideslip fusion 204 : 7 = filter is not initialised 205 : */ 206 : void getFilterFaults(uint16_t &faults) const; 207 : 208 : /* 209 : return filter gps quality check status for the specified instance 210 : An out of range instance (eg -1) returns data for the primary instance 211 : */ 212 : void getFilterGpsStatus(nav_gps_status &faults) const; 213 : 214 : /* 215 : return filter status flags for the specified instance 216 : An out of range instance (eg -1) returns data for the primary instance 217 : */ 218 : void getFilterStatus(nav_filter_status &status) const; 219 : 220 : // return a terrain altitude variance 221 : bool getTerrainAltVariance(float &terrain_alt_variance) const; 222 : 223 : // provides the height limit to be observed by the control loops 224 : // returns false if no height limiting is required 225 : // this is needed to ensure the vehicle does not fly too high when using optical flow navigation 226 : bool getHeightControlLimit(float &height) const; 227 : 228 : // return a count of yaw reset events; incremented when the 229 : // primary core changes and when the primary core resets its yaw 230 : uint16_t getYawResetCount(void); 231 : 232 : // return a count of NE position reset events; incremented when the 233 : // primary core changes and when the primary core resets its NE position 234 : uint16_t getPosNorthEastResetCount(void); 235 : 236 : // return a count of D position reset events; incremented when the 237 : // primary core changes and when the primary core resets its D position 238 : uint16_t getPosDownResetCount(void); 239 : 240 : // set and save the _baroAltNoise parameter 241 82 : void set_baro_alt_noise(float noise) { _baroAltNoise.set_and_save(noise); }; 242 : 243 : // allow the enable flag to be set by Replay 244 : void set_enable(bool enable) { _enable.set_enable(enable); } 245 : 246 : // get the enable parameter 247 13 : bool get_enable(void) const { return bool(_enable.get()); } 248 : 249 : /* 250 : * Write position and quaternion data from an external navigation system 251 : * 252 : * pos : position in the RH navigation frame. Frame is assumed to be NED (m) 253 : * quat : quaternion desribing the rotation from navigation frame to body frame 254 : * posErr : 1-sigma spherical position error (m) 255 : * angErr : 1-sigma spherical angle error (rad) 256 : * timeStamp_ms : system time the measurement was taken, not the time it was received (mSec) 257 : * delay_ms : average delay of external nav system measurements relative to inertial measurements 258 : * resetTime_ms : system time of the last position reset request (mSec) 259 : * 260 : * Sensor offsets are pulled directly from the AP_VisualOdom library 261 : * 262 : */ 263 : void writeExtNavData(const Vector3f &pos, const Quaternion &quat, float posErr, float angErr, uint32_t timeStamp_ms, uint16_t delay_ms, uint32_t resetTime_ms); 264 : 265 : /* 266 : * Write velocity data from an external navigation system 267 : * vel : velocity in NED (m) 268 : * err : velocity error (m/s) 269 : * timeStamp_ms : system time the measurement was taken, not the time it was received (mSec) 270 : * delay_ms : average delay of external nav system measurements relative to inertial measurements 271 : */ 272 : void writeExtNavVelData(const Vector3f &vel, float err, uint32_t timeStamp_ms, uint16_t delay_ms); 273 : 274 : /* 275 : check if switching lanes will reduce the normalised 276 : innovations. This is called when the vehicle code is about to 277 : trigger an EKF failsafe, and it would like to avoid that by 278 : using a different EKF lane 279 : */ 280 : void checkLaneSwitch(void); 281 : 282 : /* 283 : Request a reset of the EKF yaw. This is called when the vehicle code is about to 284 : trigger an EKF failsafe, and it would like to avoid that. 285 : */ 286 : void requestYawReset(void); 287 : 288 : // write EKF information to on-board logs 289 : void Log_Write(); 290 : 291 : // check if external navigation is being used for yaw observation 292 : bool isExtNavUsedForYaw(void) const; 293 : 294 : // check if configured to use GPS for horizontal position estimation 295 : bool configuredToUseGPSForPosXY(void) const; 296 : 297 : // Writes the default equivalent airspeed in m/s to be used in forward flight if a measured airspeed is required and not available. 298 : void writeDefaultAirSpeed(float airspeed); 299 : 300 : // get a yaw estimator instance 301 : const EKFGSF_yaw *get_yawEstimator(void) const; 302 : 303 : private: 304 : uint8_t num_cores; // number of allocated cores 305 : uint8_t primary; // current primary core 306 : NavEKF2_core *core = nullptr; 307 : bool core_malloc_failed; 308 : 309 : uint32_t _frameTimeUsec; // time per IMU frame 310 : uint8_t _framesPerPrediction; // expected number of IMU frames per prediction 311 : 312 : // EKF Mavlink Tuneable Parameters 313 : AP_Int8 _enable; // zero to disable EKF2 314 : AP_Float _gpsHorizVelNoise; // GPS horizontal velocity measurement noise : m/s 315 : AP_Float _gpsVertVelNoise; // GPS vertical velocity measurement noise : m/s 316 : AP_Float _gpsHorizPosNoise; // GPS horizontal position measurement noise m 317 : AP_Float _baroAltNoise; // Baro height measurement noise : m 318 : AP_Float _magNoise; // magnetometer measurement noise : gauss 319 : AP_Float _easNoise; // equivalent airspeed measurement noise : m/s 320 : AP_Float _windVelProcessNoise; // wind velocity state process noise : m/s^2 321 : AP_Float _wndVarHgtRateScale; // scale factor applied to wind process noise due to height rate 322 : AP_Float _magEarthProcessNoise; // Earth magnetic field process noise : gauss/sec 323 : AP_Float _magBodyProcessNoise; // Body magnetic field process noise : gauss/sec 324 : AP_Float _gyrNoise; // gyro process noise : rad/s 325 : AP_Float _accNoise; // accelerometer process noise : m/s^2 326 : AP_Float _gyroBiasProcessNoise; // gyro bias state process noise : rad/s 327 : AP_Float _accelBiasProcessNoise;// accel bias state process noise : m/s^2 328 : AP_Int16 _hgtDelay_ms; // effective average delay of Height measurements relative to inertial measurements (msec) 329 : AP_Int8 _fusionModeGPS; // 0 = use 3D velocity, 1 = use 2D velocity, 2 = use no velocity, 3 = do not use GPS 330 : AP_Int16 _gpsVelInnovGate; // Percentage number of standard deviations applied to GPS velocity innovation consistency check 331 : AP_Int16 _gpsPosInnovGate; // Percentage number of standard deviations applied to GPS position innovation consistency check 332 : AP_Int16 _hgtInnovGate; // Percentage number of standard deviations applied to height innovation consistency check 333 : AP_Int16 _magInnovGate; // Percentage number of standard deviations applied to magnetometer innovation consistency check 334 : AP_Int16 _tasInnovGate; // Percentage number of standard deviations applied to true airspeed innovation consistency check 335 : AP_Int8 _magCal; // Sets activation condition for in-flight magnetometer calibration 336 : AP_Int8 _gpsGlitchRadiusMax; // Maximum allowed discrepancy between inertial and GPS Horizontal position before GPS glitch is declared : m 337 : AP_Float _flowNoise; // optical flow rate measurement noise 338 : AP_Int16 _flowInnovGate; // Percentage number of standard deviations applied to optical flow innovation consistency check 339 : AP_Int8 _flowDelay_ms; // effective average delay of optical flow measurements rel to IMU (msec) 340 : AP_Int16 _rngInnovGate; // Percentage number of standard deviations applied to range finder innovation consistency check 341 : AP_Float _maxFlowRate; // Maximum flow rate magnitude that will be accepted by the filter 342 : AP_Int8 _altSource; // Primary alt source during optical flow navigation. 0 = use Baro, 1 = use range finder, 2 = use GPS, 3 = use Range Beacon 343 : AP_Float _gyroScaleProcessNoise;// gyro scale factor state process noise : 1/s 344 : AP_Float _rngNoise; // Range finder noise : m 345 : AP_Int8 _gpsCheck; // Bitmask controlling which preflight GPS checks are bypassed 346 : AP_Int8 _imuMask; // Bitmask of IMUs to instantiate EKF2 for 347 : AP_Int16 _gpsCheckScaler; // Percentage increase to be applied to GPS pre-flight accuracy and drift thresholds 348 : AP_Float _noaidHorizNoise; // horizontal position measurement noise assumed when synthesised zero position measurements are used to constrain attitude drift : m 349 : AP_Float _yawNoise; // magnetic yaw measurement noise : rad 350 : AP_Int16 _yawInnovGate; // Percentage number of standard deviations applied to magnetic yaw innovation consistency check 351 : AP_Int8 _tauVelPosOutput; // Time constant of output complementary filter : csec (centi-seconds) 352 : AP_Int8 _useRngSwHgt; // Maximum valid range of the range finder as a percentage of the maximum range specified by the sensor driver 353 : AP_Float _terrGradMax; // Maximum terrain gradient below the vehicle 354 : AP_Float _rngBcnNoise; // Range beacon measurement noise (m) 355 : AP_Int16 _rngBcnInnovGate; // Percentage number of standard deviations applied to range beacon innovation consistency check 356 : AP_Int8 _rngBcnDelay_ms; // effective average delay of range beacon measurements rel to IMU (msec) 357 : AP_Float _useRngSwSpd; // Maximum horizontal ground speed to use range finder as the primary height source (m/s) 358 : AP_Int8 _magMask; // Bitmask forcng specific EKF core instances to use simple heading magnetometer fusion. 359 : AP_Int8 _originHgtMode; // Bitmask controlling post alignment correction and reporting of the EKF origin height. 360 : AP_Int8 _flowUse; // Controls if the optical flow data is fused into the main navigation estimator and/or the terrain estimator. 361 : AP_Int16 _mag_ef_limit; // limit on difference between WMM tables and learned earth field. 362 : AP_Float _hrt_filt_freq; // frequency of output observer height rate complementary filter in Hz 363 : AP_Int8 _gsfRunMask; // mask controlling which EKF2 instances run a separate EKF-GSF yaw estimator 364 : AP_Int8 _gsfUseMask; // mask controlling which EKF2 instances will use EKF-GSF yaw estimator data to assit with yaw resets 365 : AP_Int8 _gsfResetMaxCount; // maximum number of times the EKF2 is allowed to reset it's yaw to the EKF-GSF estimate 366 : AP_Int32 _options; // optional behaviour bitmask 367 : 368 : // enum for processing options 369 : enum class Option { 370 : DisableExternalNav = (1U<<0), 371 : }; 372 : 373 : // return true if an option is set 374 14347 : bool option_is_set(Option option) const { 375 14347 : return (uint32_t(option) & uint32_t(_options)) != 0; 376 : } 377 : 378 : // Possible values for _flowUse 379 : #define FLOW_USE_NONE 0 380 : #define FLOW_USE_NAV 1 381 : #define FLOW_USE_TERRAIN 2 382 : 383 : // Tuning parameters 384 : const float gpsNEVelVarAccScale = 0.05f; // Scale factor applied to NE velocity measurement variance due to manoeuvre acceleration 385 : const float gpsDVelVarAccScale = 0.07f; // Scale factor applied to vertical velocity measurement variance due to manoeuvre acceleration 386 : const float extNavVelVarAccScale = 0.05f; // Scale factor applied to ext nav velocity measurement variance due to manoeuvre acceleration 387 : const float gpsPosVarAccScale = 0.05f; // Scale factor applied to horizontal position measurement variance due to manoeuvre acceleration 388 : const uint8_t magDelay_ms = 60; // Magnetometer measurement delay (msec) 389 : const uint8_t tasDelay_ms = 240; // Airspeed measurement delay (msec) 390 : const uint16_t tiltDriftTimeMax_ms = 15000; // Maximum number of ms allowed without any form of tilt aiding (GPS, flow, TAS, etc) 391 : const uint16_t posRetryTimeUseVel_ms = 10000; // Position aiding retry time with velocity measurements (msec) 392 : const uint16_t posRetryTimeNoVel_ms = 7000; // Position aiding retry time without velocity measurements (msec) 393 : const uint16_t hgtRetryTimeMode0_ms = 10000; // Height retry time with vertical velocity measurement (msec) 394 : const uint16_t hgtRetryTimeMode12_ms = 5000; // Height retry time without vertical velocity measurement (msec) 395 : const uint16_t tasRetryTime_ms = 5000; // True airspeed timeout and retry interval (msec) 396 : const uint16_t magFailTimeLimit_ms = 10000; // number of msec before a magnetometer failing innovation consistency checks is declared failed (msec) 397 : const float magVarRateScale = 0.005f; // scale factor applied to magnetometer variance due to angular rate 398 : const float gyroBiasNoiseScaler = 2.0f; // scale factor applied to gyro bias state process noise when on ground 399 : const uint8_t hgtAvg_ms = 100; // average number of msec between height measurements 400 : const uint8_t betaAvg_ms = 100; // average number of msec between synthetic sideslip measurements 401 : const float covTimeStepMax = 0.1f; // maximum time (sec) between covariance prediction updates 402 : const float covDelAngMax = 0.05f; // maximum delta angle between covariance prediction updates 403 : 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. 404 : const float fScaleFactorPnoise = 1e-10f; // Process noise added to focal length scale factor state variance at each time step 405 : const uint8_t flowTimeDeltaAvg_ms = 100; // average interval between optical flow measurements (msec) 406 : const uint8_t flowIntervalMax_ms = 100; // maximum allowable time between flow fusion events 407 : const float gndEffectBaroScaler = 4.0f; // scaler applied to the barometer observation variance when ground effect mode is active 408 : const uint8_t fusionTimeStep_ms = 10; // The minimum time interval between covariance predictions and measurement fusions in msec 409 : const float maxYawEstVelInnov = 2.0f; // Maximum acceptable length of the velocity innovation returned by the EKF-GSF yaw estimator (m/s) 410 : 411 : // origin set by one of the cores 412 : Location common_EKF_origin; 413 : bool common_origin_valid; 414 : 415 : // time at start of current filter update 416 : uint64_t imuSampleTime_us; 417 : 418 : // last time of Log_Write 419 : uint64_t lastLogWrite_us; 420 : 421 : struct { 422 : uint16_t count; // count of yaw reset events passed to consumers 423 : uint16_t last_core_count; // primary core's yaw reset count when count last changed 424 : } yaw_reset_data; 425 : 426 : struct { 427 : uint16_t count; // count of NE position reset events passed to consumers 428 : uint16_t last_core_count; // primary core's NE position reset count when count last changed 429 : } pos_reset_data; 430 : 431 : struct { 432 : uint16_t count; // count of D position reset events passed to consumers 433 : uint16_t last_core_count; // primary core's D position reset count when count last changed 434 : } pos_down_reset_data; 435 : 436 : bool runCoreSelection; // true when the primary core has stabilised and the core selection logic can be started 437 : 438 : // time of last lane switch 439 : uint32_t lastLaneSwitch_ms; 440 : 441 : enum class InitFailures { 442 : UNKNOWN, 443 : NO_ENABLE, 444 : NO_IMUS, 445 : NO_MASK, 446 : NO_MEM, 447 : NO_SETUP, 448 : NUM_INIT_FAILURES 449 : }; 450 : InitFailures initFailure; 451 : 452 : // update the yaw reset data to capture changes due to a lane switch 453 : // new_primary - index of the ekf instance that we are about to switch to as the primary 454 : // old_primary - index of the ekf instance that we are currently using as the primary 455 : void updateLaneSwitchYawResetData(uint8_t new_primary); 456 : 457 : // update the position reset data to capture changes due to a lane switch 458 : // new_primary - index of the ekf instance that we are about to switch to as the primary 459 : // old_primary - index of the ekf instance that we are currently using as the primary 460 : void updateLaneSwitchPosResetData(uint8_t new_primary); 461 : 462 : // update the position down reset data to capture changes due to a lane switch 463 : // new_primary - index of the ekf instance that we are about to switch to as the primary 464 : // old_primary - index of the ekf instance that we are currently using as the primary 465 : void updateLaneSwitchPosDownResetData(uint8_t new_primary); 466 : 467 : // return true if a new core has a better score than an existing core, including 468 : // checks for alignment 469 : bool coreBetterScore(uint8_t new_core, uint8_t current_core) const; 470 : };