diff --git a/src/blackmisc/aviation/aircraftparts.cpp b/src/blackmisc/aviation/aircraftparts.cpp index 27a5cbaf7..e24f4d5d8 100644 --- a/src/blackmisc/aviation/aircraftparts.cpp +++ b/src/blackmisc/aviation/aircraftparts.cpp @@ -14,6 +14,7 @@ #include "aircraftsituationchange.h" #include "blackmisc/comparefunctions.h" #include "blackmisc/stringutils.h" +#include "blackmisc/verify.h" #include "blackconfig/buildconfig.h" #include "QStringBuilder" @@ -152,9 +153,16 @@ namespace BlackMisc if (situation.hasGroundElevation()) { + const CLength aboveGnd = situation.getHeightAboveGround(); + if (aboveGnd.isNull() || std::isnan(aboveGnd.value())) + { + BLACK_VERIFY_X(false, Q_FUNC_INFO, "above gnd.is null"); + return parts; + } + const double nearGround1Ft = 300; const double nearGround2Ft = isLikelyTakeOffOrClimbing ? 500 : 1000; - const double aGroundFt = situation.getHeightAboveGround().value(CLengthUnit::ft()); + const double aGroundFt = aboveGnd.value(CLengthUnit::ft()); static const QString detailsInfo("above ground: %1ft near grounds: %2ft %3ft likely takeoff: %4 likely landing: %5"); if (details) { *details = detailsInfo.arg(aGroundFt).arg(nearGround1Ft).arg(nearGround2Ft).arg(boolToYesNo(isLikelyTakeOffOrClimbing), boolToYesNo(isLikelyLanding)); } @@ -325,7 +333,7 @@ namespace BlackMisc void CAircraftParts::guessParts(const CAircraftSituation &situation, const CAircraftSituationChange &change, const CAircraftModel &model) { - *this = guessedParts(situation, change, model); + *this = CAircraftParts::guessedParts(situation, change, model); } } // namespace } // namespace diff --git a/src/blackmisc/aviation/aircraftsituation.cpp b/src/blackmisc/aviation/aircraftsituation.cpp index 7ea85dac2..501f29728 100644 --- a/src/blackmisc/aviation/aircraftsituation.cpp +++ b/src/blackmisc/aviation/aircraftsituation.cpp @@ -241,8 +241,12 @@ namespace BlackMisc if (!situation.isNull()) { - const double distanceOldNewM = (distance.isNull() ? oldSituation.calculateGreatCircleDistance(newSituation) : distance).value(CLengthUnit::m()); const double distanceSituationNewM = situation.calculateGreatCircleDistance(newSituation).value(CLengthUnit::m()); + if (distanceSituationNewM < 5.0) { return newSituation.getGroundElevationPlane(); } + + const double distanceOldNewM = (distance.isNull() ? oldSituation.calculateGreatCircleDistance(newSituation) : distance).value(CLengthUnit::m()); + if (distanceOldNewM < 5.0) { return oldSituation.getGroundElevationPlane(); } + const double distRatio = distanceSituationNewM / distanceOldNewM; // very close to the situations we return tehir elevation @@ -785,15 +789,30 @@ namespace BlackMisc CLength CAircraftSituation::getHeightAboveGround() const { - if (this->getAltitude().isNull()) { return { 0, nullptr }; } + if (this->getAltitude().isNull()) { return CLength::null(); } if (this->getAltitude().getReferenceDatum() == CAltitude::AboveGround) { // we have a sure value explicitly set return this->getAltitude(); } + const CLength gh(this->getGroundElevation()); - if (gh.isNull()) { return { 0, nullptr }; } - return this->getAltitude() - gh; + if (gh.isNull()) { return CLength::null(); } + + // sanity checks + if (std::isnan(gh.value())) + { + BLACK_VERIFY_X(false, Q_FUNC_INFO, "nan ground"); + return CLength::null(); + } + if (std::isnan(this->getAltitude().value())) + { + BLACK_VERIFY_X(false, Q_FUNC_INFO, "nan altitude"); + return CLength::null(); + } + + const CLength ag = this->getAltitude() - gh; + return ag; } const CLengthUnit &CAircraftSituation::getAltitudeOrDefaultUnit() const diff --git a/src/blackmisc/geo/elevationplane.cpp b/src/blackmisc/geo/elevationplane.cpp index feb65a364..75f69acd7 100644 --- a/src/blackmisc/geo/elevationplane.cpp +++ b/src/blackmisc/geo/elevationplane.cpp @@ -52,7 +52,9 @@ namespace BlackMisc CElevationPlane::CElevationPlane(double latDeg, double lngDeg, double altitudeMSLft, const CLength &radius) : CCoordinateGeodetic(latDeg, lngDeg, altitudeMSLft), m_radius(radius) - { } + { + Q_ASSERT_X(!std::isnan(altitudeMSLft), Q_FUNC_INFO, "elv.nan"); + } void CElevationPlane::setRadiusOrMinimum(const CLength &radius) { @@ -93,7 +95,7 @@ namespace BlackMisc bool CElevationPlane::isWithinRange(const ICoordinateGeodetic &coordinate) const { if (coordinate.isNull()) { return false; } - if (isNull()) { return false; } + if (this->isNull()) { return false; } const CLength d = this->calculateGreatCircleDistance(coordinate); const bool inRange = (m_radius >= d); return inRange; diff --git a/src/blackmisc/pq/physicalquantity.cpp b/src/blackmisc/pq/physicalquantity.cpp index 436d06b87..ea993ef2f 100644 --- a/src/blackmisc/pq/physicalquantity.cpp +++ b/src/blackmisc/pq/physicalquantity.cpp @@ -53,7 +53,9 @@ namespace BlackMisc template CPhysicalQuantity::CPhysicalQuantity(double value, MU unit) : m_value(unit.isNull() ? 0.0 : value), m_unit(unit) - { } + { + Q_ASSERT_X(!std::isnan(value), Q_FUNC_INFO, "nan value"); + } template CPhysicalQuantity::CPhysicalQuantity(const QString &unitString) : diff --git a/src/blackmisc/simulation/interpolator.cpp b/src/blackmisc/simulation/interpolator.cpp index efff22cbb..6c9cca1c8 100644 --- a/src/blackmisc/simulation/interpolator.cpp +++ b/src/blackmisc/simulation/interpolator.cpp @@ -311,6 +311,7 @@ namespace BlackMisc } // check if model has been thru model matching + Q_ASSERT_X(!m_lastSituation.isNull(), Q_FUNC_INFO, "null situations"); parts.guessParts(m_lastSituation, m_pastSituationsChange, m_model); this->logParts(parts, 0, false); }