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
29// --8<-- [start:dead_reckoner]
30template <typename T>
32{
33public:
34 SEN_NOCOPY_NOMOVE(DeadReckoner)
35
36public: // RPR types from DeadReckonerTemplateBase
49
50public: // type aliases
53
54public:
57 explicit DeadReckoner(const T& object, DrConfig config = {});
58 ~DeadReckoner() override = default;
59
60public: // overrides DeadReckonerBase
61 [[nodiscard]] Situation situation(sen::TimeStamp timeStamp) override;
62 [[nodiscard]] GeodeticSituation geodeticSituation(sen::TimeStamp timeStamp) override;
63
64public:
66 [[nodiscard]] T& getObject() noexcept;
67
68public: // situation translation helpers
70 [[nodiscard]] static Situation toSituation(const SpatialVariant& spatial, sen::TimeStamp timeStamp = {});
71
73 [[nodiscard]] static GeodeticSituation toGeodeticSituation(const SpatialVariant& spatial,
74 sen::TimeStamp timeStamp = {});
75
76private:
79 [[nodiscard]] Situation extrapolateAt(sen::TimeStamp time);
80
83 [[nodiscard]] static bool isBodyReferenced(const SpatialVariant& spatial) noexcept;
84
86 void updateSpatial(sen::TimeStamp time);
87
90 [[nodiscard]] sen::TimeStamp spatialOrigin(sen::TimeStamp time) const noexcept;
91
92private:
93 const T& object_;
94 sen::TimeStamp lastTimeStamp_;
95 SpatialVariant lastSpatial_;
96};
97// --8<-- [end:dead_reckoner]
98
100
101//-------------------------------------------------------------------------------------------------------------------
102// Utils
103//-------------------------------------------------------------------------------------------------------------------
104
106[[nodiscard]] inline GeodeticSituation toGeodeticSituation(const Situation& value)
107{
108 return impl::toGeodeticSituation(value);
109}
110
112[[nodiscard]] inline Situation toSituation(const GeodeticSituation& value) { return impl::toSituation(value); }
113
114//-------------------------------------------------------------------------------------------------------------------
115// Inline implementation
116//-------------------------------------------------------------------------------------------------------------------
117
118template <typename T>
119inline DeadReckoner<T>::DeadReckoner(const T& object, DrConfig config)
120 : DeadReckonerTemplateBase<T>(config), object_ {object}
121{
123}
124
125template <typename T>
127{
128 if (!this->isSituationCached(timeStamp))
129 {
130 this->setCachedSituation(extrapolateAt(timeStamp));
131 }
132 return this->getCachedSituation();
133}
134
135template <typename T>
137{
138 if (!this->isGeodeticSituationCached(timeStamp))
139 {
140 const auto situation = extrapolateAt(timeStamp);
141
142 if (!isBodyReferenced(lastSpatial_))
143 {
145 }
146 else
147 {
148 const auto geoLocation = impl::toLla(situation.worldLocation);
149 const auto nedOrientation = impl::ecefToNed(situation.orientation, geoLocation);
151 situation.timeStamp,
152 geoLocation,
153 nedOrientation,
154 impl::bodyToNed(situation.velocityVector, nedOrientation),
155 situation.angularVelocity,
156 impl::bodyToNed(situation.accelerationVector, nedOrientation),
157 situation.angularAcceleration});
158 }
159 }
160 return this->getCachedGeodeticSituation();
161}
162
163template <typename T>
164inline T& DeadReckoner<T>::getObject() noexcept
165{
166 return const_cast<T&>(object_); // NOLINT
167}
168
169template <typename T>
171{
172 return std::visit(sen::Overloaded {[&timeStamp](const StaticSpatial& value)
173 {
174 return Situation {value.isFrozen,
175 timeStamp,
176 impl::fromRprLocation(value.worldLocation),
177 impl::fromRprOrientation(value.orientation)};
178 },
179 [&timeStamp](const FpsSpatial& value)
180 {
181 return Situation {value.isFrozen,
182 timeStamp,
183 impl::fromRprLocation(value.worldLocation),
184 impl::fromRprOrientation(value.orientation),
185 impl::fromRprVelocity(value.velocityVector)};
186 },
187 [&timeStamp](const RpsSpatial& 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 impl::fromRprAngularVelocity(value.angularVelocity)};
195 },
196 [&timeStamp](const RvsSpatial& value)
197 {
198 return Situation {value.isFrozen,
199 timeStamp,
200 impl::fromRprLocation(value.worldLocation),
201 impl::fromRprOrientation(value.orientation),
202 impl::fromRprVelocity(value.velocityVector),
203 impl::fromRprAngularVelocity(value.angularVelocity),
204 impl::fromRprAcceleration(value.accelerationVector)};
205 },
206 [&timeStamp](const FvsSpatial& value)
207 {
208 return Situation {value.isFrozen,
209 timeStamp,
210 impl::fromRprLocation(value.worldLocation),
211 impl::fromRprOrientation(value.orientation),
212 impl::fromRprVelocity(value.velocityVector),
213 {},
214 impl::fromRprAcceleration(value.accelerationVector)};
215 }},
216 spatial);
217}
218
219template <typename T>
221{
222 const auto situation = toSituation(spatial, timeStamp);
223 const auto geoLocation = impl::toLla(situation.worldLocation);
224 const auto nedOrientation = impl::ecefToNed(situation.orientation, geoLocation);
225
226 // body centered algorithms
227 if (std::find(bodyAlgorithms.begin(), bodyAlgorithms.end(), static_cast<SpatialAlgorithm>(spatial.index())) !=
228 bodyAlgorithms.end())
229 {
230 return {situation.isFrozen,
231 situation.timeStamp,
232 geoLocation,
233 nedOrientation,
234 impl::bodyToNed(situation.velocityVector, nedOrientation),
235 situation.angularVelocity,
236 impl::bodyToNed(situation.accelerationVector, nedOrientation),
237 situation.angularAcceleration};
238 }
239
240 // world-centered algorithms
241 return {situation.isFrozen,
242 situation.timeStamp,
243 geoLocation,
244 nedOrientation,
245 impl::ecefToNed(situation.velocityVector, geoLocation),
246 situation.angularVelocity,
247 impl::ecefToNed(situation.accelerationVector, geoLocation),
248 situation.angularAcceleration};
249}
250
251template <typename T>
252inline Situation DeadReckoner<T>::extrapolateAt(sen::TimeStamp time)
253{
254 updateSpatial(time);
255 const auto update = Parent::extrapolate(lastSpatial_, time, lastTimeStamp_);
256
257 // A producer may publish a different algorithm at any time, so the frame is read each query.
258 return isBodyReferenced(lastSpatial_) ? update : DeadReckonerBase::smoothIfEnabled(update);
259}
260
261template <typename T>
262inline bool DeadReckoner<T>::isBodyReferenced(const SpatialVariant& spatial) noexcept
263{
264 const auto algorithm = static_cast<SpatialAlgorithm>(spatial.index());
265 return std::find(bodyAlgorithms.begin(), bodyAlgorithms.end(), algorithm) != bodyAlgorithms.end();
266}
267
268template <typename T>
269void DeadReckoner<T>::updateSpatial(sen::TimeStamp time)
270{
271 if (const auto& newSpatial = object_.getSpatial(); newSpatial != lastSpatial_)
272 {
273 lastSpatial_ = newSpatial;
274 lastTimeStamp_ = spatialOrigin(time);
275 this->invalidateCache();
276 }
277}
278
279template <typename T>
280inline sen::TimeStamp DeadReckoner<T>::spatialOrigin(sen::TimeStamp time) const noexcept
281{
282 if constexpr (impl::HasCommitTime<T>::value)
283 {
284 if (DeadReckonerBase::getConfig().useCommitTimeAsOrigin)
285 {
286 // A producer that never advances its commit time would freeze the origin and grow the delta
287 // without bound, and one ahead of the query would extrapolate backwards.
288 if (const auto committed = object_.asObject().getLastCommitTime();
289 committed > lastTimeStamp_ && committed <= time)
290 {
291 return committed;
292 }
293 }
294 }
295
296 return time;
297}
298
299} // namespace sen::util
300
301#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 detail/dead_reckoner_base.h:279
const Situation & smoothIfEnabled(const Situation &update)
Smooths the update when configured to and returns what to publish. With smoothing off the walk is ski...
const GeodeticSituation & getCachedGeodeticSituation() const noexcept
Definition detail/dead_reckoner_base.h:281
void setCachedGeodeticSituation(const GeodeticSituation &situation)
Definition detail/dead_reckoner_base.h:274
void setCachedSituation(const Situation &situation)
Definition detail/dead_reckoner_base.h:267
bool isSituationCached(sen::TimeStamp timeStamp) const noexcept
Definition detail/dead_reckoner_base.h:262
bool isGeodeticSituationCached(sen::TimeStamp timeStamp) const noexcept
Definition detail/dead_reckoner_base.h:269
DeadReckonerTemplateBase< T > Parent
Definition dead_reckoner.h:37
typename Parent::RprOrientation RprOrientation
Definition dead_reckoner.h:45
typename Parent::StaticSpatial StaticSpatial
Definition dead_reckoner.h:39
T & getObject() noexcept
Provides direct mutable access to the internal object managed by this instance of the DeadReckoner.
Definition dead_reckoner.h:164
Situation situation(sen::TimeStamp timeStamp) override
Returns the extrapolated/smoothed situation of the object at the timestamp introduced as argument,...
Definition dead_reckoner.h:126
std::function< Situation(sen::TimeStamp)> SituationProcessor
Definition dead_reckoner.h:51
typename Parent::RprAngularVelocity RprAngularVelocity
Definition dead_reckoner.h:48
typename Parent::FpsSpatial FpsSpatial
Definition dead_reckoner.h:40
static Situation toSituation(const SpatialVariant &spatial, sen::TimeStamp timeStamp={})
Translates a SpatialVariant to a Situation struct.
Definition dead_reckoner.h:170
~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:119
typename Parent::SpatialVariant SpatialVariant
Definition dead_reckoner.h:38
typename Parent::RpsSpatial RpsSpatial
Definition dead_reckoner.h:41
static GeodeticSituation toGeodeticSituation(const SpatialVariant &spatial, sen::TimeStamp timeStamp={})
Translates a SpatialVariant to a GeodeticSituation struct.
Definition dead_reckoner.h:220
typename Parent::RprVelocity RprVelocity
Definition dead_reckoner.h:46
typename Parent::RprAcceleration RprAcceleration
Definition dead_reckoner.h:47
typename Parent::FvsSpatial FvsSpatial
Definition dead_reckoner.h:43
GeodeticSituation geodeticSituation(sen::TimeStamp timeStamp) override
Returns the extrapolated/smoothed situation of the object at the timestamp introduced as argument,...
Definition dead_reckoner.h:136
std::function< GeodeticSituation(sen::TimeStamp)> GeodeticSituationProcessor
Definition dead_reckoner.h:52
typename Parent::RvsSpatial RvsSpatial
Definition dead_reckoner.h:42
typename Parent::RprLocation RprLocation
Definition dead_reckoner.h:44
std::variant_alternative_t< 2U, SpatialVariant > RpsSpatial
Definition detail/dead_reckoner_base.h:119
DeadReckonerTemplateBase(DrConfig config={})
Definition detail/dead_reckoner_base.h:143
std::variant_alternative_t< 4U, SpatialVariant > FvsSpatial
Definition detail/dead_reckoner_base.h:121
decltype(std::declval< RvsSpatial >().orientation) RprOrientation
Definition detail/dead_reckoner_base.h:123
decltype(std::declval< RvsSpatial >().worldLocation) RprLocation
Definition detail/dead_reckoner_base.h:122
std::variant_alternative_t< 1U, SpatialVariant > FpsSpatial
Definition detail/dead_reckoner_base.h:118
std::remove_const_t< std::remove_reference_t< decltype(std::declval< T >().getSpatial())> > SpatialVariant
Definition detail/dead_reckoner_base.h:116
decltype(std::declval< RvsSpatial >().accelerationVector) RprAcceleration
Definition detail/dead_reckoner_base.h:125
std::variant_alternative_t< 0U, SpatialVariant > StaticSpatial
Definition detail/dead_reckoner_base.h:117
std::variant_alternative_t< 3U, SpatialVariant > RvsSpatial
Definition detail/dead_reckoner_base.h:120
decltype(std::declval< RvsSpatial >().angularVelocity) RprAngularVelocity
Definition detail/dead_reckoner_base.h:126
decltype(std::declval< RvsSpatial >().velocityVector) RprVelocity
Definition detail/dead_reckoner_base.h:124
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:187
Velocity fromRprVelocity(const T &value)
Translates to a Velocity struct from a RPR Velocity.
Definition dead_reckoner_impl.h:180
GeodeticWorldLocation toLla(const Location &worldLocation) noexcept
Translates from ECEF Location to Geodetic (LatLonAlt) Location.
Situation toSituation(const GeodeticSituation &value) noexcept
Converts a situation from geodetic to ECEF.
GeodeticSituation toGeodeticSituation(const Situation &value) noexcept
Converts a situation from ECEF to geodetic, building the position rotation once for all three quantit...
AngularVelocity fromRprAngularVelocity(const T &value)
Translates to AngularVelocity struct from a RPR AngularVelocity.
Definition dead_reckoner_impl.h:194
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:70
Orientation fromRprOrientation(const T &value)
Translates to an Orientation struct from a RPR Orientation.
Definition dead_reckoner_impl.h:173
SpatialAlgorithm
Length in meters.
Definition algorithms.h:58
Location fromRprLocation(const T &value)
Translates to a Location struct from a RPR WorldLocation.
Definition dead_reckoner_impl.h:167
Dead Reckoning configuration.
Definition algorithms.h:80
GeodeticSituation structure with the following parameters:
Definition algorithms.h:208
Situation structure with the following parameters:
Definition algorithms.h:176
@ 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:112
GeodeticSituation toGeodeticSituation(const Situation &value)
Transform a Situation to a GeodeticSituation.
Definition dead_reckoner.h:106
Definition assert.h:17
Helper type for std::variant lambda visitors.
Definition class_helpers.h:170
True when T can report when its data was committed. Generated RPR types can, through asObject(); a ha...
Definition dead_reckoner_impl.h:27