18 using namespace swift::config;
19 using namespace swift::misc::aviation;
20 using namespace swift::misc::geo;
21 using namespace swift::misc::math;
22 using namespace swift::misc::physical_quantities;
23 using namespace swift::misc::simulation;
25 namespace swift::misc::simulation
28 : m_startSituation(startSituation), m_pbh(0, startSituation, startSituation)
33 : m_startSituation(startSituation), m_pbh(pbh)
38 qint64 interpolatedTime)
39 :
IInterpolant(interpolatedTime), m_startSituation(startSituation), m_endSituation(endSituation),
40 m_simulationTimeFraction(timeFraction)
42 if (CBuildConfig::isLocalDeveloperDebugBuild())
45 "Time fraction needs to be within [0;1]");
50 void CInterpolatorLinear::anchor() {}
52 std::tuple<geo::CCoordinateGeodetic, aviation::CAltitude>
55 const std::array<double, 3> startVec(m_startSituation.getPosition().normalVectorDouble());
56 const std::array<double, 3> endVec(m_endSituation.getPosition().normalVectorDouble());
58 if (CBuildConfig::isLocalDeveloperDebugBuild())
60 SWIFT_VERIFY_X(CAircraftSituation::isValidVector(startVec), Q_FUNC_INFO,
"Invalid start vector");
61 SWIFT_VERIFY_X(CAircraftSituation::isValidVector(endVec), Q_FUNC_INFO,
"Invalid end vector");
68 interpolatedPosition.
setNormalVector((endVec[0] - startVec[0]) * tf + startVec[0],
69 (endVec[1] - startVec[1]) * tf + startVec[1],
70 (endVec[2] - startVec[2]) * tf + startVec[2]);
72 if (CBuildConfig::isLocalDeveloperDebugBuild())
79 const CAltitude oldAlt(m_startSituation.getCorrectedAltitude());
80 const CAltitude newAlt(m_endSituation.getCorrectedAltitude());
83 Q_FUNC_INFO,
"mismatch in reference");
86 return { interpolatedPosition, altitude };
91 const double startGroundFactor = m_startSituation.getOnGroundInfo().
getGroundFactor();
92 const double endGroundFactor = m_endSituation.getOnGroundInfo().getGroundFactor();
93 if (CAircraftSituation::isGfEqualAirborne(startGroundFactor, endGroundFactor))
95 return { COnGroundInfo::NotOnGround, COnGroundInfo::OnGroundByInterpolation };
97 else if (CAircraftSituation::isGfEqualOnGround(startGroundFactor, endGroundFactor))
99 return { COnGroundInfo::OnGround, COnGroundInfo::OnGroundByInterpolation };
104 const double interpolatedGroundFactor = (endGroundFactor - startGroundFactor) * tf + startGroundFactor;
116 Q_FUNC_INFO,
"Wrong order");
120 const bool recalculate = updated || newSplit;
129 return s.getAdjustedMSecsSinceEpoch() > m_currentTimeMsSinceEpoch;
145 if (situationsOlder.isEmpty() || situationsNewer.isEmpty())
148 if (situationsOlder.isEmpty())
152 m_interpolant = { currentSituation };
153 return m_interpolant;
157 if (situationsOlder.size() < 2)
161 m_interpolant = { currentSituation };
162 return m_interpolant;
166 startSituation = *(situationsOlder.begin() + 1);
167 endSituation = situationsOlder.front();
171 startSituation = situationsOlder.front();
172 endSituation = *(situationsNewer.end() - 1);
194 const qint64 sampleDeltaTimeMs =
196 Q_ASSERT_X(sampleDeltaTimeMs >= 0, Q_FUNC_INFO,
"Negative delta time");
204 double simulationTimeFraction = qMax(1.0 - (distanceToSplitTimeMs / sampleDeltaTimeMs), 0.0);
205 if (simulationTimeFraction >= 1.0)
207 simulationTimeFraction = 1.0;
208 if (qAbs(distanceToSplitTimeMs) > 100)
214 const double deltaTimeFractionMs = sampleDeltaTimeMs * simulationTimeFraction;
215 const qint64 interpolatedTime = startSituation.
getMSecsSinceEpoch() + qRound(deltaTimeFractionMs);
237 m_interpolant = { startSituation, endSituation, simulationTimeFraction, interpolatedTime };
240 return m_interpolant;
Class for emitting a log message.
Derived & debug()
Set the severity to debug.
iterator begin()
Returns iterator at the beginning of the sequence.
void push_back(const T &value)
Appends an element at the end of the sequence.
void clear()
Removes all elements in the sequence.
iterator end()
Returns iterator one past the end of the sequence.
qint64 getMSecsSinceEpoch() const
Timestamp as ms value.
void setMSecsSinceEpoch(qint64 mSecsSinceEpoch)
Timestamp as ms value.
qint64 getAdjustedMSecsSinceEpoch() const
Timestamp with offset added for interpolation.
qint64 getTimeOffsetMs() const
Milliseconds to add to timestamp for interpolation.
void setTimeOffsetMs(qint64 offset)
Milliseconds to add to timestamp for interpolation.
Value object encapsulating information of an aircraft's situation.
bool hasGroundElevation() const
Is ground elevation value available.
bool setGroundElevationChecked(const geo::CElevationPlane &elevationPlane, GndElevationInfo info, bool transferred=false)
Set elevation of the ground directly beneath, but checked.
bool canLikelySkipNearGroundInterpolation() const
Situation looks like an aircraft not near ground.
Altitude as used in aviation, can be AGL or MSL altitude.
ReferenceDatum getReferenceDatum() const
Get reference datum (MSL or AGL)
Information about the ground status.
double getGroundFactor() const
Get the ground factor Use this for interpolation only!! For just checking if the info is OnGround or ...
void setNormalVector(const QVector3D &normal)
Set normal vector.
Plane of same elevation, can be a single point or larger area (e.g. airport)
bool isValidVectorRange() const
Check values.
void setInterpolatedAndCheckSituation(bool succeeded, const aviation::CAircraftSituation &situation)
Set succeeded.
qint64 m_situationsLastModified
when situations were last modified
bool doLogging() const
Do logging.
CInterpolationStatus m_currentInterpolationStatus
this step's situation status
qint64 m_situationsLastModifiedUsed
interpolant based on situations last updated
qint64 m_currentTimeMsSinceEpoch
current time
aviation::CAircraftSituationList m_currentSituations
current situations obtained by remoteAircraftSituationsAndChange
aviation::COnGroundInfo interpolateGroundFactor() const
Interpolate the ground information/factor.
CInterpolant()=default
Constructor.
const aviation::CAircraftSituation & getStartSituation() const
Start situation.
std::tuple< geo::CCoordinateGeodetic, aviation::CAltitude > interpolatePositionAndAltitude() const
Perform the interpolation.
const aviation::CAircraftSituation & getEndSituation() const
End situation.
const IInterpolant & getInterpolant(SituationLog &log)
Get the interpolant for the given time point.
Simple linear interpolator for pitch, bank, heading and groundspeed from start to end situation.
geo::CElevationPlane findClosestElevationWithinRange(const geo::ICoordinateGeodetic &reference, const physical_quantities::CLength &range) const
Find closest elevation (or return NULL)
void setRecalculated(bool reCalculated)
Set recalculated interpolant.
bool isValidTimeFraction(double timeFraction)
Valid time fraction [0,1].
bool isAcceptableTimeFraction(double timeFraction)
Valid time fraction [0,1], this allows minor overshooting.
double clampValidTimeFraction(double timeFraction)
Clamp time fraction [0,1].
auto makeRange(I begin, I2 end) -> CRange< I >
Returns a CRange constructed from begin and end iterators of deduced types.
Log entry for situation interpolation.
QChar interpolator
what interpolator is used
aviation::CAircraftSituationList interpolationSituations
the interpolator uses 2, 3 situations (latest at end)
qint64 tsInterpolated
timestamp interpolated
double deltaSampleTimesMs
delta time between samples (i.e.
double simTimeFraction
time fraction, expected 0..1
qint64 tsCurrent
current timestamp
bool interpolantRecalc
interpolant recalculated
#define SWIFT_VERIFY_X(COND, WHERE, WHAT)
A weaker kind of assert.