18 Eigen::MatrixXd P = Eigen::MatrixXd::Zero(numStates, numStates);
20 P.block<9, 9>(0, 0).diagonal() = initCovariances.at(0);
21 P.block<9, 9>(9, 9).diagonal() = initCovariances.at(1);
25 for (uint32_t i = 18; i < numStates; i += 6)
27 if (!imuCharacteristicsIdentical)
31 P.block<3, 3>(i, i).diagonal() = initCovariances.at(j);
32 P.block<3, 3>(i + 3, i + 3).diagonal() = initCovariances.at(j + 1);
38void NAV::BsplineKF::processNoiseMatrix_Q(Eigen::MatrixXd& Q,
const double& dt,
const std::vector<Eigen::VectorXd>& processNoiseVariances,
const uint8_t& numStates,
const bool& imuCharacteristicsIdentical)
40 Q.block<9, 9>(0, 0).diagonal() = processNoiseVariances.at(0) * dt;
41 Q.block<9, 9>(9, 9).diagonal() = processNoiseVariances.at(1) * dt;
45 for (uint32_t i = 18; i < numStates; i += 6)
47 if (!imuCharacteristicsIdentical)
51 Q.block<3, 3>(i, i).diagonal() = processNoiseVariances.at(j) * dt;
52 Q.block<3, 3>(i + 3, i + 3).diagonal() = processNoiseVariances.at(j + 1) * dt;
58 x.block<6, 1>(0, 0) = x.block<6, 1>(3, 0);
59 x.block<6, 1>(9, 0) = x.block<6, 1>(9, 0);
64 int nCoeffsPerStackedBspline = 9;
65 auto nCoeffsRemainingAngRate =
static_cast<int>(numStates) - nCoeffsPerStackedBspline;
66 auto nCoeffsRemainingAccel =
static_cast<int>(numStates) - 2 * nCoeffsPerStackedBspline;
69 P.block<6, 6>(0, 0) = P.block<6, 6>(3, 3);
70 P.block(0, 9, 6, nCoeffsRemainingAngRate) = P.block(3, 9, 6, nCoeffsRemainingAngRate);
71 P.block(9, 0, nCoeffsRemainingAngRate, 6) = P.block(9, 3, nCoeffsRemainingAngRate, 6);
74 P.block(0, 6, numStates, 3) = Eigen::MatrixXd::Zero(numStates, 3);
75 P.block(6, 0, 3, numStates) = Eigen::MatrixXd::Zero(3, numStates);
76 P.block<3, 3>(6, 6).diagonal() = std::pow(sigmaScalingFactorAngRate, 2) * P.block<3, 3>(3, 3).diagonal();
79 P.block<6, 6>(9, 9) = P.block<6, 6>(12, 12);
80 P.block<9, 6>(0, 9) = P.block<9, 6>(0, 12);
81 P.block(9, 18, 6, nCoeffsRemainingAccel) = P.block(12, 18, 6, nCoeffsRemainingAccel);
82 P.block<6, 9>(9, 0) = P.block<6, 9>(12, 0);
83 P.block(18, 9, nCoeffsRemainingAccel, 6) = P.block(18, 12, nCoeffsRemainingAccel, 6);
86 P.block(0, 15, numStates, 3) = Eigen::MatrixXd::Zero(numStates, 3);
87 P.block(15, 0, 3, numStates) = Eigen::MatrixXd::Zero(3, numStates);
88 P.block<3, 3>(15, 15).diagonal() = std::pow(sigmaScalingFactorAccel, 2) * P.block<3, 3>(12, 12).diagonal();
91Eigen::MatrixXd
NAV::BsplineKF::designMatrix_H(
const double& ti,
const double& splineSpacing,
const Eigen::Matrix3d& DCM_accel,
const Eigen::Matrix3d& DCM_gyro,
const size_t& pinIndex,
const uint8_t& numMeasurements,
const uint8_t& numStates,
const uint8_t& numStatesEst,
const uint8_t& numStatesPerPin)
93 Eigen::MatrixXd H = Eigen::MatrixXd::Zero(numMeasurements, numStates);
98 for (
size_t knotIdx = 0; knotIdx < 3; knotIdx++)
100 auto stateIdx =
static_cast<Eigen::Index
>(3 * knotIdx);
101 H.block<3, 3>(0, stateIdx).diagonal() = qBspline.at(knotIdx) * Eigen::Vector3d::Ones();
102 LOG_DATA(
"stateIdx = {}, knotIdx = {}, H =\n{}", stateIdx, knotIdx, H);
106 H.block<3, 9>(3, 9) = DCM_accel.transpose() * H.block<3, 9>(0, 0);
108 H.block<3, 9>(0, 0) = DCM_gyro.transpose() * H.block<3, 9>(0, 0);
114 const auto stateIndex =
static_cast<uint8_t
>(numStatesEst + numStatesPerPin * (pinIndex - 1));
115 LOG_DATA(
"stateIndex = {}", stateIndex);
117 H.block<6, 6>(0, stateIndex) = Eigen::MatrixXd::Identity(6, 6);
126 std::vector<Eigen::VectorXd> initStates;
127 initStates.resize(numStates);
145 size_t pinDataBiasesIdenticalIdx = 1;
146 for (
size_t pinIndex = 1; pinIndex < numInputPins; ++pinIndex)
148 if (!imuBiasesIdentical)
150 pinDataBiasesIdenticalIdx = pinIndex;
156 initStates[2 * pinIndex] = pinData[pinDataBiasesIdenticalIdx].initAngularRateBias.array();
160 initStates[2 * pinIndex] =
deg2rad(pinData[pinDataBiasesIdenticalIdx].initAngularRateBias).array();
166 initStates[1 + 2 * pinIndex] = pinData[pinDataBiasesIdenticalIdx].initAccelerationBias.array();
170 kalmanFilter.
x.block<9, 1>(0, 0) = initStates[0];
171 kalmanFilter.
x.block<9, 1>(9, 0) = initStates[1];
172 LOG_DATA(
"Initial B-spline coefficients in the state vector x:\n{}", kalmanFilter.
x.block<18, 1>(0, 0));
174 uint32_t containerIndex = 2;
175 for (uint32_t pinIndex = 0; pinIndex < numInputPins - 1UL; ++pinIndex)
177 if (!imuBiasesIdentical)
179 containerIndex = 2 + 2 * pinIndex;
181 kalmanFilter.
x.block<3, 1>(18 + 6 * pinIndex, 0) = initStates[containerIndex];
182 kalmanFilter.
x.block<3, 1>(21 + 6 * pinIndex, 0) = initStates[1 + containerIndex];
184 LOG_DATA(
"Initial bias values:\n{}", kalmanFilter.
x.block<18, 1>(18, 0));
187 kalmanFilter.
Phi = Eigen::MatrixXd::Identity(numStates, numStates);
191 std::vector<Eigen::VectorXd> initErrorCovariances;
192 initErrorCovariances.resize(2 + 2 * (numInputPins - 1));
222 size_t pinDataIdx = 1;
223 for (
size_t pinIndex = 1; pinIndex < numInputPins; ++pinIndex)
225 if (!imuCharacteristicsIdentical)
227 pinDataIdx = pinIndex;
233 initErrorCovariances[2 * pinIndex] = pinData[pinDataIdx].initCovarianceBiasAngRate;
237 initErrorCovariances[2 * pinIndex] =
deg2rad(pinData[pinDataIdx].initCovarianceBiasAngRate);
241 initErrorCovariances[2 * pinIndex] = pinData[pinDataIdx].initCovarianceBiasAngRate.array().pow(2);
245 initErrorCovariances[2 * pinIndex] =
deg2rad(pinData[pinDataIdx].initCovarianceBiasAngRate).array().pow(2);
251 initErrorCovariances[1 + 2 * pinIndex] = pinData[pinDataIdx].initCovarianceBiasAcc;
255 initErrorCovariances[1 + 2 * pinIndex] = pinData[pinDataIdx].initCovarianceBiasAcc.array().pow(2);
262 processNoiseVariances.resize(2 * numInputPins);
292 for (
size_t pinIndex = 1; pinIndex < numInputPins; ++pinIndex)
294 if (!imuCharacteristicsIdentical)
296 pinDataIdx = pinIndex;
300 switch (pinData[pinDataIdx].varBiasAngRateNoiseUnit)
303 processNoiseVariances[2 * pinIndex] = pinData[pinDataIdx].varBiasAngRateNoise;
306 processNoiseVariances[2 * pinIndex] =
deg2rad(pinData[pinDataIdx].varBiasAngRateNoise);
309 processNoiseVariances[2 * pinIndex] =
deg2rad(pinData[pinDataIdx].varBiasAngRateNoise).array().pow(2);
312 processNoiseVariances[2 * pinIndex] = pinData[pinDataIdx].varBiasAngRateNoise.array().pow(2);
317 switch (pinData[pinDataIdx].varBiasAccelerationNoiseUnit)
320 processNoiseVariances[1 + 2 * pinIndex] = pinData[pinDataIdx].varBiasAccelerationNoise;
323 processNoiseVariances[1 + 2 * pinIndex] = pinData[pinDataIdx].varBiasAccelerationNoise.array().pow(2);
Kalman filter matrices for the B-spline Multi-IMU fusion.
Utility class for logging to console and file.
#define LOG_DATA
All output which occurs repeatedly every time observations are received.
Constructs four overlapping qaudratic B-splines.
Generalized Kalman Filter class.
Eigen::MatrixXd x
x̂ State vector
Eigen::MatrixXd P
𝐏 Error covariance matrix
Eigen::MatrixXd Q
𝐐 System/Process noise covariance matrix
Eigen::MatrixXd Phi
𝚽 State transition matrix
void rotateErrorCovariances(Eigen::MatrixXd &P, uint8_t &numStates, const double &sigmaScalingFactorAngRate=3.0, const double &sigmaScalingFactorAccel=3.0)
Rotates the B-spline coefficient error covariances in P, once a new B-spline is introduced.
std::array< double, 3 > quadraticBsplines(const double &ti, const double &splineSpacing=1.0)
Set the points/knots of the four B-splines.
void processNoiseMatrix_Q(Eigen::MatrixXd &Q, const double &dt, const std::vector< Eigen::VectorXd > &processNoiseVariances, const uint8_t &numStates, const bool &imuCharacteristicsIdentical=false)
Calculates the process noise matrix Q.
void rotateCoeffStates(Eigen::MatrixXd &x)
Rotates the B-spline coefficient states in the state vector x, once a new B-spline is introduced.
KalmanFilter initializeKalmanFilterManually(const size_t &numInputPins, const std::vector< PinData > &pinData, const PinDataBsplineKF &pinDataBsplineKF, const uint8_t &numStates, const double &dtInit, std::vector< Eigen::VectorXd > &processNoiseVariances, KalmanFilter &kalmanFilter, const bool &imuCharacteristicsIdentical, const bool &imuBiasesIdentical)
Initializes the BsplineKF manually (i.e. using GUI inputs instead of averaging)
Eigen::MatrixXd initialErrorCovarianceMatrix_P0(const std::vector< Eigen::VectorXd > &initCovariances, const uint8_t &numStates, const bool &imuCharacteristicsIdentical=false)
Initial error covariance matrix P_0.
Eigen::MatrixXd designMatrix_H(const double &ti, const double &splineSpacing, const Eigen::Matrix3d &DCM_accel, const Eigen::Matrix3d &DCM_gyro, const size_t &pinIndex, const uint8_t &numMeasurements, const uint8_t &numStates, const uint8_t &numStatesEst, const uint8_t &numStatesPerPin)
Calculates the design matrix H.
constexpr auto deg2rad(const T °)
Convert Degree to Radians.
Sensor information specific to the Bspline-KF.
Eigen::VectorXd initCovarianceCoeffsAngRate
GUI selection for the initial covariance of the B-spline coefficients of the angular rate.
PinData::AccelerationUnit initCoeffsAccelUnit
Gui selection for the unit of the initial coefficients of the acceleration B-splines.
PinData::AccelerationVarianceUnit initCovarianceCoeffsAccelUnit
Gui selection for the unit of the initial covariance for the coefficients of acceleration.
Eigen::VectorXd initCoeffsAngRate
GUI selection for the initial B-spline coefficients of the angular rate.
PinData::AngRateVarianceUnit initCovarianceCoeffsAngRateUnit
Gui selection for the unit of the initial covariance for the coefficients of angular rate.
Eigen::VectorXd varCoeffsAccelNoise
GUI selection for the coeffs of the acceleration process noise (diagonal values)
Eigen::VectorXd initCoeffsAccel
GUI selection for the initial B-spline coefficients of the acceleration.
Eigen::VectorXd initCovarianceCoeffsAccel
GUI selection for the initial covariance of the B-spline coefficients of the acceleration.
Eigen::VectorXd varCoeffsAngRateNoise
GUI selection for the coeffs of the angular rate process noise (diagonal values)
PinData::AngRateVarianceUnit varCoeffsAngRateUnit
GUI selection for the B-spline coeffs of the angular rate process noise (diagonal values)
PinData::AccelerationVarianceUnit varCoeffsAccelUnit
GUI selection for the B-spline coeffs of the acceleration process noise (diagonal values)
PinData::AngRateUnit initCoeffsAngularRateUnit
Gui selection for the unit of the initial coefficients of the angular rate B-splines.
@ m2_s4
Variance [(m^2)/(s^4), (m^2)/(s^4), (m^2)/(s^4)].
@ m_s2
Standard deviation [m/s², m/s², m/s²].
@ rad2_s2
Variance [rad²/s², rad²/s², rad²/s²].
@ deg2_s2
Variance [deg²/s², deg²/s², deg²/s²].
@ deg_s
Standard deviation [deg/s, deg/s, deg/s].
@ rad_s
Standard deviation [rad/s, rad/s, rad/s].
@ m_s2
in [m/s², m/s², m/s²]
@ deg_s
in [deg/s, deg/s, deg/s]
@ rad_s
in [rad/s, rad/s, rad/s]