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(); }