From c64851aeba9938b4fd03bcb42f8e1fb0b63fc062 Mon Sep 17 00:00:00 2001 From: Mathew Sutcliffe Date: Sun, 5 Jun 2016 14:09:50 +0100 Subject: [PATCH] refs #570 Removed the hardcoded 6 seconds, interpolator honors the offsets of the situations. --- src/blackcore/interpolator.h | 2 -- src/blackcore/interpolatorlinear.cpp | 17 ++++++++++------- src/plugins/simulator/fsx/simulatorfsx.cpp | 2 +- tests/blackcore/testinterpolator.cpp | 19 +++++++++++-------- tests/blackcore/testinterpolator.h | 2 +- 5 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/blackcore/interpolator.h b/src/blackcore/interpolator.h index 69f43ea8b..f331e8ca0 100644 --- a/src/blackcore/interpolator.h +++ b/src/blackcore/interpolator.h @@ -80,8 +80,6 @@ namespace BlackCore //! Enable debug messages void enableDebugMessages(bool enabled); - static const qint64 TimeOffsetMs = 6000; //!< offset for interpolation - protected: //! Constructor IInterpolator(BlackMisc::Simulation::IRemoteAircraftProvider *provider, const QString &objectName, QObject *parent); diff --git a/src/blackcore/interpolatorlinear.cpp b/src/blackcore/interpolatorlinear.cpp index 4f8e9357d..388598b18 100644 --- a/src/blackcore/interpolatorlinear.cpp +++ b/src/blackcore/interpolatorlinear.cpp @@ -49,19 +49,22 @@ namespace BlackCore // data, split situations by time if (currentTimeMsSinceEpoc < 0) { currentTimeMsSinceEpoc = QDateTime::currentMSecsSinceEpoch(); } - qint64 splitTimeMsSinceEpoch = currentTimeMsSinceEpoc - TimeOffsetMs; // \todo needs to be variable in the future with interim positions const auto situations = remoteAircraftSituations(callsign); + // find the first situation not in the correct order, keep only the situations before that one + auto end = std::is_sorted_until(situations.begin(), situations.end(), [](auto &&a, auto &&b) { return b.getAdjustedMSecsSinceEpoch() < a.getAdjustedMSecsSinceEpoch(); }); + auto validSituations = makeRange(situations.begin(), end); + // find the first situation earlier than the current time - auto pivot = std::partition_point(situations.begin(), situations.end(), [ = ](auto &&s) { return s.getMSecsSinceEpoch() > currentTimeMsSinceEpoc; }); - auto situationsNewer = makeRange(situations.begin(), pivot); - auto situationsOlder = makeRange(pivot, situations.end()); + auto pivot = std::partition_point(validSituations.begin(), validSituations.end(), [ = ](auto &&s) { return s.getAdjustedMSecsSinceEpoch() > currentTimeMsSinceEpoc; }); + auto situationsNewer = makeRange(validSituations.begin(), pivot); + auto situationsOlder = makeRange(pivot, validSituations.end()); // interpolation situations CAircraftSituation oldSituation; CAircraftSituation newSituation; - // latest first, now 00:26 -> 00:26 - 6000ms -> 00:20 split time + // latest first, now 00:20 split time // time pos // 00:25 10 newer // 00:20 11 newer @@ -96,13 +99,13 @@ namespace BlackCore status.interpolationSucceeded = true; // Time between start and end packet - double deltaTime = oldSituation.absMsecsTo(newSituation); + double deltaTime = std::abs(oldSituation.getAdjustedMSecsSinceEpoch() - newSituation.getAdjustedMSecsSinceEpoch()); // Fraction of the deltaTime, ideally [0.0 - 1.0] // < 0 should not happen due to the split, > 1 can happen if new values are delayed beyond split time // 1) values > 1 mean extrapolation // 2) values > 2 mean no new situations coming in - double distanceToSplitTime = newSituation.getMSecsSinceEpoch() - splitTimeMsSinceEpoch; + double distanceToSplitTime = newSituation.getAdjustedMSecsSinceEpoch() - currentTimeMsSinceEpoc; double simulationTimeFraction = 1 - (distanceToSplitTime / deltaTime); if (simulationTimeFraction > 2.0) { diff --git a/src/plugins/simulator/fsx/simulatorfsx.cpp b/src/plugins/simulator/fsx/simulatorfsx.cpp index 80a8a4096..09af64fd9 100644 --- a/src/plugins/simulator/fsx/simulatorfsx.cpp +++ b/src/plugins/simulator/fsx/simulatorfsx.cpp @@ -656,7 +656,7 @@ namespace BlackSimPlugin CAircraftPartsList parts; if (partsStatus.supportsParts) { - this->m_interpolator->getPartsBeforeTime(callsign, currentTimestamp - this->m_interpolator->TimeOffsetMs, partsStatus); + this->m_interpolator->getPartsBeforeTime(callsign, currentTimestamp, partsStatus); } if (interpolatorStatus.allTrue()) diff --git a/tests/blackcore/testinterpolator.cpp b/tests/blackcore/testinterpolator.cpp index 09a8aafc6..d6a25df88 100644 --- a/tests/blackcore/testinterpolator.cpp +++ b/tests/blackcore/testinterpolator.cpp @@ -62,10 +62,11 @@ namespace BlackCoreTest // fixed time so everything can be debugged const qint64 ts = 1425000000000; // QDateTime::currentMSecsSinceEpoch(); const qint64 deltaT = 5000; // ms + const qint64 offset = 5000; CCallsign cs("SWIFT"); for (int i = 0; i < IRemoteAircraftProvider::MaxSituationsPerCallsign; i++) { - CAircraftSituation s(getTestSituation(cs, i, ts, deltaT)); + CAircraftSituation s(getTestSituation(cs, i, ts, deltaT, offset)); // check height above ground CLength hag = (s.getAltitude() - s.geodeticHeight()); @@ -90,11 +91,11 @@ namespace BlackCoreTest IInterpolator::InterpolationStatus status; double latOld = 360.0; double lngOld = 360.0; - for (qint64 currentTime = ts - 2 * deltaT; currentTime < ts; currentTime += (deltaT / 20)) + for (qint64 currentTime = ts - 2 * deltaT + offset; currentTime < ts + offset; currentTime += (deltaT / 20)) { // This will use time range - // from: ts - 2* deltaT - IInterpolator::TimeOffsetMs - // to: ts - IInterpolator::TimeOffsetMs + // from: ts - 2 * deltaT + offset + // to: ts + offset CAircraftSituation currentSituation(interpolator.getInterpolatedSituation (cs, currentTime, false, status) ); @@ -103,6 +104,7 @@ namespace BlackCoreTest double latDeg = currentSituation.getPosition().latitude().valueRounded(CAngleUnit::deg(), 5); double lngDeg = currentSituation.getPosition().longitude().valueRounded(CAngleUnit::deg(), 5); QVERIFY2(latDeg < latOld && lngDeg < lngOld, "Values shall decrease"); + QVERIFY2(latDeg >= 0 && latDeg <= IRemoteAircraftProvider::MaxSituationsPerCallsign, "Values shall be in range"); latOld = latDeg; lngOld = lngDeg; } @@ -120,11 +122,11 @@ namespace BlackCoreTest for (int loops = 0; loops < 20; loops++) { - for (qint64 currentTime = startTimeMsSinceEpoch; currentTime < ts; currentTime += (deltaT / 20)) + for (qint64 currentTime = startTimeMsSinceEpoch + offset; currentTime < ts + offset; currentTime += (deltaT / 20)) { // This will use range - // from: ts - 2* deltaT - IInterpolator::TimeOffsetMs - // to: ts - IInterpolator::TimeOffsetMs + // from: ts - 2* deltaT + offset + // to: ts + offset CAircraftSituation currentSituation(interpolator.getInterpolatedSituation (cs, currentTime, false, status) ); @@ -155,7 +157,7 @@ namespace BlackCoreTest qDebug() << timeMs << "ms" << "for" << fetchedParts << "fetched parts"; } - CAircraftSituation CTestInterpolator::getTestSituation(const CCallsign &callsign, int number, qint64 ts, qint64 deltaT) + CAircraftSituation CTestInterpolator::getTestSituation(const CCallsign &callsign, int number, qint64 ts, qint64 deltaT, qint64 offset) { CAltitude a(number, CAltitude::MeanSeaLevel, CLengthUnit::m()); CLatitude lat(number, CAngleUnit::deg()); @@ -168,6 +170,7 @@ namespace BlackCoreTest CCoordinateGeodetic c(lat, lng, height); CAircraftSituation s(callsign, c, a, heading, pitch, bank, gs); s.setMSecsSinceEpoch(ts - deltaT * number); // values in past + s.setTimeOffsetMs(offset); return s; } diff --git a/tests/blackcore/testinterpolator.h b/tests/blackcore/testinterpolator.h index 39c0b13e4..b62418021 100644 --- a/tests/blackcore/testinterpolator.h +++ b/tests/blackcore/testinterpolator.h @@ -45,7 +45,7 @@ namespace BlackCoreTest private: //! Test situation for testing - static BlackMisc::Aviation::CAircraftSituation getTestSituation(const BlackMisc::Aviation::CCallsign &callsign, int number, qint64 ts, qint64 deltaT); + static BlackMisc::Aviation::CAircraftSituation getTestSituation(const BlackMisc::Aviation::CCallsign &callsign, int number, qint64 ts, qint64 deltaT, qint64 offset); //! Test parts static BlackMisc::Aviation::CAircraftParts getTestParts(int number, qint64 ts, qint64 deltaT);