mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-22 23:05:36 +08:00
Ref T275, extrapolate elevation function
* extrapolate will be used to "guess" elevation when a new network situation is received * we guess the elevation until we receive it from provider
This commit is contained in:
@@ -90,26 +90,26 @@ namespace BlackMisc
|
||||
|
||||
const QString &CAircraftSituation::onGroundDetailsToString(CAircraftSituation::OnGroundDetails reliability)
|
||||
{
|
||||
static const QString intElv("elevation");
|
||||
static const QString intElvCg("elevation/CG");
|
||||
static const QString intInter("interpolation");
|
||||
static const QString intGuess("guessing");
|
||||
static const QString elv("elevation");
|
||||
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");
|
||||
static const QString InNoGroundInfo("no gnd.info");
|
||||
static const QString inNoGndInfo("no gnd.info");
|
||||
|
||||
switch (reliability)
|
||||
{
|
||||
case CAircraftSituation::OnGroundByElevation: return intElv;
|
||||
case CAircraftSituation::OnGroundByElevationAndCG: return intElvCg;
|
||||
case CAircraftSituation::OnGroundByGuessing: return intGuess;
|
||||
case CAircraftSituation::OnGroundByInterpolation: return intInter;
|
||||
case CAircraftSituation::OnGroundByElevation: return elv;
|
||||
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::InNoGroundInfo: return InNoGroundInfo;
|
||||
case CAircraftSituation::InNoGroundInfo: return inNoGndInfo;
|
||||
case CAircraftSituation::NotSetGroundDetails:
|
||||
default: return unknown;
|
||||
}
|
||||
@@ -145,6 +145,7 @@ namespace BlackMisc
|
||||
static const QString cache("cached");
|
||||
static const QString test("test");
|
||||
static const QString interpolated("interpolated");
|
||||
static const QString extrapolated("extrapolated");
|
||||
|
||||
switch (details)
|
||||
{
|
||||
@@ -155,6 +156,7 @@ namespace BlackMisc
|
||||
case FromCache: return cache;
|
||||
case Test: return test;
|
||||
case Interpolated: return interpolated;
|
||||
case Extrapolated: return extrapolated;
|
||||
default: break;
|
||||
}
|
||||
return unknown;
|
||||
@@ -196,7 +198,7 @@ namespace BlackMisc
|
||||
}
|
||||
|
||||
const CLength distance = newSituation.calculateGreatCircleDistance(oldSituation);
|
||||
if (distance < newSituation.getDistancePerTime(250))
|
||||
if (distance < newSituation.getDistancePerTime250ms())
|
||||
{
|
||||
if (oldSituation.hasGroundElevation())
|
||||
{
|
||||
@@ -206,16 +208,15 @@ namespace BlackMisc
|
||||
}
|
||||
}
|
||||
|
||||
static const CLength allowedStdDev(3, CLengthUnit::ft());
|
||||
QPair<CAltitude, CAltitude> elvDevMean = change.getElevationStdDevAndMean();
|
||||
if (!elvDevMean.first.isNull() && elvDevMean.first < allowedStdDev)
|
||||
if (change.hasElevationDevWithinAllowedRange())
|
||||
{
|
||||
// not much change in known elevations
|
||||
const CAltitudePair elvDevMean = change.getElevationStdDevAndMean();
|
||||
situationToPreset.setGroundElevation(elvDevMean.second, CAircraftSituation::SituationChange);
|
||||
break;
|
||||
}
|
||||
|
||||
const CElevationPlane epInterpolated = CAircraftSituation::interpolateElevation(CAircraftSituation::null(), oldSituation, newSituation, distance);
|
||||
const CElevationPlane epInterpolated = CAircraftSituation::interpolatedElevation(CAircraftSituation::null(), oldSituation, newSituation, distance);
|
||||
if (!epInterpolated.isNull())
|
||||
{
|
||||
situationToPreset.setGroundElevation(epInterpolated, CAircraftSituation::Interpolated);
|
||||
@@ -226,7 +227,7 @@ namespace BlackMisc
|
||||
return situationToPreset.hasGroundElevation();
|
||||
}
|
||||
|
||||
CElevationPlane CAircraftSituation::interpolateElevation(const CAircraftSituation &situation, const CAircraftSituation &oldSituation, const CAircraftSituation &newSituation, const CLength &distance)
|
||||
CElevationPlane CAircraftSituation::interpolatedElevation(const CAircraftSituation &situation, const CAircraftSituation &oldSituation, const CAircraftSituation &newSituation, const CLength &distance)
|
||||
{
|
||||
if (oldSituation.isNull() || newSituation.isNull()) { return CAircraftSituation::null(); }
|
||||
if (oldSituation.equalNormalVectorDouble(newSituation)) { return newSituation.getGroundElevationPlane(); }
|
||||
@@ -257,6 +258,28 @@ namespace BlackMisc
|
||||
}
|
||||
}
|
||||
|
||||
bool CAircraftSituation::extrapolateElevation(CAircraftSituation &newSituation, const CAircraftSituation &oldSituation, const CAircraftSituation &olderSituation, const CAircraftSituationChange &oldChange)
|
||||
{
|
||||
if (newSituation.hasGroundElevation()) { return false; }
|
||||
if (oldSituation.transferGroundElevation(newSituation)) { return true; }
|
||||
if (oldSituation.isNull() || olderSituation.isNull()) { return false; }
|
||||
|
||||
if (oldChange.isNull()) { return false; }
|
||||
if (oldChange.isConstOnGround() && oldChange.hasAltitudeDevWithinAllowedRange() && oldChange.hasElevationDevWithinAllowedRange())
|
||||
{
|
||||
// we have almost const altitudes and elevations
|
||||
const double deltaAltFt = qAbs(newSituation.getAltitude().value(CLengthUnit::ft()) - olderSituation.getAltitude().value(CLengthUnit::ft()));
|
||||
if (deltaAltFt <= CAircraftSituationChange::allowedAltitudeDeviation().value(CLengthUnit::ft()))
|
||||
{
|
||||
// the ccurrent alt is also not much different
|
||||
newSituation.setGroundElevation(oldSituation.getGroundElevation(), Extrapolated);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
CVariant CAircraftSituation::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
|
||||
{
|
||||
if (index.isMyself()) { return CVariant::from(*this); }
|
||||
@@ -636,11 +659,11 @@ namespace BlackMisc
|
||||
return transferable;
|
||||
}
|
||||
|
||||
bool CAircraftSituation::transferGroundElevation(CAircraftSituation &otherSituation, const CLength &radius) const
|
||||
bool CAircraftSituation::transferGroundElevation(CAircraftSituation &transferToSituation, const CLength &radius) const
|
||||
{
|
||||
if (!this->canTransferGroundElevation(otherSituation, radius)) { return false; }
|
||||
otherSituation.setGroundElevation(this->getGroundElevationPlane(), TransferredElevation);
|
||||
Q_ASSERT_X(!otherSituation.getGroundElevationRadius().isNull(), Q_FUNC_INFO, "null radius");
|
||||
if (!this->canTransferGroundElevation(transferToSituation, radius)) { return false; }
|
||||
transferToSituation.setGroundElevation(this->getGroundElevationPlane(), TransferredElevation);
|
||||
Q_ASSERT_X(!transferToSituation.getGroundElevationRadius().isNull(), Q_FUNC_INFO, "null radius");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -649,6 +672,19 @@ namespace BlackMisc
|
||||
return CAircraftSituation::presetGroundElevation(*this, oldSituation, newSituation, change);
|
||||
}
|
||||
|
||||
bool CAircraftSituation::extrapolateElevation(const CAircraftSituation &oldSituation, const CAircraftSituation &olderSituation, const CAircraftSituationChange &change)
|
||||
{
|
||||
return CAircraftSituation::extrapolateElevation(*this, oldSituation, olderSituation, change);
|
||||
}
|
||||
|
||||
bool CAircraftSituation::interpolateElevation(const CAircraftSituation &oldSituation, const CAircraftSituation &newSituation)
|
||||
{
|
||||
const CElevationPlane ep = CAircraftSituation::interpolatedElevation(*this, oldSituation, newSituation);
|
||||
if (ep.isNull()) { return false; }
|
||||
this->setGroundElevation(ep, Interpolated);
|
||||
return true;
|
||||
}
|
||||
|
||||
CAircraftSituation::IsOnGround CAircraftSituation::isOnGroundByElevation() const
|
||||
{
|
||||
return this->isOnGroundByElevation(m_cg);
|
||||
@@ -883,6 +919,11 @@ namespace BlackMisc
|
||||
return d;
|
||||
}
|
||||
|
||||
CLength CAircraftSituation::getDistancePerTime250ms() const
|
||||
{
|
||||
return this->getDistancePerTime(250);
|
||||
}
|
||||
|
||||
void CAircraftSituation::setCallsign(const CCallsign &callsign)
|
||||
{
|
||||
m_correspondingCallsign = callsign;
|
||||
|
||||
@@ -95,7 +95,7 @@ namespace BlackMisc
|
||||
// received situation
|
||||
InFromNetwork, //!< received from network
|
||||
InFromParts, //!< set from aircraft parts
|
||||
InNoGroundInfo, //!< not know
|
||||
InNoGroundInfo, //!< not known
|
||||
// send information
|
||||
OutOnGroundOwnAircraft //!< sending on ground
|
||||
};
|
||||
@@ -117,6 +117,7 @@ namespace BlackMisc
|
||||
NoElevationInfo,
|
||||
TransferredElevation, //!< transferred from nearby situation
|
||||
Interpolated, //!< interpolated between 2 elevations
|
||||
Extrapolated, //!< extrapolated ("guessing")
|
||||
FromProvider, //!< from BlackMisc::Simulation::ISimulationEnvironmentProvider
|
||||
FromCache, //!< from cache
|
||||
SituationChange, //!< from BlackMisc::Aviation::CAircraftSituationChange
|
||||
@@ -286,14 +287,28 @@ namespace BlackMisc
|
||||
//! Transfer from "this" situation to \c otherSituation
|
||||
//! \remark "transfer" can be used, if the positions are known, "preset" if they are still unknown
|
||||
//! \sa CAircraftSituation::interpolateGroundElevation
|
||||
bool transferGroundElevation(CAircraftSituation &otherSituation, const PhysicalQuantities::CLength &radius = Geo::CElevationPlane::singlePointRadius()) const;
|
||||
//! \sa CAircraftSituation::interpolateElevation
|
||||
bool transferGroundElevation(CAircraftSituation &transferToSituation, const PhysicalQuantities::CLength &radius = Geo::CElevationPlane::singlePointRadius()) const;
|
||||
|
||||
//! Preset "this" elevation from the two adjacent positions
|
||||
//! \remark it is not required that the position of "this" is already known
|
||||
//! \remark "transfer" can be used, if the positions are known, "preset" if they are still unknown
|
||||
//! \sa CAircraftSituation::transferGroundElevation
|
||||
//! \sa CAircraftSituation::interpolateElevation
|
||||
bool presetGroundElevation(const Aviation::CAircraftSituation &oldSituation, const Aviation::CAircraftSituation &newSituation, const CAircraftSituationChange &change);
|
||||
|
||||
//! Set "this" elevation from older situations.
|
||||
//! \remark this is a future value
|
||||
//! \sa CAircraftSituation::transferGroundElevation
|
||||
//! \sa CAircraftSituation::interpolateElevation
|
||||
bool extrapolateElevation(const Aviation::CAircraftSituation &oldSituation, const Aviation::CAircraftSituation &olderSituation, const CAircraftSituationChange &change);
|
||||
|
||||
//! Interpolate "this" elevation from the two adjacent positions
|
||||
//! \remark "transfer" can be used, if the positions are known, "preset" if they are still unknown
|
||||
//! \sa CAircraftSituation::transferGroundElevation
|
||||
//! \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;
|
||||
@@ -395,6 +410,9 @@ namespace BlackMisc
|
||||
//! Distance per milliseconds
|
||||
PhysicalQuantities::CLength getDistancePerTime(int milliseconds) const;
|
||||
|
||||
//! Distance per milliseconds (250ms)
|
||||
PhysicalQuantities::CLength getDistancePerTime250ms() const;
|
||||
|
||||
//! Corresponding callsign
|
||||
const CCallsign &getCallsign() const { return m_correspondingCallsign; }
|
||||
|
||||
@@ -487,9 +505,14 @@ namespace BlackMisc
|
||||
//! \sa CAircraftSituation::transferGroundElevation
|
||||
static bool presetGroundElevation(CAircraftSituation &situationToPreset, const CAircraftSituation &oldSituation, const CAircraftSituation &newSituation, const CAircraftSituationChange &change);
|
||||
|
||||
//! Extrapolated between the 2 situations for situation
|
||||
//! \remark situation is not between oldSituation and olderSituation
|
||||
//! \remark NULL if there are no two elevations
|
||||
static bool extrapolateElevation(CAircraftSituation &newSituation, const CAircraftSituation &oldSituation, const CAircraftSituation &olderSituation, const CAircraftSituationChange &oldChange);
|
||||
|
||||
//! Interpolate between the 2 situations for situation
|
||||
//! \remark NULL if there are no two elevations
|
||||
static Geo::CElevationPlane interpolateElevation(const CAircraftSituation &situation, const CAircraftSituation &oldSituation, const CAircraftSituation &newSituation, const PhysicalQuantities::CLength &distance = PhysicalQuantities::CLength::null());
|
||||
static Geo::CElevationPlane interpolatedElevation(const CAircraftSituation &situation, const CAircraftSituation &oldSituation, const CAircraftSituation &newSituation, const PhysicalQuantities::CLength &distance = PhysicalQuantities::CLength::null());
|
||||
|
||||
private:
|
||||
CCallsign m_correspondingCallsign;
|
||||
|
||||
@@ -114,6 +114,14 @@ namespace BlackMisc
|
||||
return c;
|
||||
}
|
||||
|
||||
bool CAircraftSituationList::extrapolateElevation(const CAircraftSituationChange &change)
|
||||
{
|
||||
if (this->size() < 3) { return false; }
|
||||
const CAircraftSituation old = (*this)[1];
|
||||
const CAircraftSituation older = (*this)[2];
|
||||
return this->front().extrapolateElevation(old, older, change);
|
||||
}
|
||||
|
||||
CAircraftSituationList CAircraftSituationList::findByInboundGroundInformation(bool hasGroundInfo) const
|
||||
{
|
||||
return this->findBy(&CAircraftSituation::hasInboundGroundDetails, hasGroundInfo);
|
||||
@@ -511,6 +519,19 @@ namespace BlackMisc
|
||||
const QPair<double, double> deltaFt = CMathUtils::standardDeviationAndMean(altElvDeltas);
|
||||
return CAltitudePair(CAltitude(deltaFt.first, CAltitude::MeanSeaLevel, CAltitude::defaultUnit()), CAltitude(deltaFt.second, CAltitude::MeanSeaLevel, CAltitude::defaultUnit()));
|
||||
}
|
||||
|
||||
int CAircraftSituationList::transferElevationForward(const CLength radius)
|
||||
{
|
||||
if (this->size() < 2) { return 0; }
|
||||
Q_ASSERT_X(m_tsAdjustedSortHint == CAircraftSituationList::AdjustedTimestampLatestFirst, Q_FUNC_INFO, "need latest first");
|
||||
int c = 0;
|
||||
for (int i = 1; i < this->size(); ++i)
|
||||
{
|
||||
const CAircraftSituation &oldSituation = (*this)[i];
|
||||
CAircraftSituation &newSituation = (*this)[i - 1];
|
||||
if (oldSituation.transferGroundElevation(newSituation, radius)) { c++; }
|
||||
}
|
||||
return c;
|
||||
}
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
@@ -69,6 +69,11 @@ namespace BlackMisc
|
||||
//! Extrapolate ground flag into the future
|
||||
int extrapolateGroundFlag();
|
||||
|
||||
//! Extrapolates elevation into front element from 2nd and 3rd element
|
||||
//! \sa CAircraftSituation::extrapolateElevation
|
||||
//! \pre the list must be sorted latest first and containt at least 3 elements
|
||||
bool extrapolateElevation(const CAircraftSituationChange &change);
|
||||
|
||||
//! Find if having inbound information
|
||||
CAircraftSituationList findByInboundGroundInformation(bool hasGroundInfo) const;
|
||||
|
||||
@@ -182,6 +187,10 @@ namespace BlackMisc
|
||||
|
||||
//! Min. and max. ground distance
|
||||
PhysicalQuantities::CLengthPair minMaxGroundDistance(const PhysicalQuantities::CLength &cg) const;
|
||||
|
||||
//! Transfer elevations forward from older to newer
|
||||
//! \pre requires a list which is sorted "latest first"
|
||||
int transferElevationForward(const PhysicalQuantities::CLength radius = Geo::CElevationPlane::singlePointRadius());
|
||||
};
|
||||
|
||||
//! Situation per callsign
|
||||
|
||||
Reference in New Issue
Block a user