Sen API
Sen Libraries
Loading...
Searching...
No Matches
dead_reckoner.h
Go to the documentation of this file.
1// === dead_reckoner.h =================================================================================================
2// Sen Infrastructure
3// Released under the Apache License v2.0 (SPDX-License-Identifier Apache-2.0).
4// See the LICENSE.txt file for more information.
5// © Airbus SAS, Airbus Helicopters, and Airbus Defence and Space SAU/GmbH/SAS.
6// =====================================================================================================================
7
8#ifndef SEN_UTIL_DR_DEAD_RECKONER_H
9#define SEN_UTIL_DR_DEAD_RECKONER_H
10
13
14// sen
16
17// std
18#include <algorithm>
19
20namespace sen::util
21{
22
25
29template <typename T>
31{
32public:
33 SEN_NOCOPY_NOMOVE(DeadReckoner)
34
35public: // RPR types from DeadReckonerTemplateBase
48
49public: // type aliases
52
53public:
56 explicit DeadReckoner(const T& object, DrConfig config = {});
57 ~DeadReckoner() override = default;
58
59public: // overrides DeadReckonerBase
60 [[nodiscard]] Situation situation(sen::TimeStamp timeStamp) override;
61 [[nodiscard]] GeodeticSituation geodeticSituation(sen::TimeStamp timeStamp) override;
62
63public:
65 [[nodiscard]] T& getObject() noexcept;
66
67public: // situation translation helpers
69 [[nodiscard]] static Situation toSituation(const SpatialVariant& spatial, sen::TimeStamp timeStamp = {});
70
72 [[nodiscard]] static GeodeticSituation toGeodeticSituation(const SpatialVariant& spatial,
73 sen::TimeStamp timeStamp = {});
74
75private:
78 [[nodiscard]] SituationProcessor getSituationProcessor(bool bodyReferenced);
79
82 [[nodiscard]] GeodeticSituationProcessor getGeodeticSituationProcessor(bool bodyReferenced);
83
85 void updateSpatial(sen::TimeStamp time);
86
87private:
88 const T& object_;
89 SituationProcessor processSituation_;
90 GeodeticSituationProcessor processGeodeticSituation_;
91 sen::TimeStamp lastTimeStamp_;
92 SpatialVariant lastSpatial_;
93};
94
96
97//-------------------------------------------------------------------------------------------------------------------
98// Utils
99//-------------------------------------------------------------------------------------------------------------------
100
102[[nodiscard]] inline GeodeticSituation toGeodeticSituation(const Situation& value)
103{
104 const auto geoLocation = impl::toLla(value.worldLocation);
105 return GeodeticSituation {value.isFrozen,
106 value.timeStamp,
107 geoLocation,
108 impl::ecefToNed(value.orientation, geoLocation),
109 impl::ecefToNed(value.velocityVector, geoLocation),
110 value.angularVelocity,
111 impl::ecefToNed(value.accelerationVector, geoLocation),
112 value.angularAcceleration};
113}
114
116[[nodiscard]] inline Situation toSituation(const GeodeticSituation& value)
117{
118 // translate input geodetic situation to standard reference system
119 const auto ecefPosition = impl::toEcef(value.worldLocation);
120 const auto ecefOrientation = impl::nedToEcef(value.orientation, value.worldLocation);
121
122 return Situation {value.isFrozen,
123 value.timeStamp,
124 ecefPosition,
125 ecefOrientation,
127 value.angularVelocity,
129}
130
131//-------------------------------------------------------------------------------------------------------------------
132// Inline implementation
133//-------------------------------------------------------------------------------------------------------------------
134
135template <typename T>
136inline DeadReckoner<T>::DeadReckoner(const T& object, DrConfig config)
137 : DeadReckonerTemplateBase<T>(config), object_ {object}
138{
139 const auto& objSpatial = object_.getSpatial();
140 // true if the DR algorithm used is body-centered
141 auto isBody =
142 std::find(bodyAlgorithms.begin(), bodyAlgorithms.end(), static_cast<SpatialAlgorithm>(objSpatial.index())) !=
143 bodyAlgorithms.end();
144
145 // initialize situation and geodetic situation processors
146 processSituation_ = getSituationProcessor(isBody);
147 processGeodeticSituation_ = getGeodeticSituationProcessor(isBody);
149}
150
151template <typename T>
153{
154 if (!this->isSituationCached(timeStamp))
155 {
156 this->setCachedSituation(processSituation_(timeStamp));
157 }
158 return this->getCachedSituation();
159}
160
161template <typename T>
163{
164 if (!this->isGeodeticSituationCached(timeStamp))
165 {
166 this->setCachedGeodeticSituation(processGeodeticSituation_(timeStamp));
167 }
168 return this->getCachedGeodeticSituation();
169}
170
171template <typename T>
172inline T& DeadReckoner<T>::getObject() noexcept
173{
174 return const_cast<T&>(object_); // NOLINT
175}
176
177template <typename T>
179{
180 return std::visit(sen::Overloaded {[&timeStamp](const StaticSpatial& value)
181 {
182 return Situation {value.isFrozen,
183 timeStamp,
184 impl::fromRprLocation(value.worldLocation),
185 impl::fromRprOrientation(value.orientation)};
186 },
187 [&timeStamp](const FpsSpatial& value)
188 {
189 return Situation {value.isFrozen,
190 timeStamp,
191 impl::fromRprLocation(value.worldLocation),
192 impl::fromRprOrientation(value.orientation),
193 impl::fromRprVelocity(value.velocityVector)};
194 },
195 [&timeStamp](const RpsSpatial& value)
196 {
197 return Situation {value.isFrozen,
198 timeStamp,
199 impl::fromRprLocation(value.worldLocation),
200 impl::fromRprOrientation(value.orientation),
201 impl::fromRprVelocity(value.velocityVector),
202 impl::fromRprAngularVelocity(value.angularVelocity)};
203 },
204 [&timeStamp](const RvsSpatial& value)
205 {
206 return Situation {value.isFrozen,
207 timeStamp,
208 impl::fromRprLocation(value.worldLocation),
209 impl::fromRprOrientation(value.orientation),
210 impl::fromRprVelocity(value.velocityVector),
211 impl::fromRprAngularVelocity(value.angularVelocity),
212 impl::fromRprAcceleration(value.accelerationVector)};
213 },
214 [&timeStamp](const FvsSpatial& value)
215 {
216 return Situation {value.isFrozen,
217 timeStamp,
218 impl::fromRprLocation(value.worldLocation),
219 impl::fromRprOrientation(value.orientation),
220 impl::fromRprVelocity(value.velocityVector),
221 {},
222 impl::fromRprAcceleration(value.accelerationVector)};
223 }},
224 spatial);
225}
226
227template <typename T>
229{
230 const auto situation = toSituation(spatial, timeStamp);
231 const auto geoLocation = impl::toLla(situation.worldLocation);
232 const auto nedOrientation = impl::ecefToNed(situation.orientation, geoLocation);
233
234 // body centered algorithms
235 if (std::find(bodyAlgorithms.begin(), bodyAlgorithms.end(), static_cast<SpatialAlgorithm>(spatial.index())) !=
236 bodyAlgorithms.end())
237 {
238 return {situation.isFrozen,
239 situation.timeStamp,
240 geoLocation,
241 nedOrientation,
242 impl::bodyToNed(situation.velocityVector, nedOrientation),
243 situation.angularVelocity,
244 impl::bodyToNed(situation.accelerationVector, nedOrientation),
245 situation.angularAcceleration};
246 }
247
248 // world-centered algorithms
249 return {situation.isFrozen,
250 situation.timeStamp,
251 geoLocation,
252 nedOrientation,
253 impl::ecefToNed(situation.velocityVector, geoLocation),
254 situation.angularVelocity,
255 impl::ecefToNed(situation.accelerationVector, geoLocation),
256 situation.angularAcceleration};
257}
258
259template <typename T>
260typename DeadReckoner<T>::SituationProcessor DeadReckoner<T>::getSituationProcessor(bool bodyReferenced)
261{
262 if (bodyReferenced)
263 {
264 return [this](sen::TimeStamp time)
265 {
266 updateSpatial(time);
267 return Parent::extrapolate(lastSpatial_, time, lastTimeStamp_);
268 };
269 }
270
271 return [this](sen::TimeStamp time)
272 {
273 updateSpatial(time);
274 const auto update = Parent::extrapolate(lastSpatial_, time, lastTimeStamp_);
277 };
278}
279
280template <typename T>
281typename DeadReckoner<T>::GeodeticSituationProcessor DeadReckoner<T>::getGeodeticSituationProcessor(bool bodyReferenced)
282{
283 if (bodyReferenced)
284 {
285 return [this](sen::TimeStamp time)
286 {
287 const auto situation = processSituation_(time);
288 const auto geoLocation = impl::toLla(situation.worldLocation);
289 const auto nedOrientation = impl::ecefToNed(situation.orientation, geoLocation);
290 return GeodeticSituation {situation.isFrozen,
291 situation.timeStamp,
292 geoLocation,
293 nedOrientation,
294 impl::bodyToNed(situation.velocityVector, nedOrientation),
295 situation.angularVelocity,
296 impl::bodyToNed(situation.accelerationVector, nedOrientation),
297 situation.angularAcceleration};
298 };
299 }
300
301 return [this](sen::TimeStamp time)
302 {
303 const auto situation = processSituation_(time);
304 const auto geoLocation = impl::toLla(situation.worldLocation);
305 return GeodeticSituation {situation.isFrozen,
306 situation.timeStamp,
307 geoLocation,
308 impl::ecefToNed(situation.orientation, geoLocation),
309 impl::ecefToNed(situation.velocityVector, geoLocation),
310 situation.angularVelocity,
311 impl::ecefToNed(situation.accelerationVector, geoLocation),
312 situation.angularAcceleration};
313 };
314}
315
316template <typename T>
317void DeadReckoner<T>::updateSpatial(sen::TimeStamp time)
318{
319 if (const auto& newSpatial = object_.getSpatial(); newSpatial != lastSpatial_)
320 {
321 lastSpatial_ = newSpatial;
322 lastTimeStamp_ = time;
323 this->invalidateCache();
324 }
325}
326
327} // namespace sen::util
328
329#endif // SEN_UTIL_DR_DEAD_RECKONER_H
A point in time.
Definition timestamp.h:26
const DrConfig & getConfig() const noexcept
const Situation & getCachedSituation() const noexcept
Definition dead_reckoner_base.h:270
const GeodeticSituation & getCachedGeodeticSituation() const noexcept
Definition dead_reckoner_base.h:272
void setCachedGeodeticSituation(const GeodeticSituation &situation)
Definition dead_reckoner_base.h:265
void setCachedSituation(const Situation &situation)
Definition dead_reckoner_base.h:258
bool isSituationCached(sen::TimeStamp timeStamp) const noexcept
Definition dead_reckoner_base.h:253
void smooth(const Situation &update)
const Situation & getSmoothSituation() const noexcept
bool isGeodeticSituationCached(sen::TimeStamp timeStamp) const noexcept
Definition dead_reckoner_base.h:260
DeadReckonerTemplateBase< T > Parent
Definition dead_reckoner.h:36
typename Parent::RprOrientation RprOrientation
Definition dead_reckoner.h:44
typename Parent::StaticSpatial StaticSpatial
Definition dead_reckoner.h:38
T & getObject() noexcept
Provides direct mutable access to the internal object managed by this instance of the DeadReckoner.
Definition dead_reckoner.h:172
Situation situation(sen::TimeStamp timeStamp) override
Returns the extrapolated/smoothed situation of the object at the timestamp introduced as argument,...
Definition dead_reckoner.h:152
std::function< Situation(sen::TimeStamp)> SituationProcessor
Definition dead_reckoner.h:50
typename Parent::RprAngularVelocity RprAngularVelocity
Definition dead_reckoner.h:47
typename Parent::FpsSpatial FpsSpatial
Definition dead_reckoner.h:39
static Situation toSituation(const SpatialVariant &spatial, sen::TimeStamp timeStamp={})
Translates a SpatialVariant to a Situation struct.
Definition dead_reckoner.h:178
~DeadReckoner() override=default
DeadReckoner(const T &object, DrConfig config={})
Constructor for the DeadReckoner where an object inheriting from rpr::BaseEntity is inputted as a ref...
Definition dead_reckoner.h:136
typename Parent::SpatialVariant SpatialVariant
Definition dead_reckoner.h:37
typename Parent::RpsSpatial RpsSpatial
Definition dead_reckoner.h:40
static GeodeticSituation toGeodeticSituation(const SpatialVariant &spatial, sen::TimeStamp timeStamp={})
Translates a SpatialVariant to a GeodeticSituation struct.
Definition dead_reckoner.h:228
typename Parent::RprVelocity RprVelocity
Definition dead_reckoner.h:45
typename Parent::RprAcceleration RprAcceleration
Definition dead_reckoner.h:46
typename Parent::FvsSpatial FvsSpatial
Definition dead_reckoner.h:42
GeodeticSituation geodeticSituation(sen::TimeStamp timeStamp) override
Returns the extrapolated/smoothed situation of the object at the timestamp introduced as argument,...
Definition dead_reckoner.h:162
std::function< GeodeticSituation(sen::TimeStamp)> GeodeticSituationProcessor
Definition dead_reckoner.h:51
typename Parent::RvsSpatial RvsSpatial
Definition dead_reckoner.h:41
typename Parent::RprLocation RprLocation
Definition dead_reckoner.h:43
std::variant_alternative_t< 2U, SpatialVariant > RpsSpatial
Definition dead_reckoner_base.h:110
DeadReckonerTemplateBase(DrConfig config={})
Definition dead_reckoner_base.h:134
std::variant_alternative_t< 4U, SpatialVariant > FvsSpatial
Definition dead_reckoner_base.h:112
decltype(std::declval< RvsSpatial >().orientation) RprOrientation
Definition dead_reckoner_base.h:114
decltype(std::declval< RvsSpatial >().worldLocation) RprLocation
Definition dead_reckoner_base.h:113
std::variant_alternative_t< 1U, SpatialVariant > FpsSpatial
Definition dead_reckoner_base.h:109
std::remove_const_t< std::remove_reference_t< decltype(std::declval< T >().getSpatial())> > SpatialVariant
Definition dead_reckoner_base.h:107
decltype(std::declval< RvsSpatial >().accelerationVector) RprAcceleration
Definition dead_reckoner_base.h:116
std::variant_alternative_t< 0U, SpatialVariant > StaticSpatial
Definition dead_reckoner_base.h:108
std::variant_alternative_t< 3U, SpatialVariant > RvsSpatial
Definition dead_reckoner_base.h:111
decltype(std::declval< RvsSpatial >().angularVelocity) RprAngularVelocity
Definition dead_reckoner_base.h:117
decltype(std::declval< RvsSpatial >().velocityVector) RprVelocity
Definition dead_reckoner_base.h:115
bool isFrozen
When true, no extrapolation is performed because the entity is frozen.
Definition algorithms.h:175
Location worldLocation
Position in ECEF.
Definition algorithms.h:151
AngularVelocity angularVelocity
Angular velocity vector with respect to body reference system.
Definition algorithms.h:161
Velocity velocityVector
Velocity vector with respect to ECEF or body reference system (depending on the reference system of t...
Definition algorithms.h:158
Velocity velocityVector
Velocity vector with respect to NED.
Definition algorithms.h:188
AngularVelocity angularVelocity
Angular velocity vector with respect to body-reference system.
Definition algorithms.h:191
Orientation orientation
Orientation of the body reference system (x forward, y right, z down) with respect to NED (North - Ea...
Definition algorithms.h:185
Orientation orientation
Orientation of the body reference system (x forward, y right, z down) with respect to ECEF.
Definition algorithms.h:154
Acceleration accelerationVector
Acceleration vector with respect to ECEF or body reference system (depending on the reference system ...
Definition algorithms.h:165
Acceleration accelerationVector
Acceleration vector with respect to NED.
Definition algorithms.h:194
sen::TimeStamp timeStamp
TimeStamp of the instant when the situation is computed.
Definition algorithms.h:148
GeodeticWorldLocation worldLocation
World Location in Geodetic (Latitude, Longitude, Altitude).
Definition algorithms.h:181
bool smoothing
If true, the position and orientation of the input data is smoothed removing noise.
Definition algorithms.h:60
AngularAcceleration angularAcceleration
Angular acceleration vector with respect to body reference system.
Definition algorithms.h:168
bool isFrozen
When true, no extrapolation is performed because the entity is frozen.
Definition algorithms.h:145
sen::TimeStamp timeStamp
TimeStamp of the instant when the situation is computed.
Definition algorithms.h:178
Location toEcef(const GeodeticWorldLocation &latLonAlt) noexcept
Translates from Geodetic (LatLonAlt) to ECEF WorldLocation coordinates.
Orientation ecefToNed(const Orientation &value, const GeodeticWorldLocation &latLonAlt) noexcept
Translates the Orientation in euler angles from ECEF to NED using quaternions.
Acceleration fromRprAcceleration(const T &value)
Translates to Acceleration struct from a RPR Acceleration.
Definition dead_reckoner_impl.h:160
Velocity fromRprVelocity(const T &value)
Translates to a Velocity struct from a RPR Velocity.
Definition dead_reckoner_impl.h:153
GeodeticWorldLocation toLla(const Location &worldLocation) noexcept
Translates from ECEF Location to Geodetic (LatLonAlt) Location.
Orientation nedToEcef(const Orientation &value, const GeodeticWorldLocation &latLonAlt) noexcept
Translates the Orientation in euler angles from NED to ECEF using quaternions.
AngularVelocity fromRprAngularVelocity(const T &value)
Translates to AngularVelocity struct from a RPR AngularVelocity.
Definition dead_reckoner_impl.h:167
Velocity bodyToNed(const Velocity &value, const Orientation &orientationNed) noexcept
Translates Velocity vectors expressed in body coordinates to NED coordinates.
constexpr std::array< SpatialAlgorithm, 4U > bodyAlgorithms
Definition algorithms.h:214
Orientation fromRprOrientation(const T &value)
Translates to an Orientation struct from a RPR Orientation.
Definition dead_reckoner_impl.h:146
SpatialAlgorithm
Enumeration of the different Spatial algorithms.
Definition algorithms.h:202
Location fromRprLocation(const T &value)
Translates to a Location struct from a RPR WorldLocation.
Definition dead_reckoner_impl.h:140
Length in meters.
Definition algorithms.h:58
GeodeticSituation structure with the following parameters:
Definition algorithms.h:173
Situation structure with the following parameters:
Definition algorithms.h:143
@ time
Definition unit.h:34
Definition iterator_adapters.h:16
Situation toSituation(const GeodeticSituation &value)
Transforms a GeodeticSituation to a Situation.
Definition dead_reckoner.h:116
GeodeticSituation toGeodeticSituation(const Situation &value)
Transform a Situation to a GeodeticSituation.
Definition dead_reckoner.h:102
Definition assert.h:17
Helper type for std::variant lambda visitors.
Definition class_helpers.h:170