Ref T243, track the interpolated time ("real time" of interpolated situation)

* keep that time in interpolant
* set it for current position
* some comments and renamings
This commit is contained in:
Klaus Basan
2018-02-01 19:17:26 +01:00
parent 6a2435074c
commit f99e82ac24
5 changed files with 59 additions and 22 deletions

View File

@@ -82,7 +82,6 @@ namespace BlackMisc
// data, split situations by time
if (currentTimeMsSinceEpoc < 0) { currentTimeMsSinceEpoc = QDateTime::currentMSecsSinceEpoch(); }
currentSituation.setMSecsSinceEpoch(currentTimeMsSinceEpoc);
// interpolant function from derived class
// CInterpolatorLinear::Interpolant or CInterpolatorSpline::Interpolant
@@ -98,6 +97,7 @@ namespace BlackMisc
// use derived interpolant function
currentSituation.setPosition(interpolant.interpolatePosition(setup, hints));
currentSituation.setAltitude(interpolant.interpolateAltitude(setup, hints));
currentSituation.setMSecsSinceEpoch(interpolant.getInterpolatedTime());
// PBH before ground so we can use PBH in guessing ground
if (setup.isForcingFullInterpolation() || hints.isVtolAircraft() || status.isInterpolated())
@@ -155,7 +155,7 @@ namespace BlackMisc
}
// logging
if (m_logger && hints.isLoggingInterpolation())
if (doLogging)
{
log.tsCurrent = currentTimeMsSinceEpoc;
log.callsign = m_callsign;

View File

@@ -40,10 +40,11 @@ namespace BlackMisc
m_pbh(0, situation, situation)
{}
CInterpolatorLinear::Interpolant::Interpolant(const CAircraftSituation &situation1, const CAircraftSituation &situation2, double timeFraction) :
CInterpolatorLinear::Interpolant::Interpolant(const CAircraftSituation &situation1, const CAircraftSituation &situation2, double timeFraction, qint64 interpolatedTime) :
m_situationsAvailable(2),
m_oldSituation(situation1), m_newSituation(situation2),
m_simulationTimeFraction(timeFraction),
m_interpolatedTime(interpolatedTime),
m_pbh(m_simulationTimeFraction, situation1, situation2)
{}
@@ -130,12 +131,13 @@ namespace BlackMisc
const double distanceToSplitTimeMs = newSituation.getAdjustedMSecsSinceEpoch() - currentTimeMsSinceEpoc;
const double simulationTimeFraction = qMax(1.0 - (distanceToSplitTimeMs / sampleDeltaTimeMs), 0.0);
const double deltaTimeFractionMs = sampleDeltaTimeMs * simulationTimeFraction;
const qint64 interpolatedTime = oldSituation.getMSecsSinceEpoch() + deltaTimeFractionMs;
currentSituation.setTimeOffsetMs(oldSituation.getTimeOffsetMs() + (newSituation.getTimeOffsetMs() - oldSituation.getTimeOffsetMs()) * simulationTimeFraction);
currentSituation.setMSecsSinceEpoch(oldSituation.getMSecsSinceEpoch() + deltaTimeFractionMs);
currentSituation.setMSecsSinceEpoch(interpolatedTime);
status.setInterpolatedAndCheckSituation(true, currentSituation);
if (this->hasAttachedLogger())
if (this->hasAttachedLogger() && hints.isLoggingInterpolation())
{
log.tsCurrent = currentTimeMsSinceEpoc;
log.deltaSampleTimesMs = sampleDeltaTimeMs;
@@ -147,7 +149,7 @@ namespace BlackMisc
log.interpolationSituations.push_back(oldSituation); // oldest at back
}
return { oldSituation, newSituation, simulationTimeFraction };
return { oldSituation, newSituation, simulationTimeFraction, interpolatedTime };
}
CCoordinateGeodetic CInterpolatorLinear::Interpolant::interpolatePosition(const CInterpolationAndRenderingSetup &setup, const CInterpolationHints &hints) const

View File

@@ -44,7 +44,7 @@ namespace BlackMisc
//! Constructor
//! @{
Interpolant(const Aviation::CAircraftSituation &situation);
Interpolant(const Aviation::CAircraftSituation &situation1, const Aviation::CAircraftSituation &situation2, double timeFraction);
Interpolant(const Aviation::CAircraftSituation &situation1, const Aviation::CAircraftSituation &situation2, double timeFraction, qint64 interpolatedTime);
//! @}
//! Perform the interpolation
@@ -62,11 +62,15 @@ namespace BlackMisc
//! New situation
const Aviation::CAircraftSituation &getNewSituation() const { return m_newSituation; }
//! "Real time" representing the interpolated situation
qint64 getInterpolatedTime() const { return m_interpolatedTime; }
private:
int m_situationsAvailable = 0;
Aviation::CAircraftSituation m_oldSituation;
Aviation::CAircraftSituation m_newSituation;
double m_simulationTimeFraction = 0.0; //!< 0..1
qint64 m_interpolatedTime = 0; //!< "Real time "of interpolated situation
const CInterpolatorPbh m_pbh;
};

View File

@@ -102,9 +102,13 @@ namespace BlackMisc
Q_UNUSED(setup);
// recalculate derivatives only if they changed
if (currentTimeMsSinceEpoc > m_nextSampleTime)
if (currentTimeMsSinceEpoc > m_nextSampleAdjustedTime)
{
// find the first situation not in the correct order, keep only the situations before that one
//! \todo KB 2-2018, IMHO the sorting by adjusted times is wrong. we should sort by received time
// when mixing fast/slow updates, the postion is represented when it is sent, not when it is used
// see example below
// so why do we check here only, and do not sort
const auto end = std::is_sorted_until(m_aircraftSituations.begin(), m_aircraftSituations.end(), [](auto && a, auto && b) { return b.getAdjustedMSecsSinceEpoch() < a.getAdjustedMSecsSinceEpoch(); });
const auto validSituations = makeRange(m_aircraftSituations.begin(), end);
@@ -152,16 +156,37 @@ namespace BlackMisc
pa.dz = getDerivatives(pa.t, pa.z);
pa.da = getDerivatives(pa.t, pa.a);
m_prevSampleTime = situationsOlder.begin()->getAdjustedMSecsSinceEpoch();
m_nextSampleTime = (situationsNewer.end() - 1)->getAdjustedMSecsSinceEpoch();
m_prevSampleAdjustedTime = situationsOlder.begin()->getAdjustedMSecsSinceEpoch();
m_nextSampleAdjustedTime = (situationsNewer.end() - 1)->getAdjustedMSecsSinceEpoch();
m_prevSampleTime = situationsOlder.begin()->getMSecsSinceEpoch();
m_nextSampleTime = (situationsNewer.end() - 1)->getMSecsSinceEpoch();
m_interpolant = Interpolant(pa, situationsOlder.begin()->getAltitude().getUnit(), { *situationsOlder.begin(), *(situationsNewer.end() - 1) });
}
const double dt1 = static_cast<double>(currentTimeMsSinceEpoc - m_prevSampleTime);
const double dt2 = static_cast<double>(m_nextSampleTime - m_prevSampleTime);
// Example:
// prev.sample time 5 (received at 0) , next sample time 10 (received at 5)
// cur.time 6: dt1=6-5=1, dt2=5 => fraction 1/5
// cur.time 9: dt1=9-5=4, dt2=5 => fraction 4/5
//
// we use different offset times for interim pos. updates
// prev.sample time 5 (received at 0) , 7/r:5, 10 (rec. at 5)
// cur.time 6: dt1=6-5=1, dt2=7-5 => fraction 1/2
// cur.time 9: dt1=9-7=2, dt2=10-7=3 => fraction 2/3
// we use different offset times for fast pos. updates
const double dt1 = static_cast<double>(currentTimeMsSinceEpoc - m_prevSampleAdjustedTime);
const double dt2 = static_cast<double>(m_nextSampleAdjustedTime - m_prevSampleAdjustedTime);
const double timeFraction = dt1 / dt2;
if (this->hasAttachedLogger())
// is that correct with dt2, or would it be
// m_nextSampleTime - m_prevSampleTime
// as long as the offset time is constant, it does not matter
const qint64 interpolatedTime = m_prevSampleTime + timeFraction * dt2;
// time fraction is expected between 0-1
status.setInterpolated(true);
m_interpolant.setTimes(currentTimeMsSinceEpoc, timeFraction, interpolatedTime);
if (this->hasAttachedLogger() && hints.isLoggingInterpolation())
{
log.interpolationSituations.push_back(m_s[0]);
log.interpolationSituations.push_back(m_s[1]);
@@ -169,11 +194,10 @@ namespace BlackMisc
log.interpolator = 's';
log.deltaSampleTimesMs = dt2;
log.simulationTimeFraction = timeFraction;
log.tsInterpolated = log.newestInterpolationSituation().getMSecsSinceEpoch(); // without offset
log.noNetworkSituations = m_aircraftSituations. size();
log.tsInterpolated = interpolatedTime; // without offsets
}
status.setInterpolated(true);
m_interpolant.setTimes(currentTimeMsSinceEpoc, timeFraction);
return m_interpolant;
}
@@ -200,9 +224,10 @@ namespace BlackMisc
return CAltitude(newA, m_altitudeUnit);
}
void CInterpolatorSpline::Interpolant::setTimes(qint64 currentTimeMs, double timeFraction)
void CInterpolatorSpline::Interpolant::setTimes(qint64 currentTimeMs, double timeFraction, qint64 interpolatedTimeMs)
{
m_currentTimeMsSinceEpoc = currentTimeMs;
m_interpolatedTime = interpolatedTimeMs;
m_pbh.setTimeFraction(timeFraction);
}
@@ -210,8 +235,8 @@ namespace BlackMisc
{
for (int i = 0; i < 3; i++)
{
x[i] = 0; y[i] = 0; z[i] = 0;
a[i] = 0; t[i] = 0;
x[i] = 0; y[i] = 0; z[i] = 0;
a[i] = 0; t[i] = 0;
dx[i] = 0; dy[i] = 0; dz[i] = 0;
da[i] = 0;
}

View File

@@ -76,14 +76,18 @@ namespace BlackMisc
//! New situation
const Aviation::CAircraftSituation &getNewSituation() const { return pbh().getNewSituation(); }
//! "Real time" representing the interpolated situation
qint64 getInterpolatedTime() const { return m_interpolatedTime; }
//! Set the time values
void setTimes(qint64 currentTimeMs, double timeFraction);
void setTimes(qint64 currentTimeMs, double timeFraction, qint64 interpolatedTimeMs);
private:
PosArray m_pa;
PhysicalQuantities::CLengthUnit m_altitudeUnit;
CInterpolatorPbh m_pbh;
qint64 m_currentTimeMsSinceEpoc { 0 };
qint64 m_interpolatedTime { 0 }; //!< represented "real time" at interpolated situation
};
//! Strategy used by CInterpolator::getInterpolatedSituation
@@ -93,8 +97,10 @@ namespace BlackMisc
const CInterpolationHints &hints, CInterpolationStatus &status, CInterpolationLogger::SituationLog &log);
private:
qint64 m_prevSampleTime = 0;
qint64 m_nextSampleTime = 0;
qint64 m_prevSampleAdjustedTime = 0; //!< previous sample time + offset
qint64 m_nextSampleAdjustedTime = 0; //!< previous sample time + offset
qint64 m_prevSampleTime = 0; //!< previous sample "real time"
qint64 m_nextSampleTime = 0; //!< next sample "real time"
std::array<Aviation::CAircraftSituation, 3> m_s;
Interpolant m_interpolant;
};