21#include <imgui_internal.h>
28#include <fmt/format.h>
65 return !inputPin.queue.empty() && lckf->_inertialIntegrator.hasInitialPosition();
82 return "INS/GNSS LCKF";
92 return "Data Processor";
99 auto updatePin = [&](
bool pinExists,
bool enabled,
100 const char* pinName,
Pin::Type pinType,
const std::vector<std::string>& dataIdentifier = {},
102 if (!pinExists && enabled)
105 firable, priority,
static_cast<int>(pinIdx));
108 else if (pinExists && !enabled)
113 if (enabled) { pinIdx++; }
133 return !inputPin.queue.empty() && (!lckf->_initializeStateOverExternalPin || lckf->_inertialIntegrator.hasInitialPosition());
155 if (ImGui::CollapsingHeader(fmt::format(
"Initialization##{}",
size_t(
id)).c_str(), ImGuiTreeNodeFlags_DefaultOpen))
165 if (
ImGui::DragDouble(fmt::format(
"##initalRollPitchYaw(0) {}",
size_t(
id)).c_str(),
172 if (
ImGui::DragDouble(fmt::format(
"##initalRollPitchYaw(1) {}",
size_t(
id)).c_str(),
179 if (
ImGui::DragDouble(fmt::format(
"##initalRollPitchYaw(2) {}",
size_t(
id)).c_str(),
185 ImGui::TextUnformatted(
"Roll, Pitch, Yaw");
189 if (ImGui::CollapsingHeader(fmt::format(
"IMU Integrator settings##{}",
size_t(
id)).c_str(), ImGuiTreeNodeFlags_DefaultOpen))
196 if (ImGui::CollapsingHeader(fmt::format(
"Kalman Filter settings##{}",
size_t(
id)).c_str(), ImGuiTreeNodeFlags_DefaultOpen))
200 ImGui::SetNextItemWidth(configWidth - taylorOrderWidth);
204 ImGui::SetNextItemWidth(configWidth + ImGui::GetStyle().ItemSpacing.x);
207 ImGui::Combo(fmt::format(
"##Phi calculation algorithm {}",
size_t(
id)).c_str(), &phiCalculationAlgorithm,
"Van Loan\0Taylor\0\0"))
217 ImGui::SetNextItemWidth(taylorOrderWidth);
225 ImGui::SetCursorPosX(ImGui::GetCursorPosX() - ImGui::GetStyle().ItemSpacing.x + ImGui::GetStyle().ItemInnerSpacing.x);
228 ImGui::SetNextItemWidth(configWidth + ImGui::GetStyle().ItemSpacing.x);
230 ImGui::Combo(fmt::format(
"Q calculation algorithm##{}",
size_t(
id)).c_str(), &qCalculationAlgorithm,
"Van Loan\0Taylor 1st Order (Groves 2013)\0\0"))
236 if (ImGui::Checkbox(fmt::format(
"Enable barometric height pin##{}",
size_t(
id)).c_str(), &
_enableBaroHgt))
248 auto inputVector3WithUnit = [&](
const char* title, Eigen::Vector3d& data,
auto& unit,
const char* combo_items_separated_by_zeros,
const char* format) {
250 data.data(), unit, combo_items_separated_by_zeros,
251 format, ImGuiInputTextFlags_CharsScientific))
259 ImGui::SetNextItemOpen(
true, ImGuiCond_FirstUseEver);
260 if (ImGui::TreeNode(fmt::format(
"Q - System/Process noise covariance matrix##{}",
size_t(
id)).c_str()))
265 ImGui::SetNextItemWidth(configWidth + ImGui::GetStyle().ItemSpacing.x);
267 ImGui::Combo(fmt::format(
"Random Process Accelerometer##{}",
size_t(
id)).c_str(), &randomProcessAccel,
"Random Walk\0"
268 "Gauss-Markov 1st Order\0\0"))
276 inputVector3WithUnit(
"Standard deviation of the noise on the\naccelerometer specific-force measurements",
278 inputVector3WithUnit(fmt::format(
"Standard deviation σ of the accel {}",
280 ?
"dynamic bias, in σ²/τ"
287 int unitCorrelationLength = 0;
288 if (
gui::widgets::InputDouble3LWithUnit(fmt::format(
"Correlation length τ of the accel dynamic bias##Correlation length τ of the accel dynamic bias {}",
size_t(
id)).c_str(),
289 configWidth, unitWidth,
_tau_bad.data(), 0., std::numeric_limits<double>::max(),
290 unitCorrelationLength,
"s\0\0",
"%.2e", ImGuiInputTextFlags_CharsScientific))
297 ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 20.F);
303 ImGui::SetNextItemWidth(configWidth + ImGui::GetStyle().ItemSpacing.x);
305 ImGui::Combo(fmt::format(
"Random Process Gyroscope##{}",
size_t(
id)).c_str(), &randomProcessGyro,
"Random Walk\0"
306 "Gauss-Markov 1st Order\0\0"))
314 inputVector3WithUnit(
"Standard deviation of the noise on\nthe gyro angular-rate measurements",
316 inputVector3WithUnit(fmt::format(
"Standard deviation σ of the gyro {}",
318 ?
"dynamic bias, in σ²/τ"
325 int unitCorrelationLength = 0;
329 configWidth, unitWidth,
_tau_bgd.data(), 0., std::numeric_limits<double>::max(),
330 unitCorrelationLength,
"s\0\0",
"%.2e", ImGuiInputTextFlags_CharsScientific))
337 ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 20.F);
345 "m\0\0", 0.0, 0.0,
"%.2e", ImGuiInputTextFlags_CharsScientific))
356 "m/m\0\0", 0.0, 0.0,
"%.2e", ImGuiInputTextFlags_CharsScientific))
373 ImGui::SetNextItemOpen(
true, ImGuiCond_FirstUseEver);
374 if (ImGui::TreeNode(fmt::format(
"R - Measurement noise covariance matrix##{}",
size_t(
id)).c_str()))
376 float curPosX = ImGui::GetCursorPosX();
381 if (ImGui::IsItemHovered()) { ImGui::SetTooltip(
"Override the position variance in the measurements with these values."); }
383 float checkWidth = ImGui::GetCursorPosX() - curPosX;
388 :
"Standard deviation",
393 "%.2e", ImGuiInputTextFlags_CharsScientific))
404 if (ImGui::IsItemHovered()) { ImGui::SetTooltip(
"Override the velocity variance in the measurements with these values."); }
413 "%.2e", ImGuiInputTextFlags_CharsScientific))
426 if (ImGui::IsItemHovered()) { ImGui::SetTooltip(
"Override the barometric height variance in the measurements with this value."); }
434 0.0, 0.0,
"%.2e", ImGuiInputTextFlags_CharsScientific))
449 ImGui::SetNextItemOpen(
true, ImGuiCond_FirstUseEver);
450 if (ImGui::TreeNode(fmt::format(
"P Error covariance matrix (init)##{}",
size_t(
id)).c_str()))
456 :
"Standard deviation σ",
463 "%.2e", ImGuiInputTextFlags_CharsScientific))
473 :
"Standard deviation σ",
478 "%.2e", ImGuiInputTextFlags_CharsScientific))
489 :
"Standard deviation σ",
496 "%.2e", ImGuiInputTextFlags_CharsScientific))
504 ?
"Angles rotating the ECEF frame into the body frame."
505 :
"Angles rotating the local navigation frame into the body frame (Roll, Pitch, Yaw)");
510 :
"Standard deviation σ",
515 "%.2e", ImGuiInputTextFlags_CharsScientific))
526 :
"Standard deviation σ",
533 "%.2e", ImGuiInputTextFlags_CharsScientific))
544 :
"Standard deviation σ",
549 0.0, 0.0,
"%.2e", ImGuiInputTextFlags_CharsScientific))
558 :
"Standard deviation σ",
563 0.0, 0.0,
"%.2e", ImGuiInputTextFlags_CharsScientific))
578 ImGui::SetNextItemOpen(
true, ImGuiCond_FirstUseEver);
579 if (ImGui::TreeNode(fmt::format(
"IMU biases (init)##{}",
size_t(
id)).c_str()))
583 "%.2e", ImGuiInputTextFlags_CharsScientific))
593 "%.2e", ImGuiInputTextFlags_CharsScientific))
605 ImGui::SetNextItemOpen(
false, ImGuiCond_FirstUseEver);
606 if (ImGui::TreeNode(fmt::format(
"Kalman Filter matrices##{}",
size_t(
id)).c_str()))
608 _kalmanFilter.showKalmanFilterMatrixViews(std::to_string(
size_t(
id)).c_str());
614 if (ImGui::Checkbox(fmt::format(
"Rank check for Kalman filter matrices##{}",
size_t(
id)).c_str(), &
_checkKalmanMatricesRanks))
696 if (j.contains(
"dynamicInputPins"))
701 if (j.contains(
"inertialIntegrator"))
705 if (j.contains(
"preferAccelerationOverDeltaMeasurements"))
709 if (j.contains(
"initalRollPitchYaw"))
713 if (j.contains(
"initializeStateOverExternalPin"))
718 if (j.contains(
"checkKalmanMatricesRanks"))
723 if (j.contains(
"phiCalculationAlgorithm"))
727 if (j.contains(
"phiCalculationTaylorOrder"))
731 if (j.contains(
"qCalculationAlgorithm"))
735 if (j.contains(
"enableBaroHgt"))
741 if (j.contains(
"randomProcessAccel"))
745 if (j.contains(
"randomProcessGyro"))
749 if (j.contains(
"stdev_ra"))
753 if (j.contains(
"stdevAccelNoiseUnits"))
757 if (j.contains(
"stdev_rg"))
761 if (j.contains(
"stdevGyroNoiseUnits"))
765 if (j.contains(
"stdev_bad"))
769 if (j.contains(
"tau_bad"))
773 if (j.contains(
"stdevAccelBiasUnits"))
777 if (j.contains(
"stdev_bgd"))
781 if (j.contains(
"tau_bgd"))
785 if (j.contains(
"stdevGyroBiasUnits"))
789 if (j.contains(
"stdevBaroHeightBiasUnits"))
793 if (j.contains(
"stdevBaroHeightBias"))
797 if (j.contains(
"stdevBaroHeightScaleUnits"))
801 if (j.contains(
"stdevBaroHeightScale"))
807 if (j.contains(
"gnssMeasurementUncertaintyPositionUnit"))
811 if (j.contains(
"gnssMeasurementUncertaintyPosition"))
815 if (j.contains(
"gnssMeasurementUncertaintyPositionOverride"))
819 if (j.contains(
"gnssMeasurementUncertaintyVelocityUnit"))
823 if (j.contains(
"gnssMeasurementUncertaintyVelocity"))
827 if (j.contains(
"gnssMeasurementUncertaintyVelocityOverride"))
831 if (j.contains(
"barometricHeightMeasurementUncertaintyUnit"))
835 if (j.contains(
"barometricHeightMeasurementUncertainty"))
839 if (j.contains(
"baroHeightMeasurementUncertaintyOverride"))
844 if (j.contains(
"initCovariancePositionUnit"))
848 if (j.contains(
"initCovariancePosition"))
852 if (j.contains(
"initCovarianceVelocityUnit"))
856 if (j.contains(
"initCovarianceVelocity"))
860 if (j.contains(
"initCovarianceAttitudeAnglesUnit"))
864 if (j.contains(
"initCovarianceAttitudeAngles"))
868 if (j.contains(
"initCovarianceBiasAccelUnit"))
872 if (j.contains(
"initCovarianceBiasAccel"))
876 if (j.contains(
"initCovarianceBiasGyroUnit"))
880 if (j.contains(
"initCovarianceBiasGyro"))
884 if (j.contains(
"initCovarianceBiasHeightUnit"))
888 if (j.contains(
"initCovarianceBiasHeight"))
892 if (j.contains(
"initCovarianceScaleHeightUnit"))
896 if (j.contains(
"initCovarianceScaleHeight"))
902 if (j.contains(
"initBiasAccel"))
906 if (j.contains(
"initBiasAccelUnit"))
910 if (j.contains(
"initBiasGyro"))
914 if (j.contains(
"initBiasGyroUnit"))
939 Eigen::Vector3d variance_angles = Eigen::Vector3d::Zero();
957 Eigen::Vector3d variance_vel = Eigen::Vector3d::Zero();
968 Eigen::Vector3d e_variance = Eigen::Vector3d::Zero();
969 Eigen::Vector3d lla_variance = Eigen::Vector3d::Zero();
991 Eigen::Vector3d variance_accelBias = Eigen::Vector3d::Zero();
1003 Eigen::Vector3d variance_gyroBias = Eigen::Vector3d::Zero();
1021 double variance_heightBias = 0.0;
1033 double variance_heightScale = 0.0;
1052 variance_heightBias,
1053 variance_heightScale);
1097 auto lckfSolution = std::make_shared<InsGnssLCKFSolution>();
1098 lckfSolution->insTime = posVelAtt.
insTime;
1101 lckfSolution->setPosVelAttAndCov_e(posVelAtt.
e_position(),
1118 lckfSolution->b_biasAccel.stdDev = Eigen::Vector3d{
1124 lckfSolution->b_biasGyro.stdDev = Eigen::Vector3d{
1141 if (nodeData->insTime.empty())
1143 LOG_ERROR(
"{}: Can't set new imuObs__t0 because the observation has no time tag (insTime)",
nameId());
1147 std::shared_ptr<NAV::PosVelAtt> inertialNavSol =
nullptr;
1149 _lastImuObs = std::static_pointer_cast<const ImuObs>(nodeData);
1154 auto obs = std::static_pointer_cast<const ImuObsWDelta>(nodeData);
1164 inertialNavSol =
_inertialIntegrator.calcInertialSolutionDelta(obs->insTime, obs->dtime, obs->dvel, obs->dtheta, obs->imuPos,
nameId().c_str());
1168 auto obs = std::static_pointer_cast<const ImuObs>(nodeData);
1178 inertialNavSol =
_inertialIntegrator.calcInertialSolution(obs->insTime, obs->p_acceleration, obs->p_angularRate, obs->imuPos,
nameId().c_str());
1181 inertialNavSol && latestState && latestState->get().m.dt > 1e-8)
1183 looselyCoupledPrediction(inertialNavSol, latestState->get().m.dt, std::static_pointer_cast<const ImuObs>(nodeData)->imuPos);
1189 LOG_DATA(
"{}: e_position = {}",
nameId(), inertialNavSol->e_position().transpose());
1190 LOG_DATA(
"{}: e_velocity = {}",
nameId(), inertialNavSol->e_velocity().transpose());
1195 LOG_DATA(
"{}: [{}] Sending out predicted solution",
nameId(), inertialNavSol->insTime.toYMDHMS(
GPST));
1203 auto obs = std::static_pointer_cast<const PosVel>(queue.
extract_front());
1214 posVelAtt.
insTime = obs->insTime;
1223 LOG_DATA(
"{}: [{}] Sending out initial solution",
nameId(), obs->insTime.toYMDHMS(
GPST));
1232 posVelAtt.
insTime = obs->insTime;
1233 if (obs->n_CovarianceMatrix())
1235 Eigen::Matrix<double, 10, 10> n_cov = Eigen::Matrix<double, 10, 10>::Zero();
1242 LOG_DATA(
"{}: [{}] Sending out received solution, as no IMU data yet",
nameId(), obs->insTime.toYMDHMS(
GPST));
1252 auto obs = std::static_pointer_cast<const BaroHgt>(queue.extract_front());
1271 auto posVelAtt = std::static_pointer_cast<const PosVelAtt>(queue.
extract_front());
1275 LOG_DATA(
"{}: recvPosVelAttInit at time [{}]",
nameId(), posVelAtt->insTime.toYMDHMS());
1284 LOG_DATA(
"{}: e_position = {}",
nameId(), posVelAtt->e_position().transpose());
1285 LOG_DATA(
"{}: e_velocity = {}",
nameId(), posVelAtt->e_velocity().transpose());
1303 LOG_DATA(
"{}: sigma_ra = {} [m / (s^2 · √(s))]",
nameId(), sigma_ra.transpose());
1307 LOG_DATA(
"{}: sigma_rg = {} [rad / (s · √(s))]",
nameId(), sigma_rg.transpose());
1311 LOG_DATA(
"{}: sigma_bad = {} [m / s^2]",
nameId(), sigma_bad.transpose());
1315 LOG_DATA(
"{}: sigma_bgd = {} [rad / s]",
nameId(), sigma_bgd.transpose());
1318 double sigma_heightBias{};
1325 LOG_DATA(
"{}: sigma_heightBias = {} [m]",
nameId(), sigma_heightBias);
1328 double sigma_heightScale{};
1339 const Eigen::Vector3d& lla_position = inertialNavSol->lla_position();
1340 LOG_DATA(
"{}: lla_position = {} [rad, rad, m]",
nameId(), lla_position.transpose());
1350 Eigen::Vector3d b_acceleration = p_acceleration
1351 ? imuPos.
b_quat_p() * p_acceleration.value()
1352 : Eigen::Vector3d::Zero();
1353 LOG_DATA(
"{}: b_acceleration = {} [m/s^2]",
nameId(), b_acceleration.transpose());
1358 const Eigen::Vector3d& n_velocity = inertialNavSol->n_velocity();
1359 LOG_DATA(
"{}: n_velocity = {} [m / s]",
nameId(), n_velocity.transpose());
1361 const Eigen::Quaterniond& n_Quat_b = inertialNavSol->n_Quat_b();
1378 LOG_DATA(
"{}: n_omega_in = {} [rad/s]",
nameId(), n_omega_in.transpose());
1381 _kalmanFilter.F =
n_systemMatrix_F(n_Quat_b, b_acceleration, n_omega_in, n_velocity, lla_position, R_N, R_E, g_0, r_eS_e,
_tau_bad,
_tau_bgd);
1387 sigma_bad.array().square(), sigma_bgd.array().square(),
1388 sigma_heightBias, sigma_heightScale,
1391 n_Quat_b.toRotationMatrix(), tau_i);
1397 const Eigen::Vector3d& e_position = inertialNavSol->e_position();
1398 LOG_DATA(
"{}: e_position = {} [m]",
nameId(), e_position.transpose());
1400 const Eigen::Quaterniond& e_Quat_b = inertialNavSol->e_Quat_b();
1413 sigma_bad.array().square(), sigma_bgd.array().square(),
1414 sigma_heightBias, sigma_heightScale,
1417 e_Quat_b.toRotationMatrix(), tau_i);
1424 ? inertialNavSol->n_Quat_b()
1425 : inertialNavSol->e_Quat_b());
1429 sigma_bad, sigma_bgd,
1431 sigma_heightBias, sigma_heightScale);
1442 auto calcPhi = [&]() {
1490 auto rank = lu.rank();
1493 LOG_WARN(
"{}: [{}] P.rank = {}",
nameId(), inertialNavSol->insTime.toYMDHMS(
GPST), rank);
1502 LOG_DATA(
"{}: [{}] Updating (lastInertial at [{}])",
nameId(), posVelObs->insTime.toYMDHMS(
GPST),
1508 Eigen::Vector3d lla_position;
1517 LOG_DATA(
"{}: lla_position = {} [rad, rad, m]",
nameId(), lla_position.transpose());
1523 Eigen::Vector3d b_omega_ip = p_omega_ip
1524 ?
_lastImuObs->imuPos.b_quat_p() * p_omega_ip.value()
1525 : Eigen::Vector3d::Zero();
1526 LOG_DATA(
"{}: b_omega_ip = {} [rad/s]",
nameId(), b_omega_ip.transpose());
1535 Eigen::Vector3d b_leverArm_InsGnss =
_lastImuObs->imuPos.b_positionIMU_p();
1545 Eigen::Matrix3d n_Dcm_b =
_inertialIntegrator.getLatestState().value().get().attitude.toRotationMatrix();
1565 T_rn_p,
_inertialIntegrator.getLatestState().value().get().attitude, b_leverArm_InsGnss, b_omega_ip, n_Omega_ie);
1570 Eigen::Matrix3d e_Dcm_b =
_inertialIntegrator.getLatestState().value().get().attitude.toRotationMatrix();
1586 _inertialIntegrator.getLatestState().value().get().attitude, b_leverArm_InsGnss, b_omega_ip, e_Omega_ie);
1596 auto rank = lu.rank();
1599 LOG_WARN(
"{}: [{}] (HPH^T + R).rank = {}",
nameId(), posVelObs->insTime.toYMDHMS(
GPST), rank);
1618 auto rank = lu.rank();
1621 LOG_WARN(
"{}: [{}] (HPH^T + R).rank = {}",
nameId(), posVelObs->insTime.toYMDHMS(
GPST), rank);
1645 auto lckfSolution = std::make_shared<InsGnssLCKFSolution>();
1646 lckfSolution->insTime = posVelObs->insTime;
1656 lckfSolution->b_biasAccel.stdDev = Eigen::Vector3d{
1662 lckfSolution->b_biasGyro.stdDev = Eigen::Vector3d{
1668 LOG_DATA(
"{}: Biases after error has been applied: b_biasAccel.value = {}, b_biasGyro.value = {}",
nameId(), lckfSolution->b_biasAccel.value.transpose(), lckfSolution->b_biasGyro.value.transpose());
1675 lckfSolution->velocityError,
1676 lckfSolution->attitudeError);
1682 lckfSolution->velocityError,
1683 lckfSolution->attitudeError);
1694 LOG_DATA(
"{}: [{}] Sending out updated solution",
nameId(), lckfSolution->insTime.toYMDHMS(
GPST));
1710 Eigen::Vector3d lla_position;
1719 LOG_DATA(
"{}: lla_position = {} [rad, rad, m]",
nameId(), lla_position.transpose());
1722 double baroHeightSigmaSquared{};
1737 baroHeightSigmaSquared = std::pow(baroHgtObs->baro_heightStdev.value(), 2);
1739 LOG_DATA(
"{}: baroHeightSigmaSquared = {} [m^2]",
nameId(), baroHeightSigmaSquared);
1767 auto rank = lu.rank();
1770 LOG_WARN(
"{}: [{}] (HPH^T + R).rank = {}",
nameId(), baroHgtObs->insTime.toYMDHMS(
GPST), rank);
1789 auto rank = lu.rank();
1792 LOG_WARN(
"{}: [{}] (HPH^T + R).rank = {}",
nameId(), baroHgtObs->insTime.toYMDHMS(
GPST), rank);
1799 LOG_WARN(
"{}: [{}] P.rank = {}",
nameId(), baroHgtObs->insTime.toYMDHMS(
GPST), rank);
1816 auto lckfSolution = std::make_shared<InsGnssLCKFSolution>();
1817 lckfSolution->insTime = baroHgtObs->insTime;
1827 lckfSolution->b_biasAccel.stdDev = Eigen::Vector3d{
1833 lckfSolution->b_biasGyro.stdDev = Eigen::Vector3d{
1839 LOG_DATA(
"{}: Biases after error has been applied: b_biasAccel.value = {}, b_biasGyro.value = {}",
nameId(), lckfSolution->b_biasAccel.value.transpose(), lckfSolution->b_biasGyro.value.transpose());
1846 lckfSolution->velocityError,
1847 lckfSolution->attitudeError);
1853 lckfSolution->velocityError,
1854 lckfSolution->attitudeError);
1866 LOG_DATA(
"{}: [{}] Sending out updated solution",
nameId(), lckfSolution->insTime.toYMDHMS(
GPST));
1875 Eigen::Matrix<double, 10, 9> J = Eigen::Matrix<double, 10, 9>::Zero();
1876 J.topLeftCorner<6, 6>().setIdentity();
1879 J_units.bottomRightCorner<3, 3>().diagonal().setConstant(std::numbers::pi_v<double> / 180.0);
1882 const Eigen::Vector3d& lla_position =
_inertialIntegrator.getLatestState().value().get().position;
1885 J_units.topLeftCorner<3, 3>().diagonal() = 1.0
1895 lckfSolution->setPosVelAttAndCov_n(lla_position,
1904 lckfSolution->setPosVelAttAndCov_e(
_inertialIntegrator.getLatestState().value().get().position,
1917 const Eigen::Vector3d& b_specForce_ib,
1918 const Eigen::Vector3d& n_omega_in,
1919 const Eigen::Vector3d& n_velocity,
1920 const Eigen::Vector3d& lla_position,
1925 const Eigen::Vector3d& tau_bad,
1926 const Eigen::Vector3d& tau_bgd)
const
1928 double latitude = lla_position(0);
1929 double altitude = lla_position(2);
1931 Eigen::Vector3d beta_bad = 1. / tau_bad.array();
1932 Eigen::Vector3d beta_bgd = 1. / tau_bgd.array();
1937 F(Eigen::Matrix<double, NAV::LooselyCoupledKF::KFStates_COUNT, NAV::LooselyCoupledKF::KFStates_COUNT>::Zero(),
States);
1977 const Eigen::Vector3d& b_specForce_ib,
1978 const Eigen::Vector3d& e_position,
1979 const Eigen::Vector3d& e_gravitation,
1981 const Eigen::Vector3d& e_omega_ie,
1982 const Eigen::Vector3d& tau_bad,
1983 const Eigen::Vector3d& tau_bgd)
const
1985 Eigen::Vector3d beta_bad = 1. / tau_bad.array();
1986 Eigen::Vector3d beta_bgd = 1. / tau_bgd.array();
1991 F(Eigen::Matrix<double, NAV::LooselyCoupledKF::KFStates_COUNT, NAV::LooselyCoupledKF::KFStates_COUNT>::Zero(),
States);
2033 Eigen::Matrix3d ien_Dcm_b = ien_Quat_b.toRotationMatrix();
2037 G(Eigen::Matrix<double, NAV::LooselyCoupledKF::KFStates_COUNT, NAV::LooselyCoupledKF::KFStates_COUNT>::Zero(),
States,
States);
2048Eigen::Matrix<double, NAV::LooselyCoupledKF::KFStates_COUNT, NAV::LooselyCoupledKF::KFStates_COUNT>
2050 const Eigen::Vector3d& sigma_bad,
const Eigen::Vector3d& sigma_bgd,
2051 const Eigen::Vector3d& tau_bad,
const Eigen::Vector3d& tau_bgd,
2052 const double& sigma_heightBias,
const double& sigma_heightScale)
2054 Eigen::Matrix<double, NAV::LooselyCoupledKF::KFStates_COUNT, NAV::LooselyCoupledKF::KFStates_COUNT> W =
2055 Eigen::Matrix<double, NAV::LooselyCoupledKF::KFStates_COUNT, NAV::LooselyCoupledKF::KFStates_COUNT>::Zero();
2057 W.diagonal() << sigma_rg.array().square(),
2058 sigma_ra.array().square(),
2059 Eigen::Vector3d::Zero(),
2062 sigma_heightBias * sigma_heightBias,
2063 sigma_heightScale * sigma_heightScale;
2070 const Eigen::Vector3d& sigma2_bad,
const Eigen::Vector3d& sigma2_bgd,
2071 const double& sigma_heightBias,
const double& sigma_heightScale,
2072 const Eigen::Vector3d& tau_bad,
const Eigen::Vector3d& tau_bgd,
2073 const Eigen::Matrix3d& n_F_21,
const Eigen::Matrix3d& T_rn_p,
2074 const Eigen::Matrix3d& n_Dcm_b,
const double& tau_s)
2077 Eigen::Vector3d S_ra = sigma2_ra * tau_s;
2078 Eigen::Vector3d S_rg = sigma2_rg * tau_s;
2079 Eigen::Vector3d S_bad = sigma2_bad.array() / tau_bad.array();
2080 Eigen::Vector3d S_bgd = sigma2_bgd.array() / tau_bgd.array();
2082 Eigen::Matrix3d b_Dcm_n = n_Dcm_b.transpose();
2085 Q(Eigen::Matrix<double, NAV::LooselyCoupledKF::KFStates_COUNT, NAV::LooselyCoupledKF::KFStates_COUNT>::Zero(),
States,
States);
2126 const Eigen::Vector3d& sigma2_bad,
const Eigen::Vector3d& sigma2_bgd,
2127 const double& sigma_heightBias,
const double& sigma_heightScale,
2128 const Eigen::Vector3d& tau_bad,
const Eigen::Vector3d& tau_bgd,
2129 const Eigen::Matrix3d& e_F_21,
2130 const Eigen::Matrix3d& e_Dcm_b,
const double& tau_s)
2133 Eigen::Vector3d S_ra = sigma2_ra * tau_s;
2134 Eigen::Vector3d S_rg = sigma2_rg * tau_s;
2135 Eigen::Vector3d S_bad = sigma2_bad.array() / tau_bad.array();
2136 Eigen::Vector3d S_bgd = sigma2_bgd.array() / tau_bgd.array();
2138 Eigen::Matrix3d b_Dcm_e = e_Dcm_b.transpose();
2141 Q(Eigen::Matrix<double, NAV::LooselyCoupledKF::KFStates_COUNT, NAV::LooselyCoupledKF::KFStates_COUNT>::Zero(),
States,
States);
2184 const Eigen::Vector3d& variance_vel,
2185 const Eigen::Vector3d& variance_pos,
2186 const Eigen::Vector3d& variance_accelBias,
2187 const Eigen::Vector3d& variance_gyroBias,
2188 const double& variance_heightBias,
2189 const double& variance_heightScale)
const
2194 Eigen::Matrix<double, NAV::LooselyCoupledKF::KFStates_COUNT, NAV::LooselyCoupledKF::KFStates_COUNT> P =
2195 Eigen::Matrix<double, NAV::LooselyCoupledKF::KFStates_COUNT, NAV::LooselyCoupledKF::KFStates_COUNT>::Zero();
2199 std::pow(scaleFactorPosition, 2) * variance_pos(0),
2200 std::pow(scaleFactorPosition, 2) * variance_pos(1),
2204 variance_heightBias,
2205 variance_heightScale;
2220 H(Eigen::Matrix<double, 6, NAV::LooselyCoupledKF::KFStates_COUNT>::Zero(),
Meas,
States);
2245 H(Eigen::Matrix<double, 1, NAV::LooselyCoupledKF::KFStates_COUNT>::Zero(), std::array{
KFMeas::dHgt },
States);
2261 H(Eigen::Matrix<double, 6, NAV::LooselyCoupledKF::KFStates_COUNT>::Zero(),
Meas,
States);
2283 H(Eigen::Matrix<double, 1, NAV::LooselyCoupledKF::KFStates_COUNT>::Zero(), std::array{
KFMeas::dHgt },
States);
2294 const Eigen::Vector3d& lla_position,
2299 Eigen::Vector3d gnssSigmaSquaredPosition = Eigen::Vector3d::Zero();
2310 Eigen::Vector3d gnssSigmaSquaredVelocity = Eigen::Vector3d::Zero();
2332 R.
block<3>(
dVel,
dVel).diagonal() = gnssSigmaSquaredVelocity;
2337 R.
block<3>(
dPos,
dPos).diagonal() = gnssSigmaSquaredPosition;
2342 R.
block<3>(
dPos,
dPos).diagonal() = gnssSigmaSquaredPosition;
2343 R.
block<3>(
dVel,
dVel).diagonal() = gnssSigmaSquaredVelocity;
2348 J.topLeftCorner<3, 3>() =
n_F_dr_dv(lla_position.x(), lla_position.z(), R_N, R_E);
2371 Eigen::Vector3d gnssSigmaSquaredPosition = Eigen::Vector3d::Zero();
2382 Eigen::Vector3d gnssSigmaSquaredVelocity = Eigen::Vector3d::Zero();
2404 R.
block<3>(
dVel,
dVel).diagonal() = gnssSigmaSquaredVelocity;
2409 R.
block<3>(
dPos,
dPos).diagonal() = gnssSigmaSquaredPosition;
2414 R.
block<3>(
dPos,
dPos).diagonal() = gnssSigmaSquaredPosition;
2415 R.
block<3>(
dVel,
dVel).diagonal() = gnssSigmaSquaredVelocity;
2423 const Eigen::Vector3d& n_velocityMeasurement,
const Eigen::Vector3d& n_velocityEstimate,
2424 const Eigen::Matrix3d& T_rn_p,
const Eigen::Quaterniond& n_Quat_b,
const Eigen::Vector3d& b_leverArm_InsGnss,
2425 const Eigen::Vector3d& b_omega_ib,
const Eigen::Matrix3d& n_Omega_ie)
2428 Eigen::Vector3d deltaLLA = lla_positionMeasurement - lla_positionEstimate - T_rn_p * (n_Quat_b * b_leverArm_InsGnss);
2429 Eigen::Vector3d deltaVel = n_velocityMeasurement - n_velocityEstimate - n_Quat_b * (b_omega_ib.cross(b_leverArm_InsGnss)) + n_Omega_ie * (n_Quat_b * b_leverArm_InsGnss);
2433 Eigen::Matrix<double, 6, 1> innovation;
2434 innovation << deltaLLA, deltaVel;
2436 return { innovation,
Meas };
2442 Eigen::Matrix<double, 1, 1> innovation;
2443 innovation << baroheight - (height * heightscale + heightbias);
2450 const Eigen::Vector3d& e_velocityMeasurement,
const Eigen::Vector3d& e_velocityEstimate,
2451 const Eigen::Quaterniond& e_Quat_b,
const Eigen::Vector3d& b_leverArm_InsGnss,
2452 const Eigen::Vector3d& b_omega_ib,
const Eigen::Matrix3d& e_Omega_ie)
2455 Eigen::Vector3d deltaPos = e_positionMeasurement - e_positionEstimate - e_Quat_b * b_leverArm_InsGnss;
2456 Eigen::Vector3d deltaVel = e_velocityMeasurement - e_velocityEstimate - e_Quat_b * (b_omega_ib.cross(b_leverArm_InsGnss)) + e_Omega_ie * (e_Quat_b * b_leverArm_InsGnss);
2458 Eigen::Matrix<double, 6, 1> innovation;
2459 innovation << deltaPos, deltaVel;
2461 return { innovation,
Meas };
2466 return os << fmt::format(
"{}", obj);
2470 return os << fmt::format(
"{}", obj);
#define INS_ASSERT_USER_ERROR(_EXP, _MSG)
Assert function with message.
Error Equations for the ECEF frame.
Functions concerning the ellipsoid model.
nlohmann::json json
json namespace
Different Gravity Models.
Text Help Marker (?) with Tooltip.
Inertial Navigation Helper Functions.
Data storage class for one VectorNavImu observation.
Loosely-coupled Kalman Filter INS/GNSS errors.
Error Equations for the local navigation frame.
Utility class for logging to console and file.
#define LOG_CRITICAL(...)
Critical Event, which causes the program to work entirely and throws an exception.
#define LOG_DEBUG
Debug information. Should not be called on functions which receive observations (spamming)
#define LOG_DATA
All output which occurs repeatedly every time observations are received.
#define LOG_ERROR
Error occurred, which stops part of the program to work, but not everything.
#define LOG_WARN
Error occurred, but a fallback option exists and program continues to work normally.
#define LOG_TRACE
Detailled info to trace the execution of the program. Should not be called on functions which receive...
constexpr double SCALE_FACTOR_LAT_LON
Scale factor to convert the latitude and longitude error.
constexpr double SCALE_FACTOR_ANGULAR_RATE
Scale factor to convert the angular rate error.
constexpr double SCALE_FACTOR_ATTITUDE
Scale factor to convert the attitude error.
constexpr double SCALE_FACTOR_ACCELERATION
Scale factor to convert the acceleration error.
Kalman Filter class for the loosely coupled INS/GNSS integration.
Utility class which specifies available nodes.
Position, Velocity and Attitude Storage Class.
Position and Velocity Storage Class.
General process Noise definitions.
static std::string type()
Returns the type of the data class.
static std::string type()
Returns the type of the data class.
static std::string type()
Returns the type of the data class.
const Eigen::Quaterniond & b_quat_p() const
Quaternion from IMU platform frame to body frame.
@ NED
Local North-East-Down frame.
@ ECEF
Earth-Centered Earth-Fixed frame.
static constexpr double pseudometre
Conversion factor between latitude and longitude in [rad] to [pseudometre].
static constexpr double G_NORM
Standard gravity in [m / s^2].
static const Eigen::Vector3< double > e_omega_ie
ω_ie_e = ω_ie_i Nominal mean angular velocity of the Earth in [rad/s], in earth coordinates
@ NED
Local North-East-Down frame.
@ ECEF
Earth-Centered Earth-Fixed frame.
static std::string type()
Returns the type of the data class.
The class is responsible for all time-related tasks.
Static sized KeyedMatrix.
Static sized KeyedVector.
InitCovarianceScaleHeight _initCovarianceScaleHeightUnit
Gui selection for the Unit of the initial covariance for the height scale.
@ m_s
Standard deviation [m/s].
@ m2_s2
Variance [m^2/s^2].
KFStates
State Keys of the Kalman filter.
@ HeightScale
Baro Height Scale.
@ GyrBiasX
Gyroscope Bias X.
@ HeightBias
Baro Height Bias.
@ AccBiasZ
Accelerometer Bias Z.
@ GyrBiasZ
Gyroscope Bias Z.
@ GyrBiasY
Gyroscope Bias Y.
@ AccBiasX
Accelerometer Bias X.
@ AccBiasY
Accelerometer Bias Y.
Units::ImuAccelerometerFilterNoiseUnits _stdevAccelNoiseUnits
Gui selection for the Unit of the input stdev_ra parameter.
StdevBaroHeightScaleUnits _stdevBaroHeightScaleUnits
Gui selection for the Unit of the barometric height scale uncertainty.
RandomProcess _randomProcessAccel
Random Process used to estimate the accelerometer biases.
static KeyedMatrix< double, KFMeas, KFStates, 6, 17 > e_measurementMatrix_H(const Eigen::Matrix3d &e_Dcm_b, const Eigen::Vector3d &b_omega_ib, const Eigen::Vector3d &b_leverArm_InsGnss, const Eigen::Matrix3d &e_Omega_ie)
Measurement matrix for GNSS measurements at timestep k, represented in Earth frame coordinates.
json save() const override
Saves the node into a json object.
InitBiasAccelUnit _initBiasAccelUnit
Gui selection for the unit of the initial accelerometer biases.
InitCovarianceVelocityUnit _initCovarianceVelocityUnit
Gui selection for the Unit of the initial covariance for the velocity.
bool _preferAccelerationOverDeltaMeasurements
Prefer the raw acceleration measurements over the deltaVel & deltaTheta values.
static void pinAddCallback(Node *node)
Function to call to add a new pin.
Eigen::Vector3d _initBiasAccel
GUI selection of the initial accelerometer biases.
@ rad
Standard deviation [rad].
@ deg
Standard deviation [deg].
static KeyedVector< double, KFMeas, 6 > n_measurementInnovation_dz(const Eigen::Vector3d &lla_positionMeasurement, const Eigen::Vector3d &lla_positionEstimate, const Eigen::Vector3d &n_velocityMeasurement, const Eigen::Vector3d &n_velocityEstimate, const Eigen::Matrix3d &T_rn_p, const Eigen::Quaterniond &n_Quat_b, const Eigen::Vector3d &b_leverArm_InsGnss, const Eigen::Vector3d &b_omega_ib, const Eigen::Matrix3d &n_Omega_ie)
Measurement innovation vector 𝜹𝐳
Eigen::Vector3d _gnssMeasurementUncertaintyVelocity
GUI selection of the GNSS NED velocity measurement uncertainty (standard deviation σ or Variance σ²)
StdevBaroHeightBiasUnits _stdevBaroHeightBiasUnits
Gui selection for the Unit of the barometric height bias uncertainty.
PhiCalculationAlgorithm _phiCalculationAlgorithm
GUI option for the Phi calculation algorithm.
int _phiCalculationTaylorOrder
GUI option for the order of the Taylor polynom to calculate the Phi matrix.
Eigen::Vector3d _initCovariancePosition
GUI selection of the initial covariance diagonal values for position (standard deviation σ or Varianc...
@ deg_s
angular rate [deg/s]
@ rad_s
angular rate [rad/s]
static std::string category()
String representation of the class category.
static const std::vector< KFMeas > dPos
All position difference keys.
void updateInputPins()
Update the input pins depending on the GUI.
KeyedMatrix< double, KFMeas, KFMeas, 6, 6 > e_measurementNoiseCovariance_R(const std::shared_ptr< const PosVel > &posVelObs) const
Measurement noise covariance matrix 𝐑
static KeyedVector< double, KFMeas, 6 > e_measurementInnovation_dz(const Eigen::Vector3d &e_positionMeasurement, const Eigen::Vector3d &e_positionEstimate, const Eigen::Vector3d &e_velocityMeasurement, const Eigen::Vector3d &e_velocityEstimate, const Eigen::Quaterniond &e_Quat_b, const Eigen::Vector3d &b_leverArm_InsGnss, const Eigen::Vector3d &b_omega_ib, const Eigen::Matrix3d &e_Omega_ie)
Measurement innovation vector 𝜹𝐳
KeyedMatrix< double, KFMeas, KFMeas, 6, 6 > n_measurementNoiseCovariance_R(const std::shared_ptr< const PosVel > &posVelObs, const Eigen::Vector3d &lla_position, double R_N, double R_E) const
Measurement noise covariance matrix 𝐑
double _heightScaleTotal
Accumulator for height scale [m/m].
void recvImuObservation(InputPin::NodeDataQueue &queue, size_t pinIdx)
Receive Function for the IMU observation.
static const std::vector< KFStates > KFAccBias
All acceleration bias keys.
GnssMeasurementUncertaintyVelocityUnit _gnssMeasurementUncertaintyVelocityUnit
Gui selection for the Unit of the GNSS measurement uncertainty for the velocity.
void looselyCoupledUpdate(const std::shared_ptr< const PosVel > &posVelObs)
Updates the predicted state from the InertialNavSol with the PosVel observation.
Eigen::Vector3d _initCovarianceVelocity
GUI selection of the initial covariance diagonal values for velocity (standard deviation σ or Varianc...
static KeyedMatrix< double, KFStates, KFStates, 17, 17 > noiseInputMatrix_G(const Eigen::Quaterniond &ien_Quat_b)
Calculates the noise input matrix 𝐆
bool hasInputPinWithSameTime(const InsTime &insTime) const
Checks wether there is an input pin with the same time.
Eigen::Vector3d _initCovarianceBiasGyro
GUI selection of the initial covariance diagonal values for gyroscope biases (standard deviation σ or...
bool _gnssMeasurementUncertaintyPositionOverride
Whether to override the position uncertainty or use the one included in the measurement.
Units::ImuGyroscopeFilterNoiseUnits _stdevGyroNoiseUnits
Gui selection for the Unit of the input stdev_rg parameter.
Eigen::Vector3d _gnssMeasurementUncertaintyPosition
GUI selection of the GNSS position measurement uncertainty (standard deviation σ or Variance σ²)....
static constexpr size_t INPUT_PORT_INDEX_POS_VEL_ATT_INIT
Flow (PosVelAtt)
~LooselyCoupledKF() override
Destructor.
QCalculationAlgorithm _qCalculationAlgorithm
GUI option for the Q calculation algorithm.
@ rad_rad_m
Standard deviation LatLonAlt [rad, rad, m].
@ rad2_rad2_m2
Variance LatLonAlt^2 [rad^2, rad^2, m^2].
@ meter2
Variance NED [m^2, m^2, m^2].
@ meter
Standard deviation NED [m, m, m].
static const std::vector< KFStates > KFVel
All velocity keys.
bool _initializeStateOverExternalPin
Whether to initialize the state over an external pin.
Eigen::Vector3d _tau_bgd
Correlation length of the gyro dynamic bias in [s].
double _initCovarianceBiasHeight
GUI selection of the initial covariance diagonal values for the height bias (standard deviation σ or ...
@ m_m
Standard devation [m/m].
bool _checkKalmanMatricesRanks
Check the rank of the Kalman matrices every iteration (computational expensive)
Units::ImuAccelerometerFilterBiasUnits _stdevAccelBiasUnits
Gui selection for the Unit of the input variance_bad parameter.
GnssMeasurementUncertaintyPositionUnit _gnssMeasurementUncertaintyPositionUnit
Gui selection for the Unit of the GNSS measurement uncertainty for the position.
double _stdevBaroHeightBias
Uncertainty of the barometric height bias.
static const std::vector< KFStates > KFAtt
All attitude keys.
KeyedKalmanFilterD< KFStates, KFMeas > _kalmanFilter
Kalman Filter representation.
InitBiasGyroUnit _initBiasGyroUnit
Gui selection for the unit of the initial gyroscope biases.
double _initCovarianceScaleHeight
GUI selection of the initial covariance diagonal values for the height scale (standard deviation σ or...
static const std::vector< KFMeas > dVel
All velocity difference keys.
Eigen::Vector3d _accelBiasTotal
Accumulator for acceleration bias [m/s²].
void recvPosVelAttInit(InputPin::NodeDataQueue &queue, size_t pinIdx)
Receive Function for the PosVelAtt observation.
std::shared_ptr< const ImuObs > _lastImuObs
Last received IMU observation (to get ImuPos)
InitCovarianceBiasAccelUnit _initCovarianceBiasAccelUnit
Gui selection for the Unit of the initial covariance for the accelerometer biases.
InitCovariancePositionUnit _initCovariancePositionUnit
Gui selection for the Unit of the initial covariance for the position.
gui::widgets::DynamicInputPins _dynamicInputPins
Dynamic input pins.
Eigen::Vector3d _stdev_rg
𝜎_rg Standard deviation of the noise on the gyro angular-rate measurements
static const std::vector< KFStates > KFPosVelAtt
All position, velocity and attitude keys.
void recvBaroHeight(InputPin::NodeDataQueue &queue, size_t pinIdx)
Receive Function for the BaroHgt observation.
@ rad2_s2
Variance [rad²/s²].
@ deg2_s2
Variance [deg²/s²].
@ deg_s
Standard deviation [deg/s].
@ rad_s
Standard deviation [rad/s].
InsTime _externalInitTime
Time from the external init.
static constexpr size_t OUTPUT_PORT_INDEX_SOLUTION
Flow (InsGnssLCKFSolution)
static constexpr size_t INPUT_PORT_INDEX_IMU
Flow (ImuObs)
void deinitialize() override
Deinitialize the node.
void setSolutionPosVelAttAndCov(const std::shared_ptr< PosVelAtt > &lckfSolution, double R_N, double R_E)
Sets the covariance matrix P of the LCKF (and does the necessary unit conversions)
Eigen::Vector3d _stdev_bad
𝜎²_bad Variance of the accelerometer dynamic bias
InertialIntegrator _inertialIntegrator
Inertial Integrator.
void restore(const json &j) override
Restores the node from a json object.
void invokeCallbackWithPosVelAtt(const PosVelAtt &posVelAtt)
Invoke the callback with a PosVelAtt solution (without LCKF specific output)
KeyedMatrix< double, KFStates, KFStates, 17, 17 > e_systemMatrix_F(const Eigen::Quaterniond &e_Quat_b, const Eigen::Vector3d &b_specForce_ib, const Eigen::Vector3d &e_position, const Eigen::Vector3d &e_gravitation, double r_eS_e, const Eigen::Vector3d &e_omega_ie, const Eigen::Vector3d &tau_bad, const Eigen::Vector3d &tau_bgd) const
Calculates the system matrix 𝐅 for the ECEF frame.
void looselyCoupledPrediction(const std::shared_ptr< const PosVelAtt > &inertialNavSol, double tau_i, const ImuPos &imuPos)
Predicts the state from the InertialNavSol.
KFMeas
Measurement Keys of the Kalman filter.
@ dPosLat
Latitude difference.
@ dPosLon
Longitude difference.
@ m_s2
acceleration [m/s^2]
BaroHeightMeasurementUncertaintyUnit _barometricHeightMeasurementUncertaintyUnit
Gui selection for the Unit of the barometric height measurement uncertainty.
double _stdevBaroHeightScale
Uncertainty of the barometric height scale.
KeyedMatrix< double, KFStates, KFStates, 17, 17 > initialErrorCovarianceMatrix_P0(const Eigen::Vector3d &variance_angles, const Eigen::Vector3d &variance_vel, const Eigen::Vector3d &variance_pos, const Eigen::Vector3d &variance_accelBias, const Eigen::Vector3d &variance_gyroBias, const double &variance_heightBias, const double &variance_heightScale) const
Initial error covariance matrix P_0.
@ m2_s4
Variance [m^2/s^4].
@ m_s2
Standard deviation [m/s^2].
double _heightBiasTotal
Accumulator for height bias [m].
void recvPosVelObservation(InputPin::NodeDataQueue &queue, size_t pinIdx)
Receive Function for the PosVel observation.
bool _baroHeightMeasurementUncertaintyOverride
Whether to override the barometric height uncertainty or use the one included in the measurement.
static std::string typeStatic()
String representation of the class type.
bool _gnssMeasurementUncertaintyVelocityOverride
Whether to override the velocity uncertainty or use the one included in the measurement.
Units::ImuGyroscopeFilterBiasUnits _stdevGyroBiasUnits
Gui selection for the Unit of the input variance_bad parameter.
static const std::vector< KFStates > KFPos
All position keys.
@ m
Standard deviation [m].
Eigen::Vector3d _stdev_ra
𝜎_ra Standard deviation of the noise on the accelerometer specific-force measurements
Eigen::Vector3d _tau_bad
Correlation length of the accelerometer dynamic bias in [s].
KeyedMatrix< double, KFStates, KFStates, 17, 17 > n_systemMatrix_F(const Eigen::Quaterniond &n_Quat_b, const Eigen::Vector3d &b_specForce_ib, const Eigen::Vector3d &n_omega_in, const Eigen::Vector3d &n_velocity, const Eigen::Vector3d &lla_position, double R_N, double R_E, double g_0, double r_eS_e, const Eigen::Vector3d &tau_bad, const Eigen::Vector3d &tau_bgd) const
Calculates the system matrix 𝐅 for the local navigation frame.
InitCovarianceBiasGyroUnit _initCovarianceBiasGyroUnit
Gui selection for the Unit of the initial covariance for the gyroscope biases.
static void pinDeleteCallback(Node *node, size_t pinIdx)
Function to call to delete a pin.
std::string type() const override
String representation of the class type.
static const std::vector< KFStates > KFGyrBias
All gyroscope bias keys.
@ meter2
Variance [m^2, m^2, m^2].
@ meter
Standard deviation [m, m, m].
std::array< double, 3 > _initalRollPitchYaw
Roll, Pitch and Yaw angles in [deg] used for initialization if not taken from separate pin.
LooselyCoupledKF()
Default constructor.
static KeyedMatrix< double, KFStates, KFStates, 17, 17 > e_systemNoiseCovarianceMatrix_Q(const Eigen::Vector3d &sigma2_ra, const Eigen::Vector3d &sigma2_rg, const Eigen::Vector3d &sigma2_bad, const Eigen::Vector3d &sigma2_bgd, const double &sigma_heightBias, const double &sigma_heightScale, const Eigen::Vector3d &tau_bad, const Eigen::Vector3d &tau_bgd, const Eigen::Matrix3d &e_F_21, const Eigen::Matrix3d &e_Dcm_b, const double &tau_s)
System noise covariance matrix 𝐐_{k-1}.
@ GaussMarkov1
Gauss-Markov 1st Order.
double _barometricHeightMeasurementUncertainty
GUI selection of the barometric height measurement uncertainty (standard deviation σ or Variance σ²)
static KeyedMatrix< double, KFMeas, KFStates, 6, 17 > n_measurementMatrix_H(const Eigen::Matrix3d &T_rn_p, const Eigen::Matrix3d &n_Dcm_b, const Eigen::Vector3d &b_omega_ib, const Eigen::Vector3d &b_leverArm_InsGnss, const Eigen::Matrix3d &n_Omega_ie)
Measurement matrix for GNSS measurements at timestep k, represented in navigation coordinates.
Eigen::Vector3d _gyroBiasTotal
Accumulator gyro bias [rad/s].
bool _initialSensorBiasesApplied
Whether the accumulated biases have been initialized in the 'inertialIntegrator'.
RandomProcess _randomProcessGyro
Random Process used to estimate the gyroscope biases.
Eigen::Vector3d _initCovarianceBiasAccel
GUI selection of the initial covariance diagonal values for accelerometer biases (standard deviation ...
@ m
Standard deviation [m].
void guiConfig() override
ImGui config window which is shown on double click.
bool initialize() override
Initialize the node.
bool _enableBaroHgt
Whether to enable barometric height (including the corresponding pin)
Eigen::Vector3d _initCovarianceAttitudeAngles
GUI selection of the initial covariance diagonal values for attitude angles (standard deviation σ or ...
@ m_s
Standard deviation [m/s].
@ m2_s2
Variance [m^2/s^2].
Eigen::Matrix< double, 17, 17 > noiseScaleMatrix_W(const Eigen::Vector3d &sigma_ra, const Eigen::Vector3d &sigma_rg, const Eigen::Vector3d &sigma_bad, const Eigen::Vector3d &sigma_bgd, const Eigen::Vector3d &tau_bad, const Eigen::Vector3d &tau_bgd, const double &sigma_heightBias, const double &sigma_heightScale)
Calculates the noise scale matrix 𝐖
Eigen::Vector3d _stdev_bgd
𝜎²_bgd Variance of the gyro dynamic bias
Eigen::Vector3d _initBiasGyro
GUI selection of the initial gyroscope biases.
InitCovarianceAttitudeAnglesUnit _initCovarianceAttitudeAnglesUnit
Gui selection for the Unit of the initial covariance for the attitude angles.
static KeyedMatrix< double, KFStates, KFStates, 17, 17 > n_systemNoiseCovarianceMatrix_Q(const Eigen::Vector3d &sigma2_ra, const Eigen::Vector3d &sigma2_rg, const Eigen::Vector3d &sigma2_bad, const Eigen::Vector3d &sigma2_bgd, const double &sigma_heightBias, const double &sigma_heightScale, const Eigen::Vector3d &tau_bad, const Eigen::Vector3d &tau_bgd, const Eigen::Matrix3d &n_F_21, const Eigen::Matrix3d &T_rn_p, const Eigen::Matrix3d &n_Dcm_b, const double &tau_s)
System noise covariance matrix 𝐐_{k-1}.
InitCovarianceBiasHeightUnit _initCovarianceBiasHeightUnit
Gui selection for the Unit of the initial covariance for the height bias.
InsTime insTime
Time at which the message was received.
ImVec2 _guiConfigDefaultWindowSize
Node(std::string name)
Constructor.
std::vector< InputPin > inputPins
List of input pins.
OutputPin * CreateOutputPin(const char *name, Pin::Type pinType, const std::vector< std::string > &dataIdentifier, OutputPin::PinData data=static_cast< void * >(nullptr), int idx=-1)
Create an Output Pin object.
std::string nameId() const
Node name and id.
std::string name
Name of the Node.
InputPin * CreateInputPin(const char *name, Pin::Type pinType, const std::vector< std::string > &dataIdentifier={}, InputPin::Callback callback=static_cast< InputPin::FlowFirableCallbackFunc >(nullptr), InputPin::FlowFirableCheckFunc firable=nullptr, int priority=0, int idx=-1)
Create an Input Pin object.
void invokeCallbacks(size_t portIndex, const std::shared_ptr< const NodeData > &data)
Calls all registered callbacks on the specified output port.
bool DeleteInputPin(size_t pinIndex)
Deletes the input pin. Invalidates the pin reference given.
bool _hasConfig
Flag if the config window should be shown.
std::vector< std::string > dataIdentifier
One or multiple Data Identifiers (Unique name which is used for data flows)
Position, Velocity and Attitude Storage Class.
void setPosVelAtt_n(const Eigen::MatrixBase< DerivedP > &lla_position, const Eigen::MatrixBase< DerivedV > &n_velocity, const Eigen::QuaternionBase< DerivedA > &n_Quat_b)
Set the position, velocity and attitude.
void setPosVelAttAndCov_n(const Eigen::MatrixBase< DerivedP > &lla_position, const Eigen::MatrixBase< DerivedV > &n_velocity, const Eigen::QuaternionBase< DerivedA > &n_Quat_b, const Eigen::MatrixBase< Derived > &n_covarianceMatrix)
Set the position, velocity, attitude and the covariance matrix.
static std::string type()
Returns the type of the data class.
Eigen::Vector3d rollPitchYaw() const
Returns the Roll, Pitch and Yaw angles in [rad].
const Eigen::Quaterniond & e_Quat_b() const
Returns the Quaternion from body to Earth-fixed frame.
static std::string type()
Returns the type of the data class.
const Eigen::Vector3d & e_velocity() const
Returns the velocity in [m/s], in earth coordinates.
std::optional< std::reference_wrapper< const KeyedMatrixXd< Keys::MotionModelKey, Keys::MotionModelKey > > > e_CovarianceMatrix() const
Returns the Covariance matrix in ECEF frame.
const Eigen::Vector3d & e_position() const
Returns the coordinates in [m].
auto & front()
Returns a reference to the first element in the container.
auto extract_front()
Returns a copy of the first element in the container and removes it from the container.
bool empty() const noexcept
Checks if the container has no elements, i.e. whether 'begin() == end()'.
static float windowFontRatio()
Ratio to multiply for GUI window elements.
decltype(auto) middleCols(std::span< const ColKeyType > colKeys) const
Gets the values for the col keys.
decltype(auto) block(std::span< const RowKeyType > rowKeys, std::span< const ColKeyType > colKeys) const
Gets the values for the row and col keys.
decltype(auto) middleRows(std::span< const RowKeyType > rowKeys) const
Gets the values for the row keys.
Matrix< double, 6, 6 > Matrix6d
Double 6x6 Eigen::Matrix.
Matrix< double, 9, 9 > Matrix9d
Double 9x9 Eigen::Matrix.
bool InputIntL(const char *label, int *v, int v_min, int v_max, int step, int step_fast, ImGuiInputTextFlags flags)
Shows a value limited InputText GUI element for 'int'.
bool DragDouble(const char *label, double *v, float v_speed, double v_min, double v_max, const char *format, ImGuiSliderFlags flags)
Shows a Drag GUI element for 'double'.
constexpr std::array< StateKeyType, 3 > Pos
All position keys.
constexpr std::array< StateKeyType, 6 > PosVel
Vector with all position and velocity keys.
constexpr std::array< StateKeyType, 3 > Vel
All velocity keys.
bool NodeDataTypeAnyIsChildOf(const std::vector< std::string > &childTypes, const std::vector< std::string > &parentTypes)
Checks if any of the provided child types is a child of any of the provided parent types.
void ApplyChanges()
Signals that there have been changes to the flow.
Eigen::Matrix< typename Derived::Scalar, 3, 3 > skewSymmetricMatrix(const Eigen::MatrixBase< Derived > &a)
Calculates the skew symmetric matrix of the given vector. This is needed to perform the cross product...
Eigen::Vector3< typename Derived::Scalar > ecef2lla_WGS84(const Eigen::MatrixBase< Derived > &e_position)
Converts Earth-centered-Earth-fixed coordinates into latitude, longitude and altitude using WGS84.
Eigen::Quaternion< Scalar > e_Quat_n(const Scalar &latitude, const Scalar &longitude)
Quaternion for rotations from navigation to Earth-fixed frame.
Eigen::Matrix< typename Derived::Scalar, 4, 3 > covRPY2quatJacobian(const Eigen::QuaternionBase< Derived > &n_quat_b)
Calculates the Jacobian to convert an attitude represented in Euler angels (roll, pitch,...
Eigen::Vector3< typename Derived::Scalar > quat2eulerZYX(const Eigen::QuaternionBase< Derived > &q)
Converts the quaternion to Euler rotation angles with rotation sequence ZYX.
Eigen::Vector3< typename DerivedA::Scalar > ned2ecef(const Eigen::MatrixBase< DerivedA > &n_position, const Eigen::MatrixBase< DerivedB > &lla_position_ref)
Converts local NED coordinates into ECEF coordinates.
Eigen::Vector3< typename Derived::Scalar > lla2ecef_WGS84(const Eigen::MatrixBase< Derived > &lla_position)
Converts latitude, longitude and altitude into Earth-centered-Earth-fixed coordinates using WGS84.
Eigen::Quaternion< Scalar > n_Quat_b(Scalar roll, Scalar pitch, Scalar yaw)
Quaternion for rotations from body to navigation frame.
KeyedMatrixX< T, KeyType, KeyType > e_systemMatrix_F(const Eigen::Vector3d &ps_f_ip, const Eigen::Vector3d &ps_omega_ip, const Eigen::Quaterniond &b_quat_p, const Eigen::Vector3< T > &e_gravitation, const T &r_eS_e, std::optional< double > tau_bad, std::optional< double > tau_bgd, const Eigen::Vector3< T > &e_position, const Eigen::Quaternion< T > &e_quat_b, const Eigen::Vector3< T > &p_accelBias, const Eigen::Vector3< T > &p_gyroBias, const Eigen::Vector3< T > &p_accelScale, const Eigen::Vector3< T > &p_gyroScale, const Eigen::Quaternion< T > &p_quatAccel_ps, const Eigen::Quaternion< T > &p_quatGyro_ps, const PosVelAttDerivativeConstants &config, bool accelBiases, bool gyroBiases, bool accelScaleFactor, bool gyroScaleFactor, bool accelMisalignment, bool gyroMisalignment)
Calculate the linearized system matrix in Earth frame coordinates.
Eigen::Matrix3d n_F_dv_df(const Eigen::Matrix3d &n_Dcm_b)
Calculates the matrix 𝐅_𝜓'_𝛿f.
Eigen::Matrix< typename Derived::Scalar, 3, 3 > e_F_dv_df_b(const Eigen::MatrixBase< Derived > &e_Dcm_b)
Calculates the matrix 𝐅_𝜓'_𝛿f_b.
Eigen::Matrix3d ie_Q_dr_domega(const Eigen::Vector3d &S_bgd, const Eigen::Matrix3d &ie_F_21, const Eigen::Matrix3d &ie_Dcm_b, const double &tau_s)
Submatrix 𝐐_35 of the system noise covariance matrix 𝐐
Eigen::Matrix3d n_F_dpsi_dr(double latitude, double height, const Eigen::Vector3d &n_velocity, double R_N, double R_E)
Calculates the matrix 𝐅_𝜓'_𝛿r.
Eigen::Matrix3d ie_Q_dr_df(const Eigen::Vector3d &S_bad, const Eigen::Matrix3d &ie_Dcm_b, const double &tau_s)
Submatrix 𝐐_34 of the system noise covariance matrix 𝐐
Eigen::Matrix3< T > e_F_dr_dv()
Calculates the matrix 𝐅_𝛿r'_𝛿v.
Eigen::Matrix3d n_F_dpsi_dv(double latitude, double height, double R_N, double R_E)
Calculates the matrix 𝐅_𝜓'_𝛿v.
Eigen::Matrix3d Q_domega_psi(const Eigen::Vector3d &S_bgd, const Eigen::Matrix3d &b_Dcm_ien, const double &tau_s)
Submatrix 𝐐_51 of the system noise covariance matrix 𝐐
Eigen::Matrix3d Q_df_df(const Eigen::Vector3d &S_bad, const double &tau_s)
Submatrix 𝐐_44 of the system noise covariance matrix 𝐐
Scalar calcEarthRadius_N(const Scalar &latitude, const Scalar &a=InsConst::WGS84::a, const Scalar &e_squared=InsConst::WGS84::e_squared)
Calculates the North/South (meridian) earth radius.
const char * to_string(gui::widgets::PositionWithFrame::ReferenceFrame refFrame)
Converts the enum to a string.
Eigen::Vector3< typename DerivedA::Scalar > n_calcTransportRate(const Eigen::MatrixBase< DerivedA > &lla_position, const Eigen::MatrixBase< DerivedB > &n_velocity, const auto &R_N, const auto &R_E)
Calculates the transport rate ω_en_n (rotation rate of the Earth frame relative to the navigation fra...
Eigen::Matrix3d n_F_dr_dv(double latitude, double height, double R_N, double R_E)
Calculates the matrix 𝐅_𝛿r'_𝛿v.
Eigen::Matrix3d ien_Q_dv_dv(const Eigen::Vector3d &S_ra, const Eigen::Vector3d &S_bad, const Eigen::Vector3d &S_rg, const Eigen::Vector3d &S_bgd, const Eigen::Matrix3d &ien_F_21, const double &tau_s)
Submatrix 𝐐_22 of the system noise covariance matrix 𝐐
bool InertialIntegratorGui(const char *label, InertialIntegrator &integrator, bool &preferAccelerationOverDeltaMeasurements, float width)
Shows a GUI for advanced configuration of the InertialIntegrator.
Eigen::Matrix< typename Derived1::Scalar, 3, 3 > e_F_dv_dr(const Eigen::MatrixBase< Derived1 > &e_position, const Eigen::MatrixBase< Derived2 > &e_gravitation, const T &r_eS_e, const Eigen::Vector3d &e_omega_ie)
Calculates the matrix 𝐅_𝛿v'_𝛿r.
Eigen::Matrix3< T > e_F_dv_dv(double omega_ie)
Calculates the matrix 𝐅_𝛿v'_𝛿v.
Eigen::Matrix3d ie_Q_dr_psi(const Eigen::Vector3d &S_rg, const Eigen::Vector3d &S_bgd, const Eigen::Matrix3d &ie_F_21, const double &tau_s)
Submatrix 𝐐_31 of the system noise covariance matrix 𝐐
Eigen::Matrix< typename Derived::Scalar, 3, 3 > e_F_dw_dw(const Eigen::MatrixBase< Derived > &beta_omega)
Calculates the matrix 𝐅_𝛿ω'_𝛿ω
Eigen::Matrix3d n_F_dv_dr(const Eigen::Vector3d &n_velocity, double latitude, double height, double R_N, double R_E, double g_0, double r_eS_e)
Calculates the matrix 𝐅_𝛿v'_𝛿r.
Eigen::Matrix3d n_Q_dr_dv(const Eigen::Vector3d &S_ra, const Eigen::Vector3d &S_bad, const Eigen::Vector3d &S_rg, const Eigen::Vector3d &S_bgd, const Eigen::Matrix3d &n_F_21, const Eigen::Matrix3d &T_rn_p, const double &tau_s)
Submatrix 𝐐_32 of the system noise covariance matrix 𝐐
Eigen::Matrix3d n_F_dpsi_dw(const Eigen::Matrix3d &n_Dcm_b)
Calculates the matrix 𝐅_𝜓'_𝛿ω
Eigen::Matrix3d n_F_dw_dw(const Eigen::Vector3d &beta_omega)
Calculates the matrix 𝐅_𝛿ω'_𝛿ω
Scalar calcGeocentricRadius(const Scalar &latitude, const Scalar &R_E, const Scalar &e_squared=InsConst::WGS84::e_squared)
r_eS^e The distance of a point on the Earth's surface from the center of the Earth
Eigen::Matrix3d n_F_dv_dpsi(const Eigen::Vector3d &n_force_ib)
Calculates the matrix 𝐅_𝛿v'_𝜓
Eigen::Matrix3d Q_df_dv(const Eigen::Vector3d &S_bad, const Eigen::Matrix3d &b_Dcm_ien, const double &tau_s)
Submatrix 𝐐_42 of the system noise covariance matrix 𝐐
Eigen::Matrix< typename Derived::Scalar, 3, 3 > e_F_dv_dpsi(const Eigen::MatrixBase< Derived > &e_force_ib)
Calculates the matrix 𝐅_𝛿v'_𝜓
Eigen::Matrix3d Q_psi_psi(const Eigen::Vector3d &S_rg, const Eigen::Vector3d &S_bgd, const double &tau_s)
Submatrix 𝐐_11 of the system noise covariance matrix 𝐐
Eigen::Matrix3d n_Q_dr_df(const Eigen::Vector3d &S_bad, const Eigen::Matrix3d &T_rn_p, const Eigen::Matrix3d &n_Dcm_b, const double &tau_s)
Submatrix 𝐐_34 of the system noise covariance matrix 𝐐
Eigen::Vector3d psd2BiasGaussMarkov(const Eigen::Vector3d &sigma2_bd, const Eigen::Vector3d &tau_bd)
u_bias^2 Power Spectral Density of the bias for a Gauss-Markov random process
Eigen::Matrix3< T > e_F_dpsi_dpsi(const T &omega_ie)
Calculates the matrix 𝐅_𝜓'_𝜓
double convertUnit(const double &value, Units::PositionUncertaintyUnits unit)
Converts the value depending on the unit provided.
Eigen::Matrix3d n_F_df_df(const Eigen::Vector3d &beta_a)
Calculates the matrix 𝐅_𝛿f'_𝛿f.
Eigen::Matrix3d n_F_dpsi_dpsi(const Eigen::Vector3d &n_omega_in)
Calculates the matrix 𝐅_𝜓'_𝜓
Eigen::Vector3< typename Derived::Scalar > n_calcGravitation_EGM96(const Eigen::MatrixBase< Derived > &lla_position, size_t ndegree=10)
Calculates the gravitation (acceleration due to mass attraction of the Earth) at the WGS84 reference ...
Eigen::Matrix3d Q_domega_domega(const Eigen::Vector3d &S_bgd, const double &tau_s)
Submatrix 𝐐_55 of the system noise covariance matrix 𝐐
constexpr auto deg2rad(const T °)
Convert Degree to Radians.
Eigen::Matrix3d n_F_dr_dr(const Eigen::Vector3d &n_velocity, double latitude, double height, double R_N, double R_E)
Calculates the matrix 𝐅_𝛿r'_𝛿r.
Eigen::Matrix3d n_Q_dr_psi(const Eigen::Vector3d &S_rg, const Eigen::Vector3d &S_bgd, const Eigen::Matrix3d &n_F_21, const Eigen::Matrix3d &T_rn_p, const double &tau_s)
Submatrix 𝐐_31 of the system noise covariance matrix 𝐐
std::string MakeComboItems()
Units separated by '\0' and terminated by double '\0'.
static const internal::all_t all
Used to request all rows or columns in KeyedMatrices.
Eigen::Matrix< typename Derived::Scalar, 3, 3 > e_F_dpsi_dw(const Eigen::MatrixBase< Derived > &e_Dcm_b)
Calculates the matrix 𝐅_𝜓'_𝛿ω
Eigen::Matrix3d ie_Q_dr_dv(const Eigen::Vector3d &S_ra, const Eigen::Vector3d &S_bad, const Eigen::Vector3d &S_rg, const Eigen::Vector3d &S_bgd, const Eigen::Matrix3d &ie_F_21, const double &tau_s)
Submatrix 𝐐_32 of the system noise covariance matrix 𝐐
Eigen::Matrix3d n_Q_dr_domega(const Eigen::Vector3d &S_bgd, const Eigen::Matrix3d &n_F_21, const Eigen::Matrix3d &T_rn_p, const Eigen::Matrix3d &n_Dcm_b, const double &tau_s)
Submatrix 𝐐_35 of the system noise covariance matrix 𝐐
Eigen::Matrix3d ien_Q_dv_psi(const Eigen::Vector3d &S_rg, const Eigen::Vector3d &S_bgd, const Eigen::Matrix3d &ien_F_21, const double &tau_s)
Submatrix 𝐐_21 of the system noise covariance matrix 𝐐
Eigen::Matrix3d ie_Q_dr_dr(const Eigen::Vector3d &S_ra, const Eigen::Vector3d &S_bad, const Eigen::Vector3d &S_rg, const Eigen::Vector3d &S_bgd, const Eigen::Matrix3d &ie_F_21, const double &tau_s)
Submatrix 𝐐_33 of the system noise covariance matrix 𝐐
Eigen::Matrix3< typename Derived::Scalar > conversionMatrixCartesianCurvilinear(const Eigen::MatrixBase< Derived > &lla_position, const typename Derived::Scalar &R_N, const typename Derived::Scalar &R_E)
Conversion matrix between cartesian and curvilinear perturbations to the position.
Eigen::Matrix3d n_Q_dr_dr(const Eigen::Vector3d &S_ra, const Eigen::Vector3d &S_bad, const Eigen::Vector3d &S_rg, const Eigen::Vector3d &S_bgd, const Eigen::Matrix3d &n_F_21, const Eigen::Matrix3d &T_rn_p, const double &tau_s)
Submatrix 𝐐_33 of the system noise covariance matrix 𝐐
Eigen::Matrix< typename Derived::Scalar, 3, 3 > e_F_df_df(const Eigen::MatrixBase< Derived > &beta_a)
Calculates the matrix 𝐅_𝛿f'_𝛿f.
Eigen::Matrix3d n_F_dv_dv(const Eigen::Vector3d &n_velocity, double latitude, double height, double R_N, double R_E)
Calculates the matrix 𝐅_𝛿v'_𝛿v.
std::ostream & operator<<(std::ostream &os, const SatelliteSystem &satSys)
Stream insertion operator overload.
Eigen::Matrix3d ien_Q_dv_domega(const Eigen::Vector3d &S_bgd, const Eigen::Matrix3d &ien_F_21, const Eigen::Matrix3d &ien_Dcm_b, const double &tau_s)
Submatrix 𝐐_25 of the system noise covariance matrix 𝐐
constexpr auto rad2deg(const T &rad)
Convert Radians to Degree.
Scalar calcEarthRadius_E(const Scalar &latitude, const Scalar &a=InsConst::WGS84::a, const Scalar &e_squared=InsConst::WGS84::e_squared)
Calculates the East/West (prime vertical) earth radius.
Type of the data on the Pin.