diff --git a/src/blackcore/airspacemonitor.cpp b/src/blackcore/airspacemonitor.cpp index bba12c407..cae84ea8a 100644 --- a/src/blackcore/airspacemonitor.cpp +++ b/src/blackcore/airspacemonitor.cpp @@ -1584,13 +1584,13 @@ namespace BlackCore while (false); // do we need elevation, find on // do we already have ground details? - if (situation.getOnGroundDetails() == CAircraftSituation::NotSetGroundDetails) + if (situation.getOnGroundInfo().getGroundDetails() == COnGroundInfo::NotSetGroundDetails) { const CClient client = this->getClientOrDefaultForCallsign(callsign); if (client.hasCapability(CClient::FsdWithGroundFlag)) { // we rely on situation gnd.flag - correctedSituation.setOnGroundDetails(CAircraftSituation::InFromNetwork); + correctedSituation.setOnGroundDetails(COnGroundInfo::InFromNetwork); } else if (client.hasCapability(CClient::FsdWithAircraftConfig)) { diff --git a/src/blackcore/fsd/fsdclient.cpp b/src/blackcore/fsd/fsdclient.cpp index 5cd8f6bad..ea0422617 100644 --- a/src/blackcore/fsd/fsdclient.cpp +++ b/src/blackcore/fsd/fsdclient.cpp @@ -1241,7 +1241,8 @@ namespace BlackCore::Fsd CAngle(dataUpdate.m_bank, CAngleUnit::deg()), CSpeed(dataUpdate.m_groundSpeed, CSpeedUnit::kts())); situation.setPressureAltitude(CAltitude(dataUpdate.m_altitudePressure, CAltitude::MeanSeaLevel, CAltitude::PressureAltitude, CLengthUnit::ft())); - situation.setOnGround(dataUpdate.m_onGround); + const COnGroundInfo og(dataUpdate.m_onGround ? COnGroundInfo::OnGround : COnGroundInfo::NotOnGround, COnGroundInfo::InFromNetwork); + situation.setOnGroundInfo(og); // Ref T297, default offset time situation.setCurrentUtcTime(); @@ -1279,8 +1280,8 @@ namespace BlackCore::Fsd CAngle(-data.m_pitch, CAngleUnit::deg()), CAngle(-data.m_bank, CAngleUnit::deg()), CSpeed(data.m_groundSpeed, CSpeedUnit::kts())); - situation.setOnGround(data.m_onGround); - situation.setOnGroundDetails(CAircraftSituation::InFromNetwork); + const COnGroundInfo og(data.m_onGround ? COnGroundInfo::OnGround : COnGroundInfo::NotOnGround, COnGroundInfo::InFromNetwork); + situation.setOnGroundInfo(og); // Ref T297, default offset time situation.setCurrentUtcTime(); @@ -1771,7 +1772,8 @@ namespace BlackCore::Fsd CAngle(interimPilotDataUpdate.m_pitch, CAngleUnit::deg()), CAngle(interimPilotDataUpdate.m_bank, CAngleUnit::deg()), CSpeed(interimPilotDataUpdate.m_groundSpeed, CSpeedUnit::kts())); - situation.setOnGround(interimPilotDataUpdate.m_onGround); + const COnGroundInfo og(interimPilotDataUpdate.m_onGround ? COnGroundInfo::OnGround : COnGroundInfo::NotOnGround, COnGroundInfo::InFromNetwork); + situation.setOnGroundInfo(og); // Ref T297, default offset time situation.setCurrentUtcTime(); diff --git a/src/blackgui/models/aircraftsituationlistmodel.cpp b/src/blackgui/models/aircraftsituationlistmodel.cpp index 95c50b04b..c5e2a280e 100644 --- a/src/blackgui/models/aircraftsituationlistmodel.cpp +++ b/src/blackgui/models/aircraftsituationlistmodel.cpp @@ -28,8 +28,6 @@ namespace BlackGui::Models m_columns.addColumn(CColumn("longitude", CAircraftSituation::IndexLongitude, new CLatLonFormatter())); m_columns.addColumn(CColumn("gs.", CAircraftSituation::IndexGroundSpeed, new CSpeedKtsFormatter())); m_columns.addColumn(CColumn::standardString("PBH", "pitch bank heading", CAircraftSituation::IndexPBHInfo)); - m_columns.addColumn(CColumn("on gnd.", "is on gnd.", CAircraftSituation::IndexIsOnGround, new CBoolIconFormatter("yes", "no"), true)); - m_columns.addColumn(CColumn::standardString("reliability", CAircraftSituation::IndexOnGroundReliabilityString)); m_columns.addColumn(CColumn::standardString("gnd.elv.", CAircraftSituation::IndexGroundElevationPlusInfo)); m_columns.addColumn(CColumn::standardString("gnd.elv.alt.", { CAircraftSituation::IndexGroundElevationPlane, CElevationPlane::IndexGeodeticHeightAsString })); m_columns.addColumn(CColumn("elv.radius", { CAircraftSituation::IndexGroundElevationPlane, CElevationPlane::IndexRadius }, new CPhysiqalQuantiyFormatter(CLengthUnit::m(), 1))); diff --git a/src/blackmisc/CMakeLists.txt b/src/blackmisc/CMakeLists.txt index ccdf4abd1..5517b9bec 100644 --- a/src/blackmisc/CMakeLists.txt +++ b/src/blackmisc/CMakeLists.txt @@ -90,6 +90,8 @@ add_library(misc SHARED aviation/modulator.h aviation/navsystem.h aviation/percallsign.h + aviation/ongroundinfo.cpp + aviation/ongroundinfo.h aviation/registermetadataaviation.cpp aviation/registermetadataaviation.h aviation/selcal.cpp diff --git a/src/blackmisc/aviation/aircraftsituation.cpp b/src/blackmisc/aviation/aircraftsituation.cpp index 86a4979ed..095e0862c 100644 --- a/src/blackmisc/aviation/aircraftsituation.cpp +++ b/src/blackmisc/aviation/aircraftsituation.cpp @@ -34,7 +34,7 @@ namespace BlackMisc::Aviation CAircraftLights CAircraftSituation::guessLights() const { - const bool isOnGround = getOnGround() == CAircraftSituation::OnGround; + const bool isOnGround = this->isOnGround(); const double gsKts = getGroundSpeed().value(CSpeedUnit::kts()); CAircraftLights lights; lights.setCabinOn(true); @@ -81,8 +81,6 @@ namespace BlackMisc::Aviation void CAircraftSituation::registerMetadata() { CValueObject::registerMetadata(); - qRegisterMetaType(); - qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); } @@ -116,12 +114,11 @@ namespace BlackMisc::Aviation u" | " % m_position.toQString(i18n) % u" | alt: " % this->getAltitude().valueRoundedWithUnit(CLengthUnit::ft(), 1) % u' ' % this->getCorrectedAltitude().valueRoundedWithUnit(CLengthUnit::ft(), 1) % - u"[cor] | og: " % this->getOnGroundInfo() % + u"[cor] | og: " % this->getOnGroundInfo().toQString(i18n) % u" | CG: " % (m_cg.isNull() ? QStringLiteral("null") : m_cg.valueRoundedWithUnit(CLengthUnit::m(), 1) % u' ' % m_cg.valueRoundedWithUnit(CLengthUnit::ft(), 1)) % u" | offset: " % (m_sceneryOffset.isNull() ? QStringLiteral("null") : m_sceneryOffset.valueRoundedWithUnit(CLengthUnit::m(), 1) % u' ' % m_sceneryOffset.valueRoundedWithUnit(CLengthUnit::ft(), 1)) % - u" | factor [0..1]: " % QString::number(m_onGroundFactor, 'f', 2) % u" | skip ng: " % boolToYesNo(this->canLikelySkipNearGroundInterpolation()) % u" | bank: " % m_bank.toQString(i18n) % u" | pitch: " % m_pitch.toQString(i18n) % @@ -131,44 +128,6 @@ namespace BlackMisc::Aviation u" | elevation [" % this->getGroundElevationInfoAsString() % u"]: " % (m_groundElevationPlane.toQString(i18n)); } - const QString &CAircraftSituation::isOnGroundToString(CAircraftSituation::IsOnGround onGround) - { - static const QString notog("not on ground"); - static const QString og("on ground"); - static const QString unknown("unknown"); - - switch (onGround) - { - case CAircraftSituation::NotOnGround: return notog; - case CAircraftSituation::OnGround: return og; - case CAircraftSituation::OnGroundSituationUnknown: - default: return unknown; - } - } - - const QString &CAircraftSituation::onGroundDetailsToString(CAircraftSituation::OnGroundDetails reliability) - { - static const QString elvCg("elevation/CG"); - static const QString interpolation("interpolation"); - static const QString guess("guessing"); - static const QString unknown("unknown"); - static const QString outOwnAircraft("own aircraft"); - static const QString inNetwork("from network"); - static const QString inFromParts("from parts"); - - switch (reliability) - { - case CAircraftSituation::OnGroundByElevationAndCG: return elvCg; - case CAircraftSituation::OnGroundByGuessing: return guess; - case CAircraftSituation::OnGroundByInterpolation: return interpolation; - case CAircraftSituation::OutOnGroundOwnAircraft: return outOwnAircraft; - case CAircraftSituation::InFromNetwork: return inNetwork; - case CAircraftSituation::InFromParts: return inFromParts; - case CAircraftSituation::NotSetGroundDetails: - default: return unknown; - } - } - const QString &CAircraftSituation::altitudeCorrectionToString(CAircraftSituation::AltitudeCorrection correction) { static const QString under("underflow"); @@ -315,10 +274,7 @@ namespace BlackMisc::Aviation case IndexGroundSpeed: return m_groundSpeed.propertyByIndex(index.copyFrontRemoved()); case IndexGroundElevationPlane: return m_groundElevationPlane.propertyByIndex(index.copyFrontRemoved()); case IndexCallsign: return m_correspondingCallsign.propertyByIndex(index.copyFrontRemoved()); - case IndexIsOnGround: return QVariant::fromValue(m_onGround); - case IndexIsOnGroundString: return QVariant::fromValue(this->onGroundAsString()); - case IndexOnGroundReliability: return QVariant::fromValue(m_onGroundDetails); - case IndexOnGroundReliabilityString: return QVariant::fromValue(this->getOnGroundDetailsAsString()); + case IndexIsOnGroundInfo: return m_onGroundInfo.propertyByIndex(index.copyFrontRemoved()); case IndexGroundElevationInfo: return QVariant::fromValue(this->getGroundElevationInfo()); case IndexGroundElevationInfoTransferred: return QVariant::fromValue(this->isGroundElevationInfoTransferred()); case IndexGroundElevationInfoString: return QVariant::fromValue(this->getGroundElevationInfoAsString()); @@ -353,8 +309,7 @@ namespace BlackMisc::Aviation case IndexGroundSpeed: m_groundSpeed.setPropertyByIndex(index.copyFrontRemoved(), variant); break; case IndexGroundElevationPlane: m_groundElevationPlane.setPropertyByIndex(index.copyFrontRemoved(), variant); break; case IndexCallsign: m_correspondingCallsign.setPropertyByIndex(index.copyFrontRemoved(), variant); break; - case IndexIsOnGround: m_onGround = variant.toInt(); break; - case IndexOnGroundReliability: m_onGroundDetails = variant.toInt(); break; + case IndexIsOnGroundInfo: m_onGroundInfo.setPropertyByIndex(index.copyFrontRemoved(), variant); break; case IndexGroundElevationInfo: m_elvInfo = variant.toInt(); break; case IndexGroundElevationInfoTransferred: m_isElvInfoTransferred = variant.toBool(); break; case IndexGroundElevationPlusInfo: break; @@ -387,12 +342,7 @@ namespace BlackMisc::Aviation return Compare::compare(this->getGroundElevationInfo(), compareValue.getGroundElevationInfo()); } case IndexCallsign: return m_correspondingCallsign.comparePropertyByIndex(index.copyFrontRemoved(), compareValue.getCallsign()); - case IndexIsOnGround: - case IndexIsOnGroundString: - return Compare::compare(m_onGround, compareValue.m_onGround); - case IndexOnGroundReliability: - case IndexOnGroundReliabilityString: - return Compare::compare(m_onGroundDetails, compareValue.m_onGroundDetails); + case IndexIsOnGroundInfo: return m_onGroundInfo.comparePropertyByIndex(index.copyFrontRemoved(), compareValue.getOnGroundInfo()); case IndexGroundElevationInfo: case IndexGroundElevationInfoString: { @@ -461,7 +411,7 @@ namespace BlackMisc::Aviation m_velocity = {}; m_groundElevationPlane.setNull(); m_groundSpeed.setNull(); - m_onGroundDetails = CAircraftSituation::NotSetGroundDetails; + m_onGroundInfo = {}; m_elvInfo = NoElevationInfo; m_isElvInfoTransferred = false; m_cg.setNull(); @@ -470,63 +420,19 @@ namespace BlackMisc::Aviation bool CAircraftSituation::isOnGroundFromParts() const { - return this->isOnGround() && this->getOnGroundDetails() == InFromParts; + return this->isOnGround() && m_onGroundInfo.getGroundDetails() == COnGroundInfo::InFromParts; } bool CAircraftSituation::isOnGroundFromNetwork() const { - return this->isOnGround() && this->getOnGroundDetails() == InFromNetwork; - } - - const QString &CAircraftSituation::onGroundAsString() const - { - return CAircraftSituation::isOnGroundToString(this->getOnGround()); + return this->isOnGround() && m_onGroundInfo.getGroundDetails() == COnGroundInfo::InFromNetwork; } bool CAircraftSituation::isOnGroundInfoAvailable() const { if (this->hasInboundGroundDetails()) { return true; } - return this->getOnGround() != CAircraftSituation::OnGroundSituationUnknown && - this->getOnGroundDetails() != CAircraftSituation::NotSetGroundDetails; - } - - bool CAircraftSituation::setOnGround(bool onGround) - { - return this->setOnGround(onGround ? OnGround : NotOnGround); - } - - bool CAircraftSituation::setOnGround(CAircraftSituation::IsOnGround onGround) - { - if (this->getOnGround() == onGround) { return false; } - const int og = static_cast(onGround); - m_onGround = og; - m_onGroundFactor = (onGround == OnGround) ? 1.0 : 0.0; - return true; - } - - bool CAircraftSituation::setOnGround(CAircraftSituation::IsOnGround onGround, CAircraftSituation::OnGroundDetails details) - { - const bool set = this->setOnGround(onGround); - this->setOnGroundDetails(details); - - return set; - } - - void CAircraftSituation::setOnGroundFactor(double groundFactor) - { - if (groundFactor < 0.0) - { - groundFactor = -1.0; - } - else if (groundFactor < 0.001) - { - groundFactor = 0.0; - } - else if (groundFactor > 0.999) - { - groundFactor = 1.0; - } - m_onGroundFactor = groundFactor; + return m_onGroundInfo.getOnGround() != COnGroundInfo::OnGroundSituationUnknown && + m_onGroundInfo.getGroundDetails() != COnGroundInfo::NotSetGroundDetails; } bool CAircraftSituation::shouldGuessOnGround() const @@ -544,39 +450,22 @@ namespace BlackMisc::Aviation bool CAircraftSituation::hasGroundDetailsForGndInterpolation() const { - return this->getOnGroundDetails() != CAircraftSituation::NotSetGroundDetails; + return m_onGroundInfo.getGroundDetails() != COnGroundInfo::NotSetGroundDetails; } - const QString &CAircraftSituation::getOnGroundDetailsAsString() const + COnGroundInfo CAircraftSituation::getOnGroundInfo() const { - return CAircraftSituation::onGroundDetailsToString(this->getOnGroundDetails()); + return m_onGroundInfo; } - bool CAircraftSituation::setOnGroundDetails(CAircraftSituation::OnGroundDetails details) + void CAircraftSituation::setOnGroundDetails(COnGroundInfo::OnGroundDetails details) { - if (this->getOnGroundDetails() == details) { return false; } - m_onGroundDetails = static_cast(details); - return true; + m_onGroundInfo.setOnGroundDetails(details); } - bool CAircraftSituation::setOnGroundFromGroundFactorFromInterpolation(double threshold) + void CAircraftSituation::setOnGroundInfo(const Aviation::COnGroundInfo &info) { - this->setOnGroundDetails(OnGroundByInterpolation); - if (this->getOnGroundFactor() < 0.0) - { - this->setOnGround(NotSetGroundDetails); - return false; - } - - // set on ground but leave factor untouched - const bool og = this->getOnGroundFactor() > threshold; // 1.0 means on ground - m_onGround = og ? OnGround : NotOnGround; - return true; - } - - QString CAircraftSituation::getOnGroundInfo() const - { - return this->onGroundAsString() % u' ' % this->getOnGroundDetailsAsString(); + m_onGroundInfo = info; } CAircraftSituation::GndElevationInfo CAircraftSituation::getGroundElevationInfo() const @@ -640,21 +529,6 @@ namespace BlackMisc::Aviation return true; } - CAircraftSituation::IsOnGround CAircraftSituation::isOnGroundByElevation(const CLength &cg) const - { - const CLength groundDistance = this->getGroundDistance(cg); - if (groundDistance.isNull()) { return OnGroundSituationUnknown; } - if (groundDistance.isNegativeWithEpsilonConsidered()) { return OnGround; } - if (groundDistance.abs() < deltaNearGround()) { return OnGround; } - if (!cg.isNull()) - { - // smaller than percentage from CG - const CLength cgFactor(cg * 0.1); - if (groundDistance.abs() < cgFactor.abs()) { return OnGround; } - } - return NotOnGround; - } - bool CAircraftSituation::hasGroundElevation() const { return !this->getGroundElevation().isNull(); @@ -662,7 +536,7 @@ namespace BlackMisc::Aviation bool CAircraftSituation::hasInboundGroundDetails() const { - return this->getOnGroundDetails() == CAircraftSituation::InFromParts || this->getOnGroundDetails() == CAircraftSituation::InFromNetwork; + return m_onGroundInfo.getGroundDetails() == COnGroundInfo::InFromParts || m_onGroundInfo.getGroundDetails() == COnGroundInfo::InFromNetwork; } bool CAircraftSituation::setGroundElevation(const CAltitude &altitude, GndElevationInfo info, bool transferred) @@ -810,7 +684,7 @@ namespace BlackMisc::Aviation if (correction) { *correction = NoCorrection; } return groundPlusCG; } - const bool forceDragToGround = (enableDragToGround && this->getOnGround() == OnGround) && (this->hasInboundGroundDetails() || this->getOnGroundDetails() == OnGroundByGuessing); + const bool forceDragToGround = (enableDragToGround && isOnGround()) && (this->hasInboundGroundDetails() || m_onGroundInfo.getGroundDetails() == COnGroundInfo::OnGroundByGuessing); if (forceDragToGround) { if (correction) { *correction = DraggedToGround; } @@ -971,14 +845,14 @@ namespace BlackMisc::Aviation static const qint64 Max = std::numeric_limits::max(); if (differenceMs) { *differenceMs = Max; } - if (this->getOnGroundDetails() == CAircraftSituation::InFromNetwork) { return false; } - if (alwaysSetDetails) { this->setOnGroundDetails(InFromParts); } + if (m_onGroundInfo.getGroundDetails() == COnGroundInfo::InFromNetwork) { return false; } + if (alwaysSetDetails) { m_onGroundInfo.setOnGroundDetails(COnGroundInfo::InFromParts); } const qint64 d = this->getAdjustedTimeDifferenceMs(parts.getAdjustedMSecsSinceEpoch()); const bool adjust = (d >= 0) || qAbs(d) < (timeDeviationFactor * parts.getTimeOffsetMs()); // future or past within deviation range if (!adjust) { return false; } if (differenceMs) { *differenceMs = d; } - this->setOnGround(parts.isOnGround() ? CAircraftSituation::OnGround : CAircraftSituation::NotOnGround, CAircraftSituation::InFromParts); + m_onGroundInfo = COnGroundInfo(parts.isOnGround() ? COnGroundInfo::OnGround : COnGroundInfo::NotOnGround, COnGroundInfo::InFromParts); return true; } @@ -988,8 +862,8 @@ namespace BlackMisc::Aviation static const qint64 Max = std::numeric_limits::max(); if (differenceMs) { *differenceMs = Max; } - if (this->getOnGroundDetails() == CAircraftSituation::InFromNetwork) { return false; } - if (alwaysSetDetails) { this->setOnGroundDetails(InFromParts); } + if (m_onGroundInfo.getGroundDetails() == COnGroundInfo::InFromNetwork) { return false; } + if (alwaysSetDetails) { m_onGroundInfo.setOnGroundDetails(COnGroundInfo::InFromParts); } if (partsList.isEmpty()) { return false; } CAircraftParts bestParts; @@ -1009,8 +883,8 @@ namespace BlackMisc::Aviation } if (!adjust) { return false; } - const CAircraftSituation::IsOnGround og = bestParts.isOnGround() ? CAircraftSituation::OnGround : CAircraftSituation::NotOnGround; - this->setOnGround(og, CAircraftSituation::InFromParts); + const COnGroundInfo::IsOnGround og = bestParts.isOnGround() ? COnGroundInfo::OnGround : COnGroundInfo::NotOnGround; + m_onGroundInfo = COnGroundInfo(og, COnGroundInfo::InFromParts); return true; } } // namespace diff --git a/src/blackmisc/aviation/aircraftsituation.h b/src/blackmisc/aviation/aircraftsituation.h index 179fddc30..6071d7006 100644 --- a/src/blackmisc/aviation/aircraftsituation.h +++ b/src/blackmisc/aviation/aircraftsituation.h @@ -8,6 +8,7 @@ #include "blackmisc/aviation/altitude.h" #include "blackmisc/aviation/callsign.h" +#include "blackmisc/aviation/ongroundinfo.h" #include "blackmisc/aviation/heading.h" #include "blackmisc/aviation/aircraftvelocity.h" #include "blackmisc/blackmiscexport.h" @@ -60,10 +61,7 @@ namespace BlackMisc IndexAltitude, IndexHeading, IndexBank, - IndexIsOnGround, - IndexIsOnGroundString, - IndexOnGroundReliability, - IndexOnGroundReliabilityString, + IndexIsOnGroundInfo, IndexPitch, IndexPBHInfo, IndexVelocity, @@ -79,29 +77,6 @@ namespace BlackMisc IndexCanLikelySkipNearGroundInterpolation }; - //! Is on ground? - enum IsOnGround - { - NotOnGround, - OnGround, - OnGroundSituationUnknown - }; - - //! Reliability of on ground information - enum OnGroundDetails - { - NotSetGroundDetails, - // interpolated situation - OnGroundByInterpolation, //!< strongest for remote aircraft - OnGroundByElevationAndCG, - OnGroundByGuessing, //!< weakest - // received situation - InFromNetwork, //!< received from network - InFromParts, //!< set from aircraft parts - // send information - OutOnGroundOwnAircraft //!< sending on ground - }; - //! How was altitude corrected? enum AltitudeCorrection { @@ -205,11 +180,8 @@ namespace BlackMisc //! \copydoc Geo::ICoordinateGeodetic::longitude() virtual Geo::CLongitude longitude() const override { return m_position.longitude(); } - //! On ground? - IsOnGround getOnGround() const { return static_cast(m_onGround); } - //! Is on ground? - bool isOnGround() const { return this->getOnGround() == OnGround; } + bool isOnGround() const { return m_onGroundInfo.getOnGround() == COnGroundInfo::OnGround; } //! On ground by parts? bool isOnGroundFromParts() const; @@ -217,50 +189,26 @@ namespace BlackMisc //! On ground by network flag? bool isOnGroundFromNetwork() const; - //! On ground? - const QString &onGroundAsString() const; - //! On ground info available? bool isOnGroundInfoAvailable() const; - //! Set on ground - bool setOnGround(bool onGround); - - //! Set on ground - bool setOnGround(CAircraftSituation::IsOnGround onGround); - - //! Set on ground - bool setOnGround(CAircraftSituation::IsOnGround onGround, CAircraftSituation::OnGroundDetails details); - - //! On ground factor 0..1 (on ground), -1 not set - double getOnGroundFactor() const { return m_onGroundFactor; } - - //! Set on ground factor 0..1 (on ground), -1 not set - void setOnGroundFactor(double groundFactor); - //! Should we guess on ground? bool shouldGuessOnGround() const; //! Distance to ground, null if impossible to calculate PhysicalQuantities::CLength getGroundDistance(const PhysicalQuantities::CLength ¢erOfGravity) const; - //! On ground reliability - OnGroundDetails getOnGroundDetails() const { return static_cast(m_onGroundDetails); } - //! Do the ground details permit ground interpolation? bool hasGroundDetailsForGndInterpolation() const; - //! On ground reliability as string - const QString &getOnGroundDetailsAsString() const; - //! On ground details - bool setOnGroundDetails(CAircraftSituation::OnGroundDetails details); + void setOnGroundDetails(COnGroundInfo::OnGroundDetails details); - //! Set on ground as interpolated from ground fatcor - bool setOnGroundFromGroundFactorFromInterpolation(double threshold = 0.5); + //! On ground info + Aviation::COnGroundInfo getOnGroundInfo() const; - //! On ground info as string - QString getOnGroundInfo() const; + //! Set the on ground info + void setOnGroundInfo(const Aviation::COnGroundInfo &info); //! \copydoc Geo::ICoordinateGeodetic::geodeticHeight const CAltitude &geodeticHeight() const override { return m_position.geodeticHeight(); } @@ -313,11 +261,6 @@ namespace BlackMisc //! \sa CAircraftSituation::presetGroundElevation bool interpolateElevation(const Aviation::CAircraftSituation &oldSituation, const Aviation::CAircraftSituation &newSituation); - //! @{ - //! Is on ground by elevation data, requires elevation and CG - IsOnGround isOnGroundByElevation(const PhysicalQuantities::CLength &cg) const; - //! @} - //! Is ground elevation value available bool hasGroundElevation() const; @@ -482,12 +425,6 @@ namespace BlackMisc //! Get flag indicating this is an interim position update bool isInterim() const { return m_isInterim; } - //! Enum to string - static const QString &isOnGroundToString(IsOnGround onGround); - - //! Enum to string - static const QString &onGroundDetailsToString(OnGroundDetails reliability); - //! Enum to string static const QString &altitudeCorrectionToString(AltitudeCorrection correction); @@ -569,10 +506,8 @@ namespace BlackMisc CAircraftVelocity m_velocity; bool m_isInterim = false; //!< interim situation? bool m_isElvInfoTransferred = false; //!< the gnd.elevation has been transferred - int m_onGround = static_cast(CAircraftSituation::OnGroundSituationUnknown); - int m_onGroundDetails = static_cast(CAircraftSituation::NotSetGroundDetails); int m_elvInfo = static_cast(CAircraftSituation::NoElevationInfo); //!< where did we gnd.elevation from? - double m_onGroundFactor = -1; //!< interpolated ground flag, 1..on ground, 0..not on ground, -1 no info + Aviation::COnGroundInfo m_onGroundInfo; BLACK_METACLASS( CAircraftSituation, @@ -588,11 +523,9 @@ namespace BlackMisc BLACK_METAMEMBER(hasVelocity), BLACK_METAMEMBER(velocity), BLACK_METAMEMBER(groundElevationPlane), - BLACK_METAMEMBER(onGround), - BLACK_METAMEMBER(onGroundDetails), + BLACK_METAMEMBER(onGroundInfo), BLACK_METAMEMBER(elvInfo), BLACK_METAMEMBER(isElvInfoTransferred), - BLACK_METAMEMBER(onGroundFactor), BLACK_METAMEMBER(timestampMSecsSinceEpoch), BLACK_METAMEMBER(timeOffsetMs), BLACK_METAMEMBER(isInterim) @@ -602,8 +535,6 @@ namespace BlackMisc } // namespace Q_DECLARE_METATYPE(BlackMisc::Aviation::CAircraftSituation) -Q_DECLARE_METATYPE(BlackMisc::Aviation::CAircraftSituation::IsOnGround) -Q_DECLARE_METATYPE(BlackMisc::Aviation::CAircraftSituation::OnGroundDetails) Q_DECLARE_METATYPE(BlackMisc::Aviation::CAircraftSituation::AltitudeCorrection) Q_DECLARE_METATYPE(BlackMisc::Aviation::CAircraftSituation::GndElevationInfo) diff --git a/src/blackmisc/aviation/aircraftsituationchange.cpp b/src/blackmisc/aviation/aircraftsituationchange.cpp index dbd73c87e..97af963ba 100644 --- a/src/blackmisc/aviation/aircraftsituationchange.cpp +++ b/src/blackmisc/aviation/aircraftsituationchange.cpp @@ -94,21 +94,21 @@ namespace BlackMisc::Aviation { if (situation.getGroundSpeed().isNegativeWithEpsilonConsidered()) { - situation.setOnGround(CAircraftSituation::OnGround, CAircraftSituation::OnGroundByGuessing); + situation.setOnGroundInfo({ COnGroundInfo::OnGround, COnGroundInfo::OnGroundByGuessing }); if (details) { *details = QStringLiteral("No VTOL, push back"); } return true; } if (!situation.isMoving()) { - situation.setOnGround(CAircraftSituation::OnGround, CAircraftSituation::OnGroundByGuessing); + situation.setOnGroundInfo({ COnGroundInfo::OnGround, COnGroundInfo::OnGroundByGuessing }); if (details) { *details = QStringLiteral("No VTOL, not moving => on ground"); } return true; } } // not on ground is default - situation.setOnGround(CAircraftSituation::NotOnGround, CAircraftSituation::OnGroundByGuessing); + situation.setOnGroundInfo({ COnGroundInfo::NotOnGround, COnGroundInfo::OnGroundByGuessing }); CLength cg = situation.hasCG() ? situation.getCG() : model.getCG(); CSpeed guessedRotateSpeed = CSpeed::null(); @@ -146,11 +146,12 @@ namespace BlackMisc::Aviation // we can detect "on ground" (underflow, near ground), but not "not on ground" because of overflow // we can detect on ground for underflow, but not for overflow (so we can not rely on NotOnGround) - CAircraftSituation::IsOnGround og = situation.isOnGroundByElevation(cg); - if (og == CAircraftSituation::OnGround) + COnGroundInfo og(cg, situation.getGroundDistance(cg)); + if (og.getOnGround() == COnGroundInfo::OnGround) { if (details) { *details = QStringLiteral("elevation on ground"); } - situation.setOnGround(og, CAircraftSituation::OnGroundByGuessing); + og.setOnGroundDetails(COnGroundInfo::OnGroundByGuessing); + situation.setOnGroundInfo(og); return true; } @@ -166,7 +167,7 @@ namespace BlackMisc::Aviation } // here we stick to ground until we detect rotate up - situation.setOnGround(CAircraftSituation::OnGround, CAircraftSituation::OnGroundByGuessing); + situation.setOnGroundInfo({ COnGroundInfo::OnGround, COnGroundInfo::OnGroundByGuessing }); if (details) { *details = QStringLiteral("waiting for rotating up"); } return true; } @@ -183,7 +184,7 @@ namespace BlackMisc::Aviation if (vtol) { // no idea - situation.setOnGround(CAircraftSituation::OnGroundSituationUnknown, CAircraftSituation::NotSetGroundDetails); + situation.setOnGroundInfo({ COnGroundInfo::OnGroundSituationUnknown, COnGroundInfo::NotSetGroundDetails }); return false; } @@ -193,7 +194,7 @@ namespace BlackMisc::Aviation // does the value make any sense? if (situation.getGroundSpeed() < guessedRotateSpeed) { - situation.setOnGround(CAircraftSituation::OnGround, CAircraftSituation::OnGroundByGuessing); + situation.setOnGroundInfo({ COnGroundInfo::OnGround, COnGroundInfo::OnGroundByGuessing }); if (details) { *details = QStringLiteral("Guessing, max.guessed gs.") + guessedRotateSpeed.valueRoundedWithUnit(CSpeedUnit::kts(), 1); } return true; } diff --git a/src/blackmisc/aviation/aircraftsituationchange.h b/src/blackmisc/aviation/aircraftsituationchange.h index 221ffc1f0..e92b7b037 100644 --- a/src/blackmisc/aviation/aircraftsituationchange.h +++ b/src/blackmisc/aviation/aircraftsituationchange.h @@ -116,7 +116,7 @@ namespace BlackMisc //! \copydoc BlackMisc::Aviation::CAircraftSituationList::containsPushBack bool containsPushBack() const { return m_containsPushBack; } - //! \copydoc BlackMisc::Aviation::CAircraftSituationList::elevationStandardDeviationAndMean + //! Elevation standard deviation and mean CAltitudePair getElevationStdDevAndMean() const { return CAltitudePair(m_elvStdDev, m_elvMean); } //! Guess on ground flag diff --git a/src/blackmisc/aviation/aircraftsituationlist.cpp b/src/blackmisc/aviation/aircraftsituationlist.cpp index 5f1128fc0..2c2d13829 100644 --- a/src/blackmisc/aviation/aircraftsituationlist.cpp +++ b/src/blackmisc/aviation/aircraftsituationlist.cpp @@ -55,22 +55,22 @@ namespace BlackMisc::Aviation int c = 0; for (CAircraftSituation &situation : *this) { - situation.setOnGroundDetails(CAircraftSituation::InFromParts); + situation.setOnGroundDetails(COnGroundInfo::InFromParts); if (situation.adjustGroundFlag(parts, true, timeDeviationFactor)) { c++; }; } return c; } - bool CAircraftSituationList::containsOnGroundDetails(CAircraftSituation::OnGroundDetails details) const + bool CAircraftSituationList::containsOnGroundDetails(COnGroundInfo::OnGroundDetails details) const { - return this->contains(&CAircraftSituation::getOnGroundDetails, details); + return std::any_of(begin(), end(), [&details](const CAircraftSituation &sit) { return sit.getOnGroundInfo().getGroundDetails() == details; }); } - bool CAircraftSituationList::areAllOnGroundDetailsSame(CAircraftSituation::OnGroundDetails details) const + bool CAircraftSituationList::areAllOnGroundDetailsSame(COnGroundInfo::OnGroundDetails details) const { for (const CAircraftSituation &situation : *this) { - if (situation.getOnGroundDetails() != details) { return false; } + if (situation.getOnGroundInfo().getGroundDetails() != details) { return false; } } return true; } @@ -79,24 +79,14 @@ namespace BlackMisc::Aviation { if (this->isEmpty()) { return false; } if (this->containsNullPositionOrHeight()) { return false; } - for (const CAircraftSituation &situation : *this) - { - const CAircraftSituation::IsOnGround og = situation.getOnGround(); - if (og != CAircraftSituation::OnGround) { return false; } - } - return true; + return std::all_of(begin(), end(), [](const CAircraftSituation &situation) { return situation.isOnGround(); }); } bool CAircraftSituationList::isConstNotOnGround() const { if (this->isEmpty()) { return false; } if (this->containsNullPositionOrHeight()) { return false; } - for (const CAircraftSituation &situation : *this) - { - const CAircraftSituation::IsOnGround og = situation.getOnGround(); - if (og != CAircraftSituation::NotOnGround) { return false; } - } - return true; + return std::all_of(begin(), end(), [](const CAircraftSituation &situation) { return situation.getOnGroundInfo().getOnGround() == COnGroundInfo::NotOnGround; }); } bool CAircraftSituationList::isConstDescending(bool alreadySortedLatestFirst) const @@ -178,27 +168,27 @@ namespace BlackMisc::Aviation return true; } - QPair CAircraftSituationList::isGndFlagStableChanging(bool alreadySortedLatestFirst) const + QPair CAircraftSituationList::isGndFlagStableChanging(bool alreadySortedLatestFirst) const { - if (this->size() < 2) { return QPair(false, CAircraftSituation::OnGroundSituationUnknown); } + if (this->size() < 2) { return QPair(false, COnGroundInfo::OnGroundSituationUnknown); } const CAircraftSituationList sorted(alreadySortedLatestFirst ? (*this) : this->getSortedAdjustedLatestFirst()); - const CAircraftSituation::IsOnGround f = sorted.front().getOnGround(); - const CAircraftSituation::IsOnGround t = sorted.back().getOnGround(); - QPair ret(false, f); // changing to front (latest) + const COnGroundInfo::IsOnGround f = sorted.front().getOnGroundInfo().getOnGround(); + const COnGroundInfo::IsOnGround t = sorted.back().getOnGroundInfo().getOnGround(); + QPair ret(false, f); // changing to front (latest) if (f == t) { return ret; } bool changed = false; for (const CAircraftSituation &s : sorted) { - if (!changed && s.getOnGround() == f) { continue; } // find 1st changing + if (!changed && s.getOnGroundInfo().getOnGround() == f) { continue; } // find 1st changing if (!changed) { changed = true; continue; } // just changed - if (s.getOnGround() != t) { return ret; } // jitter, something like gnd, no gnd, gnd + if (s.getOnGroundInfo().getOnGround() != t) { return ret; } // jitter, something like gnd, no gnd, gnd } ret.first = changed; return ret; @@ -210,8 +200,8 @@ namespace BlackMisc::Aviation const CAircraftSituationList sorted(alreadySortedLatestFirst ? (*this) : this->getSortedAdjustedLatestFirst()); const CAircraftSituation latest = sorted.front(); - if (latest.getOnGround() != CAircraftSituation::NotOnGround) { return false; } - const int c = this->countOnGround(CAircraftSituation::OnGround); + if (latest.getOnGroundInfo().getOnGround() != COnGroundInfo::NotOnGround) { return false; } + const int c = this->countOnGround(COnGroundInfo::OnGround); return this->size() - 1 == c; // all others on ground } @@ -221,21 +211,21 @@ namespace BlackMisc::Aviation const CAircraftSituationList sorted(alreadySortedLatestFirst ? (*this) : this->getSortedAdjustedLatestFirst()); const CAircraftSituation latest = sorted.front(); - if (latest.getOnGround() != CAircraftSituation::OnGround) { return false; } - const int c = this->countOnGround(CAircraftSituation::NotOnGround); + if (latest.getOnGroundInfo().getOnGround() != COnGroundInfo::OnGround) { return false; } + const int c = this->countOnGround(COnGroundInfo::NotOnGround); return this->size() - 1 == c; // all others not on ground } bool CAircraftSituationList::isTakingOff(bool alreadySortedLatestFirst) const { - const QPair r = this->isGndFlagStableChanging(alreadySortedLatestFirst); - return r.first && r.second == CAircraftSituation::NotOnGround; + const QPair r = this->isGndFlagStableChanging(alreadySortedLatestFirst); + return r.first && r.second == COnGroundInfo::NotOnGround; } bool CAircraftSituationList::isTouchingDown(bool alreadySortedLatestFirst) const { - const QPair r = this->isGndFlagStableChanging(alreadySortedLatestFirst); - return r.first && r.second == CAircraftSituation::OnGround; + const QPair r = this->isGndFlagStableChanging(alreadySortedLatestFirst); + return r.first && r.second == COnGroundInfo::OnGround; } bool CAircraftSituationList::isRotatingUp(bool alreadySortedLatestFirst) const @@ -258,14 +248,9 @@ namespace BlackMisc::Aviation return false; } - int CAircraftSituationList::countOnGround(CAircraftSituation::IsOnGround og) const + int CAircraftSituationList::countOnGround(COnGroundInfo::IsOnGround og) const { - int c = 0; - for (const CAircraftSituation &situation : *this) - { - if (situation.getOnGround() == og) { c++; } - } - return c; + return std::count_if(begin(), end(), [&og](const CAircraftSituation &situation) { return situation.getOnGroundInfo().getOnGround() == og; }); } CAircraftSituation CAircraftSituationList::findClosestElevationWithinRange(const ICoordinateGeodetic &coordinate, const CLength &range) const @@ -293,24 +278,20 @@ namespace BlackMisc::Aviation return situationWithElevation; } - int CAircraftSituationList::setOnGround(CAircraftSituation::IsOnGround og) + void CAircraftSituationList::setOnGroundInfo(const COnGroundInfo &info) { - int c = 0; for (CAircraftSituation &situation : *this) { - if (situation.setOnGround(og)) { c++; } + situation.setOnGroundInfo(info); } - return c; } - int CAircraftSituationList::setOnGroundDetails(CAircraftSituation::OnGroundDetails details) + void CAircraftSituationList::setOnGroundDetails(COnGroundInfo::OnGroundDetails details) { - int c = 0; for (CAircraftSituation &situation : *this) { - if (situation.setOnGroundDetails(details)) { c++; } + situation.setOnGroundDetails(details); } - return c; } int CAircraftSituationList::addAltitudeOffset(const CLength &offset) diff --git a/src/blackmisc/aviation/aircraftsituationlist.h b/src/blackmisc/aviation/aircraftsituationlist.h index fdc5704e6..c6e61585c 100644 --- a/src/blackmisc/aviation/aircraftsituationlist.h +++ b/src/blackmisc/aviation/aircraftsituationlist.h @@ -66,14 +66,14 @@ namespace BlackMisc int adjustGroundFlag(const CAircraftParts &parts, double timeDeviationFactor = 0.1); //! Contains on ground details? - bool containsOnGroundDetails(CAircraftSituation::OnGroundDetails details) const; + bool containsOnGroundDetails(COnGroundInfo::OnGroundDetails details) const; //! Contains any push back? //! \remark only valid for non VTOL aircraft bool containsPushBack() const; //! Are all on ground details the same? - bool areAllOnGroundDetailsSame(CAircraftSituation::OnGroundDetails details) const; + bool areAllOnGroundDetailsSame(COnGroundInfo::OnGroundDetails details) const; //! Are all situations on ground? bool isConstOnGround() const; @@ -94,7 +94,7 @@ namespace BlackMisc bool isConstDecelarating(bool alreadySortedLatestFirst = false) const; //! Is the ground flag changing for the situations - QPair isGndFlagStableChanging(bool alreadySortedLatestFirst = false) const; + QPair isGndFlagStableChanging(bool alreadySortedLatestFirst = false) const; //! Is just taking off? bool isJustTakingOff(bool alreadySortedLatestFirst = false) const; @@ -111,17 +111,17 @@ namespace BlackMisc //! Is rotating up? bool isRotatingUp(bool alreadySortedLatestFirst = false) const; - //! Count the number of situations with CAircraftSituation::IsOnGround - int countOnGround(CAircraftSituation::IsOnGround og) const; + //! Count the number of situations with COnGroundInfo::IsOnGround + int countOnGround(COnGroundInfo::IsOnGround og) const; //! CLosest elevation within given range CAircraftSituation findClosestElevationWithinRange(const Geo::ICoordinateGeodetic &coordinate, const PhysicalQuantities::CLength &range = Geo::CElevationPlane::singlePointRadius()) const; //! Set on ground - int setOnGround(CAircraftSituation::IsOnGround og); + void setOnGroundInfo(const COnGroundInfo &info); //! Set on ground details for all situations - int setOnGroundDetails(CAircraftSituation::OnGroundDetails details); + void setOnGroundDetails(COnGroundInfo::OnGroundDetails details); //! Add an offset to each altitude int addAltitudeOffset(const PhysicalQuantities::CLength &offset); diff --git a/src/blackmisc/aviation/ongroundinfo.cpp b/src/blackmisc/aviation/ongroundinfo.cpp new file mode 100644 index 000000000..1c3faf6cc --- /dev/null +++ b/src/blackmisc/aviation/ongroundinfo.cpp @@ -0,0 +1,180 @@ +// SPDX-FileCopyrightText: Copyright (C) swift Project Community / Contributors +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1 + +#include "blackmisc/aviation/ongroundinfo.h" +#include "blackmisc/verify.h" + +BLACK_DEFINE_VALUEOBJECT_MIXINS(BlackMisc::Aviation, COnGroundInfo) + +using namespace BlackMisc::PhysicalQuantities; + +namespace BlackMisc::Aviation +{ + + COnGroundInfo::COnGroundInfo(IsOnGround onGround, OnGroundDetails details) : m_onGroundDetails(static_cast(details)) + { + switch (onGround) + { + case IsOnGround::OnGroundSituationUnknown: + m_onGroundFactor = -1.0; + break; + case IsOnGround::OnGround: + m_onGroundFactor = 1.0; + break; + case IsOnGround::NotOnGround: + m_onGroundFactor = 0.0; + break; + } + } + + const QString &COnGroundInfo::isOnGroundToString(IsOnGround onGround) + { + static const QString notog("not on ground"); + static const QString og("on ground"); + static const QString unknown("unknown"); + + switch (onGround) + { + case IsOnGround::NotOnGround: return notog; + case IsOnGround::OnGround: return og; + case IsOnGround::OnGroundSituationUnknown: + default: return unknown; + } + } + + const QString &COnGroundInfo::onGroundDetailsToString(OnGroundDetails reliability) + { + static const QString elvCg("elevation/CG"); + static const QString interpolation("interpolation"); + static const QString guess("guessing"); + static const QString unknown("unknown"); + static const QString outOwnAircraft("own aircraft"); + static const QString inNetwork("from network"); + static const QString inFromParts("from parts"); + + switch (reliability) + { + case OnGroundDetails::OnGroundByElevationAndCG: return elvCg; + case OnGroundDetails::OnGroundByGuessing: return guess; + case OnGroundDetails::OnGroundByInterpolation: return interpolation; + case OnGroundDetails::OutOnGroundOwnAircraft: return outOwnAircraft; + case OnGroundDetails::InFromNetwork: return inNetwork; + case OnGroundDetails::InFromParts: return inFromParts; + case OnGroundDetails::NotSetGroundDetails: + default: return unknown; + } + } + + void COnGroundInfo::registerMetadata() + { + CValueObject::registerMetadata(); + qRegisterMetaType(); + qRegisterMetaType(); + } + + COnGroundInfo::COnGroundInfo(double interpolatedGndFactor) : m_onGroundDetails(static_cast(OnGroundDetails::OnGroundByInterpolation)), m_onGroundFactor(interpolatedGndFactor) + { + // Clip small ground factor values + if (m_onGroundFactor < 0.0) + { + m_onGroundFactor = -1.0; + } + else if (m_onGroundFactor < 0.001) + { + m_onGroundFactor = 0.0; + } + else if (m_onGroundFactor > 0.999) + { + m_onGroundFactor = 1.0; + } + } + + COnGroundInfo::COnGroundInfo(const CLength &cg, const CLength &groundDistance) + { + m_onGroundDetails = static_cast(OnGroundDetails::OnGroundByElevationAndCG); + if (groundDistance.isNull()) + { + m_onGroundFactor = -1.0; + } + else if (groundDistance.isNegativeWithEpsilonConsidered()) { m_onGroundFactor = 1.0; } + else if (groundDistance.abs() < deltaNearGround()) { m_onGroundFactor = 1.0; } + else if (!cg.isNull()) + { + // smaller than percentage from CG + const CLength cgFactor(cg * 0.1); + if (groundDistance.abs() < cgFactor.abs()) { m_onGroundFactor = 1.0; } + } + m_onGroundFactor = 0.0; + } + + bool COnGroundInfo::isOnGround() const + { + BLACK_VERIFY_X(m_onGroundFactor >= 0.0, Q_FUNC_INFO, "Should only be called with positive groundfactors"); + if (m_onGroundDetails == OnGroundDetails::OnGroundByInterpolation) + { + return m_onGroundFactor > m_groundFactorThreshold; + } + else + { + return Math::CMathUtils::epsilonEqual(m_onGroundFactor, 1.0); + } + } + + COnGroundInfo::IsOnGround COnGroundInfo::getOnGround() const + { + if (this->m_onGroundFactor < 0.0) + { + return OnGroundSituationUnknown; + } + + const bool onGround = isOnGround(); + return onGround ? OnGround : NotOnGround; + } + + COnGroundInfo::OnGroundDetails COnGroundInfo::getGroundDetails() const + { + return static_cast(m_onGroundDetails); + } + + const CLength &COnGroundInfo::deltaNearGround() + { + static const CLength small(0.5, CLengthUnit::m()); + return small; + } + + QString COnGroundInfo::convertToQString(bool /*i18n*/) const + { + return u" | factor: " % QString::number(m_onGroundFactor, 'f', 2) % + u" | source: " % onGroundDetailsToString(static_cast(m_onGroundDetails)); + } + + QVariant COnGroundInfo::propertyByIndex(CPropertyIndexRef index) const + { + if (index.isMyself()) { return QVariant::fromValue(*this); } + + const ColumnIndex i = index.frontCasted(); + switch (i) + { + case IndexOnGroundFactor: return QVariant::fromValue(m_onGroundFactor); + case IndexOnGroundDetails: return QVariant::fromValue(m_onGroundDetails); + default: return CValueObject::propertyByIndex(index); + } + } + + void COnGroundInfo::setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant) + { + if (index.isMyself()) + { + (*this) = variant.value(); + return; + } + + const ColumnIndex i = index.frontCasted(); + switch (i) + { + case IndexOnGroundFactor: m_onGroundFactor = variant.toDouble(); break; + case IndexOnGroundDetails: m_onGroundDetails = variant.toInt(); break; + default: CValueObject::setPropertyByIndex(index, variant); break; + } + } +} diff --git a/src/blackmisc/aviation/ongroundinfo.h b/src/blackmisc/aviation/ongroundinfo.h new file mode 100644 index 000000000..3694e8aa8 --- /dev/null +++ b/src/blackmisc/aviation/ongroundinfo.h @@ -0,0 +1,130 @@ +// SPDX-FileCopyrightText: Copyright (C) swift Project Community / Contributors +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1 + +//! \file + +#ifndef BLACKMISC_AVIATION_ONGROUNDINFO_H +#define BLACKMISC_AVIATION_ONGROUNDINFO_H + +#include "blackmisc/blackmiscexport.h" +#include "blackmisc/valueobject.h" +#include "blackmisc/pq/length.h" + +BLACK_DECLARE_VALUEOBJECT_MIXINS(BlackMisc::Aviation, COnGroundInfo) + +namespace BlackMisc::Aviation +{ + //! Information about the ground status + class BLACKMISC_EXPORT COnGroundInfo : public CValueObject + { + public: + //! Is on ground? + enum IsOnGround + { + NotOnGround, + OnGround, + OnGroundSituationUnknown + }; + + //! Reliability of on ground information + enum OnGroundDetails + { + NotSetGroundDetails, + // interpolated situation + OnGroundByInterpolation, //!< strongest for remote aircraft + OnGroundByElevationAndCG, + OnGroundByGuessing, //!< weakest + // received situation + InFromNetwork, //!< received from network + InFromParts, //!< set from aircraft parts + // send information + OutOnGroundOwnAircraft //!< sending on ground + }; + + //! Properties by index + enum ColumnIndex + { + IndexOnGroundFactor = CPropertyIndexRef::GlobalIndexCOnGroundInfo, + IndexOnGroundDetails, + }; + + COnGroundInfo() = default; + + //! Create GroundInfo with fixed decision (on ground, not on ground or not known) and with + //! info about the source of this knowledge + COnGroundInfo(IsOnGround onGround, OnGroundDetails details); + + //! Create GroundInfo from information about CG and distance from ground + COnGroundInfo(const PhysicalQuantities::CLength &cg, const PhysicalQuantities::CLength &groundDistance); + + //! Create GroundInfo from interpolated ground factor + explicit COnGroundInfo(double interpolatedGndFactor); + + //! Get the ground factor + //! Use this for interpolation only!! + //! For just checking if the info is OnGround or NotOnGround use the getOnGround() method instead. + double getGroundFactor() const { return m_onGroundFactor; } + + //! When source of knowledge changes + void setOnGroundDetails(OnGroundDetails details) + { + // TODO Assert not by interpolation + m_onGroundDetails = static_cast(details); + } + + //! Is on ground? + //! \return IsOnGround state of this object + IsOnGround getOnGround() const; + + //! Get ground details + //! \return ground details of this object + OnGroundDetails getGroundDetails() const; + + //! \copydoc Mixin::String::toQString + QString convertToQString(bool i18n = false) const; + + //! \copydoc Mixin::Index::propertyByIndex + QVariant propertyByIndex(CPropertyIndexRef index) const; + + //! \copydoc Mixin::Index::setPropertyByIndex + void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant); + + //! Register metadata + static void registerMetadata(); + + //! Enum to string + static const QString &isOnGroundToString(IsOnGround onGround); + + //! Enum to string + static const QString &onGroundDetailsToString(OnGroundDetails reliability); + + //! Delta distance, near to ground + static const PhysicalQuantities::CLength &deltaNearGround(); + + private: + //! Check if the aircraft is considered to be on the ground. + //! Depending on the data source, different definitions are used on when the aircraft + //! is considered to be on the ground. + //! This method should only be called when the m_onGroundFactor is >= 0.0, as it is only does a binary + //! decision. + //! \return true, if the aircraft is considered to be on the ground + bool isOnGround() const; + + int m_onGroundDetails = static_cast(OnGroundDetails::NotSetGroundDetails); + double m_onGroundFactor = -1.0; //!< interpolated ground flag, 1..on ground, 0..not on ground, -1 no info + + static constexpr double m_groundFactorThreshold = 0.95; //!< With m_onGroundDetails == "OnGroundByInterpolation", this is the threshold used to decide if the ground factor is OnGround or NotOnGround + + BLACK_METACLASS( + COnGroundInfo, + BLACK_METAMEMBER(onGroundDetails), + BLACK_METAMEMBER(onGroundFactor)); + }; + +} + +Q_DECLARE_METATYPE(BlackMisc::Aviation::COnGroundInfo) +Q_DECLARE_METATYPE(BlackMisc::Aviation::COnGroundInfo::IsOnGround) +Q_DECLARE_METATYPE(BlackMisc::Aviation::COnGroundInfo::OnGroundDetails) + +#endif // BLACKMISC_AVIATION_ONGROUNDINFO_H diff --git a/src/blackmisc/aviation/registermetadataaviation.cpp b/src/blackmisc/aviation/registermetadataaviation.cpp index 4be49089d..75443748c 100644 --- a/src/blackmisc/aviation/registermetadataaviation.cpp +++ b/src/blackmisc/aviation/registermetadataaviation.cpp @@ -39,6 +39,7 @@ #include "blackmisc/aviation/aircraftpartslist.h" #include "blackmisc/aviation/livery.h" #include "blackmisc/aviation/liverylist.h" +#include "blackmisc/aviation/ongroundinfo.h" namespace BlackMisc { @@ -86,6 +87,7 @@ namespace BlackMisc CSelcal::registerMetadata(); CTrack::registerMetadata(); CTransponder::registerMetadata(); + COnGroundInfo::registerMetadata(); } } diff --git a/src/blackmisc/network/clientprovider.cpp b/src/blackmisc/network/clientprovider.cpp index e0bcdb463..f2bb27d48 100644 --- a/src/blackmisc/network/clientprovider.cpp +++ b/src/blackmisc/network/clientprovider.cpp @@ -107,7 +107,7 @@ namespace BlackMisc::Network { if (situation.getCallsign().isEmpty()) { return false; } // no callsign if (!situation.isOnGround()) { return false; } // nothing to adjust - if (situation.getOnGroundDetails() != CAircraftSituation::InFromNetwork) { return false; } // not from network + if (situation.getOnGroundInfo().getGroundDetails() != COnGroundInfo::InFromNetwork) { return false; } // not from network return this->addClientGndCapability(situation.getCallsign()); } diff --git a/src/blackmisc/propertyindexref.h b/src/blackmisc/propertyindexref.h index 9315d2900..b7cd82fb6 100644 --- a/src/blackmisc/propertyindexref.h +++ b/src/blackmisc/propertyindexref.h @@ -60,6 +60,7 @@ namespace BlackMisc GlobalIndexCPresentWeather = 4200, GlobalIndexCWindLayer = 4300, GlobalIndexCWeatherScenario = 4700, + GlobalIndexCOnGroundInfo = 4800, GlobalIndexICoordinateGeodetic = 5000, GlobalIndexICoordinateWithRelativePosition = 5100, GlobalIndexCCoordinateGeodetic = 5200, diff --git a/src/blackmisc/simulation/interpolationlogger.cpp b/src/blackmisc/simulation/interpolationlogger.cpp index d66ef76a5..0e1322340 100644 --- a/src/blackmisc/simulation/interpolationlogger.cpp +++ b/src/blackmisc/simulation/interpolationlogger.cpp @@ -361,9 +361,9 @@ namespace BlackMisc::Simulation u"" % log.situationCurrent.getGroundElevation().valueRoundedWithUnit(ft, 1) % u" " % log.situationCurrent.getGroundElevationInfoAsString() % u"" % u"" % QString::number(log.groundFactor) % u"" % - u"" % situationOld.getOnGroundInfo() % u"" % - u"" % situationNew.getOnGroundInfo() % u"" % - u"" % log.situationCurrent.getOnGroundInfo() % u"" % + u"" % situationOld.getOnGroundInfo().toQString() % u"" % + u"" % situationNew.getOnGroundInfo().toQString() % u"" % + u"" % log.situationCurrent.getOnGroundInfo().toQString() % u"" % // tableRows += u"" % log.cgAboveGround.valueRoundedWithUnit(ft, 0) % u"" % diff --git a/src/blackmisc/simulation/interpolator.cpp b/src/blackmisc/simulation/interpolator.cpp index b5a89038f..71a431f50 100644 --- a/src/blackmisc/simulation/interpolator.cpp +++ b/src/blackmisc/simulation/interpolator.cpp @@ -74,14 +74,6 @@ namespace BlackMisc::Simulation return cg; } - template - double CInterpolator::groundInterpolationFactor() - { - // done here so we can change value without "larfer" recompilations - static constexpr double f = 0.95; - return f; - } - template CAircraftSituationList CInterpolator::remoteAircraftSituationsAndChange(const CInterpolationAndRenderingSetupPerCallsign &setup) { @@ -181,10 +173,10 @@ namespace BlackMisc::Simulation if (setup.isNull() || !setup.isAircraftPartsEnabled()) { return sorted; } bool details = false; - if (situations.containsOnGroundDetails(CAircraftSituation::InFromParts)) + if (situations.containsOnGroundDetails(COnGroundInfo::InFromParts)) { // if a client supports parts, all ground situations are supposed to be parts based - details = situations.areAllOnGroundDetailsSame(CAircraftSituation::InFromParts); + details = situations.areAllOnGroundDetailsSame(COnGroundInfo::InFromParts); BLACK_VERIFY_X(details, Q_FUNC_INFO, "Once gnd.from parts -> always gnd. from parts"); } @@ -300,7 +292,7 @@ namespace BlackMisc::Simulation } // correct altitude itself - if (!interpolateGndFlag && currentSituation.getOnGroundDetails() != CAircraftSituation::OnGroundByGuessing) + if (!interpolateGndFlag && currentSituation.getOnGroundInfo().getGroundDetails() != COnGroundInfo::OnGroundByGuessing) { // just in case altCorrection = currentSituation.correctAltitude(true); // we have CG set @@ -377,7 +369,7 @@ namespace BlackMisc::Simulation { log.tsCurrent = m_currentTimeMsSinceEpoch; log.callsign = m_callsign; - log.groundFactor = currentSituation.getOnGroundFactor(); + log.groundFactor = currentSituation.getOnGroundInfo().getGroundFactor(); log.altCorrection = CAircraftSituation::altitudeCorrectionToString(altCorrection); log.situationCurrent = currentSituation; log.interpolantRecalc = interpolant.isRecalculated(); @@ -524,7 +516,7 @@ namespace BlackMisc::Simulation CLength guessedCG = model.getCG(); model.getAircraftIcaoCode().guessModelParameters(guessedCG, guessedVRotate); - if (situation.getOnGroundDetails() != CAircraftSituation::NotSetGroundDetails) + if (situation.getOnGroundInfo().getGroundDetails() != COnGroundInfo::NotSetGroundDetails) { do { @@ -613,10 +605,10 @@ namespace BlackMisc::Simulation } else { - if (situation.getOnGroundDetails() != CAircraftSituation::NotSetGroundDetails) + if (situation.getOnGroundInfo().getGroundDetails() != COnGroundInfo::NotSetGroundDetails) { // we have no ground elevation but a ground info - if (situation.getOnGroundDetails() == CAircraftSituation::OnGroundByGuessing) + if (situation.getOnGroundInfo().getGroundDetails() == COnGroundInfo::OnGroundByGuessing) { // should be OK if (details) { *details = QStringLiteral("on ground, no elv."); } diff --git a/src/blackmisc/simulation/interpolator.h b/src/blackmisc/simulation/interpolator.h index f7fd2db99..cffa36545 100644 --- a/src/blackmisc/simulation/interpolator.h +++ b/src/blackmisc/simulation/interpolator.h @@ -113,10 +113,6 @@ namespace BlackMisc::Simulation //! Do logging bool doLogging() const; - //! Decides threshold when situation is considered on ground - //! \sa BlackMisc::Aviation::CAircraftSituation::setOnGroundFromGroundFactorFromInterpolation - static double groundInterpolationFactor(); - const Aviation::CCallsign m_callsign; //!< corresponding callsign CAircraftModel m_model; //!< corresponding model (required for CG) diff --git a/src/blackmisc/simulation/interpolatorlinear.cpp b/src/blackmisc/simulation/interpolatorlinear.cpp index ed08aa703..4e7a32468 100644 --- a/src/blackmisc/simulation/interpolatorlinear.cpp +++ b/src/blackmisc/simulation/interpolatorlinear.cpp @@ -84,21 +84,20 @@ namespace BlackMisc::Simulation if (interpolateGndFactor) { - const double startGroundFactor = m_startSituation.getOnGroundFactor(); - const double endGroundFactor = m_endSituation.getOnGroundFactor(); + const double startGroundFactor = m_startSituation.getOnGroundInfo().getGroundFactor(); + const double endGroundFactor = m_endSituation.getOnGroundInfo().getGroundFactor(); if (CAircraftSituation::isGfEqualAirborne(startGroundFactor, endGroundFactor)) { - interpolatedSituation.setOnGround(false); + interpolatedSituation.setOnGroundInfo({ COnGroundInfo::NotOnGround, COnGroundInfo::OnGroundByInterpolation }); } else if (CAircraftSituation::isGfEqualOnGround(startGroundFactor, endGroundFactor)) { - interpolatedSituation.setOnGround(true); + interpolatedSituation.setOnGroundInfo({ COnGroundInfo::OnGround, COnGroundInfo::OnGroundByInterpolation }); } else { const double interpolatedGroundFactor = (endGroundFactor - startGroundFactor) * tf + startGroundFactor; - interpolatedSituation.setOnGroundFactor(interpolatedGroundFactor); - interpolatedSituation.setOnGroundFromGroundFactorFromInterpolation(groundInterpolationFactor()); + interpolatedSituation.setOnGroundInfo(COnGroundInfo(interpolatedGroundFactor)); } } return interpolatedSituation; diff --git a/src/blackmisc/simulation/interpolatorspline.cpp b/src/blackmisc/simulation/interpolatorspline.cpp index f1de92ba2..0fbbcdebe 100644 --- a/src/blackmisc/simulation/interpolatorspline.cpp +++ b/src/blackmisc/simulation/interpolatorspline.cpp @@ -218,7 +218,7 @@ namespace BlackMisc::Simulation const double a1 = m_s[1].getCorrectedAltitude(cg).value(altUnit); const double a2 = m_s[2].getCorrectedAltitude(cg).value(altUnit); // latest pa.a = { { a0, a1, a2 } }; - pa.gnd = { { m_s[0].getOnGroundFactor(), m_s[1].getOnGroundFactor(), m_s[2].getOnGroundFactor() } }; + pa.gnd = { { m_s[0].getOnGroundInfo().getGroundFactor(), m_s[1].getOnGroundInfo().getGroundFactor(), m_s[2].getOnGroundInfo().getGroundFactor() } }; pa.da = getDerivatives(pa.t, pa.a); pa.dgnd = getDerivatives(pa.t, pa.gnd); @@ -365,24 +365,20 @@ namespace BlackMisc::Simulation { const double gnd1 = m_pa.gnd[1]; const double gnd2 = m_pa.gnd[2]; // latest - do + + if (CAircraftSituation::isGfEqualAirborne(gnd1, gnd2)) { - newSituation.setOnGroundDetails(CAircraftSituation::OnGroundByInterpolation); - if (CAircraftSituation::isGfEqualAirborne(gnd1, gnd2)) - { - newSituation.setOnGround(false); - break; - } - if (CAircraftSituation::isGfEqualOnGround(gnd1, gnd2)) - { - newSituation.setOnGround(true); - break; - } - const double newGnd = evalSplineInterval(m_currentTimeMsSinceEpoc, t1, t2, gnd1, gnd2, m_pa.dgnd[1], m_pa.dgnd[2]); - newSituation.setOnGroundFactor(newGnd); - newSituation.setOnGroundFromGroundFactorFromInterpolation(groundInterpolationFactor()); + newSituation.setOnGroundInfo({ COnGroundInfo::NotOnGround, COnGroundInfo::OnGroundByInterpolation }); + } + else if (CAircraftSituation::isGfEqualOnGround(gnd1, gnd2)) + { + newSituation.setOnGroundInfo({ COnGroundInfo::OnGround, COnGroundInfo::OnGroundByInterpolation }); + } + else + { + const double newGnd = evalSplineInterval(m_currentTimeMsSinceEpoc, t1, t2, gnd1, gnd2, m_pa.dgnd[1], m_pa.dgnd[2]); + newSituation.setOnGroundInfo(COnGroundInfo(newGnd)); } - while (false); } return newSituation; } diff --git a/src/blackmisc/simulation/remoteaircraftprovider.cpp b/src/blackmisc/simulation/remoteaircraftprovider.cpp index 0cea6e2c2..8a7e6d485 100644 --- a/src/blackmisc/simulation/remoteaircraftprovider.cpp +++ b/src/blackmisc/simulation/remoteaircraftprovider.cpp @@ -303,7 +303,7 @@ namespace BlackMisc::Simulation // unify all inbound ground information if (situation.hasInboundGroundDetails()) { - newSituationsList.setOnGroundDetails(situation.getOnGroundDetails()); + newSituationsList.setOnGroundDetails(situation.getOnGroundInfo().getGroundDetails()); } } m_latestSituationByCallsign[cs] = situationCorrected; diff --git a/src/plugins/simulator/flightgear/fgswiftbustrafficproxy.h b/src/plugins/simulator/flightgear/fgswiftbustrafficproxy.h index bda06f6d1..50b8f66a4 100644 --- a/src/plugins/simulator/flightgear/fgswiftbustrafficproxy.h +++ b/src/plugins/simulator/flightgear/fgswiftbustrafficproxy.h @@ -59,7 +59,7 @@ namespace BlackSimPlugin::Flightgear this->pitchesDeg.push_back(situation.getPitch().value(BlackMisc::PhysicalQuantities::CAngleUnit::deg())); this->rollsDeg.push_back(situation.getBank().value(BlackMisc::PhysicalQuantities::CAngleUnit::deg())); this->headingsDeg.push_back(situation.getHeading().value(BlackMisc::PhysicalQuantities::CAngleUnit::deg())); - this->onGrounds.push_back(situation.getOnGround() == BlackMisc::Aviation::CAircraftSituation::OnGround); + this->onGrounds.push_back(situation.isOnGround()); this->groundSpeedKts.push_back(situation.getGroundSpeed().value(BlackMisc::PhysicalQuantities::CSpeedUnit::kts())); } diff --git a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp index a84917c4a..b9c3d2a0d 100644 --- a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp +++ b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp @@ -652,7 +652,7 @@ namespace BlackSimPlugin::FsxCommon aircraftSituation.setPressureAltitude(CAltitude(simulatorOwnAircraft.pressureAltitudeM, CAltitude::MeanSeaLevel, CAltitude::PressureAltitude, CLengthUnit::m())); // set on ground also in situation for consistency and future usage // it is duplicated in parts - aircraftSituation.setOnGround(dtb(simulatorOwnAircraft.simOnGround) ? CAircraftSituation::OnGround : CAircraftSituation::NotOnGround, CAircraftSituation::OutOnGroundOwnAircraft); + aircraftSituation.setOnGroundInfo({ dtb(simulatorOwnAircraft.simOnGround) ? COnGroundInfo::OnGround : COnGroundInfo::NotOnGround, COnGroundInfo::OutOnGroundOwnAircraft }); CAircraftVelocity aircraftVelocity(simulatorOwnAircraft.velocityWorldX, simulatorOwnAircraft.velocityWorldY, @@ -2236,7 +2236,7 @@ namespace BlackSimPlugin::FsxCommon // send GND flag also when underflow detection is available if ((sendGnd || forceUnderflowDetection) && situation.isOnGroundInfoAvailable()) { - const bool onGround = (situation.getOnGround() == CAircraftSituation::OnGround); + const bool onGround = situation.isOnGround(); position.OnGround = onGround ? 1U : 0U; } diff --git a/src/plugins/simulator/xplane/simulatorxplane.cpp b/src/plugins/simulator/xplane/simulatorxplane.cpp index 1b6092f06..4eb68998b 100644 --- a/src/plugins/simulator/xplane/simulatorxplane.cpp +++ b/src/plugins/simulator/xplane/simulatorxplane.cpp @@ -953,7 +953,7 @@ namespace BlackSimPlugin::XPlane // adjust altitude to compensate for XP12 temperature effect const CLength relativeAltitude = interpolatedSituation.geodeticHeight() - getOwnAircraftPosition().geodeticHeight(); const double altitudeDeltaWeight = 2 - qBound(3000.0, relativeAltitude.abs().value(CLengthUnit::ft()), 6000.0) / 3000; - const CLength alt = interpolatedSituation.getAltitude() + m_altitudeDelta * altitudeDeltaWeight * (1 - interpolatedSituation.getOnGroundFactor()); + const CLength alt = interpolatedSituation.getAltitude() + m_altitudeDelta * altitudeDeltaWeight * (1 - interpolatedSituation.getOnGroundInfo().getGroundFactor()); interpolatedSituation.setAltitude({ alt, interpolatedSituation.getAltitude().getReferenceDatum() }); // update situation diff --git a/src/plugins/simulator/xplane/xswiftbustrafficproxy.h b/src/plugins/simulator/xplane/xswiftbustrafficproxy.h index 1eedc6b5f..0d0ab285c 100644 --- a/src/plugins/simulator/xplane/xswiftbustrafficproxy.h +++ b/src/plugins/simulator/xplane/xswiftbustrafficproxy.h @@ -63,7 +63,7 @@ namespace BlackSimPlugin::XPlane this->pitchesDeg.push_back(situation.getPitch().value(BlackMisc::PhysicalQuantities::CAngleUnit::deg())); this->rollsDeg.push_back(situation.getBank().value(BlackMisc::PhysicalQuantities::CAngleUnit::deg())); this->headingsDeg.push_back(situation.getHeading().value(BlackMisc::PhysicalQuantities::CAngleUnit::deg())); - this->onGrounds.push_back(situation.getOnGround() == BlackMisc::Aviation::CAircraftSituation::OnGround); + this->onGrounds.push_back(situation.isOnGround()); } QStringList callsigns; //!< List of callsigns diff --git a/tests/blackmisc/aviation/testaircraftsituation/testaircraftsituation.cpp b/tests/blackmisc/aviation/testaircraftsituation/testaircraftsituation.cpp index 7e0ebbf47..334f2a41e 100644 --- a/tests/blackmisc/aviation/testaircraftsituation/testaircraftsituation.cpp +++ b/tests/blackmisc/aviation/testaircraftsituation/testaircraftsituation.cpp @@ -76,7 +76,7 @@ namespace BlackMiscTest void CTestAircraftSituation::allGndFlagsAndTakeOff() const { CAircraftSituationList situations = testSituations(); - situations.setOnGround(CAircraftSituation::OnGround); + situations.setOnGroundInfo({ COnGroundInfo::OnGround, COnGroundInfo::NotSetGroundDetails }); const CAircraftSituationChange change(situations, cg(), false); QVERIFY2(change.isConstOnGround(), "Expect const on ground"); QVERIFY(!change.isConstNotOnGround()); @@ -87,7 +87,7 @@ namespace BlackMiscTest QVERIFY(situations.isSortedAdjustedLatestFirstWithoutNullPositions()); CAircraftSituation f = situations.front(); - f.setOnGround(false); + f.setOnGroundInfo({ COnGroundInfo::NotOnGround, COnGroundInfo::NotSetGroundDetails }); situations.pop_front(); situations.push_front(f); const CAircraftSituationChange change2(situations, cg(), false); @@ -100,7 +100,7 @@ namespace BlackMiscTest void CTestAircraftSituation::allNotGndFlagsAndTouchdown() const { CAircraftSituationList situations = testSetDescendingAltitudes(testSituations()); - situations.setOnGround(CAircraftSituation::NotOnGround); + situations.setOnGroundInfo({ COnGroundInfo::NotOnGround, COnGroundInfo::NotSetGroundDetails }); const CAircraftSituationChange change(situations, cg(), false); QVERIFY2(change.isConstNotOnGround(), "Expect const not on ground"); QVERIFY(!change.isConstOnGround()); @@ -111,7 +111,7 @@ namespace BlackMiscTest QVERIFY(situations.isSortedAdjustedLatestFirstWithoutNullPositions()); CAircraftSituation f = situations.front(); - f.setOnGround(true); + f.setOnGroundInfo({ COnGroundInfo::OnGround, COnGroundInfo::NotSetGroundDetails }); situations.pop_front(); situations.push_front(f); const CAircraftSituationChange change2(situations, cg(), false); @@ -215,7 +215,8 @@ namespace BlackMiscTest corAlt = situation.getCorrectedAltitude(true, &correction); QVERIFY2(corAlt == alt, "Expect same altitude, no overflow since not on gnd."); - situation.setOnGround(CAircraftSituation::OnGround, CAircraftSituation::InFromNetwork); + situation.setOnGroundInfo({ COnGroundInfo::OnGround, COnGroundInfo::InFromNetwork }); + corAlt = situation.getCorrectedAltitude(true, &correction); QVERIFY2(correction == CAircraftSituation::DraggedToGround, "Expect dragged to gnd."); QVERIFY2(corAlt < alt, "Expect corrected altitude dragged to gnd."); diff --git a/tests/blackmisc/simulation/testinterpolatorparts/testinterpolatorparts.cpp b/tests/blackmisc/simulation/testinterpolatorparts/testinterpolatorparts.cpp index 42c7548dc..258237254 100644 --- a/tests/blackmisc/simulation/testinterpolatorparts/testinterpolatorparts.cpp +++ b/tests/blackmisc/simulation/testinterpolatorparts/testinterpolatorparts.cpp @@ -132,27 +132,27 @@ namespace BlackMiscTest for (int i = 0; i < number; i++) { CAircraftSituation s = createTestSituation(cs, i, ts, deltaT, 0); - s.setOnGround(CAircraftSituation::OnGroundSituationUnknown, CAircraftSituation::NotSetGroundDetails); + s.setOnGroundInfo({ COnGroundInfo::OnGroundSituationUnknown, COnGroundInfo::NotSetGroundDetails }); situations.push_back(s); } CAircraftSituation s0 = situations[0]; s0.adjustGroundFlag(partsOnGround, true); - QVERIFY2(s0.getOnGround(), "Supposed to be on ground"); + QVERIFY2(s0.getOnGroundInfo().getOnGround(), "Supposed to be on ground"); s0 = situations[0]; s0.adjustGroundFlag(partsNotOnGround, true); - QVERIFY2(!s0.getOnGround(), "Supposed to be not on ground"); + QVERIFY2(!s0.getOnGroundInfo().getOnGround(), "Supposed to be not on ground"); qint64 distanceMs = -1; const qint64 Offset = 33; partsOnGround.addMsecsToOffset(Offset); CAircraftSituation s1 = situations[1]; - s1.setOnGroundDetails(CAircraftSituation::NotSetGroundDetails); + s1.setOnGroundInfo({ COnGroundInfo::OnGroundSituationUnknown, COnGroundInfo::NotSetGroundDetails }); s1.adjustGroundFlag(partsOnGround, true, 0.1, &distanceMs); - QVERIFY2(s1.getOnGround(), "Supposed to be on ground"); + QVERIFY2(s1.getOnGroundInfo().getOnGround(), "Supposed to be on ground"); QVERIFY2(distanceMs == deltaT - Offset, "Offset time wrong"); - QVERIFY2(s1.getOnGroundDetails() == CAircraftSituation::InFromParts, "Wrong details"); + QVERIFY2(s1.getOnGroundInfo().getGroundDetails() == COnGroundInfo::InFromParts, "Wrong details"); } CAircraftParts CTestInterpolatorParts::createTestParts(int number, qint64 ts, qint64 deltaT, bool onGround)