0.3.0
Loading...
Searching...
No Matches
InertialIntegrator.cpp
Go to the documentation of this file.
1// This file is part of INSTINCT, the INS Toolkit for Integrated
2// Navigation Concepts and Training by the Institute of Navigation of
3// the University of Stuttgart, Germany.
4//
5// This Source Code Form is subject to the terms of the Mozilla Public
6// License, v. 2.0. If a copy of the MPL was not distributed with this
7// file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9/// @file InertialIntegrator.cpp
10/// @brief Inertial Measurement Integrator
11/// @author T. Topp (topp@ins.uni-stuttgart.de)
12/// @date 2023-12-09
13
15
18
22
23namespace NAV
24{
25
28
30{
31 _states.clear();
33 _p_lastBiasAngularRate.setZero();
35}
36
38{
39 return !_states.empty();
40}
41
42void InertialIntegrator::setInitialState(const PosVelAtt& state, const char* nameId)
43{
44 _states.clear();
45 addState(state, nameId);
46}
47
48void InertialIntegrator::addState(const PosVelAtt& state, [[maybe_unused]] const char* nameId)
49{
50 _states.push_back(State{
51 .epoch = state.insTime,
52 .position = _integrationFrame == IntegrationFrame::ECEF ? state.e_position() : state.lla_position(),
53 .velocity = _integrationFrame == IntegrationFrame::ECEF ? state.e_velocity() : state.n_velocity(),
54 .attitude = _integrationFrame == IntegrationFrame::ECEF ? state.e_Quat_b() : state.n_Quat_b(),
55 .m = Measurement{
56 .averagedMeasurement = false,
57 .dt = 0.0,
58 .p_acceleration = Eigen::Vector3d::Zero(),
59 .p_angularRate = Eigen::Vector3d::Zero(),
60 } });
61 LOG_DATA("{}: Adding state for [{}]. Now has {} states", nameId, state.insTime.toYMDHMS(GPST), _states.size());
62}
63
64void InertialIntegrator::setTotalSensorBiases(const Eigen::Vector3d& p_biasAcceleration, const Eigen::Vector3d& p_biasAngularRate)
65{
66 _p_lastBiasAcceleration = p_biasAcceleration;
67 _p_lastBiasAngularRate = p_biasAngularRate;
68}
69
70void InertialIntegrator::applySensorBiasesIncrements(const Eigen::Vector3d& p_deltaBiasAcceleration, const Eigen::Vector3d& p_deltaBiasAngularRate)
71{
72 _p_lastBiasAcceleration += p_deltaBiasAcceleration;
73 _p_lastBiasAngularRate += p_deltaBiasAngularRate;
74}
75
76void InertialIntegrator::applyStateErrors_n(const Eigen::Vector3d& lla_positionError, const Eigen::Vector3d& n_velocityError, const Eigen::Vector3d& n_attitudeError_b)
77{
78 INS_ASSERT_USER_ERROR(_integrationFrame == IntegrationFrame::NED, "You can only apply errors to the selected integration frame");
79 INS_ASSERT_USER_ERROR(!_states.empty(), "You can only apply errors if the states vector is not empty");
80
81 _states.back().position -= lla_positionError;
82 _states.back().velocity -= n_velocityError;
83 // Attitude correction, see Titterton and Weston (2004), p. 407 eq. 13.15
84 Eigen::Matrix3d n_Dcm_b = (Eigen::Matrix3d::Identity() - math::skewSymmetricMatrix(n_attitudeError_b)) * _states.back().attitude.toRotationMatrix();
85 _states.back().attitude = Eigen::Quaterniond(n_Dcm_b).normalized();
86
87 // TODO: Test this out again
88 // Attitude correction, see Titterton and Weston (2004), p. 407 eq. 13.16
89 // Eigen::Quaterniond n_Quat_b = posVelAtt->n_Quat_b()
90 // * (Eigen::AngleAxisd(attError(0), Eigen::Vector3d::UnitX())
91 // * Eigen::AngleAxisd(attError(1), Eigen::Vector3d::UnitY())
92 // * Eigen::AngleAxisd(attError(2), Eigen::Vector3d::UnitZ()))
93 // .normalized();
94 // posVelAttCorrected->setAttitude_n_Quat_b(n_Quat_b.normalized());
95
96 // Eigen::Vector3d attError = pvaError->n_attitudeError();
97 // const Eigen::Quaterniond& n_Quat_b = posVelAtt->n_Quat_b();
98 // Eigen::Quaterniond n_Quat_b_c{ n_Quat_b.w() + 0.5 * (+attError(0) * n_Quat_b.x() + attError(1) * n_Quat_b.y() + attError(2) * n_Quat_b.z()),
99 // n_Quat_b.x() + 0.5 * (-attError(0) * n_Quat_b.w() + attError(1) * n_Quat_b.z() - attError(2) * n_Quat_b.y()),
100 // n_Quat_b.y() + 0.5 * (-attError(0) * n_Quat_b.z() - attError(1) * n_Quat_b.w() + attError(2) * n_Quat_b.x()),
101 // n_Quat_b.z() + 0.5 * (+attError(0) * n_Quat_b.y() - attError(1) * n_Quat_b.x() - attError(2) * n_Quat_b.w()) };
102 // posVelAttCorrected->setAttitude_n_Quat_b(n_Quat_b_c.normalized());
103}
104
105void InertialIntegrator::applyStateErrors_e(const Eigen::Vector3d& e_positionError, const Eigen::Vector3d& e_velocityError, const Eigen::Vector3d& e_attitudeError_b)
106{
107 INS_ASSERT_USER_ERROR(_integrationFrame == IntegrationFrame::ECEF, "You can only apply errors to the selected integration frame");
108 INS_ASSERT_USER_ERROR(!_states.empty(), "You can only apply errors if the states vector is not empty");
109
110 _states.back().position -= e_positionError;
111 _states.back().velocity -= e_velocityError;
112 // Attitude correction, see Titterton and Weston (2004), p. 407 eq. 13.15
113 Eigen::Matrix3d e_Dcm_b = (Eigen::Matrix3d::Identity() - math::skewSymmetricMatrix(e_attitudeError_b)) * _states.back().attitude.toRotationMatrix();
114 _states.back().attitude = Eigen::Quaterniond(e_Dcm_b).normalized();
115}
116
117std::optional<std::reference_wrapper<const InertialIntegrator::State>> InertialIntegrator::getLatestState() const
118{
119 if (_states.empty()) { return {}; }
120 return _states.back();
121}
122
124{
126}
127
129{
131}
132
137
142
147
148std::optional<Eigen::Vector3d> InertialIntegrator::p_calcCurrentAcceleration() const
149{
150 if (_states.empty()) { return {}; }
151
152 return _states.back().m.p_acceleration + _states.back().p_biasAcceleration;
153}
154
155std::optional<Eigen::Vector3d> InertialIntegrator::p_calcCurrentAngularRate() const
156{
157 if (_states.empty()) { return {}; }
158
159 return _states.back().m.p_angularRate + _states.back().p_biasAngularRate;
160}
161
162void InertialIntegrator::addMeasurement(const InsTime& epoch, double dt, const Eigen::Vector3d& p_acceleration, const Eigen::Vector3d& p_angularRate, [[maybe_unused]] const char* nameId)
163{
164 LOG_DATA("{}: Adding measurement [{}]. Last state at [{}]", nameId, epoch.toYMDHMS(GPST), _states.back().epoch.toYMDHMS(GPST));
165 INS_ASSERT_USER_ERROR(!_states.empty(), "You need to add an initial state first");
166
167 if (_states.back().epoch == epoch)
168 {
169 LOG_DATA("{}: Updating existing state", nameId);
170 _states.back().m.averagedMeasurement = _accelerationsAreAveragedMeasurements;
171 _states.back().m.dt = dt;
172 _states.back().m.p_acceleration = p_acceleration;
173 _states.back().m.p_angularRate = p_angularRate;
174 _states.back().p_biasAcceleration = _p_lastBiasAcceleration;
175 _states.back().p_biasAngularRate = _p_lastBiasAngularRate;
176 return;
177 }
178
179 LOG_DATA("{}: Adding as new state", nameId);
180 _states.push_back(State{
181 .epoch = epoch,
182 .position = _states.back().position,
183 .velocity = _states.back().velocity,
184 .attitude = _states.back().attitude,
185 .m = Measurement{
186 .averagedMeasurement = _accelerationsAreAveragedMeasurements,
187 .dt = dt,
188 .p_acceleration = p_acceleration,
189 .p_angularRate = p_angularRate,
190 },
191 .p_biasAcceleration = _p_lastBiasAcceleration,
192 .p_biasAngularRate = _p_lastBiasAngularRate,
193 });
194}
195
196void InertialIntegrator::addDeltaMeasurement(const InsTime& epoch, double dt, double deltaTime, const Eigen::Vector3d& p_deltaVelocity, const Eigen::Vector3d& p_deltaTheta, const char* nameId)
197{
198 LOG_DATA("{}: Adding delta measurement for [{}]", nameId, epoch.toYMDHMS(GPST));
199 Eigen::Vector3d p_acceleration = Eigen::Vector3d::Zero();
200 Eigen::Vector3d p_angularRate = Eigen::Vector3d::Zero();
201
202 if (deltaTime > 0.0) // dt given by sensor (should never be 0 or negative, but check here just in case)
203 {
204 p_acceleration = p_deltaVelocity / deltaTime;
205 p_angularRate = p_deltaTheta / deltaTime;
206 }
207 else if (std::abs(dt) > 0.0) // Time difference between messages (differs from dt if message lost)
208 {
209 // Negative values of dTimeLastState should not happen, but algorithm can work with it to propagate backwards
210 p_acceleration = p_deltaVelocity / dt;
211 p_angularRate = p_deltaTheta / dt;
212 }
213
214 addMeasurement(epoch, dt, p_acceleration, p_angularRate, nameId);
215 _states.back().m.averagedMeasurement = true;
216}
217
218std::shared_ptr<PosVelAtt> InertialIntegrator::lastStateAsPosVelAtt() const
219{
220 INS_ASSERT_USER_ERROR(!_states.empty(), "You need to add an initial state first");
221
222 auto posVelAtt = std::make_shared<PosVelAtt>();
223 posVelAtt->insTime = _states.back().epoch;
224 switch (_integrationFrame)
225 {
227 posVelAtt->setPosVelAtt_n(_states.back().position, _states.back().velocity, _states.back().attitude);
228 break;
230 posVelAtt->setPosVelAtt_e(_states.back().position, _states.back().velocity, _states.back().attitude);
231 break;
232 }
233
234 return posVelAtt;
235}
236
237std::shared_ptr<PosVelAtt> InertialIntegrator::calcInertialSolution(const InsTime& obsTime,
238 const Eigen::Vector3d& p_acceleration, const Eigen::Vector3d& p_angularRate,
239 const ImuPos& imuPos, const char* nameId)
240{
241 if (!hasInitialPosition() || obsTime < _states.back().epoch) { return nullptr; }
242 if (_states.back().epoch.empty()) { _states.back().epoch = obsTime; }
243
244 auto dt = static_cast<double>((obsTime - _states.back().epoch).count());
245 addMeasurement(obsTime, dt, p_acceleration, p_angularRate, nameId);
246 if (std::abs(dt) < 1e-8)
247 {
248 LOG_DATA("{}: Returning state [{}], as no time difference between measurement.", nameId, _states.back().epoch.toYMDHMS(GPST));
249 return lastStateAsPosVelAtt();
250 }
251
252 return calcInertialSolutionFromMeasurementBuffer(imuPos, nameId);
253}
254
255std::shared_ptr<PosVelAtt> InertialIntegrator::calcInertialSolutionDelta(const InsTime& obsTime, double deltaTime,
256 const Eigen::Vector3d& p_deltaVelocity, const Eigen::Vector3d& p_deltaTheta,
257 const ImuPos& imuPos, const char* nameId)
258{
259 if (!hasInitialPosition() || obsTime < _states.back().epoch) { return nullptr; }
260 if (_states.back().epoch.empty()) { _states.back().epoch = obsTime; }
261
262 auto dt = static_cast<double>((obsTime - _states.back().epoch).count());
263 addDeltaMeasurement(obsTime, dt, deltaTime, p_deltaVelocity, p_deltaTheta, nameId);
264 if (std::abs(dt) < 1e-8)
265 {
266 LOG_DATA("{}: Returning state [{}], as no time difference between measurement.", nameId, _states.back().epoch.toYMDHMS(GPST));
267 return lastStateAsPosVelAtt();
268 }
269
270 return calcInertialSolutionFromMeasurementBuffer(imuPos, nameId);
271}
272
273std::shared_ptr<PosVelAtt> InertialIntegrator::calcInertialSolutionFromMeasurementBuffer(const ImuPos& imuPos, const char* nameId)
274{
275 INS_ASSERT_USER_ERROR(!_states.empty(), "You need to add an initial state first");
276 INS_ASSERT_USER_ERROR(_states.size() >= 2, "You need to add an initial state and at least one measurement first");
277
278 LOG_DATA("{}: Calculating inertial solution from buffer. States t0 = [{}], t1 = [{}]",
279 nameId, _states.back().epoch.toYMDHMS(GPST), _states.at(_states.size() - 2).epoch.toYMDHMS(GPST));
280
281 auto y = calcInertialSolution(imuPos, _states.back(), _states.at(_states.size() - 2), nameId);
282
283 auto posVelAtt = std::make_shared<PosVelAtt>();
284 posVelAtt->insTime = _states.back().epoch;
285 switch (_integrationFrame)
286 {
288 posVelAtt->setPosVelAtt_n(y.segment<3>(0), y.segment<3>(3), Eigen::Quaterniond(y.segment<4>(6)));
289 break;
291 posVelAtt->setPosVelAtt_e(y.segment<3>(0), y.segment<3>(3), Eigen::Quaterniond(y.segment<4>(6)));
292 break;
293 }
294
295 switch (_integrationFrame)
296 {
298 _states.back().position = posVelAtt->lla_position();
299 _states.back().velocity = posVelAtt->n_velocity();
300 _states.back().attitude = posVelAtt->n_Quat_b();
301 break;
303 _states.back().position = posVelAtt->e_position();
304 _states.back().velocity = posVelAtt->e_velocity();
305 _states.back().attitude = posVelAtt->e_Quat_b();
306 break;
307 }
308
309 return posVelAtt;
310}
311
332
333bool InertialIntegratorGui(const char* label, InertialIntegrator& integrator, bool& preferAccelerationOverDeltaMeasurements, float width)
334{
335 bool changed = false;
336
337 if (integrator._lockIntegrationFrame) { ImGui::BeginDisabled(); }
338 ImGui::SetNextItemWidth(width * gui::NodeEditorApplication::windowFontRatio());
339 if (auto integrationFrame = static_cast<int>(integrator._integrationFrame);
340 ImGui::Combo(fmt::format("Integration Frame##{}", label).c_str(), &integrationFrame, "ECEF\0NED\0\0"))
341 {
342 integrator._integrationFrame = static_cast<decltype(integrator._integrationFrame)>(integrationFrame);
343 LOG_DEBUG("Integration Frame changed to {}", integrator._integrationFrame == InertialIntegrator::IntegrationFrame::NED ? "NED" : "ECEF");
344 changed = true;
345 }
346 if (integrator._lockIntegrationFrame) { ImGui::EndDisabled(); }
347
348 ImGui::SetNextItemWidth(width * gui::NodeEditorApplication::windowFontRatio());
349 if (ImGui::BeginCombo(fmt::format("Integration Algorithm##{}", label).c_str(), to_string(integrator._integrationAlgorithm)))
350 {
351 for (size_t i = 0; i < static_cast<size_t>(InertialIntegrator::IntegrationAlgorithm::MultiStepRK3); i++) // TODO: InertialIntegrator::IntegrationAlgorithm::COUNT
352 {
353 const bool is_selected = (static_cast<size_t>(integrator._integrationAlgorithm) == i);
354 if (ImGui::Selectable(to_string(static_cast<InertialIntegrator::IntegrationAlgorithm>(i)), is_selected))
355 {
357 integrator.setBufferSizes();
358 LOG_DEBUG("Integration Algorithm Attitude changed to {}", fmt::underlying(integrator._integrationAlgorithm));
359 changed = true;
360 }
361
362 // Set the initial focus when opening the combo (scrolling + keyboard navigation focus)
363 if (is_selected)
364 {
365 ImGui::SetItemDefaultFocus();
366 }
367 }
368
369 ImGui::EndCombo();
370 }
371
372 changed |= ImGui::Checkbox(fmt::format("Prefer raw measurements over delta##{}", label).c_str(), &preferAccelerationOverDeltaMeasurements);
373
374 if (preferAccelerationOverDeltaMeasurements)
375 {
376 changed |= ImGui::Checkbox(fmt::format("Accumulated Acceleration##{}", label).c_str(), &integrator._accelerationsAreAveragedMeasurements);
377 ImGui::SameLine();
378 gui::widgets::HelpMarker("Some IMUs operate at higher rates than their output rate. (e.g. internal rate 800Hz and output rate is 100Hz)\n"
379 "- Such IMUs often output averaged accelerations between the current and last output.\n"
380 "- If the connected IMU (e.g. a VectorNavSensor node) is such as sensor, please check this.\n"
381 "- If delta measurements are used, this is automatically true");
382 }
383
384 ImGui::SetNextItemOpen(false, ImGuiCond_FirstUseEver);
385 if (ImGui::TreeNode(fmt::format("Compensation models##{}", label).c_str()))
386 {
387 ImGui::TextUnformatted("Acceleration compensation");
388 {
389 ImGui::Indent();
390 ImGui::SetNextItemWidth(230 * gui::NodeEditorApplication::windowFontRatio());
391 if (ComboGravitationModel(fmt::format("Gravitation Model##{}", label).c_str(), integrator._posVelAttDerivativeConstants.gravitationModel))
392 {
393 LOG_DEBUG("Gravity Model changed to {}", NAV::to_string(integrator._posVelAttDerivativeConstants.gravitationModel));
394 changed = true;
395 }
396 if (ImGui::Checkbox(fmt::format("Coriolis acceleration ##{}", label).c_str(), &integrator._posVelAttDerivativeConstants.coriolisAccelerationCompensationEnabled))
397 {
398 LOG_DEBUG("coriolisAccelerationCompensationEnabled changed to {}", integrator._posVelAttDerivativeConstants.coriolisAccelerationCompensationEnabled);
399 changed = true;
400 }
401 if (ImGui::Checkbox(fmt::format("Centrifugal acceleration##{}", label).c_str(), &integrator._posVelAttDerivativeConstants.centrifgalAccelerationCompensationEnabled))
402 {
403 LOG_DEBUG("centrifgalAccelerationCompensationEnabled changed to {}", integrator._posVelAttDerivativeConstants.centrifgalAccelerationCompensationEnabled);
404 changed = true;
405 }
406 ImGui::Unindent();
407 }
408 ImGui::TextUnformatted("Angular rate compensation");
409 {
410 ImGui::Indent();
411 if (ImGui::Checkbox(fmt::format("Earth rotation rate##{}", label).c_str(), &integrator._posVelAttDerivativeConstants.angularRateEarthRotationCompensationEnabled))
412 {
413 LOG_DEBUG("angularRateEarthRotationCompensationEnabled changed to {}", integrator._posVelAttDerivativeConstants.angularRateEarthRotationCompensationEnabled);
414 changed = true;
415 }
417 {
418 if (ImGui::Checkbox(fmt::format("Transport rate##{}", label).c_str(), &integrator._posVelAttDerivativeConstants.angularRateTransportRateCompensationEnabled))
419 {
420 LOG_DEBUG("angularRateTransportRateCompensationEnabled changed to {}", integrator._posVelAttDerivativeConstants.angularRateTransportRateCompensationEnabled);
421 changed = true;
422 }
423 }
424 ImGui::Unindent();
425 }
426
427 ImGui::TreePop();
428 }
429
430 return changed;
431}
432
433void to_json(json& j, const InertialIntegrator& data)
434{
435 j = json{
436 { "integrationFrame", data._integrationFrame },
437 { "lockIntegrationFrame", data._lockIntegrationFrame },
438 { "integrationAlgorithm", data._integrationAlgorithm },
439 { "accelerationsAreAveragedMeasurements", data._accelerationsAreAveragedMeasurements },
440 { "posVelAttDerivativeConstants", data._posVelAttDerivativeConstants },
441 };
442}
443
444void from_json(const json& j, InertialIntegrator& data)
445{
446 if (j.contains("integrationFrame")) { j.at("integrationFrame").get_to(data._integrationFrame); }
447 if (j.contains("lockIntegrationFrame")) { j.at("lockIntegrationFrame").get_to(data._lockIntegrationFrame); }
448 if (j.contains("integrationAlgorithm"))
449 {
450 j.at("integrationAlgorithm").get_to(data._integrationAlgorithm);
451 data.setBufferSizes();
452 }
453 if (j.contains("accelerationsAreAveragedMeasurements")) { j.at("accelerationsAreAveragedMeasurements").get_to(data._accelerationsAreAveragedMeasurements); }
454 if (j.contains("posVelAttDerivativeConstants")) { j.at("posVelAttDerivativeConstants").get_to(data._posVelAttDerivativeConstants); }
455}
456
458{
459 switch (algorithm)
460 {
462 return "Runge-Kutta 1st order (explicit) / (Forward) Euler method";
464 return "Runge-Kutta 2nd order (explicit)";
466 return "Heun's method (2nd order) (explicit)";
468 return "Runge-Kutta 3rd order (explicit) / Simpson's rule";
470 return "Heun's method (3nd order) (explicit)";
472 return "Runge-Kutta 4th order (explicit)";
474 return "Runge-Kutta 3rd order (explicit) / Simpson's rule (multistep)";
476 return "Runge-Kutta 4th order (explicit) (multistep)";
478 return "";
479 }
480 return "";
481}
482
484{
485 switch (frame)
486 {
488 return "ECEF";
490 return "NED";
491 }
492 return "";
493}
494
495} // namespace NAV
#define INS_ASSERT_USER_ERROR(_EXP, _MSG)
Assert function with message.
Definition Assert.h:21
Functions concerning the ellipsoid model.
nlohmann::json json
json namespace
Text Help Marker (?) with Tooltip.
Inertial Navigation Helper Functions.
Inertial Measurement Integrator.
#define LOG_DEBUG
Debug information. Should not be called on functions which receive observations (spamming)
Definition Logger.hpp:67
#define LOG_DATA
All output which occurs repeatedly every time observations are received.
Definition Logger.hpp:29
Simple Math functions.
IMU Position.
Definition ImuPos.hpp:26
IntegrationAlgorithm _integrationAlgorithm
Integration algorithm used for the update.
void applyStateErrors_e(const Eigen::Vector3d &e_positionError, const Eigen::Vector3d &e_velocityError, const Eigen::Vector3d &e_attitudeError_b)
Apply the errors to the latest state.
std::optional< Eigen::Vector3d > p_calcCurrentAcceleration() const
Calculate the current acceleration, if measurements area available.
bool hasInitialPosition() const
Checks if an initial position is set.
Eigen::Vector3d _p_lastBiasAcceleration
Initial values for the acceleration bias [m/s^2].
std::shared_ptr< PosVelAtt > calcInertialSolution(const InsTime &obsTime, const Eigen::Vector3d &p_acceleration, const Eigen::Vector3d &p_angularRate, const ImuPos &imuPos, const char *nameId)
Calculates the inertial navigation solution.
std::optional< Eigen::Vector3d > p_calcCurrentAngularRate() const
Calculate the current angular rate, if measurements area available.
void addState(const PosVelAtt &state, const char *nameId)
Pushes the state to the list of states.
void applyStateErrors_n(const Eigen::Vector3d &lla_positionError, const Eigen::Vector3d &n_velocityError, const Eigen::Vector3d &n_attitudeError_b)
Apply the errors to the latest state.
IntegrationAlgorithm
Available Integration Algorithms.
@ SingleStepRungeKutta4
Runge-Kutta 4th order (explicit)
@ MultiStepRK4
Multistep Runge-Kutta 4th order (explicit) (taking 2 old epochs into account)
@ SingleStepHeun2
Heun's method (2nd order) (explicit)
@ COUNT
Amount of available integration algorithms.
@ MultiStepRK3
Multistep Runge-Kutta 3rd order (explicit) / Simpson's rule (taking 2 old epochs into account)
@ SingleStepRungeKutta3
Runge-Kutta 3rd order (explicit) / Simpson's rule.
@ SingleStepRungeKutta2
Runge-Kutta 2nd order (explicit) / Explicit midpoint method.
@ SingleStepHeun3
Heun's method (3nd order) (explicit)
@ SingleStepRungeKutta1
Runge-Kutta 1st order (explicit) / (Forward) Euler method.
bool _accelerationsAreAveragedMeasurements
If true, then the measurements are accumulated values over the last epoch. (always true when using de...
void setTotalSensorBiases(const Eigen::Vector3d &p_biasAcceleration, const Eigen::Vector3d &p_biasAngularRate)
Sets the sensor biases total values.
const Eigen::Vector3d & p_getLastAccelerationBias() const
Return the last acceleration bias in platform frame coordinates in [m/s^2].
void setBufferSizes()
Resizes the measurement and state buffers depending on the integration algorithm.
std::shared_ptr< PosVelAtt > calcInertialSolutionFromMeasurementBuffer(const ImuPos &imuPos, const char *nameId)
Calculates the inertial navigation solution.
void addMeasurement(const InsTime &epoch, double dt, const Eigen::Vector3d &p_acceleration, const Eigen::Vector3d &p_angularRate, const char *nameId)
Adds the measurement to the tracking buffer.
InertialIntegrator()=default
Default Constructor.
std::shared_ptr< PosVelAtt > calcInertialSolutionDelta(const InsTime &obsTime, double deltaTime, const Eigen::Vector3d &p_deltaVelocity, const Eigen::Vector3d &p_deltaTheta, const ImuPos &imuPos, const char *nameId)
Calculates the inertial navigation solution.
bool areAccelerationsAveragedMeasurements() const
Wether the measurements are accumulated values over the last epoch. (always true when using delta mea...
std::optional< std::reference_wrapper< const State > > getLatestState() const
Get the latest state if it exists.
void addDeltaMeasurement(const InsTime &epoch, double dt, double deltaTime, const Eigen::Vector3d &p_deltaVelocity, const Eigen::Vector3d &p_deltaTheta, const char *nameId)
Adds the measurement to the tracking buffer.
IntegrationFrame
Available Integration Frames.
@ ECEF
Earth-Centered Earth-Fixed frame.
void setInitialState(const PosVelAtt &state, const char *nameId)
Sets the initial state.
void reset()
Clears all internal data.
IntegrationFrame _integrationFrame
Frame to integrate the observations in.
PosVelAttDerivativeConstants _posVelAttDerivativeConstants
Settings for the models to use.
IntegrationFrame getIntegrationFrame() const
Returns the selected integration frame.
Eigen::Vector3d _p_lastBiasAngularRate
Initial values for the angular rate bias [rad/s].
ScrollingBuffer< State > _states
List of states. Length depends on algorithm used.
bool _lockIntegrationFrame
Wether to lock the integration frame.
std::shared_ptr< PosVelAtt > lastStateAsPosVelAtt() const
Returns the last state as PosVelAtt.
const Eigen::Vector3d & p_getLastAngularRateBias() const
Return the last angular rate bias in platform frame coordinates in [rad/s].
void applySensorBiasesIncrements(const Eigen::Vector3d &p_deltaBiasAcceleration, const Eigen::Vector3d &p_deltaBiasAngularRate)
Sets the sensor biases increment.
GenericState< double > State
Inertial state and measurements.
const PosVelAttDerivativeConstants & getConstants() const
Returns the selected compensation models.
The class is responsible for all time-related tasks.
Definition InsTime.hpp:710
constexpr InsTime_YMDHMS toYMDHMS(TimeSystem timesys=UTC, int digits=-1) const
Converts this time object into a different format.
Definition InsTime.hpp:871
InsTime insTime
Time at which the message was received.
Definition NodeData.hpp:123
Position, Velocity and Attitude Storage Class.
Definition PosVelAtt.hpp:25
const Eigen::Quaterniond & n_Quat_b() const
Returns the Quaternion from body to navigation frame (NED)
const Eigen::Quaterniond & e_Quat_b() const
Returns the Quaternion from body to Earth-fixed frame.
const Eigen::Vector3d & n_velocity() const
Returns the velocity in [m/s], in navigation coordinates.
Definition PosVel.hpp:211
const Eigen::Vector3d & e_velocity() const
Returns the velocity in [m/s], in earth coordinates.
Definition PosVel.hpp:208
const Eigen::Vector3d & e_position() const
Returns the coordinates in [m].
Definition Pos.hpp:249
const Eigen::Vector3d & lla_position() const
Returns the latitude 𝜙, longitude λ and altitude (height above ground) in [rad, rad,...
Definition Pos.hpp:237
static float windowFontRatio()
Ratio to multiply for GUI window elements.
void HelpMarker(const char *desc, const char *symbol="(?)")
Text Help Marker, e.g. '(?)', with Tooltip.
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...
Definition Math.hpp:90
@ GPST
GPS Time.
void to_json(json &j, const Node &node)
Converts the provided node into a json object.
Definition Node.cpp:990
const char * to_string(gui::widgets::PositionWithFrame::ReferenceFrame refFrame)
Converts the enum to a string.
bool InertialIntegratorGui(const char *label, InertialIntegrator &integrator, bool &preferAccelerationOverDeltaMeasurements, float width)
Shows a GUI for advanced configuration of the InertialIntegrator.
bool ComboGravitationModel(const char *label, GravitationModel &gravitationModel)
Shows a ComboBox to select the gravitation model.
Definition Gravity.cpp:38
void from_json(const json &j, Node &node)
Converts the provided json object into a node object.
Definition Node.cpp:1007
Values needed to calculate the PosVelAttDerivative for the local-navigation frame.
bool centrifgalAccelerationCompensationEnabled
Apply the centrifugal acceleration compensation to the measured accelerations.
bool angularRateEarthRotationCompensationEnabled
Apply the Earth rotation rate compensation to the measured angular rates.
bool angularRateTransportRateCompensationEnabled
Apply the transport rate compensation to the measured angular rates.
GravitationModel gravitationModel
Gravity Model to use.
bool coriolisAccelerationCompensationEnabled
Apply the Coriolis acceleration compensation to the measured accelerations.