mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-12 15:25:34 +08:00
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:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user