|
|
|
@ -1317,6 +1317,7 @@ void NavEKF3_core::CovariancePrediction(Vector3f *rotVarVecPtr)
@@ -1317,6 +1317,7 @@ void NavEKF3_core::CovariancePrediction(Vector3f *rotVarVecPtr)
|
|
|
|
|
P[row][column] = P[column][row] = nextP[column][row]; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
calcTiltErrorVariance(); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1659,6 +1660,8 @@ void NavEKF3_core::CovariancePrediction(Vector3f *rotVarVecPtr)
@@ -1659,6 +1660,8 @@ void NavEKF3_core::CovariancePrediction(Vector3f *rotVarVecPtr)
|
|
|
|
|
// constrain values to prevent ill-conditioning
|
|
|
|
|
ConstrainVariances(); |
|
|
|
|
|
|
|
|
|
calcTiltErrorVariance(); |
|
|
|
|
|
|
|
|
|
hal.util->perf_end(_perf_CovariancePrediction); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1938,47 +1941,50 @@ void NavEKF3_core::zeroAttCovOnly()
@@ -1938,47 +1941,50 @@ void NavEKF3_core::zeroAttCovOnly()
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// calculate the variances for the rotation vector equivalent
|
|
|
|
|
Vector3f NavEKF3_core::calcRotVecVariances() |
|
|
|
|
// calculate the tilt error variance
|
|
|
|
|
void NavEKF3_core::calcTiltErrorVariance() |
|
|
|
|
{ |
|
|
|
|
Vector3f rotVarVec; |
|
|
|
|
float q0 = stateStruct.quat[0]; |
|
|
|
|
float q1 = stateStruct.quat[1]; |
|
|
|
|
float q2 = stateStruct.quat[2]; |
|
|
|
|
float q3 = stateStruct.quat[3]; |
|
|
|
|
if (q0 < 0) { |
|
|
|
|
q0 = -q0; |
|
|
|
|
q1 = -q1; |
|
|
|
|
q2 = -q2; |
|
|
|
|
q3 = -q3; |
|
|
|
|
} |
|
|
|
|
float t2 = q0*q0; |
|
|
|
|
float t3 = acosf(q0); |
|
|
|
|
float t4 = -t2+1.0f; |
|
|
|
|
float t5 = t2-1.0f; |
|
|
|
|
if ((t4 > 1e-9f) && (t5 < -1e-9f)) { |
|
|
|
|
float t6 = 1.0f/t5; |
|
|
|
|
float t7 = q1*t6*2.0f; |
|
|
|
|
float t8 = 1.0f/powf(t4,1.5f); |
|
|
|
|
float t9 = q0*q1*t3*t8*2.0f; |
|
|
|
|
float t10 = t7+t9; |
|
|
|
|
float t11 = 1.0f/sqrtf(t4); |
|
|
|
|
float t12 = q2*t6*2.0f; |
|
|
|
|
float t13 = q0*q2*t3*t8*2.0f; |
|
|
|
|
float t14 = t12+t13; |
|
|
|
|
float t15 = q3*t6*2.0f; |
|
|
|
|
float t16 = q0*q3*t3*t8*2.0f; |
|
|
|
|
float t17 = t15+t16; |
|
|
|
|
rotVarVec.x = t10*(P[0][0]*t10+P[1][0]*t3*t11*2.0f)+t3*t11*(P[0][1]*t10+P[1][1]*t3*t11*2.0f)*2.0f; |
|
|
|
|
rotVarVec.y = t14*(P[0][0]*t14+P[2][0]*t3*t11*2.0f)+t3*t11*(P[0][2]*t14+P[2][2]*t3*t11*2.0f)*2.0f; |
|
|
|
|
rotVarVec.z = t17*(P[0][0]*t17+P[3][0]*t3*t11*2.0f)+t3*t11*(P[0][3]*t17+P[3][3]*t3*t11*2.0f)*2.0f; |
|
|
|
|
} else { |
|
|
|
|
rotVarVec.x = 4.0f * P[1][1]; |
|
|
|
|
rotVarVec.y = 4.0f * P[2][2]; |
|
|
|
|
rotVarVec.z = 4.0f * P[3][3]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return rotVarVec; |
|
|
|
|
const float &q0 = stateStruct.quat[0]; |
|
|
|
|
const float &q1 = stateStruct.quat[1]; |
|
|
|
|
const float &q2 = stateStruct.quat[2]; |
|
|
|
|
const float &q3 = stateStruct.quat[3]; |
|
|
|
|
|
|
|
|
|
// equations generated by quaternion_error_propagation(): in AP_NavEKF3/derivation/main.py
|
|
|
|
|
// only diagonals have been used
|
|
|
|
|
// dq0 ... dq3 terms have been zeroed
|
|
|
|
|
const float PS1 = q0*q1 + q2*q3; |
|
|
|
|
const float PS2 = q1*PS1; |
|
|
|
|
const float PS4 = sq(q0) - sq(q1) - sq(q2) + sq(q3); |
|
|
|
|
const float PS5 = q0*PS4; |
|
|
|
|
const float PS6 = 2*PS2 + PS5; |
|
|
|
|
const float PS8 = PS1*q2; |
|
|
|
|
const float PS10 = PS4*q3; |
|
|
|
|
const float PS11 = PS10 + 2*PS8; |
|
|
|
|
const float PS12 = PS1*q3; |
|
|
|
|
const float PS13 = PS4*q2; |
|
|
|
|
const float PS14 = -2*PS12 + PS13; |
|
|
|
|
const float PS15 = PS1*q0; |
|
|
|
|
const float PS16 = q1*PS4; |
|
|
|
|
const float PS17 = 2*PS15 - PS16; |
|
|
|
|
const float PS18 = q0*q2 - q1*q3; |
|
|
|
|
const float PS19 = PS18*q2; |
|
|
|
|
const float PS20 = 2*PS19 + PS5; |
|
|
|
|
const float PS22 = q1*PS18; |
|
|
|
|
const float PS23 = -PS10 + 2*PS22; |
|
|
|
|
const float PS25 = PS18*q3; |
|
|
|
|
const float PS26 = PS16 + 2*PS25; |
|
|
|
|
const float PS28 = PS18*q0; |
|
|
|
|
const float PS29 = -PS13 + 2*PS28; |
|
|
|
|
const float PS32 = PS12 + PS28; |
|
|
|
|
const float PS33 = PS19 + PS2; |
|
|
|
|
const float PS34 = PS15 - PS25; |
|
|
|
|
const float PS35 = PS22 - PS8; |
|
|
|
|
|
|
|
|
|
tiltErrorVariance = 4*sq(PS11)*P[2][2] + 4*sq(PS14)*P[3][3] + 4*sq(PS17)*P[0][0] + 4*sq(PS6)*P[1][1]; |
|
|
|
|
tiltErrorVariance += 4*sq(PS20)*P[2][2] + 4*sq(PS23)*P[1][1] + 4*sq(PS26)*P[3][3] + 4*sq(PS29)*P[0][0]; |
|
|
|
|
tiltErrorVariance += 16*sq(PS32)*P[1][1] + 16*sq(PS33)*P[3][3] + 16*sq(PS34)*P[2][2] + 16*sq(PS35)*P[0][0]; |
|
|
|
|
|
|
|
|
|
tiltErrorVariance = constrain_float(tiltErrorVariance, 0.0f, sq(radians(30.0f))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void NavEKF3_core::bestRotationOrder(rotationOrder &order) |
|
|
|
|