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// std
15#include <algorithm>
16
17namespace sen::util
18{
19
22
26template <typename T>
28{
29public:
30 SEN_NOCOPY_NOMOVE(DeadReckoner)
31
32public: // RPR types from DeadReckonerTemplateBase
45
46public: // type aliases
49
50public:
53 explicit DeadReckoner(const T& object, DrConfig config = {});
54 ~DeadReckoner() override = default;
55
56public: // overrides DeadReckonerBase
57 [[nodiscard]] Situation situation(sen::TimeStamp timeStamp) override;
58 [[nodiscard]] GeodeticSituation geodeticSituation(sen::TimeStamp timeStamp) override;
59
60public:
62 [[nodiscard]] T& getObject() noexcept;
63
64public: // situation translation helpers
66 [[nodiscard]] static Situation toSituation(const SpatialVariant& spatial, sen::TimeStamp timeStamp = {});
67
69 [[nodiscard]] static GeodeticSituation toGeodeticSituation(const SpatialVariant& spatial,
70 sen::TimeStamp timeStamp = {});
71
72private:
75 [[nodiscard]] SituationProcessor getSituationProcessor(bool bodyReferenced);
76
79 [[nodiscard]] GeodeticSituationProcessor getGeodeticSituationProcessor(bool bodyReferenced);
80
82 void updateSpatial(sen::TimeStamp time);
83
84private:
85 const T& object_;
86 SituationProcessor processSituation_;
87 GeodeticSituationProcessor processGeodeticSituation_;
88 sen::TimeStamp lastTimeStamp_;
89 SpatialVariant lastSpatial_;
90};
91
93
94//-------------------------------------------------------------------------------------------------------------------
95// Utils
96//-------------------------------------------------------------------------------------------------------------------
97
99[[nodiscard]] inline GeodeticSituation toGeodeticSituation(const Situation& value)
100{
101 const auto geoLocation = impl::toLla(value.worldLocation);
102 return GeodeticSituation {value.isFrozen,
103 value.timeStamp,
104 geoLocation,
105 impl::ecefToNed(value.orientation, geoLocation),
106 impl::ecefToNed(value.velocityVector, geoLocation),
107 value.angularVelocity,
108 impl::ecefToNed(value.accelerationVector, geoLocation),
109 value.angularAcceleration};
110}
111
113[[nodiscard]] inline Situation toSituation(const GeodeticSituation& value)
114{
115 // translate input geodetic situation to standard reference system
116 const auto ecefPosition = impl::toEcef(value.worldLocation);
117 const auto ecefOrientation = impl::nedToEcef(value.orientation, value.worldLocation);
118
119 return Situation {value.isFrozen,
120 value.timeStamp,
121 ecefPosition,
122 ecefOrientation,
124 value.angularVelocity,
126}
127
128//-------------------------------------------------------------------------------------------------------------------
129// Inline implementation
130//-------------------------------------------------------------------------------------------------------------------
131
132template <typename T>
133inline DeadReckoner<T>::DeadReckoner(const T& object, DrConfig config)
134 : DeadReckonerTemplateBase<T>(config), object_ {object}
135{
136 // true if the DR algorithm used is body-centered
137 auto isBody = std::find(bodyAlgorithms.begin(),
138 bodyAlgorithms.end(),
139 static_cast<SpatialAlgorithm>(object_.getSpatial().index())) != bodyAlgorithms.end();
140
141 // initialize situation and geodetic situation processors
142 processSituation_ = getSituationProcessor(isBody);
143 processGeodeticSituation_ = getGeodeticSituationProcessor(isBody);
144}
145
146template <typename T>
148{
149 if (!this->isSituationCached(timeStamp))
150 {
151 this->setCachedSituation(processSituation_(timeStamp));
152 }
153 return this->getCachedSituation();
154}
155
156template <typename T>
158{
159 if (!this->isGeodeticSituationCached(timeStamp))
160 {
161 this->setCachedGeodeticSituation(processGeodeticSituation_(timeStamp));
162 }
163 return this->getCachedGeodeticSituation();
164}
165
166template <typename T>
167inline T& DeadReckoner<T>::getObject() noexcept
168{
169 return const_cast<T&>(object_); // NOLINT
170}
171
172template <typename T>
174{
175 return std::visit(sen::Overloaded {[&timeStamp](const StaticSpatial& value)
176 {
177 return Situation {value.isFrozen,
178 timeStamp,
179 impl::fromRprLocation(value.worldLocation),
180 impl::fromRprOrientation(value.orientation)};
181 },
182 [&timeStamp](const FpsSpatial& value)
183 {
184 return Situation {value.isFrozen,
185 timeStamp,
186 impl::fromRprLocation(value.worldLocation),
187 impl::fromRprOrientation(value.orientation),
188 impl::fromRprVelocity(value.velocityVector)};
189 },
190 [&timeStamp](const RpsSpatial& value)
191 {
192 return Situation {value.isFrozen,
193 timeStamp,
194 impl::fromRprLocation(value.worldLocation),
195 impl::fromRprOrientation(value.orientation),
196 impl::fromRprVelocity(value.velocityVector),
197 impl::fromRprAngularVelocity(value.angularVelocity)};
198 },
199 [&timeStamp](const RvsSpatial& value)
200 {
201 return Situation {value.isFrozen,
202 timeStamp,
203 impl::fromRprLocation(value.worldLocation),
204 impl::fromRprOrientation(value.orientation),
205 impl::fromRprVelocity(value.velocityVector),
206 impl::fromRprAngularVelocity(value.angularVelocity),
207 impl::fromRprAcceleration(value.accelerationVector)};
208 },
209 [&timeStamp](const FvsSpatial& value)
210 {
211 return Situation {value.isFrozen,
212 timeStamp,
213 impl::fromRprLocation(value.worldLocation),
214 impl::fromRprOrientation(value.orientation),
215 impl::fromRprVelocity(value.velocityVector),
216 {},
217 impl::fromRprAcceleration(value.accelerationVector)};
218 }},
219 spatial);
220}
221
222template <typename T>
224{
225 const auto situation = toSituation(spatial, timeStamp);
226 const auto geoLocation = impl::toLla(situation.worldLocation);
227 const auto nedOrientation = impl::ecefToNed(situation.orientation, geoLocation);
228
229 // body centered algorithms
230 if (std::find(bodyAlgorithms.begin(), bodyAlgorithms.end(), static_cast<SpatialAlgorithm>(spatial.index())) !=
231 bodyAlgorithms.end())
232 {
233 return {situation.isFrozen,
234 situation.timeStamp,
235 geoLocation,
236 nedOrientation,
237 impl::bodyToNed(situation.velocityVector, nedOrientation),
238 situation.angularVelocity,
239 impl::bodyToNed(situation.accelerationVector, nedOrientation),
240 situation.angularAcceleration};
241 }
242
243 // world-centered algorithms
244 return {situation.isFrozen,
245 situation.timeStamp,
246 geoLocation,
247 nedOrientation,
248 impl::ecefToNed(situation.velocityVector, geoLocation),
249 situation.angularVelocity,
250 impl::ecefToNed(situation.accelerationVector, geoLocation),
251 situation.angularAcceleration};
252}
253
254template <typename T>
255typename DeadReckoner<T>::SituationProcessor DeadReckoner<T>::getSituationProcessor(bool bodyReferenced)
256{
257 if (bodyReferenced)
258 {
259 return [this](sen::TimeStamp time)
260 {
261 updateSpatial(time);
262 return Parent::extrapolate(lastSpatial_, time, lastTimeStamp_);
263 };
264 }
265
266 return [this](sen::TimeStamp time)
267 {
268 updateSpatial(time);
269 const auto update = Parent::extrapolate(lastSpatial_, time, lastTimeStamp_);
272 };
273}
274
275template <typename T>
276typename DeadReckoner<T>::GeodeticSituationProcessor DeadReckoner<T>::getGeodeticSituationProcessor(bool bodyReferenced)
277{
278 if (bodyReferenced)
279 {
280 return [this](sen::TimeStamp time)
281 {
282 const auto situation = processSituation_(time);
283 const auto geoLocation = impl::toLla(situation.worldLocation);
284 const auto nedOrientation = impl::ecefToNed(situation.orientation, geoLocation);
285 return GeodeticSituation {situation.isFrozen,
286 situation.timeStamp,
287 geoLocation,
288 nedOrientation,
289 impl::bodyToNed(situation.velocityVector, nedOrientation),
290 situation.angularVelocity,
291 impl::bodyToNed(situation.accelerationVector, nedOrientation),
292 situation.angularAcceleration};
293 };
294 }
295
296 return [this](sen::TimeStamp time)
297 {
298 const auto situation = processSituation_(time);
299 const auto geoLocation = impl::toLla(situation.worldLocation);
300 return GeodeticSituation {situation.isFrozen,
301 situation.timeStamp,
302 geoLocation,
303 impl::ecefToNed(situation.orientation, geoLocation),
304 impl::ecefToNed(situation.velocityVector, geoLocation),
305 situation.angularVelocity,
306 impl::ecefToNed(situation.accelerationVector, geoLocation),
307 situation.angularAcceleration};
308 };
309}
310
311template <typename T>
312void DeadReckoner<T>::updateSpatial(sen::TimeStamp time)
313{
314 if (const auto& newSpatial = object_.getSpatial(); newSpatial != lastSpatial_)
315 {
316 lastSpatial_ = newSpatial;
317 lastTimeStamp_ = time;
318 this->invalidateCache();
319 }
320}
321
322} // namespace sen::util
323
324#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:33
typename Parent::RprOrientation RprOrientation
Definition dead_reckoner.h:41
typename Parent::StaticSpatial StaticSpatial
Definition dead_reckoner.h:35
T & getObject() noexcept
Provides direct mutable access to the internal object managed by this instance of the DeadReckoner.
Definition dead_reckoner.h:167
Situation situation(sen::TimeStamp timeStamp) override
Returns the extrapolated/smoothed situation of the object at the timestamp introduced as argument,...
Definition dead_reckoner.h:147
std::function< Situation(sen::TimeStamp)> SituationProcessor
Definition dead_reckoner.h:47
typename Parent::RprAngularVelocity RprAngularVelocity
Definition dead_reckoner.h:44
typename Parent::FpsSpatial FpsSpatial
Definition dead_reckoner.h:36
static Situation toSituation(const SpatialVariant &spatial, sen::TimeStamp timeStamp={})
Translates a SpatialVariant to a Situation struct.
Definition dead_reckoner.h:173
~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:133
typename Parent::SpatialVariant SpatialVariant
Definition dead_reckoner.h:34
typename Parent::RpsSpatial RpsSpatial
Definition dead_reckoner.h:37
static GeodeticSituation toGeodeticSituation(const SpatialVariant &spatial, sen::TimeStamp timeStamp={})
Translates a SpatialVariant to a GeodeticSituation struct.
Definition dead_reckoner.h:223
typename Parent::RprVelocity RprVelocity
Definition dead_reckoner.h:42
typename Parent::RprAcceleration RprAcceleration
Definition dead_reckoner.h:43
typename Parent::FvsSpatial FvsSpatial
Definition dead_reckoner.h:39
GeodeticSituation geodeticSituation(sen::TimeStamp timeStamp) override
Returns the extrapolated/smoothed situation of the object at the timestamp introduced as argument,...
Definition dead_reckoner.h:157
std::function< GeodeticSituation(sen::TimeStamp)> GeodeticSituationProcessor
Definition dead_reckoner.h:48
typename Parent::RvsSpatial RvsSpatial
Definition dead_reckoner.h:38
typename Parent::RprLocation RprLocation
Definition dead_reckoner.h:40
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:113
GeodeticSituation toGeodeticSituation(const Situation &value)
Transform a Situation to a GeodeticSituation.
Definition dead_reckoner.h:99
Definition assert.h:17
Helper type for std::variant lambda visitors.
Definition class_helpers.h:170