45 #include <mathlib/mathlib.h> 71 v_tas_pred = sqrtf((ve - vwe) * (ve - vwe) + (vn - vwn) * (vn - vwn) + vd * vd);
74 if (v_tas_pred > 1.0
f) {
80 SH_TAS[0] = 1.0f/v_tas_pred;
81 SH_TAS[1] = (SH_TAS[0]*(2.0f*ve - 2.0f*vwe))*0.5f;
82 SH_TAS[2] = (SH_TAS[0]*(2.0f*vn - 2.0f*vwn))*0.5f;
84 for (uint8_t i = 0; i <
_k_num_states; i++) { H_TAS[i] = 0.0f; }
88 H_TAS[6] = vd*SH_TAS[0];
89 H_TAS[22] = -SH_TAS[2];
90 H_TAS[23] = -SH_TAS[1];
93 float _airspeed_innov_var_temp = (R_TAS + SH_TAS[2]*(
P[4][4]*SH_TAS[2] +
P[5][4]*SH_TAS[1] -
P[22][4]*SH_TAS[2] -
P[23][4]*SH_TAS[1] +
P[6][4]*vd*SH_TAS[0]) + SH_TAS[1]*(
P[4][5]*SH_TAS[2] +
P[5][5]*SH_TAS[1] -
P[22][5]*SH_TAS[2] -
P[23][5]*SH_TAS[1] +
P[6][5]*vd*SH_TAS[0]) - SH_TAS[2]*(
P[4][22]*SH_TAS[2] +
P[5][22]*SH_TAS[1] -
P[22][22]*SH_TAS[2] -
P[23][22]*SH_TAS[1] +
P[6][22]*vd*SH_TAS[0]) - SH_TAS[1]*(
P[4][23]*SH_TAS[2] +
P[5][23]*SH_TAS[1] -
P[22][23]*SH_TAS[2] -
P[23][23]*SH_TAS[1] +
P[6][23]*vd*SH_TAS[0]) + vd*SH_TAS[0]*(
P[4][6]*SH_TAS[2] +
P[5][6]*SH_TAS[1] -
P[22][6]*SH_TAS[2] -
P[23][6]*SH_TAS[1] +
P[6][6]*vd*SH_TAS[0]));
95 if (_airspeed_innov_var_temp >= R_TAS) {
96 SK_TAS[0] = 1.0f / _airspeed_innov_var_temp;
103 if (update_wind_only) {
117 SK_TAS[1] = SH_TAS[1];
119 if (update_wind_only) {
121 for (
unsigned row = 0; row <= 21; row++) {
127 Kfusion[0] = SK_TAS[0]*(
P[0][4]*SH_TAS[2] -
P[0][22]*SH_TAS[2] +
P[0][5]*SK_TAS[1] -
P[0][23]*SK_TAS[1] +
P[0][6]*vd*SH_TAS[0]);
128 Kfusion[1] = SK_TAS[0]*(
P[1][4]*SH_TAS[2] -
P[1][22]*SH_TAS[2] +
P[1][5]*SK_TAS[1] -
P[1][23]*SK_TAS[1] +
P[1][6]*vd*SH_TAS[0]);
129 Kfusion[2] = SK_TAS[0]*(
P[2][4]*SH_TAS[2] -
P[2][22]*SH_TAS[2] +
P[2][5]*SK_TAS[1] -
P[2][23]*SK_TAS[1] +
P[2][6]*vd*SH_TAS[0]);
130 Kfusion[3] = SK_TAS[0]*(
P[3][4]*SH_TAS[2] -
P[3][22]*SH_TAS[2] +
P[3][5]*SK_TAS[1] -
P[3][23]*SK_TAS[1] +
P[3][6]*vd*SH_TAS[0]);
131 Kfusion[4] = SK_TAS[0]*(
P[4][4]*SH_TAS[2] -
P[4][22]*SH_TAS[2] +
P[4][5]*SK_TAS[1] -
P[4][23]*SK_TAS[1] +
P[4][6]*vd*SH_TAS[0]);
132 Kfusion[5] = SK_TAS[0]*(
P[5][4]*SH_TAS[2] -
P[5][22]*SH_TAS[2] +
P[5][5]*SK_TAS[1] -
P[5][23]*SK_TAS[1] +
P[5][6]*vd*SH_TAS[0]);
133 Kfusion[6] = SK_TAS[0]*(
P[6][4]*SH_TAS[2] -
P[6][22]*SH_TAS[2] +
P[6][5]*SK_TAS[1] -
P[6][23]*SK_TAS[1] +
P[6][6]*vd*SH_TAS[0]);
134 Kfusion[7] = SK_TAS[0]*(
P[7][4]*SH_TAS[2] -
P[7][22]*SH_TAS[2] +
P[7][5]*SK_TAS[1] -
P[7][23]*SK_TAS[1] +
P[7][6]*vd*SH_TAS[0]);
135 Kfusion[8] = SK_TAS[0]*(
P[8][4]*SH_TAS[2] -
P[8][22]*SH_TAS[2] +
P[8][5]*SK_TAS[1] -
P[8][23]*SK_TAS[1] +
P[8][6]*vd*SH_TAS[0]);
136 Kfusion[9] = SK_TAS[0]*(
P[9][4]*SH_TAS[2] -
P[9][22]*SH_TAS[2] +
P[9][5]*SK_TAS[1] -
P[9][23]*SK_TAS[1] +
P[9][6]*vd*SH_TAS[0]);
137 Kfusion[10] = SK_TAS[0]*(
P[10][4]*SH_TAS[2] -
P[10][22]*SH_TAS[2] +
P[10][5]*SK_TAS[1] -
P[10][23]*SK_TAS[1] +
P[10][6]*vd*SH_TAS[0]);
138 Kfusion[11] = SK_TAS[0]*(
P[11][4]*SH_TAS[2] -
P[11][22]*SH_TAS[2] +
P[11][5]*SK_TAS[1] -
P[11][23]*SK_TAS[1] +
P[11][6]*vd*SH_TAS[0]);
139 Kfusion[12] = SK_TAS[0]*(
P[12][4]*SH_TAS[2] -
P[12][22]*SH_TAS[2] +
P[12][5]*SK_TAS[1] -
P[12][23]*SK_TAS[1] +
P[12][6]*vd*SH_TAS[0]);
140 Kfusion[13] = SK_TAS[0]*(
P[13][4]*SH_TAS[2] -
P[13][22]*SH_TAS[2] +
P[13][5]*SK_TAS[1] -
P[13][23]*SK_TAS[1] +
P[13][6]*vd*SH_TAS[0]);
141 Kfusion[14] = SK_TAS[0]*(
P[14][4]*SH_TAS[2] -
P[14][22]*SH_TAS[2] +
P[14][5]*SK_TAS[1] -
P[14][23]*SK_TAS[1] +
P[14][6]*vd*SH_TAS[0]);
142 Kfusion[15] = SK_TAS[0]*(
P[15][4]*SH_TAS[2] -
P[15][22]*SH_TAS[2] +
P[15][5]*SK_TAS[1] -
P[15][23]*SK_TAS[1] +
P[15][6]*vd*SH_TAS[0]);
143 Kfusion[16] = SK_TAS[0]*(
P[16][4]*SH_TAS[2] -
P[16][22]*SH_TAS[2] +
P[16][5]*SK_TAS[1] -
P[16][23]*SK_TAS[1] +
P[16][6]*vd*SH_TAS[0]);
144 Kfusion[17] = SK_TAS[0]*(
P[17][4]*SH_TAS[2] -
P[17][22]*SH_TAS[2] +
P[17][5]*SK_TAS[1] -
P[17][23]*SK_TAS[1] +
P[17][6]*vd*SH_TAS[0]);
145 Kfusion[18] = SK_TAS[0]*(
P[18][4]*SH_TAS[2] -
P[18][22]*SH_TAS[2] +
P[18][5]*SK_TAS[1] -
P[18][23]*SK_TAS[1] +
P[18][6]*vd*SH_TAS[0]);
146 Kfusion[19] = SK_TAS[0]*(
P[19][4]*SH_TAS[2] -
P[19][22]*SH_TAS[2] +
P[19][5]*SK_TAS[1] -
P[19][23]*SK_TAS[1] +
P[19][6]*vd*SH_TAS[0]);
147 Kfusion[20] = SK_TAS[0]*(
P[20][4]*SH_TAS[2] -
P[20][22]*SH_TAS[2] +
P[20][5]*SK_TAS[1] -
P[20][23]*SK_TAS[1] +
P[20][6]*vd*SH_TAS[0]);
148 Kfusion[21] = SK_TAS[0]*(
P[21][4]*SH_TAS[2] -
P[21][22]*SH_TAS[2] +
P[21][5]*SK_TAS[1] -
P[21][23]*SK_TAS[1] +
P[21][6]*vd*SH_TAS[0]);
150 Kfusion[22] = SK_TAS[0]*(
P[22][4]*SH_TAS[2] -
P[22][22]*SH_TAS[2] +
P[22][5]*SK_TAS[1] -
P[22][23]*SK_TAS[1] +
P[22][6]*vd*SH_TAS[0]);
151 Kfusion[23] = SK_TAS[0]*(
P[23][4]*SH_TAS[2] -
P[23][22]*SH_TAS[2] +
P[23][5]*SK_TAS[1] -
P[23][23]*SK_TAS[1] +
P[23][6]*vd*SH_TAS[0]);
184 KH[0] = Kfusion[row] * H_TAS[4];
185 KH[1] = Kfusion[row] * H_TAS[5];
186 KH[2] = Kfusion[row] * H_TAS[6];
187 KH[3] = Kfusion[row] * H_TAS[22];
188 KH[4] = Kfusion[row] * H_TAS[23];
190 for (
unsigned column = 0; column <
_k_num_states; column++) {
191 float tmp = KH[0] *
P[4][column];
192 tmp += KH[1] * P[5][column];
193 tmp += KH[2] * P[6][column];
194 tmp += KH[3] * P[22][column];
195 tmp += KH[4] * P[23][column];
196 KHP[row][column] = tmp;
206 if (
P[i][i] < KHP[i][i]) {
224 for (
unsigned column = 0; column <
_k_num_states; column++) {
225 P[row][column] =
P[row][column] - KHP[row][column];
233 fuse(Kfusion, _airspeed_innov);
247 wind_var[0] =
P[22][22];
248 wind_var[1] =
P[23][23];
254 memcpy(tas, &tempvar,
sizeof(
float));
264 float euler_yaw = euler321(2);
float tas_innov_gate
True Airspeed innovation consistency gate size (STD)
constexpr _Tp constrain(_Tp val, _Tp min_val, _Tp max_val)
stateSample _state
state struct of the ekf running at the delayed time horizon
#define ECL_ERR_TIMESTAMPED
void get_true_airspeed(float *tas) override
void initialiseCovariance()
bool _is_wind_dead_reckoning
airspeedSample _airspeed_sample_delayed
struct estimator::fault_status_u::@57 flags
float P[_k_num_states][_k_num_states]
state covariance matrix
void zeroCols(float(&cov_mat)[_k_num_states][_k_num_states], uint8_t first, uint8_t last)
void get_wind_velocity(float *wind) override
float eas_noise
EAS measurement noise standard deviation used for airspeed fusion (m/s)
void fuse(float *K, float innovation)
uint64_t time_us
timestamp of the measurement (uSec)
float eas2tas
equivalent to true airspeed factor
bool bad_airspeed
5 - true if fusion of the airspeed has encountered a numerical error
uint64_t time_us
timestamp of the measurement (uSec)
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
Vector3f vel
NED velocity in earth frame in m/s.
static constexpr float sq(float var)
bool _tas_data_ready
true when new true airspeed data has fallen behind the fusion time horizon and is available to be fus...
fault_status_u _fault_status
float _airspeed_innov_var
airspeed measurement innovation variance ((m/sec)**2)
void fixCovarianceErrors()
imuSample _imu_sample_delayed
Quatf quat_nominal
quaternion defining the rotation from body to earth frame
void resetWindCovariance()
innovation_fault_status_u _innov_check_fail_status
float true_airspeed
true airspeed measurement (m/sec)
uint64_t _time_last_arsp_fuse
time the last fusion of airspeed measurements were performed (uSec)
void zeroRows(float(&cov_mat)[_k_num_states][_k_num_states], uint8_t first, uint8_t last)
float _airspeed_innov
airspeed measurement innovation (m/sec)
void get_wind_velocity_var(float *wind_var) override
struct estimator::innovation_fault_status_u::@58 flags
Vector2f wind_vel
wind velocity in m/s
bool reject_airspeed
7 - true if the airspeed observation has been rejected
static constexpr uint8_t _k_num_states
number of EKF states
Class for core functions for ekf attitude and position estimator.