Sen API
Sen Libraries
Loading...
Searching...
No Matches
settable_dead_reckoner.h
Go to the documentation of this file.
1// === settable_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_SETTABLE_DEAD_RECKONER_H
9#define SEN_UTIL_DR_SETTABLE_DEAD_RECKONER_H
10
11#include "dead_reckoner.h"
14
15// std
16#include <cmath>
17
18namespace sen::util
19{
20
23
24//--------------------------------------------------------------------------------------------------------------
25// Types
26//--------------------------------------------------------------------------------------------------------------
27
29enum class ReferenceSystem : u32
30{
33};
34
35// --8<-- [start:dr_threshold]
45// --8<-- [end:dr_threshold]
46
49template <typename T>
52{
53public:
54 SEN_NOCOPY_NOMOVE(SettableDeadReckoner)
55
56public:
57 explicit SettableDeadReckoner(T& object, DrThreshold thresholds = {});
58 ~SettableDeadReckoner() override = default;
59
60public:
73
74public:
76 [[nodiscard]] T& object() noexcept;
77
79 [[nodiscard]] const T& object() const noexcept;
80
81public:
84 bool setSpatial(const Situation& situation);
85
89
92 void setFrozen(sen::TimeStamp timeStamp, bool value);
93
94private:
97 SpatialVariant toSpatialVariant(const Situation& situation, const DrThreshold& threshold);
98
99private:
100 T& obj_;
101 sen::TimeStamp lastTimeStamp_;
102 DrThreshold threshold_;
103 const f64 orientationThresholdCos; // constant used to determine if the orientation threshold has been exceeded
104};
105
107
108//-------------------------------------------------------------------------------------------------------------------
109// Inline implementation
110//-------------------------------------------------------------------------------------------------------------------
111
112template <typename T>
114 : obj_ {object}
115 , threshold_ {thresholds}
116 , orientationThresholdCos {cos(static_cast<f64>(threshold_.orientationThreshold) * 0.5)}
117{
118}
119
120template <typename T>
122{
123 return obj_;
124}
125
126template <typename T>
127inline const T& SettableDeadReckoner<T>::object() const noexcept
128{
129 return obj_;
130}
131
132template <typename T>
134{
135 const auto extrapolation = Parent::extrapolate(obj_.getSpatial(), situation.timeStamp, lastTimeStamp_);
136 if (impl::maxDistanceExceeded(situation.worldLocation, extrapolation.worldLocation, threshold_.distanceThreshold) ||
137 impl::maxRotationExceeded(situation.orientation, extrapolation.orientation, orientationThresholdCos))
138 {
139 lastTimeStamp_ = situation.timeStamp;
140 obj_.setNextSpatial(toSpatialVariant(situation, threshold_));
141 return true;
142 }
143
144 return false;
145}
146
147template <typename T>
149{
150 // translate input geodetic situation to standard reference system
151 const auto ecefPosition = impl::toEcef(situation.worldLocation);
152 const auto ecefOrientation = impl::nedToEcef(situation.orientation, situation.worldLocation);
153 const auto extrapolation = Parent::extrapolate(obj_.getSpatial(), situation.timeStamp, lastTimeStamp_);
154 if (impl::maxDistanceExceeded(ecefPosition, extrapolation.worldLocation, threshold_.distanceThreshold) ||
155 impl::maxRotationExceeded(ecefOrientation, extrapolation.orientation, orientationThresholdCos))
156 {
157 lastTimeStamp_ = situation.timeStamp;
158 obj_.setNextSpatial(toSpatialVariant(impl::toSituation(situation, ecefPosition, ecefOrientation), threshold_));
159 return true;
160 }
161
162 return false;
163}
164
165template <typename T>
166inline void SettableDeadReckoner<T>::setFrozen(sen::TimeStamp timeStamp, bool value)
167{
168 auto situation = Parent::extrapolate(obj_.getNextSpatial(), timeStamp, lastTimeStamp_);
169 if (situation.isFrozen == value)
170 {
171 return;
172 }
173
174 situation.isFrozen = value;
175 lastTimeStamp_ = timeStamp;
176
177 obj_.setNextSpatial(toSpatialVariant(situation, threshold_));
178}
179
180template <typename T>
181inline typename SettableDeadReckoner<T>::SpatialVariant SettableDeadReckoner<T>::toSpatialVariant(
182 const Situation& situation,
183 const DrThreshold& threshold)
184{
185 const auto isMoving = impl::isMoving(situation.velocityVector);
186 const auto isAccelerating = impl::isAccelerating(situation.accelerationVector);
187 const auto isRotating = impl::isRotating(situation.angularVelocity);
188
189 // A static spatial carries no angular velocity, so an entity turning on the spot must not take it.
190 if (!isMoving && !isAccelerating && !isRotating)
191 {
192 return SpatialVariant {std::in_place_index<static_cast<size_t>(SpatialAlgorithm::drStatic)>,
196 }
197
198 const auto isWorld = threshold.referenceSystem == ReferenceSystem::world;
199
200 // not accelerating; a motionless entity has already gone to the static case
201 if (!isAccelerating)
202 {
203 // not rotating
204 if (!isRotating)
205 {
206 if (isWorld)
207 {
208 return SpatialVariant {std::in_place_index<static_cast<size_t>(SpatialAlgorithm::drFPW)>,
210 situation.isFrozen,
212 impl::toRpr<RprVelocity>(situation.velocityVector)}};
213 }
214 return SpatialVariant {std::in_place_index<static_cast<size_t>(SpatialAlgorithm::drFPB)>,
216 situation.isFrozen,
218 impl::toRpr<RprVelocity>(situation.velocityVector)}};
219 }
220
221 // rotating
222 if (isWorld)
223 {
224 return SpatialVariant {std::in_place_index<static_cast<size_t>(SpatialAlgorithm::drRPW)>,
226 situation.isFrozen,
228 impl::toRpr<RprVelocity>(situation.velocityVector),
230 }
231 return SpatialVariant {std::in_place_index<static_cast<size_t>(SpatialAlgorithm::drRPB)>,
233 situation.isFrozen,
235 impl::toRpr<RprVelocity>(situation.velocityVector),
237 }
238 // fast-moving not rotating
239 if (!isRotating)
240 {
241 if (isWorld)
242 {
243 return SpatialVariant {std::in_place_index<static_cast<size_t>(SpatialAlgorithm::drFVW)>,
245 situation.isFrozen,
247 impl::toRpr<RprVelocity>(situation.velocityVector),
248 impl::toRpr<RprAcceleration>(situation.accelerationVector)}};
249 }
250 return SpatialVariant {std::in_place_index<static_cast<size_t>(SpatialAlgorithm::drFVB)>,
252 situation.isFrozen,
254 impl::toRpr<RprVelocity>(situation.velocityVector),
255 impl::toRpr<RprAcceleration>(situation.accelerationVector)}};
256 }
257
258 // fast-moving rotating
259 if (isWorld)
260 {
261 return SpatialVariant {std::in_place_index<static_cast<size_t>(SpatialAlgorithm::drRVW)>,
263 situation.isFrozen,
265 impl::toRpr<RprVelocity>(situation.velocityVector),
266 impl::toRpr<RprAcceleration>(situation.accelerationVector),
268 }
269 return SpatialVariant {std::in_place_index<static_cast<size_t>(SpatialAlgorithm::drRVB)>,
271 situation.isFrozen,
273 impl::toRpr<RprVelocity>(situation.velocityVector),
274 impl::toRpr<RprAcceleration>(situation.accelerationVector),
276}
277
278} // namespace sen::util
279
280#endif // SEN_UTIL_DR_SETTABLE_DEAD_RECKONER_H
A point in time.
Definition timestamp.h:26
virtual Situation situation(sen::TimeStamp timeStamp)
Returns the extrapolated/smoothed situation of the object at the timestamp introduced as argument,...
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
static Situation extrapolate(const SpatialVariant &spatial, sen::TimeStamp time, sen::TimeStamp lastTimeStamp)
Returns the extrapolated situation of the RPR Entity given its Spatial field and two timestamps that ...
Definition detail/dead_reckoner_base.h:148
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
typename Parent::SpatialVariant SpatialVariant
Definition settable_dead_reckoner.h:62
bool setSpatial(const Situation &situation)
Updates the spatial property of the object when the extrapolation error exceeds the threshold....
Definition settable_dead_reckoner.h:133
typename Parent::FvsSpatial FvsSpatial
Definition settable_dead_reckoner.h:67
typename Parent::RprVelocity RprVelocity
Definition settable_dead_reckoner.h:70
typename Parent::StaticSpatial StaticSpatial
Definition settable_dead_reckoner.h:63
T & object() noexcept
Returns a mutable reference to the RPR object whose position is extrapolated.
Definition settable_dead_reckoner.h:121
typename Parent::RprAcceleration RprAcceleration
Definition settable_dead_reckoner.h:71
SettableDeadReckoner(T &object, DrThreshold thresholds={})
Definition settable_dead_reckoner.h:113
DeadReckonerTemplateBase< T > Parent
Definition settable_dead_reckoner.h:61
typename Parent::RprAngularVelocity RprAngularVelocity
Definition settable_dead_reckoner.h:72
void setFrozen(sen::TimeStamp timeStamp, bool value)
Directly sets the frozen state of the object's spatial to true/false. The timestamp is needed to cohe...
Definition settable_dead_reckoner.h:166
typename Parent::FpsSpatial FpsSpatial
Definition settable_dead_reckoner.h:64
~SettableDeadReckoner() override=default
typename Parent::RvsSpatial RvsSpatial
Definition settable_dead_reckoner.h:66
typename Parent::RprOrientation RprOrientation
Definition settable_dead_reckoner.h:69
typename Parent::RprLocation RprLocation
Definition settable_dead_reckoner.h:68
typename Parent::RpsSpatial RpsSpatial
Definition settable_dead_reckoner.h:65
ReferenceSystem referenceSystem
Definition settable_dead_reckoner.h:43
Location worldLocation
Position in ECEF.
Definition algorithms.h:184
AngularVelocity angularVelocity
Angular velocity vector with respect to body reference system.
Definition algorithms.h:194
Velocity velocityVector
Velocity vector with respect to ECEF or body reference system (depending on the reference system of t...
Definition algorithms.h:191
AngleRadians orientationThreshold
Definition settable_dead_reckoner.h:42
Orientation orientation
Orientation of the body reference system (x forward, y right, z down) with respect to ECEF.
Definition algorithms.h:187
Acceleration accelerationVector
Acceleration vector with respect to ECEF or body reference system (depending on the reference system ...
Definition algorithms.h:198
LengthMeters distanceThreshold
Definition settable_dead_reckoner.h:41
bool isFrozen
When true, no extrapolation is performed because the entity is frozen.
Definition algorithms.h:178
Location toEcef(const GeodeticWorldLocation &latLonAlt) noexcept
Translates from Geodetic (LatLonAlt) to ECEF WorldLocation coordinates.
bool maxRotationExceeded(const Orientation &newOrientation, const Orientation &extrapolatedOrientation, f64 threshold)
Returns true when the rotation threshold has been exceeded.
Orientation nedToEcef(const Orientation &value, const GeodeticWorldLocation &latLonAlt) noexcept
Translates the Orientation in euler angles from NED to ECEF using quaternions.
T toRpr(const Location &value)
Translates a Location struct to a RPR WorldLocation given as template argument.
Definition dead_reckoner_impl.h:137
bool isRotating(const AngularVelocity &omega)
Returns true when angular velocity acceleration is not null.
Situation toSituation(const GeodeticSituation &value) noexcept
Converts a situation from geodetic to ECEF.
bool isMoving(const Velocity &velocity)
Returns true when entity velocity is not null.
bool maxDistanceExceeded(const Location &newPosition, const Location &extrapolatedPosition, f64 threshold)
Returns true when the distance threshold has been exceeded.
bool isAccelerating(const Acceleration &acceleration)
Returns true when entity acceleration is not null.
ReferenceSystem
Enumeration of the reference system: world-centered or body-centered.
Definition settable_dead_reckoner.h:30
@ world
Definition settable_dead_reckoner.h:31
@ body
Definition settable_dead_reckoner.h:32
@ drFPW
Definition algorithms.h:60
@ drRVB
Definition algorithms.h:66
@ drFPB
Definition algorithms.h:64
@ drRVW
Definition algorithms.h:62
@ drFVB
Definition algorithms.h:67
@ drRPW
Definition algorithms.h:61
@ drRPB
Definition algorithms.h:65
@ drStatic
Definition algorithms.h:59
@ drFVW
Definition algorithms.h:63
How far the extrapolation may drift from the data before the Spatial is written: a distance per axis ...
Definition settable_dead_reckoner.h:40
GeodeticSituation structure with the following parameters:
Definition algorithms.h:208
Situation structure with the following parameters:
Definition algorithms.h:176
uint32_t u32
Definition numbers.h:25
float64_t f64
Definition numbers.h:29
Definition iterator_adapters.h:16
Definition assert.h:17