diff --git a/src/blackmisc/aviation/aircraftsituationchange.cpp b/src/blackmisc/aviation/aircraftsituationchange.cpp index f4f7a4715..3d04ed247 100644 --- a/src/blackmisc/aviation/aircraftsituationchange.cpp +++ b/src/blackmisc/aviation/aircraftsituationchange.cpp @@ -92,6 +92,11 @@ namespace BlackMisc return this->guessedSceneryDeviation() - cg; } + bool CAircraftSituationChange::hasSceneryDeviation() const + { + return !m_guessedSceneryDeviation.isNull(); + } + QString CAircraftSituationChange::convertToQString(bool i18n) const { Q_UNUSED(i18n); @@ -102,15 +107,15 @@ namespace BlackMisc QStringLiteral(" | situations:") % QString::number(m_situationsCount) % QStringLiteral(" | ts adj.: ") % QString::number(m_oldestAdjustedTimestampMSecsSinceEpoch) % QStringLiteral("-") % QString::number(m_latestAdjustedTimestampMSecsSinceEpoch) % QStringLiteral(" | just takeoff: ") % boolToYesNo(this->isJustTakingOff()) % QStringLiteral(" just touchdown: ") % boolToYesNo(this->isJustTouchingDown()) % - QStringLiteral(" | all gnd: ") % boolToYesNo(this->isConstOnGround()) % QStringLiteral("/ ") % boolToYesNo(this->wasConstOnGround()) % - QStringLiteral(" | all not gnd: ") % boolToYesNo(this->isConstNotOnGround()) % QStringLiteral("/ ") % boolToYesNo(this->wasConstNotOnGround()) % + QStringLiteral(" | all gnd: ") % boolToYesNo(this->isConstOnGround()) % QStringLiteral("/") % boolToYesNo(this->wasConstOnGround()) % + QStringLiteral(" | all not gnd: ") % boolToYesNo(this->isConstNotOnGround()) % QStringLiteral("/") % boolToYesNo(this->wasConstNotOnGround()) % QStringLiteral(" | ascending: ") % boolToYesNo(this->isConstAscending()) % QStringLiteral(" descending: ") % boolToYesNo(this->isConstDescending()) % QStringLiteral(" | accelerating.: ") % boolToYesNo(this->isConstAccelerating()) % QStringLiteral(" decelarating: ") % boolToYesNo(this->isConstDecelarating()) % QStringLiteral(" | rotate up: ") % boolToYesNo(this->isRotatingUp()) % QStringLiteral(" | push back: ") % boolToYesNo(this->containsPushBack()) % - QStringLiteral(" | scenery delta: ") % m_guessedSceneryDeviation.valueRoundedWithUnit(1) % - QStringLiteral(" | alt.delta: ") % m_altAglMean.valueRoundedWithUnit(1) % QStringLiteral("/") % m_altAglStdDev.valueRoundedWithUnit(1) % - QStringLiteral(" | std.dev: pitch ") % m_pitchMean.valueRoundedWithUnit(1) % QStringLiteral("/") % m_pitchStdDev.valueRoundedWithUnit(1) % + QStringLiteral(" | scenery delta: ") % m_guessedSceneryDeviation.valueRoundedWithUnit(1) % QStringLiteral(" [") % this->getGuessedSceneryDeviationAsString() % + QStringLiteral("] | AGL delta: ") % m_altAglMean.valueRoundedWithUnit(1) % QStringLiteral("/") % m_altAglStdDev.valueRoundedWithUnit(1) % + QStringLiteral(" | std.dev/mean: pitch ") % m_pitchMean.valueRoundedWithUnit(1) % QStringLiteral("/") % m_pitchStdDev.valueRoundedWithUnit(1) % QStringLiteral(" gs ") % m_gsMean.valueRoundedWithUnit(1) % QStringLiteral("/") % m_gsStdDev.valueRoundedWithUnit(1) % QStringLiteral(" alt. ") % m_altMean.valueRoundedWithUnit(1) % QStringLiteral("/") % m_altStdDev.valueRoundedWithUnit(1) % QStringLiteral(" elv. ") % m_elvMean.valueRoundedWithUnit(1) % QStringLiteral("/") % m_elvStdDev.valueRoundedWithUnit(1); @@ -164,21 +169,13 @@ namespace BlackMisc { if (situations.isEmpty()) { return false; } - const QList gsValues = situations.groundSpeedValues(CSpeedUnit::kts()); - if (gsValues.size() == situations.size()) - { - const QPair gsKts = CMathUtils::standardDeviationAndMean(gsValues); - m_gsStdDev = CSpeed(gsKts.first, CSpeedUnit::kts()); - m_gsMean = CSpeed(gsKts.second, CSpeedUnit::kts()); - } + const QPair gsStdDevMean = situations.groundSpeedStandardDeviationAndMean(); + m_gsStdDev = gsStdDevMean.first; + m_gsMean = gsStdDevMean.second; - const QList pitchValues = situations.pitchValues(CAngleUnit::deg()); - if (gsValues.size() == situations.size()) - { - const QPair pitchDeg = CMathUtils::standardDeviationAndMean(pitchValues); - m_pitchStdDev = CAngle(pitchDeg.first, CAngleUnit::deg()); - m_pitchMean = CAngle(pitchDeg.second, CAngleUnit::deg()); - } + const QPair pitchStdDevMean = situations.pitchStandardDeviationAndMean(); + m_pitchStdDev = pitchStdDevMean.first; + m_pitchMean = pitchStdDevMean.second; const QList altValues = situations.altitudeValues(CLengthUnit::ft()); if (altValues.size() == situations.size()) @@ -207,7 +204,7 @@ namespace BlackMisc m_altAglStdDev = CLength(deltaFt.first, CLengthUnit::ft()); m_altAglMean = CLength(deltaFt.second, CLengthUnit::ft()); - this->guessSceneryDeviation(); + this->guessSceneryDeviation(situations); } } return true; @@ -219,7 +216,25 @@ namespace BlackMisc return null; } - void CAircraftSituationChange::guessSceneryDeviation() + const QString &CAircraftSituationChange::guessedSceneryDeviationToString(GuessedSceneryDeviation hint) + { + static const QString noInfo("no info"); + static const QString completeOg("complete og"); + static const QString wasOg("was og"); + static const QString someOg("some og"); + + switch (hint) + { + case AllOnGround: return completeOg; + case WasOnGround: return wasOg; + case SomeSituationsOnGround: return someOg; + case NoDeviationInfo: + default: break; + } + return noInfo; + } + + void CAircraftSituationChange::guessSceneryDeviation(const CAircraftSituationList &situations) { m_guessedSceneryDeviation = CLength::null(); if (m_altAglStdDev.isNull()) { return; } @@ -228,15 +243,23 @@ namespace BlackMisc // only for a small deviation we can calculate scenery differemce static const CLength maxDeviation(2, CLengthUnit::ft()); - // Only on ground + // On ground or was on ground if (this->wasConstOnGround()) { if (m_altAglStdDev > maxDeviation) { return; } m_guessedSceneryDeviation = m_altAglMean; + this->setSceneryDeviationHint(this->isConstOnGround() ? AllOnGround : WasOnGround); } - else if (this->wasConstOnGround()) + else { - + const CAircraftSituationList situationsOg = situations.findOnGroundWithElevation(CAircraftSituation::OnGround); + if (situationsOg.size() >= 2) + { + const QPair altAgl = situationsOg.altitudeAglStandardDeviationAndMean(); + if (altAgl.first > maxDeviation) { return; } // deviation + m_guessedSceneryDeviation = altAgl.second; // AGL mean; + this->setSceneryDeviationHint(SomeSituationsOnGround); + } } } } // namespace diff --git a/src/blackmisc/aviation/aircraftsituationchange.h b/src/blackmisc/aviation/aircraftsituationchange.h index 76d76c283..6194abab6 100644 --- a/src/blackmisc/aviation/aircraftsituationchange.h +++ b/src/blackmisc/aviation/aircraftsituationchange.h @@ -53,6 +53,15 @@ namespace BlackMisc IndexContainsPushBack }; + //! Hint about the guessed scenery deviation + enum GuessedSceneryDeviation + { + NoDeviationInfo, + AllOnGround, //!< based on all situations on ground + WasOnGround, //!< was on ground except last situation + SomeSituationsOnGround //!< some situations on ground + }; + //! Default constructor. CAircraftSituationChange(); @@ -111,16 +120,16 @@ namespace BlackMisc //! \note distance is without CG, so on ground it can also be used to calculate QPair getAltAglStdDevAndMean() const { return QPair(m_altAglStdDev, m_altAglMean); } - //! Altitude values + //! \copydoc BlackMisc::Aviation::CAircraftSituationList::altitudeStandardDeviationAndMean QPair getAltitudeStdDevAndMean() const { return QPair(m_altStdDev, m_altMean); } - //! Elevation values + //! \copydoc BlackMisc::Aviation::CAircraftSituationList::elevationStandardDeviationAndMean QPair getElevationStdDevAndMean() const { return QPair(m_elvStdDev, m_elvMean); } - //! Ground speed values + //! \copydoc BlackMisc::Aviation::CAircraftSituationList::groundSpeedStandardDeviationAndMean QPair getGroundSpeedStdDevAndMean() const { return QPair(m_gsStdDev, m_gsMean); } - //! Pitch values + //! \copydoc BlackMisc::Aviation::CAircraftSituationList::pitchStandardDeviationAndMean QPair getPitchStdDevAndMean() const { return QPair(m_pitchStdDev, m_pitchMean); } //! Scnenery deviation (if it can be calculated, otherwise PhysicalQuantities::CLength::null) @@ -130,6 +139,15 @@ namespace BlackMisc //! Get scenery deviation under consideration of CG PhysicalQuantities::CLength getGuessedSceneryDeviation(const PhysicalQuantities::CLength &cg) const; + //! Scenery deviation hint + GuessedSceneryDeviation getSceneryDeviationHint() const { return static_cast(m_guessedSceneryDeviationHint); } + + //! Scenery deviation hint hint as string + const QString &getGuessedSceneryDeviationAsString() const { return guessedSceneryDeviationToString(this->getSceneryDeviationHint()); } + + //! Scenery deviation available? + bool hasSceneryDeviation() const; + //! \copydoc Mixin::String::toQString QString convertToQString(bool i18n = false) const; @@ -145,9 +163,15 @@ namespace BlackMisc //! NULL object static const CAircraftSituationChange &null(); + //! The enum as string + static const QString &guessedSceneryDeviationToString(GuessedSceneryDeviation hint); + private: + //! Scenery deviation hint + void setSceneryDeviationHint(GuessedSceneryDeviation hint) { m_guessedSceneryDeviationHint = static_cast(hint); } + //! Guess scenery deviation - void guessSceneryDeviation(); + void guessSceneryDeviation(const CAircraftSituationList &situations); int m_situationsCount = -1; CCallsign m_correspondingCallsign; @@ -167,6 +191,7 @@ namespace BlackMisc bool m_constAccelerating = false; bool m_constDecelerating = false; bool m_containsPushBack = false; + int m_guessedSceneryDeviationHint = static_cast(NoDeviationInfo); CAltitude m_altStdDev = CAltitude::null(); CAltitude m_altMean = CAltitude::null(); CAltitude m_elvStdDev = CAltitude::null(); @@ -202,6 +227,7 @@ namespace BlackMisc BLACK_METAMEMBER(pitchStdDev), BLACK_METAMEMBER(pitchMean), BLACK_METAMEMBER(guessedSceneryDeviation), + BLACK_METAMEMBER(guessedSceneryDeviationHint), BLACK_METAMEMBER(timestampMSecsSinceEpoch), BLACK_METAMEMBER(oldestTimestampMSecsSinceEpoch), BLACK_METAMEMBER(oldestAdjustedTimestampMSecsSinceEpoch), @@ -212,5 +238,6 @@ namespace BlackMisc } // namespace Q_DECLARE_METATYPE(BlackMisc::Aviation::CAircraftSituationChange) +Q_DECLARE_METATYPE(BlackMisc::Aviation::CAircraftSituationChange::GuessedSceneryDeviation) #endif // guard