diff --git a/src/blackcore/airspacemonitor.cpp b/src/blackcore/airspacemonitor.cpp index 8fc6be747..34456f2a9 100644 --- a/src/blackcore/airspacemonitor.cpp +++ b/src/blackcore/airspacemonitor.cpp @@ -1391,15 +1391,21 @@ namespace BlackCore // and avoids unnecessary elevation fetching for low flying smaller GA aircraft const CAircraftIcaoCode icao = this->getAircraftInRangeModelForCallsign(callsign).getAircraftIcaoCode(); if (!icao.hasDesignator()) { break; } // what is that? - if (!icao.isVtol()) + if (icao.isVtol()) { - // Not for VTOLs + // VTOLs over 60kts likely not on ground + // it could be that a low flying helicopter near ground + if (situation.getGroundSpeed().value(CSpeedUnit::kts()) > 60) { break; } + } + else + { + // NO VTOL CLength cg(nullptr); CSpeed rotateSpeed(nullptr); icao.guessModelParameters(cg, rotateSpeed); if (!rotateSpeed.isNull()) { - rotateSpeed *= 1.2; // some margin + rotateSpeed *= 1.25; // some margin if (situation.getGroundSpeed() > rotateSpeed) { break; } } } @@ -1414,6 +1420,7 @@ namespace BlackCore } // we NEED elevation + // actually distance of 200k/h 100ms is just 6.1 meters const CLength dpt = correctedSituation.getDistancePerTime(100, CElevationPlane::singlePointRadius()); const CAircraftSituationList situationsBeforeStoring = this->remoteAircraftSituations(callsign); const CAircraftSituation situationWithElvBeforeStoring = situationsBeforeStoring.findClosestElevationWithinRange(correctedSituation, dpt); @@ -1435,7 +1442,7 @@ namespace BlackCore } // we have a new situation, so we try to get the elevation - // so far we have requested it, but we set it upfront either by + // we will requested it, but we set it upfront either by // // a) average value from other planes in the vicinity (cache, not moving) or // b) by extrapolating @@ -1450,11 +1457,12 @@ namespace BlackCore bool fromNonMoving = false; bool triedExtrapolation = false; bool couldNotExtrapolate = false; + int fromWhere = -1; // debugging - CElevationPlane averagePlane = this->averageElevationOfOnGroundAircraft(situation, CElevationPlane::majorAirportRadius(), 2, 3); + CElevationPlane averagePlane = this->averageElevationOfOnGroundAircraft(situation, CElevationPlane::minorAirportRadius(), 2, 3); if (averagePlane.isNull()) { - averagePlane = this->averageElevationOfNonMovingAircraft(situation, CElevationPlane::majorAirportRadius(), 2, 3); + averagePlane = this->averageElevationOfNonMovingAircraft(situation, CElevationPlane::minorAirportRadius(), 2, 3); fromNonMoving = true; } @@ -1464,6 +1472,7 @@ namespace BlackCore correctedSituation.setGroundElevation(averagePlane, CAircraftSituation::Average); if (fromNonMoving) { m_foundInNonMovingAircraft++; } else { m_foundInElevationsOnGnd++; } + fromWhere = 10; } else { @@ -1473,6 +1482,7 @@ namespace BlackCore const bool extrapolated = correctedSituation.extrapolateElevation(situationsBeforeStoring[0], situationsBeforeStoring[1], changesBeforeStoring); triedExtrapolation = true; couldNotExtrapolate = !extrapolated; + fromWhere = 20; } } @@ -1484,11 +1494,19 @@ namespace BlackCore // experimental, could become ASSERT BLACK_VERIFY_X(needToRequestElevation, Q_FUNC_INFO, "Request should already be set"); } - needToRequestElevation = true; // should be the true already + needToRequestElevation = true; // should be "true" already Q_UNUSED(triedExtrapolation) Q_UNUSED(couldNotExtrapolate) } + else + { + // sanity check on the situation + if (CBuildConfig::isLocalDeveloperDebugBuild()) + { + BLACK_VERIFY_X(!correctedSituation.getGroundElevation().isZeroEpsilonConsidered(), Q_FUNC_INFO, "Suspicious elevation"); + } + } } // gnd. elevation } while (false); // do we need elevation, find on diff --git a/src/blackcore/simulator.cpp b/src/blackcore/simulator.cpp index 31063b81c..accf2f133 100644 --- a/src/blackcore/simulator.cpp +++ b/src/blackcore/simulator.cpp @@ -369,7 +369,7 @@ namespace BlackCore bool updatedForOnGroundPosition = false; const int updated = CRemoteAircraftAware::updateAircraftGroundElevation(callsign, plane, CAircraftSituation::FromProvider, &updatedForOnGroundPosition); - // update in simulator + // update in simulator and cache const bool likelyOnGroundElevation = updated > 0 && updatedForOnGroundPosition; ISimulationEnvironmentProvider::rememberGroundElevation(callsign, likelyOnGroundElevation, plane); // in simulator @@ -1220,16 +1220,24 @@ namespace BlackCore CAltitude elevation = situation.getGroundElevation(); if (elevation.isNull()) { + // calculate elevation const CLength cg = ownAircraft.getModel().getCG(); elevation = (cg.isNull() || situation.getAltitude().isNull()) ? CAltitude::null() : (situation.getAltitude().withOffset(cg * -1.0)); } + // own ground elevations if (elevation.hasMeanSeaLevelValue()) { - const CCallsign cs = situation.hasCallsign() ? situation.getCallsign() : ownAircraft.getCallsign(); - const CLength radius = settings.getRecordedGndRadius().isNull() ? CElevationPlane::singlePointRadius() : settings.getRecordedGndRadius(); + const CCallsign cs = situation.hasCallsign() ? situation.getCallsign() : ownAircraft.getCallsign(); + const CLength radius = settings.getRecordedGndRadius().isNull() ? CElevationPlane::singlePointRadius() : settings.getRecordedGndRadius(); const CElevationPlane ep(situation, radius); const bool remembered = this->rememberGroundElevation(cs, situation.isOnGround(), ep, radius); + + if (CBuildConfig::isLocalDeveloperDebugBuild()) + { + const bool invalid = situation.isOnGround() && elevation.isZeroEpsilonConsidered(); + BLACK_AUDIT_X(!invalid, Q_FUNC_INFO, "On ground in water"); + } Q_UNUSED(remembered) // false means it was already in that cache, or something else is wrong } } diff --git a/src/blackmisc/aviation/aircraftsituation.cpp b/src/blackmisc/aviation/aircraftsituation.cpp index aaa8b8161..966e641df 100644 --- a/src/blackmisc/aviation/aircraftsituation.cpp +++ b/src/blackmisc/aviation/aircraftsituation.cpp @@ -302,7 +302,12 @@ namespace BlackMisc if (situationToBeUpdated.hasGroundElevation()) { return false; } // if acceptable transfer - if (oldSituation.transferGroundElevationFromMe(situationToBeUpdated)) { return true; } + if (oldSituation.transferGroundElevationFromMe(situationToBeUpdated)) + { + // change or keep type is the question + // situationToBeUpdated.setGroundElevationInfo(Extrapolated); + return true; + } if (oldSituation.isNull() || olderSituation.isNull()) { return false; } if (oldChange.isNull()) { return false; } @@ -575,7 +580,7 @@ namespace BlackMisc CLength cg = m_cg.isNull() ? model.getCG() : m_cg; CSpeed guessedRotateSpeed = CSpeed::null(); - CSpeed sureRotateSpeed = CSpeed(130, CSpeedUnit::kts()); + CSpeed sureRotateSpeed = CSpeed(130, CSpeedUnit::kts()); model.getAircraftIcaoCode().guessModelParameters(cg, guessedRotateSpeed); if (!guessedRotateSpeed.isNull()) { diff --git a/src/blackmisc/aviation/aircraftsituationlist.cpp b/src/blackmisc/aviation/aircraftsituationlist.cpp index b8f87ede2..72ab6ba8c 100644 --- a/src/blackmisc/aviation/aircraftsituationlist.cpp +++ b/src/blackmisc/aviation/aircraftsituationlist.cpp @@ -68,8 +68,9 @@ namespace BlackMisc const CElevationPlane &elevationPlane, CAircraftSituation::GndElevationInfo info, const CAircraftModel &model, CAircraftSituationChange *changeOut, bool *setForOnGroundPosition) { + if (setForOnGroundPosition) { *setForOnGroundPosition = false; } // set a default if (elevationPlane.isNull()) { return 0; } - if (this->isEmpty()) { return 0; } + if (this->isEmpty()) { return 0; } // the change has the timestamps of the latest situation Q_ASSERT_X(m_tsAdjustedSortHint == CAircraftSituationList::AdjustedTimestampLatestFirst || this->isSortedAdjustedLatestFirstWithoutNullPositions(), Q_FUNC_INFO, "Need sorted situations without NULL positions"); diff --git a/src/blackmisc/geo/coordinategeodeticlist.cpp b/src/blackmisc/geo/coordinategeodeticlist.cpp index 8d61e8b62..c4fb93b15 100644 --- a/src/blackmisc/geo/coordinategeodeticlist.cpp +++ b/src/blackmisc/geo/coordinategeodeticlist.cpp @@ -29,7 +29,7 @@ namespace BlackMisc CElevationPlane CCoordinateGeodeticList::averageGeodeticHeight(const CCoordinateGeodetic &reference, const CLength &range, const CLength &maxDeviation, int minValues, int sufficentValues) const { - if (this->size() < minValues) { return CElevationPlane::null(); } // no change to succeed + if (this->size() < minValues) { return CElevationPlane::null(); } // no chance to succeed QList valuesInFt; const CCoordinateGeodeticList sorted = this->findWithGeodeticMSLHeight().findWithinRange(reference, range).sortedByEuclideanDistanceSquared(reference); diff --git a/src/blackmisc/simulation/interpolationlogger.cpp b/src/blackmisc/simulation/interpolationlogger.cpp index 3a720482a..b55c15158 100644 --- a/src/blackmisc/simulation/interpolationlogger.cpp +++ b/src/blackmisc/simulation/interpolationlogger.cpp @@ -426,9 +426,9 @@ namespace BlackMisc if (!situationNew.hasGroundElevation()) { continue; } newPosTs = situationNew.getMSecsSinceEpoch(); kml += CKmlUtils::asPlacemark( - QStringLiteral("%1: %2 %3 %4 alt.cor: %5").arg(n++).arg( + QStringLiteral("%1: %2 %3 info: %4 alt.cor: %5").arg(n++).arg( situationNew.getFormattedUtcTimestampHmsz(), - situationNew.getGroundElevationPlane().getAltitude().toQString(true), + situationNew.getGroundElevationAndInfo(), log.elevationInfo, log.altCorrection), situationNew.getGroundElevationPlane().toQString(true), situationNew.getGroundElevationPlane(), s) % u"\n"; diff --git a/src/blackmisc/simulation/interpolator.cpp b/src/blackmisc/simulation/interpolator.cpp index 238392608..5a327a8c2 100644 --- a/src/blackmisc/simulation/interpolator.cpp +++ b/src/blackmisc/simulation/interpolator.cpp @@ -145,6 +145,16 @@ namespace BlackMisc BLACK_VERIFY_X(details, Q_FUNC_INFO, "Once gnd.from parts -> always gnd. from parts"); } + if (CBuildConfig::isLocalDeveloperDebugBuild()) + { + for (const CAircraftSituation &s : situations) + { + if (!s.hasGroundElevation()) { continue; } + BLACK_VERIFY_X(!s.getGroundElevation().isZeroEpsilonConsidered(), Q_FUNC_INFO, "Suspicous 0 gnd. value"); + } + } + + // result return sorted && details; } diff --git a/src/blackmisc/simulation/interpolatorspline.cpp b/src/blackmisc/simulation/interpolatorspline.cpp index ae69cdf56..15119a200 100644 --- a/src/blackmisc/simulation/interpolatorspline.cpp +++ b/src/blackmisc/simulation/interpolatorspline.cpp @@ -98,7 +98,7 @@ namespace BlackMisc if (CBuildConfig::isLocalDeveloperDebugBuild()) { - BLACK_VERIFY_X(t >= 0, Q_FUNC_INFO, "Expect t >= 0"); + BLACK_VERIFY_X(t >= 0, Q_FUNC_INFO, "Expect t >= 0"); BLACK_VERIFY_X(t <= 1.0, Q_FUNC_INFO, "Expect t <= 1"); } return y; @@ -225,9 +225,9 @@ namespace BlackMisc const double a0 = m_s[0].getCorrectedAltitude(cg).value(altUnit); // oldest 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.da = getDerivatives(pa.t, pa.a); + pa.a = {{ a0, a1, a2 }}; + pa.gnd = {{ m_s[0].getOnGroundFactor(), m_s[1].getOnGroundFactor(), m_s[2].getOnGroundFactor() }}; + pa.da = getDerivatives(pa.t, pa.a); pa.dgnd = getDerivatives(pa.t, pa.gnd); m_prevSampleAdjustedTime = m_s[1].getAdjustedMSecsSinceEpoch(); @@ -257,7 +257,7 @@ namespace BlackMisc if (CBuildConfig::isLocalDeveloperDebugBuild()) { BLACK_VERIFY_X(dt1 >= 0, Q_FUNC_INFO, "Expect postive dt1"); - BLACK_VERIFY_X(dt2 > 0, Q_FUNC_INFO, "Expect postive dt2"); + BLACK_VERIFY_X(dt2 > 0, Q_FUNC_INFO, "Expect postive dt2"); BLACK_VERIFY_X(isAcceptableTimeFraction(timeFraction), Q_FUNC_INFO, "Expect fraction 0-1"); } timeFraction = clampValidTimeFraction(timeFraction); @@ -334,7 +334,7 @@ namespace BlackMisc { Q_ASSERT_X(t1 < t2, Q_FUNC_INFO, "Expect sorted times, latest first"); // that means a bug in our code init the values BLACK_VERIFY_X(m_currentTimeMsSinceEpoc >= t1, Q_FUNC_INFO, "invalid timestamp t1"); - BLACK_VERIFY_X(m_currentTimeMsSinceEpoc < t2, Q_FUNC_INFO, "invalid timestamp t2"); // t1==t2 results in div/0 + BLACK_VERIFY_X(m_currentTimeMsSinceEpoc < t2, Q_FUNC_INFO, "invalid timestamp t2"); // t1==t2 results in div/0 } if (!valid) { return CAircraftSituation::null(); } diff --git a/src/blackmisc/simulation/simulationenvironmentprovider.cpp b/src/blackmisc/simulation/simulationenvironmentprovider.cpp index bbea24c29..d453a51d3 100644 --- a/src/blackmisc/simulation/simulationenvironmentprovider.cpp +++ b/src/blackmisc/simulation/simulationenvironmentprovider.cpp @@ -9,9 +9,12 @@ #include "simulationenvironmentprovider.h" #include "blackmisc/aviation/aircraftsituationchange.h" -#include "verify.h" +#include "blackmisc/verify.h" +#include "blackconfig/buildconfig.h" + #include +using namespace BlackConfig; using namespace BlackMisc::Aviation; using namespace BlackMisc::Geo; using namespace BlackMisc::PhysicalQuantities; @@ -50,6 +53,12 @@ namespace BlackMisc { if (m_elvCoordinatesGnd.size() > m_maxElevationsGnd) { m_elvCoordinatesGnd.pop_back(); } m_elvCoordinatesGnd.push_front(elevationCoordinate); + + if (CBuildConfig::isLocalDeveloperDebugBuild()) + { + BLACK_VERIFY_X(!elevationCoordinate.geodeticHeight().isNull(), Q_FUNC_INFO, "NULL value"); + BLACK_VERIFY_X(!elevationCoordinate.geodeticHeight().isZeroEpsilonConsidered(), Q_FUNC_INFO, "Suspicous 0 value"); + } } else {