@ -252,6 +252,7 @@ void NavEKF3_core::InitialiseVariables()
@@ -252,6 +252,7 @@ void NavEKF3_core::InitialiseVariables()
lastYawReset_ms = 0 ;
tiltAlignComplete = false ;
yawAlignComplete = false ;
have_table_earth_field = false ;
stateIndexLim = 23 ;
baroStoreIndex = 0 ;
rangeStoreIndex = 0 ;
@ -1539,6 +1540,22 @@ void NavEKF3_core::ConstrainVariances()
@@ -1539,6 +1540,22 @@ void NavEKF3_core::ConstrainVariances()
}
}
// constrain states using WMM tables and specified limit
void NavEKF3_core : : MagTableConstrain ( void )
{
// constrain to error from table earth field
float limit_ga = frontend - > _mag_ef_limit * 0.001f ;
stateStruct . earth_magfield . x = constrain_float ( stateStruct . earth_magfield . x ,
table_earth_field_ga . x - limit_ga ,
table_earth_field_ga . x + limit_ga ) ;
stateStruct . earth_magfield . y = constrain_float ( stateStruct . earth_magfield . y ,
table_earth_field_ga . y - limit_ga ,
table_earth_field_ga . y + limit_ga ) ;
stateStruct . earth_magfield . z = constrain_float ( stateStruct . earth_magfield . z ,
table_earth_field_ga . z - limit_ga ,
table_earth_field_ga . z + limit_ga ) ;
}
// constrain states to prevent ill-conditioning
void NavEKF3_core : : ConstrainStates ( )
{
@ -1555,7 +1572,13 @@ void NavEKF3_core::ConstrainStates()
@@ -1555,7 +1572,13 @@ void NavEKF3_core::ConstrainStates()
// the accelerometer bias limit is controlled by a user adjustable parameter
for ( uint8_t i = 13 ; i < = 15 ; i + + ) statesArray [ i ] = constrain_float ( statesArray [ i ] , - frontend - > _accBiasLim * dtEkfAvg , frontend - > _accBiasLim * dtEkfAvg ) ;
// earth magnetic field limit
for ( uint8_t i = 16 ; i < = 18 ; i + + ) statesArray [ i ] = constrain_float ( statesArray [ i ] , - 1.0f , 1.0f ) ;
if ( frontend - > _mag_ef_limit < = 0 | | ! have_table_earth_field ) {
// constrain to +/-1Ga
for ( uint8_t i = 16 ; i < = 18 ; i + + ) statesArray [ i ] = constrain_float ( statesArray [ i ] , - 1.0f , 1.0f ) ;
} else {
// use table constrain
MagTableConstrain ( ) ;
}
// body magnetic field limit
for ( uint8_t i = 19 ; i < = 21 ; i + + ) statesArray [ i ] = constrain_float ( statesArray [ i ] , - 0.5f , 0.5f ) ;
// wind velocity limit 100 m/s (could be based on some multiple of max airspeed * EAS2TAS) - TODO apply circular limit
@ -1599,7 +1622,7 @@ Quaternion NavEKF3_core::calcQuatAndFieldStates(float roll, float pitch)
@@ -1599,7 +1622,7 @@ Quaternion NavEKF3_core::calcQuatAndFieldStates(float roll, float pitch)
float magHeading = atan2f ( initMagNED . y , initMagNED . x ) ;
// get the magnetic declination
float magDecAng = use_compass ( ) ? _ahrs - > get_compass ( ) - > get_d eclination( ) : 0 ;
float magDecAng = MagD eclination( ) ;
// calculate yaw angle rel to true north
yaw = magDecAng - magHeading ;
@ -1624,7 +1647,11 @@ Quaternion NavEKF3_core::calcQuatAndFieldStates(float roll, float pitch)
@@ -1624,7 +1647,11 @@ Quaternion NavEKF3_core::calcQuatAndFieldStates(float roll, float pitch)
// don't do this if the earth field has already been learned
if ( ! magFieldLearned ) {
initQuat . rotation_matrix ( Tbn ) ;
stateStruct . earth_magfield = Tbn * magDataDelayed . mag ;
if ( have_table_earth_field & & frontend - > _mag_ef_limit > 0 ) {
stateStruct . earth_magfield = table_earth_field_ga ;
} else {
stateStruct . earth_magfield = Tbn * magDataDelayed . mag ;
}
// set the NE earth magnetic field states using the published declination
// and set the corresponding variances and covariances