From 181ed36f3daf57435f4d4f68196f40abff6062e6 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Fri, 1 Jun 2018 18:02:11 +0200 Subject: [PATCH] Ref T270, interpolator optimization by passing aircraft number Rational: Except for FS9 we interpolate all aircraft in one loop at the same time. This can cause that some steps are always done at the same time for all aircraft of that loop. By passing the number we can more equally distribute such tasks, avoiding peaks. --- src/blackmisc/simulation/interpolator.cpp | 37 ++++++++++++------- src/blackmisc/simulation/interpolator.h | 17 ++++++--- .../simulation/interpolatormulti.cpp | 6 +-- src/blackmisc/simulation/interpolatormulti.h | 2 +- .../simulation/interpolatorspline.cpp | 4 +- .../simulator/emulated/simulatoremulated.cpp | 3 +- src/plugins/simulator/fs9/fs9client.cpp | 2 +- .../simulator/fsxcommon/simconnectobject.cpp | 4 +- .../simulator/fsxcommon/simconnectobject.h | 2 +- .../fsxcommon/simulatorfsxcommon.cpp | 3 +- .../simulator/xplane/simulatorxplane.cpp | 5 ++- .../simulator/xplane/xplanempaircraft.cpp | 4 +- .../simulator/xplane/xplanempaircraft.h | 3 +- 13 files changed, 55 insertions(+), 37 deletions(-) diff --git a/src/blackmisc/simulation/interpolator.cpp b/src/blackmisc/simulation/interpolator.cpp index 3d991871e..e8f8f3667 100644 --- a/src/blackmisc/simulation/interpolator.cpp +++ b/src/blackmisc/simulation/interpolator.cpp @@ -142,18 +142,19 @@ namespace BlackMisc } template - CInterpolationResult CInterpolator::getInterpolation(qint64 currentTimeSinceEpoc, const CInterpolationAndRenderingSetupPerCallsign &setup) + CInterpolationResult CInterpolator::getInterpolation(qint64 currentTimeSinceEpoc, const CInterpolationAndRenderingSetupPerCallsign &setup, int aircraftNumber) { CInterpolationResult result; do { // make sure we can also interpolate parts only (needed in unit tests) - const bool init = this->initIniterpolationStepData(currentTimeSinceEpoc, setup); + if (aircraftNumber < 0) { aircraftNumber = 0; } + const bool init = this->initIniterpolationStepData(currentTimeSinceEpoc, setup, aircraftNumber); if (!m_unitTest && !init) { break; } // failure in real scenarios, unit tests move on Q_ASSERT_X(m_currentTimeMsSinceEpoch > 0, Q_FUNC_INFO, "No valid timestamp, interpolator initialized?"); const CAircraftSituation interpolatedSituation = this->getInterpolatedSituation(); - const CAircraftParts interpolatedParts = this->getInterpolatedOrGuessedParts(); + const CAircraftParts interpolatedParts = this->getInterpolatedOrGuessedParts(aircraftNumber); result.setValues(interpolatedSituation, interpolatedParts); } @@ -168,12 +169,12 @@ namespace BlackMisc { if (m_currentSituations.isEmpty()) { - m_lastInterpolation = CAircraftSituation::null(); + m_lastSituation = CAircraftSituation::null(); return CAircraftSituation::null(); } const CAircraftSituation latest = m_currentSituations.front(); - CAircraftSituation currentSituation = m_lastInterpolation.isNull() ? latest : m_lastInterpolation; + CAircraftSituation currentSituation = m_lastSituation.isNull() ? latest : m_lastSituation; if (currentSituation.getCallsign() != m_callsign) { BLACK_VERIFY_X(false, Q_FUNC_INFO, "Wrong callsign"); @@ -246,7 +247,7 @@ namespace BlackMisc } // bye - m_lastInterpolation = currentSituation; + m_lastSituation = currentSituation; return currentSituation; } @@ -286,8 +287,14 @@ namespace BlackMisc } template - CAircraftParts CInterpolator::getInterpolatedOrGuessedParts() + CAircraftParts CInterpolator::getInterpolatedOrGuessedParts(int aircraftNumber) { + Q_ASSERT_X(m_partsToSituationInterpolationRatio >= 1 && m_partsToSituationInterpolationRatio < 11, Q_FUNC_INFO, "Wrong ratio"); + if (!m_unitTest && !m_lastParts.isNull() && ((m_interpolatedSituationsCounter + aircraftNumber) % m_partsToSituationInterpolationRatio) == 0) + { + return m_lastParts; + } + CAircraftParts parts; if (m_currentSetup.isAircraftPartsEnabled()) { @@ -300,9 +307,11 @@ namespace BlackMisc if (!m_currentPartsStatus.isSupportingParts()) { // check if model has been thru model matching - parts.guessParts(m_lastInterpolation, m_currentSituationChange, m_model); + parts.guessParts(m_lastSituation, m_currentSituationChange, m_model); this->logParts(parts, 0, false); } + + m_lastParts = parts; return parts; } @@ -335,13 +344,13 @@ namespace BlackMisc QStringLiteral(" parts: ") % QString::number(this->remoteAircraftPartsCount(m_callsign)) % QStringLiteral(" 1st interpolation: ") % - boolToYesNo(m_lastInterpolation.isNull()); + boolToYesNo(m_lastSituation.isNull()); } template void CInterpolator::resetLastInterpolation() { - m_lastInterpolation.setNull(); + m_lastSituation.setNull(); } template @@ -361,12 +370,12 @@ namespace BlackMisc } template - bool CInterpolator::initIniterpolationStepData(qint64 currentTimeSinceEpoc, const CInterpolationAndRenderingSetupPerCallsign &setup) + bool CInterpolator::initIniterpolationStepData(qint64 currentTimeSinceEpoc, const CInterpolationAndRenderingSetupPerCallsign &setup, int aircraftNumber) { Q_ASSERT_X(!m_callsign.isEmpty(), Q_FUNC_INFO, "Missing callsign"); const qint64 lastModifed = this->situationsLastModified(m_callsign); - const bool slowUpdateStep = ((m_interpolatedSituationsCounter % 25) == 0); // flag when parts are updated, which need not to be updated every time + const bool slowUpdateStep = (((m_interpolatedSituationsCounter + aircraftNumber) % 25) == 0); // flag when parts are updated, which need not to be updated every time const bool changedSetup = m_currentSetup != setup; const bool changedSituations = lastModifed > m_situationsLastModified; @@ -392,7 +401,7 @@ namespace BlackMisc if (m_currentSituations.isEmpty()) { const bool inRange = this->isAircraftInRange(m_callsign); - m_lastInterpolation = CAircraftSituation::null(); // no interpolation possible for that step + m_lastSituation = CAircraftSituation::null(); // no interpolation possible for that step m_currentInterpolationStatus.setExtraInfo(inRange ? QString("No situations, but remote aircraft '%1'").arg(m_callsign.asString()) : QString("Unknown remote aircraft: '%1'").arg(m_callsign.asString())); @@ -400,7 +409,7 @@ namespace BlackMisc else { success = true; - m_interpolatedSituationsCounter++; + m_interpolatedSituationsCounter++; // counter updated in initIniterpolationStepData // with the latest updates of T243 the order and the offsets are supposed to be correct // so even mixing fast/slow updates shall work diff --git a/src/blackmisc/simulation/interpolator.h b/src/blackmisc/simulation/interpolator.h index 8a9a4906f..5255fc26a 100644 --- a/src/blackmisc/simulation/interpolator.h +++ b/src/blackmisc/simulation/interpolator.h @@ -167,10 +167,10 @@ namespace BlackMisc static const CLogCategoryList &getLogCategories(); //! Latest interpolation result - const Aviation::CAircraftSituation &getLastInterpolatedSituation() const { return m_lastInterpolation; } + const Aviation::CAircraftSituation &getLastInterpolatedSituation() const { return m_lastSituation; } //! Parts and situation interpolated - CInterpolationResult getInterpolation(qint64 currentTimeSinceEpoc, const CInterpolationAndRenderingSetupPerCallsign &setup); + CInterpolationResult getInterpolation(qint64 currentTimeSinceEpoc, const CInterpolationAndRenderingSetupPerCallsign &setup, int aircraftNumber = -1); //! Takes input between 0 and 1 and returns output between 0 and 1 smoothed with an S-shaped curve. //! @@ -214,7 +214,10 @@ namespace BlackMisc CInterpolationLogger *logger); //! Inits all data for this current interpolation step - bool initIniterpolationStepData(qint64 currentTimeSinceEpoc, const CInterpolationAndRenderingSetupPerCallsign &setup); + //! \param currentTimeSinceEpoc + //! \param setup + //! \param aircraftNumber passing the aircraft number allows to equally distribute among the steps and not to do it always together for all aircraft + bool initIniterpolationStepData(qint64 currentTimeSinceEpoc, const CInterpolationAndRenderingSetupPerCallsign &setup, int aircraftNumber); //! Current interpolated situation Aviation::CAircraftSituation getInterpolatedSituation(); @@ -223,7 +226,7 @@ namespace BlackMisc Aviation::CAircraftParts getInterpolatedParts(); //! Interpolated parts, if not available guessed parts - Aviation::CAircraftParts getInterpolatedOrGuessedParts(); + Aviation::CAircraftParts getInterpolatedOrGuessedParts(int aircraftNumber); //! Center of gravity const PhysicalQuantities::CLength &getModelCG() const { return m_model.getCG(); } @@ -245,12 +248,14 @@ namespace BlackMisc CInterpolationAndRenderingSetupPerCallsign m_currentSetup; //!< used setup CInterpolationStatus m_currentInterpolationStatus; //!< this step's status CPartsStatus m_currentPartsStatus; //!< this step's status - Aviation::CAircraftSituation m_lastInterpolation { Aviation::CAircraftSituation::null() }; //!< latest interpolation + int m_partsToSituationInterpolationRatio = 2; //!< ratio between parts and situation interpolation, 1..always, 2..every 2nd situation + Aviation::CAircraftSituation m_lastSituation { Aviation::CAircraftSituation::null() }; //!< latest interpolation + Aviation::CAircraftParts m_lastParts { Aviation::CAircraftParts::null() }; //!< latest parts PhysicalQuantities::CLength m_currentSceneryOffset { PhysicalQuantities::CLength::null() }; //!< calculated scenery offset if any qint64 m_situationsLastModified { -1 }; //!< when situations were last modified qint64 m_situationsLastModifiedUsed { -1 }; //!< interpolant 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: used for statistics, every n-th interpolation .... bool m_unitTest = false; //!< mark as unit test diff --git a/src/blackmisc/simulation/interpolatormulti.cpp b/src/blackmisc/simulation/interpolatormulti.cpp index 4840c3dd6..76dc105cd 100644 --- a/src/blackmisc/simulation/interpolatormulti.cpp +++ b/src/blackmisc/simulation/interpolatormulti.cpp @@ -22,12 +22,12 @@ namespace BlackMisc m_linear(callsign, p1, p2, p3, logger) {} - CInterpolationResult CInterpolatorMulti::getInterpolation(qint64 currentTimeSinceEpoc, const CInterpolationAndRenderingSetupPerCallsign &setup) + CInterpolationResult CInterpolatorMulti::getInterpolation(qint64 currentTimeSinceEpoc, const CInterpolationAndRenderingSetupPerCallsign &setup, int aircraftNumber) { switch (setup.getInterpolatorMode()) { - case CInterpolationAndRenderingSetupBase::Linear: return m_linear.getInterpolation(currentTimeSinceEpoc, setup); - case CInterpolationAndRenderingSetupBase::Spline: return m_spline.getInterpolation(currentTimeSinceEpoc, setup); + case CInterpolationAndRenderingSetupBase::Linear: return m_linear.getInterpolation(currentTimeSinceEpoc, setup, aircraftNumber); + case CInterpolationAndRenderingSetupBase::Spline: return m_spline.getInterpolation(currentTimeSinceEpoc, setup, aircraftNumber); default: break; } diff --git a/src/blackmisc/simulation/interpolatormulti.h b/src/blackmisc/simulation/interpolatormulti.h index 18c7caa9a..baf8a5c6a 100644 --- a/src/blackmisc/simulation/interpolatormulti.h +++ b/src/blackmisc/simulation/interpolatormulti.h @@ -29,7 +29,7 @@ namespace BlackMisc CInterpolationLogger *logger = nullptr); //! \copydoc CInterpolator::getInterpolation - CInterpolationResult getInterpolation(qint64 currentTimeSinceEpoc, const CInterpolationAndRenderingSetupPerCallsign &setup); + CInterpolationResult getInterpolation(qint64 currentTimeSinceEpoc, const CInterpolationAndRenderingSetupPerCallsign &setup, int aircraftNumber); //! \copydoc CInterpolator::getLastInterpolatedSituation const Aviation::CAircraftSituation &getLastInterpolatedSituation(CInterpolationAndRenderingSetupBase::InterpolatorMode mode) const; diff --git a/src/blackmisc/simulation/interpolatorspline.cpp b/src/blackmisc/simulation/interpolatorspline.cpp index 472124524..fd84f04c7 100644 --- a/src/blackmisc/simulation/interpolatorspline.cpp +++ b/src/blackmisc/simulation/interpolatorspline.cpp @@ -103,7 +103,7 @@ namespace BlackMisc // m_s[0] .. oldest -> m_[2] .. latest // general idea, we interpolate from current situation -> latest situation - if (m_lastInterpolation.isNull()) + if (m_lastSituation.isNull()) { if (!m_currentSituations.isEmpty()) { @@ -117,7 +117,7 @@ namespace BlackMisc } else { - m_s[0] = m_s[1] = m_s[2] = m_lastInterpolation; // current + m_s[0] = m_s[1] = m_s[2] = m_lastSituation; // current m_s[0].addMsecs(-CFsdSetup::c_positionTimeOffsetMsec); // oldest m_s[2].addMsecs(CFsdSetup::c_positionTimeOffsetMsec); // latest if (m_currentSituations.isEmpty()) { return true; } diff --git a/src/plugins/simulator/emulated/simulatoremulated.cpp b/src/plugins/simulator/emulated/simulatoremulated.cpp index ace8dccbd..fe54389ba 100644 --- a/src/plugins/simulator/emulated/simulatoremulated.cpp +++ b/src/plugins/simulator/emulated/simulatoremulated.cpp @@ -421,6 +421,7 @@ namespace BlackSimPlugin void CSimulatorEmulated::fetchFromInterpolator() { const qint64 now = QDateTime::currentMSecsSinceEpoch(); + int aircraftNumber = 0; for (const CSimulatedAircraft &aircraft : m_renderedAircraft) { const CCallsign cs = aircraft.getCallsign(); @@ -428,7 +429,7 @@ namespace BlackSimPlugin const CInterpolationAndRenderingSetupPerCallsign setup = this->getInterpolationSetupPerCallsignOrDefault(cs); // threadsafe copy CInterpolatorMulti *im = m_interpolators[cs]; Q_ASSERT_X(im, Q_FUNC_INFO, "interpolator missing"); - CInterpolationResult result = im->getInterpolation(now, setup); + const CInterpolationResult result = im->getInterpolation(now, setup, aircraftNumber++); const CAircraftSituation s = result; const CAircraftParts p = result; m_countInterpolatedParts++; diff --git a/src/plugins/simulator/fs9/fs9client.cpp b/src/plugins/simulator/fs9/fs9client.cpp index d94321b1a..f4868b872 100644 --- a/src/plugins/simulator/fs9/fs9client.cpp +++ b/src/plugins/simulator/fs9/fs9client.cpp @@ -174,7 +174,7 @@ namespace BlackSimPlugin if (m_clientStatus == Disconnected) { return; } const CInterpolationAndRenderingSetupPerCallsign setup = this->simulator()->getInterpolationSetupConsolidated(m_callsign); - const CInterpolationResult result = m_interpolator.getInterpolation(QDateTime::currentMSecsSinceEpoch(), setup); + const CInterpolationResult result = m_interpolator.getInterpolation(QDateTime::currentMSecsSinceEpoch(), setup, 0); // Test only for successful position. FS9 requires constant positions if (!result.getInterpolationStatus().hasValidSituation()) { return; } diff --git a/src/plugins/simulator/fsxcommon/simconnectobject.cpp b/src/plugins/simulator/fsxcommon/simconnectobject.cpp index 263b4a78e..b8afda935 100644 --- a/src/plugins/simulator/fsxcommon/simconnectobject.cpp +++ b/src/plugins/simulator/fsxcommon/simconnectobject.cpp @@ -118,10 +118,10 @@ namespace BlackSimPlugin return m_interpolator->attachLogger(logger); } - CInterpolationResult CSimConnectObject::getInterpolation(qint64 currentTimeSinceEpoc, const CInterpolationAndRenderingSetupPerCallsign &setup) const + CInterpolationResult CSimConnectObject::getInterpolation(qint64 currentTimeSinceEpoc, const CInterpolationAndRenderingSetupPerCallsign &setup, int aircraftNumber) const { if (!m_interpolator) { CInterpolationResult result; result.reset(); return result; } - return m_interpolator->getInterpolation(currentTimeSinceEpoc, setup); + return m_interpolator->getInterpolation(currentTimeSinceEpoc, setup, aircraftNumber); } const CAircraftSituation &CSimConnectObject::getLastInterpolatedSituation(CInterpolationAndRenderingSetupBase::InterpolatorMode mode) const diff --git a/src/plugins/simulator/fsxcommon/simconnectobject.h b/src/plugins/simulator/fsxcommon/simconnectobject.h index 0af70d81c..e4b1b225e 100644 --- a/src/plugins/simulator/fsxcommon/simconnectobject.h +++ b/src/plugins/simulator/fsxcommon/simconnectobject.h @@ -167,7 +167,7 @@ namespace BlackSimPlugin void attachInterpolatorLogger(BlackMisc::Simulation::CInterpolationLogger *logger) const; //! \copydoc BlackMisc::Simulation::CInterpolator::getInterpolation - BlackMisc::Simulation::CInterpolationResult getInterpolation(qint64 currentTimeSinceEpoc, const BlackMisc::Simulation::CInterpolationAndRenderingSetupPerCallsign &setup) const; + BlackMisc::Simulation::CInterpolationResult getInterpolation(qint64 currentTimeSinceEpoc, const BlackMisc::Simulation::CInterpolationAndRenderingSetupPerCallsign &setup, int aircraftNumber) const; //! \copydoc BlackMisc::Simulation::CInterpolator::getLastInterpolatedSituation const BlackMisc::Aviation::CAircraftSituation &getLastInterpolatedSituation(BlackMisc::Simulation::CInterpolationAndRenderingSetupBase::InterpolatorMode mode) const; diff --git a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp index 6d7c045c9..63041f98b 100644 --- a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp +++ b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp @@ -1254,6 +1254,7 @@ namespace BlackSimPlugin // interpolation for all remote aircraft const QList simObjects(m_simConnectObjects.values()); + int simObjectNumber = 0; for (const CSimConnectObject &simObject : simObjects) { // happening if aircraft is not yet added to simulator or to be deleted @@ -1270,7 +1271,7 @@ namespace BlackSimPlugin const bool sendGround = setup.isSendingGndFlagToSimulator(); // Interpolated situation - const CInterpolationResult result = simObject.getInterpolation(currentTimestamp, setup); + const CInterpolationResult result = simObject.getInterpolation(currentTimestamp, setup, simObjectNumber++); if (result.getInterpolationStatus().hasValidSituation()) { // update situation diff --git a/src/plugins/simulator/xplane/simulatorxplane.cpp b/src/plugins/simulator/xplane/simulatorxplane.cpp index 88bc3efd3..6208f8d83 100644 --- a/src/plugins/simulator/xplane/simulatorxplane.cpp +++ b/src/plugins/simulator/xplane/simulatorxplane.cpp @@ -711,6 +711,7 @@ namespace BlackSimPlugin PlanesPositions planesPositions; PlanesSurfaces planesSurfaces; + int aircraftNumber = 0; for (const CXPlaneMPAircraft &xplaneAircraft : xplaneAircraftList) { const CCallsign callsign(xplaneAircraft.getCallsign()); @@ -720,7 +721,7 @@ namespace BlackSimPlugin const CInterpolationAndRenderingSetupPerCallsign setup = this->getInterpolationSetupConsolidated(callsign); // interpolated situation/parts - const CInterpolationResult result = xplaneAircraft.getInterpolation(currentTimestamp, setup); + const CInterpolationResult result = xplaneAircraft.getInterpolation(currentTimestamp, setup, aircraftNumber++); if (result.getInterpolationStatus().hasValidSituation()) { const CAircraftSituation interpolatedSituation(result); @@ -767,7 +768,7 @@ namespace BlackSimPlugin } // all callsigns - if (! planesPositions.isEmpty()) + if (!planesPositions.isEmpty()) { m_trafficProxy->setPlanesPositions(planesPositions); } diff --git a/src/plugins/simulator/xplane/xplanempaircraft.cpp b/src/plugins/simulator/xplane/xplanempaircraft.cpp index d0c53a3c2..6a8ed9c59 100644 --- a/src/plugins/simulator/xplane/xplanempaircraft.cpp +++ b/src/plugins/simulator/xplane/xplanempaircraft.cpp @@ -48,10 +48,10 @@ namespace BlackSimPlugin return m_interpolator->attachLogger(logger); } - CInterpolationResult CXPlaneMPAircraft::getInterpolation(qint64 currentTimeSinceEpoc, const CInterpolationAndRenderingSetupPerCallsign &setup) const + CInterpolationResult CXPlaneMPAircraft::getInterpolation(qint64 currentTimeSinceEpoc, const CInterpolationAndRenderingSetupPerCallsign &setup, int aircraftNumber) const { Q_ASSERT(m_interpolator); - return m_interpolator->getInterpolation(currentTimeSinceEpoc, setup); + return m_interpolator->getInterpolation(currentTimeSinceEpoc, setup, aircraftNumber); } CCallsignSet CXPlaneMPAircraftObjects::getAllCallsigns() const diff --git a/src/plugins/simulator/xplane/xplanempaircraft.h b/src/plugins/simulator/xplane/xplanempaircraft.h index 8525fda36..ce54982e2 100644 --- a/src/plugins/simulator/xplane/xplanempaircraft.h +++ b/src/plugins/simulator/xplane/xplanempaircraft.h @@ -62,6 +62,7 @@ namespace BlackSimPlugin void setSituationAsSent(const BlackMisc::Aviation::CAircraftSituation &position) { m_situationAsSent = position; } //! Same as sent + //! \deprecated KB T273 bool isSameAsSent(const BlackMisc::Aviation::CAircraftSituation &position) const; //! VTOL? @@ -77,7 +78,7 @@ namespace BlackSimPlugin void attachInterpolatorLogger(BlackMisc::Simulation::CInterpolationLogger *logger) const; //! \copydoc BlackMisc::Simulation::CInterpolator::getInterpolation - BlackMisc::Simulation::CInterpolationResult getInterpolation(qint64 currentTimeSinceEpoc, const BlackMisc::Simulation::CInterpolationAndRenderingSetupPerCallsign &setup) const; + BlackMisc::Simulation::CInterpolationResult getInterpolation(qint64 currentTimeSinceEpoc, const BlackMisc::Simulation::CInterpolationAndRenderingSetupPerCallsign &setup, int aircraftNumber) const; //! Interpolator BlackMisc::Simulation::CInterpolatorMulti *getInterpolator() const { return m_interpolator.data(); }