20#include <imgui_internal.h>
69 if (j.contains(
"initAngularRateBias"))
73 if (j.contains(
"initAngularRateBiasUnit"))
77 if (j.contains(
"initAccelerationBias"))
81 if (j.contains(
"initAccelerationBiasUnit"))
85 if (j.contains(
"initCovarianceAngularRate"))
89 if (j.contains(
"initCovarianceAngularRateUnit"))
93 if (j.contains(
"initCovarianceAcceleration"))
97 if (j.contains(
"initCovarianceAccelerationUnit"))
101 if (j.contains(
"initCovarianceBiasAngRate"))
105 if (j.contains(
"initCovarianceBiasAngRateUnit"))
109 if (j.contains(
"initCovarianceBiasAcc"))
113 if (j.contains(
"initCovarianceBiasAccUnit"))
118 if (j.contains(
"varBiasAccelerationNoise"))
122 if (j.contains(
"varBiasAccelerationNoiseUnit"))
126 if (j.contains(
"varBiasAngRateNoise"))
130 if (j.contains(
"varBiasAngRateNoiseUnit"))
135 if (j.contains(
"measurementUncertaintyAngularRate"))
139 if (j.contains(
"measurementUncertaintyAngularRateUnit"))
143 if (j.contains(
"measurementUncertaintyAcceleration"))
147 if (j.contains(
"measurementUncertaintyAccelerationUnit"))
186 if (j.contains(
"initAngularRate"))
190 if (j.contains(
"initAngularRateUnit"))
194 if (j.contains(
"initAcceleration"))
198 if (j.contains(
"initAccelerationUnit"))
202 if (j.contains(
"initAngularAcc"))
206 if (j.contains(
"initAngularAccUnit"))
210 if (j.contains(
"initJerk"))
212 j.at(
"initJerk").get_to(data.
initJerk);
214 if (j.contains(
"initJerkUnit"))
219 if (j.contains(
"initCovarianceAngularAcc"))
223 if (j.contains(
"initCovarianceAngularAccUnit"))
227 if (j.contains(
"initCovarianceJerk"))
231 if (j.contains(
"initCovarianceJerkUnit"))
237 if (j.contains(
"varAngularAccNoise"))
241 if (j.contains(
"varAngularAccNoiseUnit"))
245 if (j.contains(
"varJerkNoise"))
249 if (j.contains(
"varJerkNoiseUnit"))
285 if (j.contains(
"initCoeffsAngRate"))
289 if (j.contains(
"initCoeffsAngularRateUnit"))
293 if (j.contains(
"initCoeffsAccel"))
297 if (j.contains(
"initCoeffsAccelUnit"))
301 if (j.contains(
"initCovarianceCoeffsAngRate"))
305 if (j.contains(
"initCovarianceCoeffsAngRateUnit"))
309 if (j.contains(
"initCovarianceCoeffsAccel"))
313 if (j.contains(
"initCovarianceCoeffsAccelUnit"))
320 if (j.contains(
"varCoeffsAngRateNoise"))
324 if (j.contains(
"varCoeffsAngRateUnit"))
328 if (j.contains(
"varCoeffsAccelNoise"))
332 if (j.contains(
"varCoeffsAccelUnit"))
369 return "Data Processor";
374 constexpr float configWidth = 380.0F;
375 constexpr float unitWidth = 150.0F;
377 if (ImGui::BeginTable(fmt::format(
"Pin Settings##{}",
size_t(
id)).c_str(),
inputPins.size() > 1 ? 2 : 1,
378 ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoHostExtendX, ImVec2(0.0F, 0.0F)))
380 ImGui::TableSetupColumn(
"Pin");
383 ImGui::TableSetupColumn(
"");
385 ImGui::TableHeadersRow();
387 for (
size_t pinIndex = 0; pinIndex <
_pinData.size(); ++pinIndex)
389 ImGui::TableNextRow();
390 ImGui::TableNextColumn();
392 ImGui::TextUnformatted(fmt::format(
"{}",
inputPins.at(pinIndex).name).c_str());
396 ImGui::TableNextColumn();
397 if (!(pinIndex == 0))
399 if (ImGui::Button(fmt::format(
"x##{} - {}",
size_t(
id), pinIndex).c_str()))
408 if (ImGui::IsItemHovered())
410 ImGui::SetTooltip(
"Delete the pin");
416 ImGui::TableNextRow();
417 ImGui::TableNextColumn();
418 if (ImGui::Button(fmt::format(
"Add Pin##{}",
size_t(
id)).c_str()))
436 ImGui::SetNextItemOpen(
true, ImGuiCond_FirstUseEver);
438 ImGui::SetNextItemWidth(columnWidth);
447 gui::widgets::HelpMarker(
"IRWKF: Integrated-Random-Walk Kalman-Filter (estimates angular acceleration and jerk).\nB-spline KF: Kalman-Filter that estimates three equally spaced quadratic B-splines for angular rate and acceleration, respectively.");
449 ImGui::SetNextItemOpen(
true, ImGuiCond_FirstUseEver);
451 ImGui::SetNextItemWidth(columnWidth);
458 gui::widgets::HelpMarker(
"The inverse of this rate is used as the initial 'dt' for the Kalman Filter Prediction (Phi and Q).");
462 ImGui::SetNextItemWidth(columnWidth);
472 if (ImGui::Checkbox(fmt::format(
"Rank check for Kalman filter matrices##{}",
size_t(
id)).c_str(), &
_checkKalmanMatricesRanks))
482 ImGui::BeginDisabled();
484 if (ImGui::Checkbox(fmt::format(
"Auto-initialize Kalman filter##{}",
size_t(
id)).c_str(), &
_autoInitKF))
494 LOG_INFO(
"{}: Auto-initialization for KF turned off. This is currently only available for the IRWKF.",
nameId());
496 ImGui::EndDisabled();
499 gui::widgets::HelpMarker(
"Initializes the KF by averaging the data over a specified time frame. Currently only available for the IRWKF fusion type.");
500 if (ImGui::Checkbox(fmt::format(
"Characteristics of the multiple IMUs are identical##{}",
size_t(
id)).c_str(), &
_imuCharacteristicsIdentical))
507 if (ImGui::Checkbox(fmt::format(
"Biases of the multiple IMUs are identical##{}",
size_t(
id)).c_str(), &
_imuBiasesIdentical))
523 ImGui::Text(
"Kalman Filter initialization (auto-init)");
525 ImGui::SetNextItemWidth(columnWidth);
534 if (ImGui::Checkbox(fmt::format(
"Initialize Jerk variance to acceleration variance and angular acceleration variance to angular rate variance##{}",
size_t(
id)).c_str(), &
_initJerkAngAcc))
544 ImGui::Text(
"Kalman Filter initialization (manual init)");
547 ImGui::SetNextItemOpen(
true, ImGuiCond_FirstUseEver);
548 if (ImGui::TreeNode(fmt::format(
"x - State vector##{}",
size_t(
id)).c_str()))
555 "%.2e", ImGuiInputTextFlags_CharsScientific))
563 configWidth, unitWidth,
_pinDataIRWKF.initAcceleration.data(),
_pinDataIRWKF.initAccelerationUnit,
"m/s²\0\0",
"%.2e", ImGuiInputTextFlags_CharsScientific))
573 "%.2e", ImGuiInputTextFlags_CharsScientific))
582 "%.2e", ImGuiInputTextFlags_CharsScientific))
594 "%.2e", ImGuiInputTextFlags_CharsScientific))
601 "%.2e", ImGuiInputTextFlags_CharsScientific))
616 configWidth, unitWidth,
_pinData[1].initAngularRateBias.data(),
_pinData[1].initAngularRateBiasUnit,
"deg/s\0rad/s\0\0",
617 "%.2e", ImGuiInputTextFlags_CharsScientific))
623 configWidth, unitWidth,
_pinData[1].initAccelerationBias.data(),
_pinData[1].initAccelerationBiasUnit,
"m/s^2\0\0",
624 "%.2e", ImGuiInputTextFlags_CharsScientific))
630 for (
size_t pinIndex = 2; pinIndex <
_nInputPins; ++pinIndex)
633 configWidth, unitWidth,
_pinData[pinIndex].initAngularRateBias.data(),
_pinData[pinIndex].initAngularRateBiasUnit,
"deg/s\0rad/s\0\0",
634 "%.2e", ImGuiInputTextFlags_CharsScientific))
640 configWidth, unitWidth,
_pinData[pinIndex].initAccelerationBias.data(),
_pinData[pinIndex].initAccelerationBiasUnit,
"m/s^2\0\0",
641 "%.2e", ImGuiInputTextFlags_CharsScientific))
652 ImGui::SetNextItemOpen(
true, ImGuiCond_FirstUseEver);
653 if (ImGui::TreeNode(fmt::format(
"P - Error covariance matrix##{}",
size_t(
id)).c_str()))
661 :
"Standard deviation σ",
664 configWidth, unitWidth,
_pinData[0].initCovarianceAngularRate.data(),
_pinData[0].initCovarianceAngularRateUnit,
"(rad/s)²\0"
668 "%.2e", ImGuiInputTextFlags_CharsScientific))
671 LOG_DATA(
"{}: AngRateVarianceUnit changed to {}",
nameId(), fmt::underlying(
_pinData[0].initCovarianceAngularRateUnit));
679 :
"Standard deviation σ",
682 configWidth, unitWidth,
_pinDataIRWKF.initCovarianceAngularAcc.data(),
_pinDataIRWKF.initCovarianceAngularAccUnit,
"(rad^2)/(s^4)\0"
686 "%.2e", ImGuiInputTextFlags_CharsScientific))
689 LOG_DATA(
"{}: PinData::AngularAccVarianceUnit changed to {}",
nameId(), fmt::underlying(
_pinDataIRWKF.initCovarianceAngularAccUnit));
696 :
"Standard deviation σ",
699 configWidth, unitWidth,
_pinData[0].initCovarianceAcceleration.data(),
_pinData[0].initCovarianceAccelerationUnit,
"(m^2)/(s^4)\0"
701 "%.2e", ImGuiInputTextFlags_CharsScientific))
703 LOG_DATA(
"{}: initCovarianceAcceleration changed to {}",
nameId(),
_pinData[0].initCovarianceAcceleration);
704 LOG_DATA(
"{}: PinData::AccelerationVarianceUnit changed to {}",
nameId(), fmt::underlying(
_pinData[0].initCovarianceAccelerationUnit));
711 :
"Standard deviation σ",
716 "%.2e", ImGuiInputTextFlags_CharsScientific))
729 :
"Standard deviation σ",
736 "%.2e", ImGuiInputTextFlags_CharsScientific))
744 :
"Standard deviation σ",
749 "%.2e", ImGuiInputTextFlags_CharsScientific))
767 :
"Standard deviation σ",
770 configWidth, unitWidth,
_pinData[1].initCovarianceBiasAngRate.data(),
_pinData[1].initCovarianceBiasAngRateUnit,
"(rad^2)/(s^2)\0"
774 "%.2e", ImGuiInputTextFlags_CharsScientific))
777 LOG_DATA(
"{}: PinData::AngRateVarianceUnit changed to {}",
nameId(), fmt::underlying(
_pinData[1].initCovarianceBiasAngRateUnit));
784 :
"Standard deviation σ",
787 configWidth, unitWidth,
_pinData[1].initCovarianceBiasAcc.data(),
_pinData[1].initCovarianceBiasAccUnit,
"(m^2)/(s^4)\0"
789 "%.2e", ImGuiInputTextFlags_CharsScientific))
792 LOG_DATA(
"{}: PinData::AccelerationVarianceUnit changed to {}",
nameId(), fmt::underlying(
_pinData[1].initCovarianceBiasAccUnit));
797 for (
size_t pinIndex = 2; pinIndex <
_nInputPins; ++pinIndex)
803 :
"Standard deviation σ",
806 configWidth, unitWidth,
_pinData[pinIndex].initCovarianceBiasAngRate.data(),
_pinData[pinIndex].initCovarianceBiasAngRateUnit,
"(rad^2)/(s^2)\0"
810 "%.2e", ImGuiInputTextFlags_CharsScientific))
812 LOG_DATA(
"{}: initCovarianceBiasAngRate changed to {}",
nameId(),
_pinData[pinIndex].initCovarianceBiasAngRate);
813 LOG_DATA(
"{}: PinData::AngRateVarianceUnit changed to {}",
nameId(), fmt::underlying(
_pinData[pinIndex].initCovarianceBiasAngRateUnit));
820 :
"Standard deviation σ",
823 configWidth, unitWidth,
_pinData[pinIndex].initCovarianceBiasAcc.data(),
_pinData[pinIndex].initCovarianceBiasAccUnit,
"(m^2)/(s^4)\0"
825 "%.2e", ImGuiInputTextFlags_CharsScientific))
828 LOG_DATA(
"{}: PinData::AccelerationVarianceUnit changed to {}",
nameId(), fmt::underlying(
_pinData[pinIndex].initCovarianceBiasAccUnit));
843 ImGui::Text(
"Kalman Filter noise setting");
846 ImGui::SetNextItemOpen(
true, ImGuiCond_FirstUseEver);
847 if (ImGui::TreeNode(fmt::format(
"Q - System/Process noise covariance matrix##{}",
size_t(
id)).c_str()))
849 ImGui::SetNextItemWidth(configWidth + ImGui::GetStyle().ItemSpacing.x);
857 :
"Standard deviation σ",
864 "%.2e", ImGuiInputTextFlags_CharsScientific))
874 :
"Standard deviation σ",
879 "%.2e", ImGuiInputTextFlags_CharsScientific))
892 :
"Standard deviation σ",
899 "%.2e", ImGuiInputTextFlags_CharsScientific))
907 :
"Standard deviation σ",
912 "%.2e", ImGuiInputTextFlags_CharsScientific))
930 :
"Standard deviation σ",
933 configWidth, unitWidth,
_pinData[1].varBiasAngRateNoise.data(),
_pinData[1].varBiasAngRateNoiseUnit,
"(rad/s)^2\0"
937 "%.2e", ImGuiInputTextFlags_CharsScientific))
940 LOG_DATA(
"{}: varBiasAngRateNoiseUnit changed to {}",
nameId(), fmt::underlying(
_pinData[1].varBiasAngRateNoiseUnit));
947 :
"Standard deviation σ",
950 configWidth, unitWidth,
_pinData[1].varBiasAccelerationNoise.data(),
_pinData[1].varBiasAccelerationNoiseUnit,
"(m^2)/(s^4)\0"
952 "%.2e", ImGuiInputTextFlags_CharsScientific))
954 LOG_DATA(
"{}: varBiasAccelerationNoise changed to {}",
nameId(),
_pinData[1].varBiasAccelerationNoise.transpose());
955 LOG_DATA(
"{}: varBiasAccelerationNoiseUnit changed to {}",
nameId(), fmt::underlying(
_pinData[1].varBiasAccelerationNoiseUnit));
960 for (
size_t pinIndex = 2; pinIndex <
_nInputPins; ++pinIndex)
966 :
"Standard deviation σ",
969 configWidth, unitWidth,
_pinData[pinIndex].varBiasAngRateNoise.data(),
_pinData[pinIndex].varBiasAngRateNoiseUnit,
"(rad/s)^2\0"
973 "%.2e", ImGuiInputTextFlags_CharsScientific))
975 LOG_DATA(
"{}: varBiasAngRateNoise changed to {}",
nameId(),
_pinData[pinIndex].varBiasAngRateNoise.transpose());
976 LOG_DATA(
"{}: varBiasAngRateNoiseUnit changed to {}",
nameId(), fmt::underlying(
_pinData[pinIndex].varBiasAngRateNoiseUnit));
983 :
"Standard deviation σ",
986 configWidth, unitWidth,
_pinData[pinIndex].varBiasAccelerationNoise.data(),
_pinData[pinIndex].varBiasAccelerationNoiseUnit,
"(m^2)/(s^4)\0"
988 "%.2e", ImGuiInputTextFlags_CharsScientific))
990 LOG_DATA(
"{}: varBiasAccelerationNoise changed to {}",
nameId(),
_pinData[pinIndex].varBiasAccelerationNoise.transpose());
991 LOG_DATA(
"{}: varBiasAccelerationNoiseUnit changed to {}",
nameId(), fmt::underlying(
_pinData[pinIndex].varBiasAccelerationNoiseUnit));
1001 ImGui::SetNextItemOpen(
true, ImGuiCond_FirstUseEver);
1002 if (ImGui::TreeNode(fmt::format(
"R - Measurement noise covariance matrix##{}",
size_t(
id)).c_str()))
1004 ImGui::SetNextItemWidth(configWidth + ImGui::GetStyle().ItemSpacing.x);
1010 :
"Standard deviation σ",
1013 configWidth, unitWidth,
_pinData[0].measurementUncertaintyAngularRate.data(),
_pinData[0].measurementUncertaintyAngularRateUnit,
"(rad/s)^2\0"
1017 "%.2e", ImGuiInputTextFlags_CharsScientific))
1019 LOG_DATA(
"{}: stdevAngularAcc changed to {}",
nameId(),
_pinData[0].measurementUncertaintyAngularRate.transpose());
1020 LOG_DATA(
"{}: stdevAngularAccUnit changed to {}",
nameId(), fmt::underlying(
_pinData[0].measurementUncertaintyAngularRateUnit));
1027 :
"Standard deviation σ",
1030 configWidth, unitWidth,
_pinData[0].measurementUncertaintyAcceleration.data(),
_pinData[0].measurementUncertaintyAccelerationUnit,
"(m^2)/(s^4)\0"
1032 "%.2e", ImGuiInputTextFlags_CharsScientific))
1034 LOG_DATA(
"{}: stdevJerk changed to {}",
nameId(),
_pinData[0].measurementUncertaintyAcceleration.transpose());
1035 LOG_DATA(
"{}: stdevJerkUnit changed to {}",
nameId(), fmt::underlying(
_pinData[0].measurementUncertaintyAccelerationUnit));
1040 for (
size_t pinIndex = 1; pinIndex <
_nInputPins; ++pinIndex)
1046 :
"Standard deviation σ",
1049 configWidth, unitWidth,
_pinData[pinIndex].measurementUncertaintyAngularRate.data(),
_pinData[pinIndex].measurementUncertaintyAngularRateUnit,
"(rad/s)^2\0"
1053 "%.2e", ImGuiInputTextFlags_CharsScientific))
1055 LOG_DATA(
"{}: stdevAngularAcc changed to {}",
nameId(),
_pinData[pinIndex].measurementUncertaintyAngularRate.transpose());
1056 LOG_DATA(
"{}: stdevAngularAccUnit changed to {}",
nameId(), fmt::underlying(
_pinData[pinIndex].measurementUncertaintyAngularRateUnit));
1063 :
"Standard deviation σ",
1066 configWidth, unitWidth,
_pinData[pinIndex].measurementUncertaintyAcceleration.data(),
_pinData[pinIndex].measurementUncertaintyAccelerationUnit,
"(m^2)/(s^4)\0"
1068 "%.2e", ImGuiInputTextFlags_CharsScientific))
1070 LOG_DATA(
"{}: stdevJerk changed to {}",
nameId(),
_pinData[pinIndex].measurementUncertaintyAcceleration.transpose());
1071 LOG_DATA(
"{}: stdevJerkUnit changed to {}",
nameId(), fmt::underlying(
_pinData[pinIndex].measurementUncertaintyAccelerationUnit));
1114 if (j.contains(
"imuFusionType"))
1118 if (j.contains(
"checkKalmanMatricesRanks"))
1122 if (j.contains(
"nInputPins"))
1127 if (j.contains(
"imuFrequency"))
1131 if (j.contains(
"numStates"))
1135 if (j.contains(
"pinData"))
1139 if (j.contains(
"pinDataIRWKF"))
1143 if (j.contains(
"pinDataBsplineKF"))
1147 if (j.contains(
"initCoeffsAngRateTemp"))
1151 if (j.contains(
"initCoeffsAccelTemp"))
1155 if (j.contains(
"initCovarianceCoeffsAngRateTemp"))
1159 if (j.contains(
"initCovarianceCoeffsAccelTemp"))
1163 if (j.contains(
"procNoiseCoeffsAngRateTemp"))
1167 if (j.contains(
"procNoiseCoeffsAccelTemp"))
1171 if (j.contains(
"autoInitKF"))
1175 if (j.contains(
"initJerkAngAcc"))
1179 if (j.contains(
"_kfInitialized"))
1183 if (j.contains(
"averageEndTime"))
1187 if (j.contains(
"splineSpacing"))
1212 for (
size_t pinIndex = 0; pinIndex <
_pinData.size(); pinIndex++)
1214 if (!
inputPins.at(pinIndex).isPinLinked())
1216 LOG_INFO(
"Fewer links than input pins - Consider deleting pins that are not connected to limit KF matrices to the necessary size.");
1253 size_t pinDataIdx = 0;
1254 for (
size_t pinIndex = 0; pinIndex <
_nInputPins; ++pinIndex)
1258 pinDataIdx = pinIndex;
1262 switch (
_pinData[pinDataIdx].measurementUncertaintyAngularRateUnit)
1279 switch (
_pinData[pinDataIdx].measurementUncertaintyAccelerationUnit)
1347 auto imuObs = std::static_pointer_cast<const ImuObs>(queue.
extract_front());
1349 if (imuObs->insTime.empty())
1351 LOG_ERROR(
"{}: Can't set new imuObs__t0 because the observation has no time tag (insTime/timeSinceStartup)",
nameId());
1370 auto dt =
static_cast<double>((imuObs->insTime -
_latestTimestamp).count());
1426 LOG_DATA(
"DCM_accel =\n{}", DCM_accel);
1466 _kalmanFilter =
IRWKF::initializeKalmanFilterAuto(
_nInputPins,
_pinData,
_pinDataIRWKF,
_cumulatedPinIds,
_cumulatedImuObs,
_initJerkAngAcc, dtInit,
_numStates,
_numMeasurements,
_processNoiseVariances,
_kalmanFilter);
1480 auto imuObsFiltered = std::make_shared<ImuObs>(this->
_imuPos);
1520 imuObsFiltered->insTime = imuObs->insTime;
1530 LOG_DATA(
"{}: timeSinceStartup: {}, qBsplines (stacked B-spline values, cumulatively = 1) = {}, {}, {}",
nameId(),
_timeSinceStartup, qBsplines.at(0), qBsplines.at(1), qBsplines.at(2));
1535 auto angRateEst =
_kalmanFilter.x.block<3, 1>(0, 0) * qBsplines.at(0)
1540 auto accelEst =
_kalmanFilter.x.block<3, 1>(9, 0) * qBsplines.at(0)
1544 LOG_DATA(
"{}: imuObs->insTime = {}, timeSinceStartup = {}, angRateEst = {}, accelEst = {}",
nameId(), imuObs->insTime.toYMDHMS(),
_timeSinceStartup, angRateEst.transpose(), accelEst.transpose());
1546 imuObsFiltered->p_acceleration = accelEst;
1547 imuObsFiltered->p_angularRate = angRateEst;
1553 LOG_ERROR(
"{}: imuObsFiltered->insTime < _lastFiltObs --> {}",
nameId(),
static_cast<double>((imuObsFiltered->insTime -
_lastFiltObs).count()));
1559 for (
size_t OUTPUT_PORT_INDEX_BIAS = 1; OUTPUT_PORT_INDEX_BIAS <
_nInputPins; ++OUTPUT_PORT_INDEX_BIAS)
1561 auto imuRelativeBiases = std::make_shared<InsGnssLCKFSolution>();
1562 imuRelativeBiases->insTime = imuObs->insTime;
1569 LOG_DATA(
"{}: timeSinceStartup = {}, Relative bias {}1 Gyro: {}",
nameId(),
_timeSinceStartup, OUTPUT_PORT_INDEX_BIAS + 1, imuRelativeBiases->b_biasGyro.value.transpose());
1570 LOG_DATA(
"{}: timeSinceStartup = {}, Relative bias {}1 Accel: {}",
nameId(),
_timeSinceStartup, OUTPUT_PORT_INDEX_BIAS + 1, imuRelativeBiases->b_biasAccel.value.transpose());
1580 return alpha * R + (1.0 - alpha) * (e * e.transpose() + H * P * H.transpose());
Kalman filter matrices for the B-spline Multi-IMU fusion.
Combo representing an enumeration.
nlohmann::json json
json namespace
Text Help Marker (?) with Tooltip.
Kalman filter matrices for the Integrated-Random-Walk (IRW) Multi-IMU fusion.
Combines signals of sensors that provide the same signal-type to one signal.
Loosely-coupled Kalman Filter INS/GNSS errors.
Defines how to save certain datatypes to json.
Utility class for logging to console and file.
#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_INFO
Info to the user on the state of the program.
#define LOG_TRACE
Detailled info to trace the execution of the program. Should not be called on functions which receive...
Constructs four overlapping qaudratic B-splines.
KalmanFilter _kalmanFilter
Kalman Filter representation.
void updateNumberOfInputPins()
Adds/Deletes Input Pins depending on the variable _nInputPins.
std::vector< Eigen::Matrix3d > _imuRotations_accel
Rotations of all connected accelerometers - key: pinIndex, value: Rotation matrix of the acceleromete...
uint8_t _numStatesEst
Number of estimated states (depends on imuFusionType)
const uint8_t _numStatesEstIRWKF
Number of states estimated by the IRW-KF (angular rate, angular acceleration, specific force,...
void initializeMountingAngles()
Initializes the rotation matrices used for the mounting angles of the sensors.
std::string type() const override
String representation of the Class Type.
bool initialize() override
Initialize the node.
Eigen::Vector3d _procNoiseCoeffsAccelTemp
Temporary vector for the initial coefficients' process noise for the acceleration.
bool _kfInitialized
flag to check whether KF has been auto-initialized
bool _checkKalmanMatricesRanks
Check the rank of the Kalman matrices every iteration (computationally expensive)
bool _imuCharacteristicsIdentical
If the multiple IMUs have the same characteristics, GUI input cells can be reduced considerably.
std::vector< Eigen::Matrix3d > _imuRotations_gyro
Rotations of all connected gyros - key: pinIndex, value: Rotation matrix of the gyro platform to body...
Eigen::Vector3d _initCovarianceCoeffsAngRateTemp
Temporary vector for the initial coefficients' initial covariance for the angular rate.
std::vector< Eigen::Vector3d > _measurementNoiseVariances
Container for measurement noises of each sensor.
const uint8_t _numBsplines
Number of quadratic B-splines that make up the entire 3D stacked B-spline.
json save() const override
Saves the node into a json object.
void recvSignal(InputPin::NodeDataQueue &queue, size_t pinIdx)
Receive Function for the signal at the time tₖ
const uint8_t _numMeasurements
Number of measurements overall.
size_t _nInputPins
Number of input pins.
InsTime _lastFiltObs
Previous observation (for timestamp)
~ImuFusion() override
Destructor.
void measurementNoiseMatrix_R(Eigen::MatrixXd &R, size_t pinIndex=0) const
Calculates the initial measurement noise matrix R.
ImuPos _imuPos
Position and rotation information for conversion from platform to body frame.
InsTime _firstTimestamp
Saves the first timestamp in [s].
PinDataIRWKF _pinDataIRWKF
Stores IRW-KF specific parameter data.
Eigen::Vector3d _initCoeffsAccelTemp
Temporary vector for the initial coefficients for acceleration.
double _imuFrequency
Highest IMU sample rate in [Hz] (for time step in KF prediction)
std::vector< Eigen::Vector3d > _biasCovariances
Container for the bias covariances.
double _averageEndTime
Time until averaging ends and filtering starts in [s].
static std::string typeStatic()
String representation of the Class Type.
bool _imuPosSet
Check whether the combined solution has an '_imuPos' set.
static Eigen::MatrixXd measurementNoiseMatrix_R_adaptive(double alpha, const Eigen::MatrixXd &R, const Eigen::VectorXd &e, const Eigen::MatrixXd &H, const Eigen::MatrixXd &P)
Calculates the adaptive measurement noise matrix R.
static constexpr size_t OUTPUT_PORT_INDEX_COMBINED_SIGNAL
Flow (ImuObs)
void guiConfig() override
ImGui config window which is shown on double click.
ImuFusion()
Default constructor.
std::vector< std::shared_ptr< const NAV::ImuObs > > _cumulatedImuObs
Container that collects all imuObs for averaging for auto-init of the KF.
void restore(const json &j) override
Restores the node from a json object.
static std::string category()
String representation of the Class Category.
Eigen::Vector3d _initCovarianceCoeffsAccelTemp
Temporary vector for the initial coefficients' initial covariance for the acceleration.
std::vector< size_t > _cumulatedPinIds
Container that collects all pinIds for averaging for auto-init of the KF.
uint8_t _numStates
Number of states overall.
const uint8_t _numStatesEstBsplineKF
Number of states estimated by the B-spline KF (3 stacked B-splines in 3D for angular rate and specifi...
double _timeSinceStartup
Time since startup in [s].
bool _initJerkAngAcc
flag to determine how jerk and angular acceleration states are initialized if '_autoInitKF = true'
std::vector< Eigen::VectorXd > _processNoiseVariances
Container for process noise of each state.
void deinitialize() override
Deinitialize the node.
double _latestKnot
Latest knot in [s].
const uint8_t _numStatesPerPin
Number of states per pin (biases of accel and gyro)
ImuFusionType _imuFusionType
KF-type for the IMU fusion, selected in the GUI.
bool _autoInitKF
Auto-initialize the Kalman Filter - GUI setting.
@ Bspline
B-spline Kalman filter.
@ IRWKF
IRW Kalman filter.
double _splineSpacing
Time difference between two quadratic B-splines in the stacked B-spline.
std::vector< PinData > _pinData
Stores parameter data for each connected sensor.
Eigen::Vector3d _procNoiseCoeffsAngRateTemp
Temporary vector for the initial coefficients' process noise for the angular rate.
void combineSignals(const std::shared_ptr< const ImuObs > &imuObs)
Combines the signals.
PinDataBsplineKF _pinDataBsplineKF
Stores Bspline-KF specific parameter data.
bool _imuBiasesIdentical
If the multiple IMUs have the same bias, GUI input cells can be reduced considerably.
InsTime _latestTimestamp
Saves the timestamp of the measurement before in [s].
InsTime _avgEndTime
Time until averaging ends and filtering starts as 'InsTime'.
Eigen::Vector3d _initCoeffsAngRateTemp
Temporary vector for the initial coefficients for angular rate.
static std::string type()
Returns the type of the data class.
Imu(const Imu &)=delete
Copy constructor.
The class is responsible for all time-related tasks.
Generalized Kalman Filter class.
bool doDeinitialize(bool wait=false)
Asks the node worker to deinitialize the node.
ImVec2 _guiConfigDefaultWindowSize
std::vector< OutputPin > outputPins
List of output pins.
bool DeleteOutputPin(size_t pinIndex)
Deletes the output pin. Invalidates the pin reference given.
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.
auto extract_front()
Returns a copy of the first element in the container and removes it from the container.
static float windowFontRatio()
Ratio to multiply for GUI window elements.
bool InputDoubleL(const char *label, double *v, double v_min, double v_max, double step, double step_fast, const char *format, ImGuiInputTextFlags flags)
Shows a value limited InputText GUI element for 'double'.
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 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.
void stateTransitionMatrix_Phi(Eigen::MatrixXd &Phi, const double &dt)
Calculates the state-transition-matrix 𝚽
Eigen::MatrixXd designMatrix_H(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.
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.
KalmanFilter initializeKalmanFilterManually(const size_t &numInputPins, const std::vector< PinData > &pinData, const PinDataIRWKF &pinDataIRWKF, const uint8_t &numStates, const double &dtInit, std::vector< Eigen::VectorXd > &processNoiseVariances, KalmanFilter &kalmanFilter, const bool &imuCharacteristicsIdentical, const bool &imuBiasesIdentical)
Initializes the IRWKF manually (i.e. using GUI inputs instead of averaging)
KalmanFilter initializeKalmanFilterAuto(const size_t &nInputPins, const std::vector< PinData > &pinData, const PinDataIRWKF &pinDataIRWKF, const std::vector< size_t > &cumulatedPinIds, const std::vector< std::shared_ptr< const NAV::ImuObs > > &cumulatedImuObs, const bool &initJerkAngAcc, const double &dtInit, const uint8_t &numStates, const uint8_t &numMeasurements, std::vector< Eigen::VectorXd > &processNoiseVariances, KalmanFilter &kalmanFilter)
Initializes the IRWKF automatically, i.e. init values are calculated by averaging the data in the fir...
void ApplyChanges()
Signals that there have been changes to the flow.
void to_json(json &j, const Node &node)
Converts the provided node into a json object.
void from_json(const json &j, Node &node)
Converts the provided json object into a node object.
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.
Sensor information specific to the IRW-KF.
JerkVarianceUnit initCovarianceJerkUnit
Gui selection for the unit of the initial covariance for the jerk.
PinData::AccelerationUnit initAccelerationUnit
Gui selection for the unit of the initial acceleration.
Eigen::Vector3d initAcceleration
GUI selection for the initial acceleration.
AngularAccUnit initAngularAccUnit
Gui selection for the unit of the initial angular acceleration.
Eigen::Vector3d initCovarianceAngularAcc
GUI selection for the initial covariance diagonal values for angular acceleration (standard deviation...
Eigen::Vector3d initAngularRate
GUI selection for the initial angular rate.
Eigen::Vector3d initCovarianceJerk
GUI selection for the initial covariance diagonal values for jerk (standard deviation σ or Variance σ...
Eigen::Vector3d varJerkNoise
GUI selection for the jerk process noise diagonal values.
AngularAccVarianceUnit varAngularAccNoiseUnit
Gui selection for the unit of the angular acceleration process noise.
Eigen::Vector3d initJerk
GUI selection for the initial jerk.
Eigen::Vector3d varAngularAccNoise
GUI selection for the angular acceleration process noise diagonal values.
@ m2_s6
Variance [(m^2)/(s^6), (m^2)/(s^6), (m^2)/(s^6)].
AngularAccVarianceUnit initCovarianceAngularAccUnit
Gui selection for the unit of the initial covariance for the angular acceleration.
PinData::AngRateUnit initAngularRateUnit
Gui selection for the unit of the initial angular rate.
Eigen::Vector3d initAngularAcc
GUI selection for the initial angular acceleration.
JerkVarianceUnit varJerkNoiseUnit
Gui selection for the unit of the jerk process noise.
JerkUnit initJerkUnit
Gui selection for the Unit of the initial jerk.
@ deg2_s4
Variance [(deg^2)/(s^4), (deg^2)/(s^4), (deg^2)/(s^4)].
@ rad2_s4
Variance [(rad^2)/(s^4), (rad^2)/(s^4), (rad^2)/(s^4)].
Information about a sensor which is connected to a certain pin (i.e. sensor characteristics defined i...
AccelerationVarianceUnit measurementUncertaintyAccelerationUnit
Gui selection for the unit of the acceleration's measurement uncertainty.
Eigen::Vector3d initCovarianceAngularRate
GUI selection for the initial covariance diagonal values for angular rate (standard deviation σ or Va...
Eigen::Vector3d measurementUncertaintyAngularRate
Gui selection for the angular rate measurement uncertainty diagonal values.
@ 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²].
AccelerationVarianceUnit initCovarianceBiasAccUnit
Gui selection for the Unit of the initial covariance for the acceleration biases.
Eigen::Vector3d varBiasAngRateNoise
GUI selection for the process noise of the angular rate diagonal values (standard deviation σ or Vari...
Eigen::Vector3d initCovarianceBiasAcc
GUI selection for the initial covariance diagonal values for acceleration biases (standard deviation ...
Eigen::Vector3d initCovarianceAcceleration
GUI selection for the initial covariance diagonal values for acceleration (standard deviation σ or Va...
Eigen::Vector3d measurementUncertaintyAcceleration
Gui selection for the acceleration measurement uncertainty diagonal values.
AngRateVarianceUnit varBiasAngRateNoiseUnit
Gui selection for the Unit of the process noise of the angular rate.
AccelerationUnit initAccelerationBiasUnit
GUI selection for the unit of the initial angular acceleration bias.
AngRateVarianceUnit measurementUncertaintyAngularRateUnit
Gui selection for the unit of the angular rate's measurement uncertainty.
@ 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].
Eigen::Vector3d initAccelerationBias
GUI selection for the initial acceleration bias.
Eigen::Vector3d initAngularRateBias
GUI selection for the initial angular rate bias.
AngRateVarianceUnit initCovarianceAngularRateUnit
Gui selection for the Unit of the initial covariance for the angular rate.
Eigen::Vector3d initCovarianceBiasAngRate
GUI selection for the initial covariance diagonal values for angular rate biases (standard deviation ...
AccelerationVarianceUnit initCovarianceAccelerationUnit
Gui selection for the Unit of the initial covariance for the acceleration.
Eigen::Vector3d varBiasAccelerationNoise
GUI selection for the process noise of the acceleration diagonal values (standard deviation σ or Vari...
AngRateVarianceUnit initCovarianceBiasAngRateUnit
Gui selection for the Unit of the initial covariance for the angular rate biases.
AccelerationVarianceUnit varBiasAccelerationNoiseUnit
Gui selection for the Unit of the process noise of the acceleration.
AngRateUnit initAngularRateBiasUnit
GUI selection for the unit of the initial angular rate bias.