52 Matrix3f P_att = Matrix3f::Identity() * config.
P_ATT;
53 Matrix3f P_bias = Matrix3f::Identity() * config.
P_BIAS;
54 P << P_pos, MatrixXf::Zero(3, 9),
55 MatrixXf::Zero(3, 3), P_vel, MatrixXf::Zero(3, 6),
56 MatrixXf::Zero(3, 6), P_att, MatrixXf::Zero(3, 3),
57 MatrixXf::Zero(3, 9), P_bias;
78 F_lin = Matrix<float, 6, 6>::Identity();
79 F_lin.block<3, 3>(0, 3) = config.
T * Matrix3f::Identity();
80 F_lin_tr = F_lin.transpose();
82 F_quat << -Matrix3f::Identity(), -Matrix3f::Identity() * config.
T,
83 Matrix3f::Zero(3, 3), Matrix3f::Identity();
84 F_quat_tr = F_quat.transpose();
86 G_quat << -Matrix3f::Identity(), Matrix3f::Zero(3, 3),
87 Matrix3f::Zero(3, 3), Matrix3f::Identity();
88 G_quat_tr = G_quat.transpose();
95 Vector3f pos = x.block<3, 1>(
IDX_POS, 0);
96 Vector3f vel = x.block<3, 1>(
IDX_VEL, 0);
99 pos = pos + vel * config.
T;
102 Vector3f a = A * acceleration - gravityNed;
105 vel = vel + a * config.
T;
108 x.block<3, 1>(
IDX_POS, 0) = pos;
109 x.block<3, 1>(
IDX_VEL, 0) = vel;
112 Matrix<float, 6, 6> Pl = P.block<6, 6>(0, 0);
113 P.block<6, 6>(0, 0) = F_lin * Pl * F_lin_tr + Q_lin;
124 Vector3f bias = x.block<3, 1>(
IDX_BIAS, 0);
125 Vector4f q = x.block<4, 1>(
IDX_QUAT, 0);
127 Vector3f omega = angularSpeed - bias;
130 { 0.0f, omega(2), -omega(1), omega(0)},
131 {-omega(2), 0.0f, omega(0), omega(1)},
132 { omega(1), -omega(0), 0.0f, omega(2)},
133 {-omega(0), -omega(1), -omega(2), 0.0f}
138 q = (Matrix4f::Identity() + 0.5F * omega_mat * config.
T) * q;
147 Pq = F_quat * Pq * F_quat_tr + G_quat * Q_quat * G_quat_tr;
153 predictGyro(Vector3f{angularSpeed.angularSpeedX, angularSpeed.angularSpeedY,
154 angularSpeed.angularSpeedZ});
164 Matrix<float, 1, 6> H = Matrix<float, 1, 6>::Zero();
168 H[2] = Constants::a * Constants::n * reference.
refPressure *
169 powf(1 + Constants::a * d / temp, Constants::n - 1) / temp;
171 Matrix<float, 6, 6> Pl = P.block<6, 6>(0, 0);
172 float S = H * Pl * H.transpose() + R;
181 Matrix<float, 1, 1> e = Matrix<float, 1, 1>(pressure - y_hat);
182 Matrix<float, 6, 1> K = Pl * H.transpose() / S;
183 P.block<6, 6>(0, 0) = (Matrix<float, 6, 6>::Identity() - K * H) * Pl;
186 x.head<6>() = x.head<6>() + K * e;
192 H_gps = Matrix<float, 4, 6>::Zero();
195 float angle_rad = (reference.
refLatitude + x(0) / Constants::gpsLatConst) *
196 Constants::DEGREES_TO_RADIANS;
198 float H11 = 1 / Constants::gpsLatConst;
200 float H21 = (x(1) * sin(angle_rad)) /
201 (Constants::gpsLatConst * Constants::gpsLonConst *
202 pow(cos(angle_rad), 2));
203 float H22 = 1 / (Constants::gpsLonConst * cos(angle_rad));
206 H_gps.coeffRef(0, 0) = H11 * 1000;
207 H_gps.coeffRef(0, 1) = H12 * 1000;
208 H_gps.coeffRef(1, 0) = H21 * 1000;
209 H_gps.coeffRef(1, 1) = H22 * 1000;
211 H_gps.coeffRef(2, 3) = 1;
212 H_gps.coeffRef(3, 4) = 1;
214 H_gps_tr = H_gps.transpose();
216 Matrix<float, 1, 4> R_molt = {1, 1, std::max(std::abs(gps(2)), 30.0f),
217 std::max(std::abs(gps(3)), 30.0f)};
218 Matrix<float, 4, 4> R_gps = config.
SIGMA_GPS.asDiagonal().toDenseMatrix() *
219 config.
SIGMA_GPS.asDiagonal().toDenseMatrix() *
220 R_molt.asDiagonal().toDenseMatrix();
223 float lat = x(0) / Constants::gpsLatConst + reference.
refLatitude;
224 float lon = x(1) / (Constants::gpsLonConst *
225 cos(lat * Constants::DEGREES_TO_RADIANS)) +
227 Matrix<float, 4, 1> z{lat, lon, x(3), x(4)};
228 Vector4f e{(gps(0) - z(0)) * 1000.0f, (gps(1) - z(1)) * 1000.0f,
229 gps(2) - z(2), gps(3) - z(3)};
231 Matrix<float, 6, 6> Pl = P.block<6, 6>(0, 0);
233 Matrix<float, 4, 4> S = H_gps * Pl * H_gps_tr + R_gps;
236 if (S.determinant() < 1e-3)
239 Matrix<float, 6, 4> K = Pl * H_gps_tr * S.inverse();
242 x.head<6>() = x.head<6>() + K * e;
244 P.block<6, 6>(0, 0) = (Matrix<float, 6, 6>::Identity() - K * H_gps) * Pl;
252 correctGPS(Vector4f{gps.latitude, gps.longitude, gps.velocityNorth,
258 Vector4f q = x.block<4, 1>(
IDX_QUAT, 0);
262 Vector3f mEst = A * config.
NED_MAG;
266 { 0, -mEst(2), mEst(1)},
267 { mEst(2), 0, -mEst(0)},
268 {-mEst(1), mEst(0), 0}
272 Matrix<float, 3, 6> H;
273 H << M, Matrix3f::Zero(3, 3);
275 Matrix<float, 3, 3> S = H * Pq * H.transpose() + R_mag;
277 Matrix<float, 6, 3> K = Pq * H.transpose() * S.inverse();
278 Matrix<float, 6, 1> dx = K * (mag - mEst);
279 Vector4f r{0.5f * dx(0), 0.5f * dx(1), 0.5f * dx(2),
280 sqrtf(1.0f - 0.25f * dx.head<3>().squaredNorm())};
283 x.block<3, 1>(
IDX_BIAS, 0) += dx.tail<3>();
284 Matrix<float, 6, 6> tmp = Matrix<float, 6, 6>::Identity() - K * H;
285 Pq = tmp * Pq * tmp.transpose() + K * R_mag * K.transpose();
291 Vector3f magV = {mag.magneticFieldX, mag.magneticFieldY,
298 Vector4f q = x.block<4, 1>(
IDX_QUAT, 0);
302 Vector3f aEst = A * gravityNed;
308 { 0, -aEst(2), aEst(1)},
309 { aEst(2), 0, -aEst(0)},
310 {-aEst(1), aEst(0), 0}
314 Matrix<float, 3, 6> H;
315 H << M, Matrix3f::Zero(3, 3);
317 Matrix<float, 3, 3> S = H * Pq * H.transpose() + R_acc;
319 Matrix<float, 6, 3> K = Pq * H.transpose() * S.inverse();
320 Matrix<float, 6, 1> dx = K * (acc - aEst);
321 Vector4f r{0.5f * dx(0), 0.5f * dx(1), 0.5f * dx(2),
322 sqrtf(1.0f - 0.25f * dx.head<3>().squaredNorm())};
325 x.block<3, 1>(
IDX_BIAS, 0) += dx.tail<3>();
326 Matrix<float, 6, 6> tmp = Matrix<float, 6, 6>::Identity() - K * H;
327 Pq = tmp * Pq * tmp.transpose() + K * R_mag * K.transpose();
333 Vector3f accV = {acc.accelerationX, acc.accelerationY, acc.accelerationZ};
339 using namespace Constants;
341 const float d = x(2);
342 const float vd = x(5);
343 const float totalPressure = staticPressure + dynamicPressure;
344 const float relTemperature =
349 1 + (GAMMA_AIR - 1) / 2 * (vd * vd / (GAMMA_AIR * R * relTemperature));
351 Matrix<float, 1, 6> H = Matrix<float, 1, 6>::Zero();
352 H(0, 5) = -GAMMA_AIR * temp * vd;
360 Matrix<float, 6, 6> Pl = P.block<6, 6>(0, 0);
361 float S = H * Pl * H.transpose() + R;
368 std::pow(temp, (GAMMA_AIR / (GAMMA_AIR - 1))) - 1;
369 float y_measure = dynamicPressure / totalPressure;
371 float e = y_measure - y_hat;
372 Matrix<float, 6, 1> K = Pl * H.transpose() / S;
373 P.block<6, 6>(0, 0) = (Matrix<float, 6, 6>::Identity() - K * H) * Pl;
376 x.head<6>() = x.head<6>() + K * e;
388void NAS::setX(
const Matrix<float, 13, 1>& x) { this->x = x; }
392 this->reference = reference;
void predictGyro(const Eigen::Vector3f &angularSpeed)
Prediction with gyroscope data.
void correctPitot(const float staticPressure, const float dynamicPressure)
Correction with pitot pressures.
Eigen::Matrix< float, 13, 1 > getX() const
void predictAcc(const Eigen::Vector3f &acceleration)
Prediction with accelerometer data.
static constexpr uint16_t IDX_BIAS
NASState getState() const
void correctAcc(const Eigen::Vector3f &acc)
Correction with accelerometer data.
void correctMag(const Eigen::Vector3f &mag)
Correction with magnetometer data.
void setState(const NASState &state)
static constexpr uint16_t IDX_POS
< Index of position elements in the state.
void setReferenceValues(const ReferenceValues reference)
Changes the reference values.
void correctGPS(const Eigen::Vector4f &gps)
Correction with gps data.
void correctBaro(const float pressure)
Correction with barometer data.
static constexpr uint16_t IDX_VEL
Index of quaternions elements in the state.
ReferenceValues getReferenceValues()
Returns the current reference values.
static constexpr uint16_t IDX_QUAT
Index of bias elements in the state.
void setX(const Eigen::Matrix< float, 13, 1 > &x)
float relPressure(float altitude, float pressureRef, float temperatureRef)
Returns the pressure given the altitude with respect to a reference pressure and temperature,...
float relTemperature(float altitude, float temperatureRef)
Returns the temperature at the given altitude with respect to the reference temperature.
Matrix3f quat2rotationMatrix(const Vector4f &q)
Vector4f quatProd(const Vector4f &q1, const Vector4f &q2)
uint64_t getTimestamp()
Returns the current timer value in microseconds.
This file includes all the types the logdecoder script will decode.
Structure to handle accelerometer data.
Structure to handle GPS data.
Structure to handle gyroscope data.
Structure to handle magnetometer data.
float SIGMA_ACC
[m/s^2] Estimated accelerometer variance
Eigen::Vector4f SIGMA_GPS
float SIGMA_PITOT
[Pa] Estimated variance of the pitot velocity
float SIGMA_POS
[m] Estimated variance of the position noise
float P_ATT
Attitude prediction covariance.
float P_POS
Position prediction covariance horizontal.
float SIGMA_BETA
[rad/s^2] Estimated gyroscope bias variance
float P_BIAS
Bias prediction covariance.
Eigen::Vector3f NED_MAG
Normalized magnetic field vector in NED frame.
float SIGMA_W
[rad] Estimated gyroscope variance
float P_POS_VERTICAL
Position prediction covariance vertical.
float SIGMA_VEL
[m/s] Estimated variance of the velocity noise
float SIGMA_MAG
[uT] Estimated magnetometer variance
float P_VEL
Velocity prediction covariance horizontal.
float SIGMA_BAR
[Pa] Estimated altitude variance
float P_VEL_VERTICAL
Velocity prediction covariance vertical.
Eigen::Matrix< float, 13, 1 > getX() const
Reference values for the Apogee Detection Algorithm.