mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-22 23:05:36 +08:00
Ref T261, CAircraftSituationChange improvements
* min/max ground distance, also added in situation list * use model's vtol/CG info * improved scenery deviation guessing * adjusted interpolator scenery deviation handling
This commit is contained in:
committed by
Roland Winklmeier
parent
ed78eb5f0b
commit
ea585ae166
@@ -33,10 +33,7 @@ namespace BlackMisc
|
||||
{
|
||||
CAircraftSituationChange::CAircraftSituationChange() {}
|
||||
|
||||
CAircraftSituationChange::CAircraftSituationChange(const CAircraftSituation &s1, const CAircraftSituation &s2) :
|
||||
CAircraftSituationChange::CAircraftSituationChange(CAircraftSituationList({s1, s2})) {}
|
||||
|
||||
CAircraftSituationChange::CAircraftSituationChange(const CAircraftSituationList &situations, bool alreadySortedLatestFirst, bool calcStdDeviations)
|
||||
CAircraftSituationChange::CAircraftSituationChange(const CAircraftSituationList &situations, const PhysicalQuantities::CLength &cg, bool isVtol, bool alreadySortedLatestFirst, bool calcStdDeviations)
|
||||
{
|
||||
if (situations.size() < 2) { return; }
|
||||
const CAircraftSituationList sorted(alreadySortedLatestFirst ? situations : situations.getSortedAdjustedLatestFirst());
|
||||
@@ -65,7 +62,7 @@ namespace BlackMisc
|
||||
m_justTouchdown = sorted.isJustTouchingDown(true);
|
||||
m_constAccelerating = sorted.isConstAccelerating(true);
|
||||
m_constDecelerating = sorted.isConstDecelarating(true);
|
||||
m_containsPushBack = sorted.containsPushBack();
|
||||
m_containsPushBack = !isVtol && sorted.containsPushBack();
|
||||
|
||||
if (sorted.size() >= 3)
|
||||
{
|
||||
@@ -76,7 +73,7 @@ namespace BlackMisc
|
||||
|
||||
if (calcStdDeviations)
|
||||
{
|
||||
this->calculateStdDeviations(situations);
|
||||
this->calculateStdDeviations(situations, cg);
|
||||
m_rotateUp = sorted.front().getPitch() > (m_pitchMean + m_pitchStdDev);
|
||||
}
|
||||
else
|
||||
@@ -85,13 +82,6 @@ namespace BlackMisc
|
||||
}
|
||||
}
|
||||
|
||||
CLength CAircraftSituationChange::getGuessedSceneryDeviation(const CLength &cg) const
|
||||
{
|
||||
if (cg.isNull()) { return this->guessedSceneryDeviation(); }
|
||||
if (this->guessedSceneryDeviation().isNull()) { return CLength::null(); }
|
||||
return this->guessedSceneryDeviation() - cg;
|
||||
}
|
||||
|
||||
bool CAircraftSituationChange::hasSceneryDeviation() const
|
||||
{
|
||||
return !m_guessedSceneryDeviation.isNull();
|
||||
@@ -114,7 +104,7 @@ namespace BlackMisc
|
||||
QStringLiteral(" | rotate up: ") % boolToYesNo(this->isRotatingUp()) %
|
||||
QStringLiteral(" | push back: ") % boolToYesNo(this->containsPushBack()) %
|
||||
QStringLiteral(" | scenery delta: ") % m_guessedSceneryDeviation.valueRoundedWithUnit(1) % QStringLiteral(" [") % this->getGuessedSceneryDeviationAsString() %
|
||||
QStringLiteral("] | AGL delta: ") % m_altAglMean.valueRoundedWithUnit(1) % QStringLiteral("/") % m_altAglStdDev.valueRoundedWithUnit(1) %
|
||||
QStringLiteral("] | AGL delta: ") % m_gndDistMean.valueRoundedWithUnit(1) % QStringLiteral("/") % m_gndDistStdDev.valueRoundedWithUnit(1) %
|
||||
QStringLiteral(" | std.dev/mean: pitch ") % m_pitchMean.valueRoundedWithUnit(1) % QStringLiteral("/") % m_pitchStdDev.valueRoundedWithUnit(1) %
|
||||
QStringLiteral(" gs ") % m_gsMean.valueRoundedWithUnit(1) % QStringLiteral("/") % m_gsStdDev.valueRoundedWithUnit(1) %
|
||||
QStringLiteral(" alt. ") % m_altMean.valueRoundedWithUnit(1) % QStringLiteral("/") % m_altStdDev.valueRoundedWithUnit(1) %
|
||||
@@ -165,7 +155,7 @@ namespace BlackMisc
|
||||
}
|
||||
}
|
||||
|
||||
bool CAircraftSituationChange::calculateStdDeviations(const CAircraftSituationList &situations)
|
||||
bool CAircraftSituationChange::calculateStdDeviations(const CAircraftSituationList &situations, const CLength &cg)
|
||||
{
|
||||
if (situations.isEmpty()) { return false; }
|
||||
|
||||
@@ -177,34 +167,39 @@ namespace BlackMisc
|
||||
m_pitchStdDev = pitchStdDevMean.first;
|
||||
m_pitchMean = pitchStdDevMean.second;
|
||||
|
||||
const QList<double> altValues = situations.altitudeValues(CLengthUnit::ft());
|
||||
const QList<double> altValues = situations.altitudeValues(CAltitude::defaultUnit());
|
||||
if (altValues.size() == situations.size())
|
||||
{
|
||||
const QPair<double, double> altFt = CMathUtils::standardDeviationAndMean(altValues);
|
||||
m_altStdDev = CAltitude(altFt.first, CAltitude::MeanSeaLevel, CLengthUnit::ft());
|
||||
m_altMean = CAltitude(altFt.second, CAltitude::MeanSeaLevel, CLengthUnit::ft());
|
||||
const QPair<double, double> altDevMean = CMathUtils::standardDeviationAndMean(altValues);
|
||||
m_altStdDev = CAltitude(altDevMean.first, CAltitude::MeanSeaLevel, CAltitude::defaultUnit());
|
||||
m_altMean = CAltitude(altDevMean.second, CAltitude::MeanSeaLevel, CAltitude::defaultUnit());
|
||||
}
|
||||
|
||||
const QList<double> elvValues = situations.elevationValues(CLengthUnit::ft());
|
||||
const QList<double> elvValues = situations.elevationValues(CAltitude::defaultUnit());
|
||||
if (elvValues.size() == situations.size())
|
||||
{
|
||||
const QPair<double, double> elvFt = CMathUtils::standardDeviationAndMean(elvValues);
|
||||
m_elvStdDev = CAltitude(elvFt.first, CAltitude::MeanSeaLevel, CLengthUnit::ft());
|
||||
m_elvMean = CAltitude(elvFt.second, CAltitude::MeanSeaLevel, CLengthUnit::ft());
|
||||
const QPair<double, double> elvDevMean = CMathUtils::standardDeviationAndMean(elvValues);
|
||||
m_elvStdDev = CAltitude(elvDevMean.first, CAltitude::MeanSeaLevel, CAltitude::defaultUnit());
|
||||
m_elvMean = CAltitude(elvDevMean.second, CAltitude::MeanSeaLevel, CAltitude::defaultUnit());
|
||||
|
||||
if (altValues.size() == situations.size())
|
||||
{
|
||||
QList<double> altElvDeltas;
|
||||
QList<double> gndDistance;
|
||||
for (int i = 0; i < altValues.size(); i++)
|
||||
{
|
||||
const double delta = altValues[i] - elvValues[i];
|
||||
altElvDeltas.push_back(delta);
|
||||
gndDistance.push_back(delta);
|
||||
}
|
||||
const QPair<double, double> deltaFt = CMathUtils::standardDeviationAndMean(altElvDeltas);
|
||||
m_altAglStdDev = CLength(deltaFt.first, CLengthUnit::ft());
|
||||
m_altAglMean = CLength(deltaFt.second, CLengthUnit::ft());
|
||||
const QPair<double, double> gndDistanceDevMean = CMathUtils::standardDeviationAndMean(gndDistance);
|
||||
m_gndDistStdDev = CLength(gndDistanceDevMean.first, CAltitude::defaultUnit());
|
||||
m_gndDistMean = CLength(gndDistanceDevMean.second, CAltitude::defaultUnit());
|
||||
|
||||
this->guessSceneryDeviation(situations);
|
||||
const auto gndDistMinMax = std::minmax_element(gndDistance.constBegin(), gndDistance.constEnd());
|
||||
const double gndDistMin = *gndDistMinMax.first;
|
||||
const double gndDistMax = *gndDistMinMax.second;
|
||||
m_minGroundDistance = CLength(gndDistMin, CAltitude::defaultUnit());
|
||||
m_maxGroundDistance = CLength(gndDistMax, CAltitude::defaultUnit());
|
||||
this->guessSceneryDeviation(cg);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -221,45 +216,53 @@ namespace BlackMisc
|
||||
static const QString noInfo("no info");
|
||||
static const QString completeOg("complete og");
|
||||
static const QString wasOg("was og");
|
||||
static const QString someOg("some og");
|
||||
static const QString smallAGLDev("small AGL dev. near gnd.");
|
||||
|
||||
switch (hint)
|
||||
{
|
||||
case AllOnGround: return completeOg;
|
||||
case WasOnGround: return wasOg;
|
||||
case SomeSituationsOnGround: return someOg;
|
||||
case SmallAGLDeviationNearGround: return smallAGLDev;
|
||||
case NoDeviationInfo:
|
||||
default: break;
|
||||
}
|
||||
return noInfo;
|
||||
}
|
||||
|
||||
void CAircraftSituationChange::guessSceneryDeviation(const CAircraftSituationList &situations)
|
||||
void CAircraftSituationChange::setSceneryDeviation(const CLength &deviation, const CLength &cg, CAircraftSituationChange::GuessedSceneryDeviation hint)
|
||||
{
|
||||
m_guessedSceneryDeviation = deviation;
|
||||
m_guessedSceneryDeviationCG = cg.isNull() ? CLength::null() : deviation - cg;
|
||||
this->setSceneryDeviationHint(hint);
|
||||
}
|
||||
|
||||
void CAircraftSituationChange::guessSceneryDeviation(const CLength &cg)
|
||||
{
|
||||
m_guessedSceneryDeviation = CLength::null();
|
||||
if (m_altAglStdDev.isNull()) { return; }
|
||||
if (m_altAglMean.isNull()) { return; }
|
||||
this->setSceneryDeviationHint(NoDeviationInfo);
|
||||
if (m_gndDistStdDev.isNull()) { return; }
|
||||
if (m_gndDistMean.isNull()) { return; }
|
||||
|
||||
// only for a small deviation we can calculate scenery differemce
|
||||
static const CLength maxDeviation(2, CLengthUnit::ft());
|
||||
|
||||
// On ground or was on ground
|
||||
if (this->wasConstOnGround())
|
||||
// Small deviation means "const" AGL
|
||||
if (m_gndDistStdDev <= maxDeviation)
|
||||
{
|
||||
if (m_altAglStdDev > maxDeviation) { return; }
|
||||
m_guessedSceneryDeviation = m_altAglMean;
|
||||
this->setSceneryDeviationHint(this->isConstOnGround() ? AllOnGround : WasOnGround);
|
||||
}
|
||||
else
|
||||
{
|
||||
const CAircraftSituationList situationsOg = situations.findOnGroundWithElevation(CAircraftSituation::OnGround);
|
||||
if (situationsOg.size() >= 2)
|
||||
do
|
||||
{
|
||||
const QPair<CAltitude, CAltitude> altAgl = situationsOg.altitudeAglStandardDeviationAndMean();
|
||||
if (altAgl.first > maxDeviation) { return; } // deviation
|
||||
m_guessedSceneryDeviation = altAgl.second; // AGL mean;
|
||||
this->setSceneryDeviationHint(SomeSituationsOnGround);
|
||||
if (this->isConstOnGround()) { this->setSceneryDeviation(m_gndDistMean, cg, AllOnGround); break; }
|
||||
if (this->isConstOnGround()) { this->setSceneryDeviation(m_gndDistMean, cg, WasOnGround); break; }
|
||||
if (!m_altStdDev.isNull() && m_altStdDev <= maxDeviation)
|
||||
{
|
||||
// small alt.deviation too!
|
||||
if (!m_maxGroundDistance.isNull() && m_maxGroundDistance < cg)
|
||||
{
|
||||
if (this->isConstOnGround()) { this->setSceneryDeviation(m_gndDistMean, cg, SmallAGLDeviationNearGround); break; }
|
||||
}
|
||||
}
|
||||
}
|
||||
while (false);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
@@ -59,17 +59,14 @@ namespace BlackMisc
|
||||
NoDeviationInfo,
|
||||
AllOnGround, //!< based on all situations on ground
|
||||
WasOnGround, //!< was on ground except last situation
|
||||
SomeSituationsOnGround //!< some situations on ground
|
||||
SmallAGLDeviationNearGround //!< "Almost const AGL" near Ground
|
||||
};
|
||||
|
||||
//! Default constructor.
|
||||
CAircraftSituationChange();
|
||||
|
||||
//! Ctor with 2 situations
|
||||
CAircraftSituationChange(const CAircraftSituation &s1, const CAircraftSituation &s2);
|
||||
|
||||
//! Ctor with n situations
|
||||
CAircraftSituationChange(const CAircraftSituationList &situations, bool alreadySortedLatestFirst = false, bool calcStdDeviations = false);
|
||||
CAircraftSituationChange(const CAircraftSituationList &situations, const PhysicalQuantities::CLength &cg, bool isVtol, bool alreadySortedLatestFirst = false, bool calcStdDeviations = false);
|
||||
|
||||
//! Get callsign
|
||||
const CCallsign &getCallsign() const { return m_correspondingCallsign; }
|
||||
@@ -116,9 +113,9 @@ namespace BlackMisc
|
||||
//! \copydoc BlackMisc::Aviation::CAircraftSituationList::containsPushBack
|
||||
bool containsPushBack() const { return m_containsPushBack; }
|
||||
|
||||
//! AGL if it can be calculated, otherwise NULL
|
||||
//! Ground distance (AGL) if it can be calculated, otherwise NULL
|
||||
//! \note distance is without CG, so on ground it can also be used to calculate
|
||||
QPair<PhysicalQuantities::CLength, PhysicalQuantities::CLength> getAltAglStdDevAndMean() const { return QPair<PhysicalQuantities::CLength, PhysicalQuantities::CLength>(m_altAglStdDev, m_altAglMean); }
|
||||
QPair<PhysicalQuantities::CLength, PhysicalQuantities::CLength> getGroundDistanceStdDevAndMean() const { return QPair<PhysicalQuantities::CLength, PhysicalQuantities::CLength>(m_gndDistStdDev, m_gndDistMean); }
|
||||
|
||||
//! \copydoc BlackMisc::Aviation::CAircraftSituationList::altitudeStandardDeviationAndMean
|
||||
QPair<CAltitude, CAltitude> getAltitudeStdDevAndMean() const { return QPair<CAltitude, CAltitude>(m_altStdDev, m_altMean); }
|
||||
@@ -132,12 +129,15 @@ namespace BlackMisc
|
||||
//! \copydoc BlackMisc::Aviation::CAircraftSituationList::pitchStandardDeviationAndMean
|
||||
QPair<PhysicalQuantities::CAngle, PhysicalQuantities::CAngle> getPitchStdDevAndMean() const { return QPair<PhysicalQuantities::CAngle, PhysicalQuantities::CAngle>(m_pitchStdDev, m_pitchMean); }
|
||||
|
||||
//! \copydoc BlackMisc::Aviation::CAircraftSituationList::minMaxGroundDistance
|
||||
QPair<PhysicalQuantities::CLength, PhysicalQuantities::CLength> getMinMaxGroundDistance() const { return QPair<PhysicalQuantities::CLength, PhysicalQuantities::CLength>(m_minGroundDistance, m_maxGroundDistance); }
|
||||
|
||||
//! Scnenery deviation (if it can be calculated, otherwise PhysicalQuantities::CLength::null)
|
||||
//! This is without CG, so substract CG to get deviation
|
||||
const PhysicalQuantities::CLength &guessedSceneryDeviation() const { return m_guessedSceneryDeviation; }
|
||||
|
||||
//! Get scenery deviation under consideration of CG
|
||||
PhysicalQuantities::CLength getGuessedSceneryDeviation(const PhysicalQuantities::CLength &cg) const;
|
||||
PhysicalQuantities::CLength getGuessedSceneryDeviationCG() const { return m_guessedSceneryDeviationCG; }
|
||||
|
||||
//! Scenery deviation hint
|
||||
GuessedSceneryDeviation getSceneryDeviationHint() const { return static_cast<GuessedSceneryDeviation>(m_guessedSceneryDeviationHint); }
|
||||
@@ -158,7 +158,7 @@ namespace BlackMisc
|
||||
void setPropertyByIndex(const CPropertyIndex &index, const CVariant &variant);
|
||||
|
||||
//! Calculate the standard deviiations
|
||||
bool calculateStdDeviations(const CAircraftSituationList &situations);
|
||||
bool calculateStdDeviations(const CAircraftSituationList &situations, const PhysicalQuantities::CLength &cg);
|
||||
|
||||
//! NULL object
|
||||
static const CAircraftSituationChange &null();
|
||||
@@ -170,8 +170,11 @@ namespace BlackMisc
|
||||
//! Scenery deviation hint
|
||||
void setSceneryDeviationHint(GuessedSceneryDeviation hint) { m_guessedSceneryDeviationHint = static_cast<int>(hint); }
|
||||
|
||||
//! Set scenery deviation
|
||||
void setSceneryDeviation(const PhysicalQuantities::CLength &deviation, const PhysicalQuantities::CLength &cg, GuessedSceneryDeviation hint);
|
||||
|
||||
//! Guess scenery deviation
|
||||
void guessSceneryDeviation(const CAircraftSituationList &situations);
|
||||
void guessSceneryDeviation(const PhysicalQuantities::CLength &cg);
|
||||
|
||||
int m_situationsCount = -1;
|
||||
CCallsign m_correspondingCallsign;
|
||||
@@ -200,9 +203,12 @@ namespace BlackMisc
|
||||
PhysicalQuantities::CSpeed m_gsMean = PhysicalQuantities::CSpeed::null();
|
||||
PhysicalQuantities::CAngle m_pitchStdDev = PhysicalQuantities::CAngle::null();
|
||||
PhysicalQuantities::CAngle m_pitchMean = PhysicalQuantities::CAngle::null();
|
||||
PhysicalQuantities::CLength m_altAglStdDev = PhysicalQuantities::CLength::null();
|
||||
PhysicalQuantities::CLength m_altAglMean = PhysicalQuantities::CLength::null();
|
||||
PhysicalQuantities::CLength m_gndDistStdDev = PhysicalQuantities::CLength::null();
|
||||
PhysicalQuantities::CLength m_gndDistMean = PhysicalQuantities::CLength::null();
|
||||
PhysicalQuantities::CLength m_guessedSceneryDeviation = PhysicalQuantities::CLength::null();
|
||||
PhysicalQuantities::CLength m_guessedSceneryDeviationCG = PhysicalQuantities::CLength::null();
|
||||
PhysicalQuantities::CLength m_maxGroundDistance = PhysicalQuantities::CLength::null();
|
||||
PhysicalQuantities::CLength m_minGroundDistance = PhysicalQuantities::CLength::null();
|
||||
|
||||
BLACK_METACLASS(
|
||||
CAircraftSituationChange,
|
||||
@@ -222,11 +228,12 @@ namespace BlackMisc
|
||||
BLACK_METAMEMBER(elvMean),
|
||||
BLACK_METAMEMBER(gsStdDev),
|
||||
BLACK_METAMEMBER(gsMean),
|
||||
BLACK_METAMEMBER(altAglStdDev),
|
||||
BLACK_METAMEMBER(altAglMean),
|
||||
BLACK_METAMEMBER(gndDistStdDev),
|
||||
BLACK_METAMEMBER(gndDistMean),
|
||||
BLACK_METAMEMBER(pitchStdDev),
|
||||
BLACK_METAMEMBER(pitchMean),
|
||||
BLACK_METAMEMBER(guessedSceneryDeviation),
|
||||
BLACK_METAMEMBER(guessedSceneryDeviationCG),
|
||||
BLACK_METAMEMBER(guessedSceneryDeviationHint),
|
||||
BLACK_METAMEMBER(timestampMSecsSinceEpoch),
|
||||
BLACK_METAMEMBER(oldestTimestampMSecsSinceEpoch),
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace BlackMisc
|
||||
if (this->isEmpty()) { return 0; }
|
||||
|
||||
Q_ASSERT_X(this->isSortedAdjustedLatestFirstWithoutNullPositions(), Q_FUNC_INFO, "Need sorted situations without NULL positions");
|
||||
const CAircraftSituationChange change(*this, true, true);
|
||||
const CAircraftSituationChange change(*this, model.getCG(), model.isVtol(), true, true);
|
||||
int c = 0;
|
||||
bool first = true;
|
||||
if (this->front().getCallsign().equalsString("AFL2353"))
|
||||
@@ -431,6 +431,18 @@ namespace BlackMisc
|
||||
return values;
|
||||
}
|
||||
|
||||
QList<double> CAircraftSituationList::groundDistanceValues(const CLengthUnit &unit, const CLength &cg) const
|
||||
{
|
||||
QList<double> values;
|
||||
for (const CAircraftSituation &s : *this)
|
||||
{
|
||||
const CLength distance(s.getGroundDistance(cg));
|
||||
if (distance.isNull()) { continue; }
|
||||
values.push_back(distance.value(unit));
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
QPair<CSpeed, CSpeed> CAircraftSituationList::groundSpeedStandardDeviationAndMean() const
|
||||
{
|
||||
const QList<double> gsValues = this->groundSpeedValues(CSpeedUnit::kts());
|
||||
@@ -449,18 +461,28 @@ namespace BlackMisc
|
||||
|
||||
QPair<CAltitude, CAltitude> CAircraftSituationList::elevationStandardDeviationAndMean() const
|
||||
{
|
||||
const QList<double> elvValues = this->elevationValues(CLengthUnit::ft());
|
||||
const QList<double> elvValues = this->elevationValues(CAltitude::defaultUnit());
|
||||
if (elvValues.size() != this->size()) { return QPair<CAltitude, CAltitude>(CAltitude::null(), CAltitude::null()); }
|
||||
const QPair<double, double> elvFt = CMathUtils::standardDeviationAndMean(elvValues);
|
||||
return QPair<CAltitude, CAltitude>(CAltitude(elvFt.first, CAltitude::MeanSeaLevel, CLengthUnit::ft()), CAltitude(elvFt.second, CAltitude::MeanSeaLevel, CLengthUnit::ft()));
|
||||
return QPair<CAltitude, CAltitude>(CAltitude(elvFt.first, CAltitude::MeanSeaLevel, CAltitude::defaultUnit()), CAltitude(elvFt.second, CAltitude::MeanSeaLevel, CAltitude::defaultUnit()));
|
||||
}
|
||||
|
||||
QPair<CAltitude, CAltitude> CAircraftSituationList::altitudeStandardDeviationAndMean() const
|
||||
{
|
||||
const QList<double> altValues = this->altitudeValues(CLengthUnit::ft());
|
||||
const QList<double> altValues = this->altitudeValues(CAltitude::defaultUnit());
|
||||
if (altValues.size() != this->size()) { return QPair<CAltitude, CAltitude>(CAltitude::null(), CAltitude::null()); }
|
||||
const QPair<double, double> altFt = CMathUtils::standardDeviationAndMean(altValues);
|
||||
return QPair<CAltitude, CAltitude>(CAltitude(altFt.first, CAltitude::MeanSeaLevel, CLengthUnit::ft()), CAltitude(altFt.second, CAltitude::MeanSeaLevel, CLengthUnit::ft()));
|
||||
return QPair<CAltitude, CAltitude>(CAltitude(altFt.first, CAltitude::MeanSeaLevel, CAltitude::defaultUnit()), CAltitude(altFt.second, CAltitude::MeanSeaLevel, CAltitude::defaultUnit()));
|
||||
}
|
||||
|
||||
QPair<CLength, CLength> CAircraftSituationList::minMaxGroundDistance(const CLength &cg) const
|
||||
{
|
||||
const QList<double> gndDistance = this->groundDistanceValues(CAltitude::defaultUnit(), cg);
|
||||
if (gndDistance.size() != this->size()) { return QPair<CLength, CLength>(CLength::null(), CLength::null()); }
|
||||
const auto gndDistMinMax = std::minmax_element(gndDistance.constBegin(), gndDistance.constEnd());
|
||||
const double gndDistMin = *gndDistMinMax.first;
|
||||
const double gndDistMax = *gndDistMinMax.second;
|
||||
return QPair<CLength, CLength>(CLength(gndDistMin, CAltitude::defaultUnit()), CLength(gndDistMax, CAltitude::defaultUnit()));
|
||||
}
|
||||
|
||||
QPair<CAltitude, CAltitude> CAircraftSituationList::altitudeAglStandardDeviationAndMean() const
|
||||
@@ -478,7 +500,7 @@ namespace BlackMisc
|
||||
altElvDeltas.push_back(delta);
|
||||
}
|
||||
const QPair<double, double> deltaFt = CMathUtils::standardDeviationAndMean(altElvDeltas);
|
||||
return QPair<CAltitude, CAltitude>(CAltitude(deltaFt.first, CAltitude::MeanSeaLevel, CLengthUnit::ft()), CAltitude(deltaFt.second, CAltitude::MeanSeaLevel, CLengthUnit::ft()));
|
||||
return QPair<CAltitude, CAltitude>(CAltitude(deltaFt.first, CAltitude::MeanSeaLevel, CAltitude::defaultUnit()), CAltitude(deltaFt.second, CAltitude::MeanSeaLevel, CAltitude::defaultUnit()));
|
||||
}
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
@@ -150,12 +150,15 @@ namespace BlackMisc
|
||||
//! All elevation values
|
||||
QList<double> elevationValues(const PhysicalQuantities::CLengthUnit &unit) const;
|
||||
|
||||
//! All corrected altitude values
|
||||
//! All altitude values
|
||||
QList<double> altitudeValues(const PhysicalQuantities::CLengthUnit &unit) const;
|
||||
|
||||
//! All corrected altitude values
|
||||
QList<double> correctedAltitudeValues(const PhysicalQuantities::CLengthUnit &unit, const PhysicalQuantities::CLength &cg) const;
|
||||
|
||||
//! All ground distance values
|
||||
QList<double> groundDistanceValues(const PhysicalQuantities::CLengthUnit &unit, const PhysicalQuantities::CLength &cg) const;
|
||||
|
||||
//! Pitch angles standard deviation and mean
|
||||
QPair<PhysicalQuantities::CAngle, PhysicalQuantities::CAngle> pitchStandardDeviationAndMean() const;
|
||||
|
||||
@@ -168,6 +171,9 @@ namespace BlackMisc
|
||||
//! Elevation standard deviation and mean
|
||||
QPair<CAltitude, CAltitude> altitudeStandardDeviationAndMean() const;
|
||||
|
||||
//! Min. and max. ground distance
|
||||
QPair<PhysicalQuantities::CLength, PhysicalQuantities::CLength> minMaxGroundDistance(const PhysicalQuantities::CLength &cg) const;
|
||||
|
||||
//! Elevation standard deviation and mean
|
||||
//! \note distance is without CG, so on ground it can also be used to calculate
|
||||
QPair<CAltitude, CAltitude> altitudeAglStandardDeviationAndMean() const;
|
||||
|
||||
@@ -75,13 +75,22 @@ namespace BlackMisc
|
||||
CAircraftSituationList CInterpolator<Derived>::remoteAircraftSituationsAndChange(bool useSceneryOffset)
|
||||
{
|
||||
CAircraftSituationList validSituations = this->remoteAircraftSituations(m_callsign);
|
||||
m_currentSituationChange = CAircraftSituationChange(validSituations, true, true);
|
||||
m_currentSituationChange = CAircraftSituationChange(validSituations, m_model.getCG(), m_model.isVtol(), true, true);
|
||||
if (useSceneryOffset && m_currentSituationChange.hasSceneryDeviation() && m_model.hasCG())
|
||||
{
|
||||
const CLength os = m_currentSituationChange.getGuessedSceneryDeviation(m_model.getCG());
|
||||
validSituations.addAltitudeOffset(os);
|
||||
m_currentSituationChange = CAircraftSituationChange(validSituations, true, true); // recalculate
|
||||
const CLength os = m_currentSituationChange.getGuessedSceneryDeviationCG();
|
||||
m_currentSceneryOffset = os;
|
||||
if (!os.isNull())
|
||||
{
|
||||
const CLength addValue = os * -1.0; // positive values means too high, negative values too low
|
||||
int changed = validSituations.addAltitudeOffset(addValue);
|
||||
m_currentSituationChange = CAircraftSituationChange(validSituations, m_model.getCG(), m_model.isVtol(), true, true); // recalculate
|
||||
Q_UNUSED(changed);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_currentSceneryOffset = CLength::null();
|
||||
}
|
||||
return validSituations;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,8 @@ namespace BlackMisc
|
||||
{
|
||||
Q_ASSERT_X(situations.isSortedAdjustedLatestFirstWithoutNullPositions(), Q_FUNC_INFO, "Expect latest first");
|
||||
}
|
||||
const CAircraftSituationChange change = CAircraftSituationChange(situations, true, true);
|
||||
const CAircraftModel model = this->getAircraftInRangeModelForCallsign(callsign);
|
||||
const CAircraftSituationChange change = CAircraftSituationChange(situations, model.getCG(), model.isVtol(), true, true);
|
||||
return change;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace BlackMiscTest
|
||||
{
|
||||
CAircraftSituationList situations = testSituations();
|
||||
situations.setOnGround(CAircraftSituation::OnGround);
|
||||
const CAircraftSituationChange change(situations);
|
||||
const CAircraftSituationChange change(situations, cg(), false);
|
||||
QVERIFY2(change.isConstOnGround(), "Expect const on ground");
|
||||
QVERIFY(!change.isConstNotOnGround());
|
||||
QVERIFY(!change.isJustTakingOff());
|
||||
@@ -52,7 +52,7 @@ namespace BlackMiscTest
|
||||
f.setOnGround(false);
|
||||
situations.pop_front();
|
||||
situations.push_front(f);
|
||||
const CAircraftSituationChange change2(situations);
|
||||
const CAircraftSituationChange change2(situations, cg(), false);
|
||||
QVERIFY2(change2.isJustTakingOff(), "Expect just take off");
|
||||
QVERIFY(!change2.isJustTouchingDown());
|
||||
QVERIFY(change.wasConstOnGround());
|
||||
@@ -63,7 +63,7 @@ namespace BlackMiscTest
|
||||
{
|
||||
CAircraftSituationList situations = testSetDescendingAltitudes(testSituations());
|
||||
situations.setOnGround(CAircraftSituation::NotOnGround);
|
||||
const CAircraftSituationChange change(situations);
|
||||
const CAircraftSituationChange change(situations, cg(), false);
|
||||
QVERIFY2(change.isConstNotOnGround(), "Expect const not on ground");
|
||||
QVERIFY(!change.isConstOnGround());
|
||||
QVERIFY(!change.isJustTakingOff());
|
||||
@@ -76,7 +76,7 @@ namespace BlackMiscTest
|
||||
f.setOnGround(true);
|
||||
situations.pop_front();
|
||||
situations.push_front(f);
|
||||
const CAircraftSituationChange change2(situations);
|
||||
const CAircraftSituationChange change2(situations, cg(), false);
|
||||
QVERIFY2(change2.isJustTouchingDown(), "Expect just touchdown");
|
||||
QVERIFY(!change2.isJustTakingOff());
|
||||
QVERIFY(!change.wasConstOnGround());
|
||||
@@ -98,7 +98,7 @@ namespace BlackMiscTest
|
||||
void CTestAircraftSituation::rotateUp()
|
||||
{
|
||||
CAircraftSituationList situations = testSetRotateUpPitch(testSituations());
|
||||
const CAircraftSituationChange change(situations);
|
||||
const CAircraftSituationChange change(situations, cg(), false);
|
||||
QVERIFY2(!change.isRotatingUp(), "Do not expect rotate up");
|
||||
|
||||
CAircraftSituation f = situations.front();
|
||||
@@ -106,7 +106,7 @@ namespace BlackMiscTest
|
||||
f.setPitch(CAngle(7.3, CAngleUnit::deg()));
|
||||
situations.push_front(f);
|
||||
|
||||
const CAircraftSituationChange change2(situations);
|
||||
const CAircraftSituationChange change2(situations, cg(), false);
|
||||
QVERIFY2(change2.isRotatingUp(), "Expect rotate up");
|
||||
}
|
||||
|
||||
@@ -237,6 +237,12 @@ namespace BlackMiscTest
|
||||
}
|
||||
return newSituations;
|
||||
}
|
||||
|
||||
const CLength &CTestAircraftSituation::cg()
|
||||
{
|
||||
static const CLength cg(2.0, CLengthUnit::m());
|
||||
return cg;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
//! \endcond
|
||||
|
||||
@@ -64,6 +64,9 @@ namespace BlackMiscTest
|
||||
|
||||
//! Set descending altitudes
|
||||
static BlackMisc::Aviation::CAircraftSituationList testSetRotateUpPitch(const BlackMisc::Aviation::CAircraftSituationList &situations);
|
||||
|
||||
//! CG
|
||||
static const BlackMisc::PhysicalQuantities::CLength &cg();
|
||||
};
|
||||
} // namespace
|
||||
|
||||
|
||||
Reference in New Issue
Block a user