Ref T261, interpolator adjustments

* using interface IInterpolant, renamed to CInterpolant for concrete implmentation
* CInterpolatorPBH has itws own file now, is included
* linear interpolator only re-calculates interpolant when needed (same as spline interpolator)
This commit is contained in:
Klaus Basan
2018-05-06 03:06:56 +02:00
committed by Roland Winklmeier
parent ef72cf7cd4
commit bac3d14d50
7 changed files with 145 additions and 120 deletions

View File

@@ -18,6 +18,7 @@ namespace BlackMisc
{ {
namespace Simulation namespace Simulation
{ {
//! Interpolant interface
class IInterpolant class IInterpolant
{ {
public: public:
@@ -41,7 +42,7 @@ namespace BlackMisc
IInterpolant(qint64 interpolatedTime, int situationsAvailable) : m_interpolatedTime(interpolatedTime), m_situationsAvailable(situationsAvailable) {} IInterpolant(qint64 interpolatedTime, int situationsAvailable) : m_interpolatedTime(interpolatedTime), m_situationsAvailable(situationsAvailable) {}
qint64 m_interpolatedTime = -1; //!< "Real time "of interpolated situation qint64 m_interpolatedTime = -1; //!< "Real time "of interpolated situation
int m_situationsAvailable = 0; //!< used situations int m_situationsAvailable = 0; //!< used situations
CInterpolatorPbh m_pbh; //!< the used PBH interpolator CInterpolatorPbh m_pbh; //!< the used PBH interpolator
}; };
} // namespace } // namespace

View File

@@ -71,6 +71,21 @@ namespace BlackMisc
return f; return f;
} }
template<typename Derived>
CAircraftSituationList CInterpolator<Derived>::remoteAircraftSituationsAndChange(bool useSceneryOffset)
{
CAircraftSituationList validSituations = this->remoteAircraftSituations(m_callsign);
m_situationChange = CAircraftSituationChange(validSituations, true, true);
if (useSceneryOffset && m_situationChange.hasSceneryDeviation() && m_model.hasCG())
{
const CLength os = m_situationChange.getGuessedSceneryDeviation(m_model.getCG());
validSituations.addAltitudeOffset(os);
m_situationChange = CAircraftSituationChange(validSituations, true, true); // recalculate
m_lastSceneryOffset = os;
}
return validSituations;
}
template<typename Derived> template<typename Derived>
void CInterpolator<Derived>::deferredInit() void CInterpolator<Derived>::deferredInit()
{ {

View File

@@ -41,9 +41,9 @@ namespace BlackMisc
//! Interpolator, calculation inbetween positions //! Interpolator, calculation inbetween positions
template <typename Derived> template <typename Derived>
class CInterpolator : class CInterpolator :
public CSimulationEnvironmentAware, protected CSimulationEnvironmentAware,
public CInterpolationSetupAware, protected CInterpolationSetupAware,
public CRemoteAircraftAware protected CRemoteAircraftAware
{ {
public: public:
//! Log categories //! Log categories
@@ -109,13 +109,17 @@ namespace BlackMisc
//! \sa BlackMisc::Aviation::CAircraftSituation::setOnGroundFromGroundFactorFromInterpolation //! \sa BlackMisc::Aviation::CAircraftSituation::setOnGroundFromGroundFactorFromInterpolation
static double groundInterpolationFactor(); static double groundInterpolationFactor();
const Aviation::CCallsign m_callsign; //!< corresponding callsign
CAircraftModel m_model; //!< corresponding model CAircraftModel m_model; //!< corresponding model
const Aviation::CCallsign m_callsign; //!< corresponding callsign
Aviation::CAircraftSituation m_lastInterpolation { Aviation::CAircraftSituation::null() }; //!< latest interpolation Aviation::CAircraftSituation m_lastInterpolation { Aviation::CAircraftSituation::null() }; //!< latest interpolation
Aviation::CAircraftSituationChange m_situationChange; //!< situations change Aviation::CAircraftSituationChange m_situationChange; //!< situations change
PhysicalQuantities::CLength m_lastSceneryOffset = PhysicalQuantities::CLength::null();
qint64 m_situationsLastModifiedUsed { -1 }; //!< based on situations last updated qint64 m_situationsLastModifiedUsed { -1 }; //!< based on situations last updated
int m_interpolatedSituationsCounter = 0; //!< counter for each interpolated situations: statistics, every n-th interpolation .... int m_interpolatedSituationsCounter = 0; //!< counter for each interpolated situations: statistics, every n-th interpolation ....
//! Get situations and calculate change, also correct altitudes if applicable
Aviation::CAircraftSituationList remoteAircraftSituationsAndChange(bool useSceneryOffset);
//! Verify gnd flag, times, ... true means "OK" //! Verify gnd flag, times, ... true means "OK"
bool verifyInterpolationSituations(const Aviation::CAircraftSituation &oldest, const Aviation::CAircraftSituation &newer, const Aviation::CAircraftSituation &latest, bool verifyInterpolationSituations(const Aviation::CAircraftSituation &oldest, const Aviation::CAircraftSituation &newer, const Aviation::CAircraftSituation &latest,
const CInterpolationAndRenderingSetupPerCallsign &setup = CInterpolationAndRenderingSetupPerCallsign::null()); const CInterpolationAndRenderingSetupPerCallsign &setup = CInterpolationAndRenderingSetupPerCallsign::null());

View File

@@ -36,20 +36,25 @@ namespace BlackMisc
{ {
namespace Simulation namespace Simulation
{ {
CInterpolatorLinear::Interpolant::Interpolant(const CAircraftSituation &situation) : CInterpolatorLinear::CInterpolant::CInterpolant(const CAircraftSituation &situation) :
m_situationsAvailable(1), m_oldSituation(situation), IInterpolant(1, CInterpolatorPbh(0, situation, situation)),
m_pbh(0, situation, situation) m_oldSituation(situation)
{} { }
CInterpolatorLinear::Interpolant::Interpolant(const CAircraftSituation &situation1, const CAircraftSituation &situation2, double timeFraction, qint64 interpolatedTime) : CInterpolatorLinear::CInterpolant::CInterpolant(const CAircraftSituation &situation, const CInterpolatorPbh &pbh) :
m_situationsAvailable(2), IInterpolant(1, pbh),
m_oldSituation(situation)
{ }
CInterpolatorLinear::CInterpolant::CInterpolant(const CAircraftSituation &situation1, const CAircraftSituation &situation2, double timeFraction, qint64 interpolatedTime) :
IInterpolant(interpolatedTime, 2),
m_oldSituation(situation1), m_newSituation(situation2), m_oldSituation(situation1), m_newSituation(situation2),
m_simulationTimeFraction(timeFraction), m_simulationTimeFraction(timeFraction)
m_interpolatedTime(interpolatedTime), {
m_pbh(m_simulationTimeFraction, situation1, situation2) m_pbh = CInterpolatorPbh(m_simulationTimeFraction, situation1, situation2);
{} }
CAircraftSituation CInterpolatorLinear::Interpolant::interpolatePositionAndAltitude(const CAircraftSituation &situation, bool interpolateGndFactor) const CAircraftSituation CInterpolatorLinear::CInterpolant::interpolatePositionAndAltitude(const CAircraftSituation &situation, bool interpolateGndFactor) const
{ {
const std::array<double, 3> oldVec(m_oldSituation.getPosition().normalVectorDouble()); const std::array<double, 3> oldVec(m_oldSituation.getPosition().normalVectorDouble());
const std::array<double, 3> newVec(m_newSituation.getPosition().normalVectorDouble()); const std::array<double, 3> newVec(m_newSituation.getPosition().normalVectorDouble());
@@ -92,7 +97,7 @@ namespace BlackMisc
return newSituation; return newSituation;
} }
CInterpolatorLinear::Interpolant CInterpolatorLinear::getInterpolant( CInterpolatorLinear::CInterpolant CInterpolatorLinear::getInterpolant(
qint64 currentTimeMsSinceEpoc, qint64 currentTimeMsSinceEpoc,
const CInterpolationAndRenderingSetupPerCallsign &setup, const CInterpolationAndRenderingSetupPerCallsign &setup,
CInterpolationStatus &status, SituationLog &log) CInterpolationStatus &status, SituationLog &log)
@@ -100,82 +105,84 @@ namespace BlackMisc
Q_UNUSED(setup); Q_UNUSED(setup);
status.reset(); status.reset();
// with the latest updates of T243 the order and the offsets are supposed to be correct
// so even mixing fast/slow updates shall work
const CAircraftSituationList validSituations = this->remoteAircraftSituations(m_callsign); // if needed, we could also copy here
if (!CBuildConfig::isReleaseBuild())
{
BLACK_VERIFY_X(validSituations.isSortedAdjustedLatestFirstWithoutNullPositions(), Q_FUNC_INFO, "Wrong sort order");
Q_ASSERT_X(validSituations.size() <= IRemoteAircraftProvider::MaxSituationsPerCallsign, Q_FUNC_INFO, "Wrong size");
}
const qint64 tsLastModified = this->situationsLastModified(m_callsign); const qint64 tsLastModified = this->situationsLastModified(m_callsign);
// set default situations
CAircraftSituation oldSituation = m_interpolant.getOldSituation();
CAircraftSituation newSituation = m_interpolant.getNewSituation();
if (m_situationsLastModifiedUsed < tsLastModified || m_situationChange.isNull()) if (m_situationsLastModifiedUsed < tsLastModified || m_situationChange.isNull())
{ {
m_situationsLastModifiedUsed = tsLastModified; m_situationsLastModifiedUsed = tsLastModified;
m_situationChange = CAircraftSituationChange(validSituations, true, true);
}
// find the first situation earlier than the current time // with the latest updates of T243 the order and the offsets are supposed to be correct
const auto pivot = std::partition_point(validSituations.begin(), validSituations.end(), [ = ](auto &&s) { return s.getAdjustedMSecsSinceEpoch() > currentTimeMsSinceEpoc; }); // so even mixing fast/slow updates shall work
const auto situationsNewer = makeRange(validSituations.begin(), pivot); const CAircraftSituationList validSituations = this->remoteAircraftSituationsAndChange(true);
const auto situationsOlder = makeRange(pivot, validSituations.end()); if (!CBuildConfig::isReleaseBuild())
// interpolation situations
CAircraftSituation oldSituation;
CAircraftSituation newSituation;
// latest first, now 00:20 split time
// time pos
// 00:25 10 newer
// 00:20 11 newer
// <----- split
// 00:15 12 older
// 00:10 13 older
// 00:05 14 older
// The first condition covers a situation, when there are no before / after situations.
// We just place at the last position until we get before / after situations
if (situationsOlder.isEmpty() || situationsNewer.isEmpty())
{
// no before situations
if (situationsOlder.isEmpty())
{ {
const CAircraftSituation currentSituation(*(situationsNewer.end() - 1)); // oldest newest BLACK_VERIFY_X(validSituations.isSortedAdjustedLatestFirstWithoutNullPositions(), Q_FUNC_INFO, "Wrong sort order");
status.setInterpolatedAndCheckSituation(false, currentSituation); Q_ASSERT_X(validSituations.size() <= IRemoteAircraftProvider::MaxSituationsPerCallsign, Q_FUNC_INFO, "Wrong size");
return currentSituation;
} }
// only one before situation // find the first situation earlier than the current time
if (situationsOlder.size() < 2) const auto pivot = std::partition_point(validSituations.begin(), validSituations.end(), [ = ](auto &&s) { return s.getAdjustedMSecsSinceEpoch() > currentTimeMsSinceEpoc; });
const auto situationsNewer = makeRange(validSituations.begin(), pivot);
const auto situationsOlder = makeRange(pivot, validSituations.end());
// latest first, now 00:20 split time
// time pos
// 00:25 10 newer
// 00:20 11 newer
// <----- split
// 00:15 12 older
// 00:10 13 older
// 00:05 14 older
// The first condition covers a situation, when there are no before / after situations.
// We just place at the last position until we get before / after situations
if (situationsOlder.isEmpty() || situationsNewer.isEmpty())
{ {
const CAircraftSituation currentSituation(situationsOlder.front()); // latest oldest // no before situations
status.setInterpolatedAndCheckSituation(false, currentSituation); if (situationsOlder.isEmpty())
return currentSituation; {
const CAircraftSituation currentSituation(*(situationsNewer.end() - 1)); // oldest newest
status.setInterpolatedAndCheckSituation(false, currentSituation);
m_interpolant = { currentSituation };
return m_interpolant;
}
// only one before situation
if (situationsOlder.size() < 2)
{
const CAircraftSituation currentSituation(situationsOlder.front()); // latest oldest
status.setInterpolatedAndCheckSituation(false, currentSituation);
m_interpolant = { currentSituation };
return m_interpolant;
}
// extrapolate from two before situations
oldSituation = *(situationsOlder.begin() + 1); // before newest
newSituation = situationsOlder.front(); // newest
}
else
{
oldSituation = situationsOlder.front(); // first oldest (aka newest oldest)
newSituation = *(situationsNewer.end() - 1); // latest newest (aka oldest of newer block)
Q_ASSERT(oldSituation.getAdjustedMSecsSinceEpoch() < newSituation.getAdjustedMSecsSinceEpoch());
} }
// extrapolate from two before situations // adjust ground if required
oldSituation = *(situationsOlder.begin() + 1); // before newest if (!oldSituation.canLikelySkipNearGroundInterpolation() && !oldSituation.hasGroundElevation())
newSituation = situationsOlder.front(); // newest {
} const CElevationPlane planeOld = this->findClosestElevationWithinRange(oldSituation, CElevationPlane::singlePointRadius());
else oldSituation.setGroundElevationChecked(planeOld);
{ }
oldSituation = situationsOlder.front(); // first oldest (aka newest oldest) if (!newSituation.canLikelySkipNearGroundInterpolation() && !newSituation.hasGroundElevation())
newSituation = *(situationsNewer.end() - 1); // latest newest (aka oldest of newer block) {
Q_ASSERT(oldSituation.getAdjustedMSecsSinceEpoch() < newSituation.getAdjustedMSecsSinceEpoch()); const CElevationPlane planeNew = this->findClosestElevationWithinRange(newSituation, CElevationPlane::singlePointRadius());
} newSituation.setGroundElevationChecked(planeNew);
}
// adjust ground if required } // modified situations
if (!oldSituation.canLikelySkipNearGroundInterpolation() && !oldSituation.hasGroundElevation())
{
const CElevationPlane planeOld = this->findClosestElevationWithinRange(oldSituation, CElevationPlane::singlePointRadius());
oldSituation.setGroundElevationChecked(planeOld);
}
if (!newSituation.canLikelySkipNearGroundInterpolation() && !newSituation.hasGroundElevation())
{
const CElevationPlane planeNew = this->findClosestElevationWithinRange(newSituation, CElevationPlane::singlePointRadius());
newSituation.setGroundElevationChecked(planeNew);
}
CAircraftSituation currentSituation(oldSituation); // also sets ground elevation if available CAircraftSituation currentSituation(oldSituation); // also sets ground elevation if available
@@ -209,7 +216,8 @@ namespace BlackMisc
log.interpolationSituations.push_back(oldSituation); // oldest at back log.interpolationSituations.push_back(oldSituation); // oldest at back
} }
return { oldSituation, newSituation, simulationTimeFraction, interpolatedTime }; m_interpolant = { oldSituation, newSituation, simulationTimeFraction, interpolatedTime };
return m_interpolant;
} }
} // namespace } // namespace
} // namespace } // namespace

View File

@@ -13,7 +13,8 @@
#define BLACKMISC_SIMULATION_INTERPOLATORLINEAR_H #define BLACKMISC_SIMULATION_INTERPOLATORLINEAR_H
#include "interpolator.h" #include "interpolator.h"
#include "blackmisc/simulation/interpolationlogger.h" #include "interpolationlogger.h"
#include "interpolant.h"
#include "blackmisc/aviation/aircraftsituation.h" #include "blackmisc/aviation/aircraftsituation.h"
#include "blackmisc/blackmiscexport.h" #include "blackmisc/blackmiscexport.h"
#include <QString> #include <QString>
@@ -37,41 +38,37 @@ namespace BlackMisc
CInterpolator(callsign, simEnvProvider, setupProvider, remoteAircraftProvider, logger) {} CInterpolator(callsign, simEnvProvider, setupProvider, remoteAircraftProvider, logger) {}
//! Linear function that performs the actual interpolation //! Linear function that performs the actual interpolation
class Interpolant class BLACKMISC_EXPORT CInterpolant : public IInterpolant
{ {
public: public:
//! Constructor //! Constructor
//! @{ //! @{
Interpolant(const Aviation::CAircraftSituation &situation); CInterpolant() {}
Interpolant(const Aviation::CAircraftSituation &situation1, const Aviation::CAircraftSituation &situation2, double timeFraction, qint64 interpolatedTime); CInterpolant(const Aviation::CAircraftSituation &situation);
CInterpolant(const Aviation::CAircraftSituation &situation, const CInterpolatorPbh &pbh);
CInterpolant(const Aviation::CAircraftSituation &situation1, const Aviation::CAircraftSituation &situation2, double timeFraction, qint64 interpolatedTime);
//! @} //! @}
//! Perform the interpolation //! Perform the interpolation
Aviation::CAircraftSituation interpolatePositionAndAltitude(const Aviation::CAircraftSituation &situation, bool interpolateGndFactor) const; Aviation::CAircraftSituation interpolatePositionAndAltitude(const Aviation::CAircraftSituation &situation, bool interpolateGndFactor) const;
//! Interpolator for pitch, bank, heading, groundspeed
const CInterpolatorPbh &pbh() const { return m_pbh; }
//! Old situation //! Old situation
const Aviation::CAircraftSituation &getOldSituation() const { return m_oldSituation; } const Aviation::CAircraftSituation &getOldSituation() const { return m_oldSituation; }
//! New situation //! New situation
const Aviation::CAircraftSituation &getNewSituation() const { return m_newSituation; } const Aviation::CAircraftSituation &getNewSituation() const { return m_newSituation; }
//! "Real time" representing the interpolated situation
qint64 getInterpolatedTime() const { return m_interpolatedTime; }
private: private:
int m_situationsAvailable = 0;
Aviation::CAircraftSituation m_oldSituation; Aviation::CAircraftSituation m_oldSituation;
Aviation::CAircraftSituation m_newSituation; Aviation::CAircraftSituation m_newSituation;
double m_simulationTimeFraction = 0.0; //!< 0..1 double m_simulationTimeFraction = 0.0; //!< 0..1
qint64 m_interpolatedTime = 0; //!< "Real time "of interpolated situation
const CInterpolatorPbh m_pbh; //!< pitch, bank, ground speed and heading
}; };
//! Get the interpolant for the given time point //! Get the interpolant for the given time point
Interpolant getInterpolant(qint64 currentTimeMsSinceEpoc, const CInterpolationAndRenderingSetupPerCallsign &setup, CInterpolationStatus &status, SituationLog &log); CInterpolant getInterpolant(qint64 currentTimeMsSinceEpoc, const CInterpolationAndRenderingSetupPerCallsign &setup, CInterpolationStatus &status, SituationLog &log);
private:
CInterpolant m_interpolant; //!< current interpolant
}; };
} // ns } // ns
} // ns } // ns

View File

@@ -145,7 +145,7 @@ namespace BlackMisc
return true; return true;
} }
CInterpolatorSpline::Interpolant CInterpolatorSpline::getInterpolant( CInterpolatorSpline::CInterpolant CInterpolatorSpline::getInterpolant(
qint64 currentTimeMsSinceEpoc, qint64 currentTimeMsSinceEpoc,
const CInterpolationAndRenderingSetupPerCallsign &setup, const CInterpolationAndRenderingSetupPerCallsign &setup,
CInterpolationStatus &status, CInterpolationStatus &status,
@@ -161,14 +161,13 @@ namespace BlackMisc
{ {
// with the latest updates of T243 the order and the offsets are supposed to be correct // with the latest updates of T243 the order and the offsets are supposed to be correct
// so even mixing fast/slow updates shall work // so even mixing fast/slow updates shall work
const CAircraftSituationList validSituations = this->remoteAircraftSituations(m_callsign);
m_situationsLastModifiedUsed = lastModified; m_situationsLastModifiedUsed = lastModified;
const CAircraftSituationList validSituations = this->remoteAircraftSituationsAndChange(true);
const bool fillStatus = this->fillSituationsArray(validSituations); const bool fillStatus = this->fillSituationsArray(validSituations);
if (!fillStatus) if (!fillStatus)
{ {
return m_interpolant; return m_interpolant;
} }
m_situationChange = CAircraftSituationChange(validSituations, true, true);
const std::array<std::array<double, 3>, 3> normals {{ m_s[0].getPosition().normalVectorDouble(), m_s[1].getPosition().normalVectorDouble(), m_s[2].getPosition().normalVectorDouble() }}; const std::array<std::array<double, 3>, 3> normals {{ m_s[0].getPosition().normalVectorDouble(), m_s[1].getPosition().normalVectorDouble(), m_s[2].getPosition().normalVectorDouble() }};
PosArray pa; PosArray pa;
pa.x = {{ normals[0][0], normals[1][0], normals[2][0] }}; // oldest -> latest pa.x = {{ normals[0][0], normals[1][0], normals[2][0] }}; // oldest -> latest
@@ -201,7 +200,7 @@ namespace BlackMisc
m_nextSampleAdjustedTime = m_s[2].getAdjustedMSecsSinceEpoch(); // latest m_nextSampleAdjustedTime = m_s[2].getAdjustedMSecsSinceEpoch(); // latest
m_prevSampleTime = m_s[1].getMSecsSinceEpoch(); m_prevSampleTime = m_s[1].getMSecsSinceEpoch();
m_nextSampleTime = m_s[2].getMSecsSinceEpoch(); // latest m_nextSampleTime = m_s[2].getMSecsSinceEpoch(); // latest
m_interpolant = Interpolant(pa, m_s[2].getAltitudeUnit(), CInterpolatorPbh(m_s[1], m_s[2])); m_interpolant = CInterpolant(pa, m_s[2].getAltitudeUnit(), CInterpolatorPbh(m_s[1], m_s[2]));
Q_ASSERT_X(m_prevSampleAdjustedTime < m_nextSampleAdjustedTime, Q_FUNC_INFO, "Wrong time order"); Q_ASSERT_X(m_prevSampleAdjustedTime < m_nextSampleAdjustedTime, Q_FUNC_INFO, "Wrong time order");
} }
@@ -286,7 +285,14 @@ namespace BlackMisc
return true; return true;
} }
CAircraftSituation CInterpolatorSpline::Interpolant::interpolatePositionAndAltitude(const CAircraftSituation &currentSituation, bool interpolateGndFactor) const CInterpolatorSpline::CInterpolant::CInterpolant(const CInterpolatorSpline::PosArray &pa, const CLengthUnit &altitudeUnit, const CInterpolatorPbh &pbh) :
m_pa(pa), m_altitudeUnit(altitudeUnit)
{
m_pbh = pbh;
m_situationsAvailable = pa.size();
}
CAircraftSituation CInterpolatorSpline::CInterpolant::interpolatePositionAndAltitude(const CAircraftSituation &currentSituation, bool interpolateGndFactor) const
{ {
const double t1 = m_pa.t[1]; const double t1 = m_pa.t[1];
const double t2 = m_pa.t[2]; const double t2 = m_pa.t[2];
@@ -323,7 +329,7 @@ namespace BlackMisc
return newSituation; return newSituation;
} }
void CInterpolatorSpline::Interpolant::setTimes(qint64 currentTimeMs, double timeFraction, qint64 interpolatedTimeMs) void CInterpolatorSpline::CInterpolant::setTimes(qint64 currentTimeMs, double timeFraction, qint64 interpolatedTimeMs)
{ {
m_currentTimeMsSinceEpoc = currentTimeMs; m_currentTimeMsSinceEpoc = currentTimeMs;
m_interpolatedTime = interpolatedTimeMs; m_interpolatedTime = interpolatedTimeMs;

View File

@@ -12,8 +12,9 @@
#ifndef BLACKMISC_SIMULATION_INTERPOLATORSPLINE_H #ifndef BLACKMISC_SIMULATION_INTERPOLATORSPLINE_H
#define BLACKMISC_SIMULATION_INTERPOLATORSPLINE_H #define BLACKMISC_SIMULATION_INTERPOLATORSPLINE_H
#include "blackmisc/simulation/interpolator.h" #include "interpolator.h"
#include "blackmisc/simulation/interpolationlogger.h" #include "interpolationlogger.h"
#include "interpolant.h"
#include "blackmisc/aviation/aircraftsituation.h" #include "blackmisc/aviation/aircraftsituation.h"
#include "blackmisc/blackmiscexport.h" #include "blackmisc/blackmiscexport.h"
#include <QString> #include <QString>
@@ -44,49 +45,42 @@ namespace BlackMisc
//! 3 coordinates for spline interpolation @{ //! 3 coordinates for spline interpolation @{
std::array<double, 3> x, y, z, a, gnd, t, dx, dy, dz, da, dgnd; std::array<double, 3> x, y, z, a, gnd, t, dx, dy, dz, da, dgnd;
//! Array size
int size() const { return x.size(); }
//! @} //! @}
}; };
//! Cubic function that performs the actual interpolation //! Cubic function that performs the actual interpolation
class BLACKMISC_EXPORT Interpolant class BLACKMISC_EXPORT CInterpolant : public IInterpolant
{ {
public: public:
//! Default //! Default
Interpolant() : m_pa(PosArray::zeroPosArray()) {} CInterpolant() : m_pa(PosArray::zeroPosArray()) {}
//! Constructor //! Constructor
Interpolant( CInterpolant(const PosArray &pa, const PhysicalQuantities::CLengthUnit &altitudeUnit, const CInterpolatorPbh &pbh);
const PosArray &pa, const PhysicalQuantities::CLengthUnit &altitudeUnit, const CInterpolatorPbh &pbh) :
m_pa(pa), m_altitudeUnit(altitudeUnit), m_pbh(pbh) {}
//! Perform the interpolation //! Perform the interpolation
Aviation::CAircraftSituation interpolatePositionAndAltitude(const Aviation::CAircraftSituation &currentSituation, bool interpolateGndFactor) const; Aviation::CAircraftSituation interpolatePositionAndAltitude(const Aviation::CAircraftSituation &currentSituation, bool interpolateGndFactor) const;
//! Interpolator for pitch, bank, heading, groundspeed
const CInterpolatorPbh &pbh() const { return m_pbh; }
//! Old situation //! Old situation
const Aviation::CAircraftSituation &getOldSituation() const { return pbh().getOldSituation(); } const Aviation::CAircraftSituation &getOldSituation() const { return pbh().getOldSituation(); }
//! New situation //! New situation
const Aviation::CAircraftSituation &getNewSituation() const { return pbh().getNewSituation(); } const Aviation::CAircraftSituation &getNewSituation() const { return pbh().getNewSituation(); }
//! "Real time" representing the interpolated situation
qint64 getInterpolatedTime() const { return m_interpolatedTime; }
//! Set the time values //! Set the time values
void setTimes(qint64 currentTimeMs, double timeFraction, qint64 interpolatedTimeMs); void setTimes(qint64 currentTimeMs, double timeFraction, qint64 interpolatedTimeMs);
private: private:
PosArray m_pa; //! current positions array, latest values last PosArray m_pa; //! current positions array, latest values last
PhysicalQuantities::CLengthUnit m_altitudeUnit; PhysicalQuantities::CLengthUnit m_altitudeUnit;
CInterpolatorPbh m_pbh;
qint64 m_currentTimeMsSinceEpoc { -1 }; qint64 m_currentTimeMsSinceEpoc { -1 };
qint64 m_interpolatedTime { -1 }; //!< represented "real time" at interpolated situation
}; };
//! Strategy used by CInterpolator::getInterpolatedSituation //! Strategy used by CInterpolator::getInterpolatedSituation
Interpolant getInterpolant(qint64 currentTimeMsSinceEpoc, CInterpolant getInterpolant(qint64 currentTimeMsSinceEpoc,
const CInterpolationAndRenderingSetupPerCallsign &setup, CInterpolationStatus &status, SituationLog &log); const CInterpolationAndRenderingSetupPerCallsign &setup, CInterpolationStatus &status, SituationLog &log);
private: private:
@@ -110,7 +104,7 @@ namespace BlackMisc
qint64 m_prevSampleTime = 0; //!< previous sample "real time" qint64 m_prevSampleTime = 0; //!< previous sample "real time"
qint64 m_nextSampleTime = 0; //!< next sample "real time" qint64 m_nextSampleTime = 0; //!< next sample "real time"
std::array<Aviation::CAircraftSituation, 3> m_s; //!< used situations std::array<Aviation::CAircraftSituation, 3> m_s; //!< used situations
Interpolant m_interpolant; CInterpolant m_interpolant;
}; };
} // ns } // ns
} // ns } // ns