mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-14 08:45:36 +08:00
Ref T275, moved "preset" of elevation to situation class (from interpolator)
This commit is contained in:
@@ -144,6 +144,7 @@ namespace BlackMisc
|
|||||||
static const QString change("situation change");
|
static const QString change("situation change");
|
||||||
static const QString cache("cached");
|
static const QString cache("cached");
|
||||||
static const QString test("test");
|
static const QString test("test");
|
||||||
|
static const QString interpolated("interpolated");
|
||||||
|
|
||||||
switch (details)
|
switch (details)
|
||||||
{
|
{
|
||||||
@@ -153,6 +154,7 @@ namespace BlackMisc
|
|||||||
case SituationChange: return change;
|
case SituationChange: return change;
|
||||||
case FromCache: return cache;
|
case FromCache: return cache;
|
||||||
case Test: return test;
|
case Test: return test;
|
||||||
|
case Interpolated: return interpolated;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
return unknown;
|
return unknown;
|
||||||
@@ -176,6 +178,85 @@ namespace BlackMisc
|
|||||||
return cg;
|
return cg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CAircraftSituation::presetGroundElevation(CAircraftSituation &situationToPreset, const CAircraftSituation &oldSituation, const CAircraftSituation &newSituation, const CAircraftSituationChange &change)
|
||||||
|
{
|
||||||
|
// IMPORTANT: we do not know what the situation will be interpolated to, so we cannot transfer
|
||||||
|
situationToPreset.resetGroundElevation();
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (oldSituation.equalNormalVectorDouble(newSituation))
|
||||||
|
{
|
||||||
|
if (oldSituation.hasGroundElevation())
|
||||||
|
{
|
||||||
|
// same positions, we can use existing elevation
|
||||||
|
// means we were not moving between old an new
|
||||||
|
situationToPreset.setGroundElevation(oldSituation.getGroundElevationPlane(), CAircraftSituation::TransferredElevation);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const CLength distance = newSituation.calculateGreatCircleDistance(oldSituation);
|
||||||
|
if (distance < newSituation.getDistancePerTime(250))
|
||||||
|
{
|
||||||
|
if (oldSituation.hasGroundElevation())
|
||||||
|
{
|
||||||
|
// almost same positions, we can use existing elevation
|
||||||
|
situationToPreset.setGroundElevation(oldSituation.getGroundElevationPlane(), CAircraftSituation::TransferredElevation);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const CLength allowedStdDev(3, CLengthUnit::ft());
|
||||||
|
QPair<CAltitude, CAltitude> elvDevMean = change.getElevationStdDevAndMean();
|
||||||
|
if (!elvDevMean.first.isNull() && elvDevMean.first < allowedStdDev)
|
||||||
|
{
|
||||||
|
// not much change in known elevations
|
||||||
|
situationToPreset.setGroundElevation(elvDevMean.second, CAircraftSituation::SituationChange);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CElevationPlane epInterpolated = CAircraftSituation::interpolateElevation(CAircraftSituation::null(), oldSituation, newSituation, distance);
|
||||||
|
if (!epInterpolated.isNull())
|
||||||
|
{
|
||||||
|
situationToPreset.setGroundElevation(epInterpolated, CAircraftSituation::Interpolated);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (false);
|
||||||
|
return situationToPreset.hasGroundElevation();
|
||||||
|
}
|
||||||
|
|
||||||
|
CElevationPlane CAircraftSituation::interpolateElevation(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(); }
|
||||||
|
|
||||||
|
const double newElvFt = newSituation.getGroundElevation().value(CLengthUnit::ft());
|
||||||
|
const double oldElvFt = oldSituation.getGroundElevation().value(CLengthUnit::ft());
|
||||||
|
const double deltaElvFt = newElvFt - oldElvFt;
|
||||||
|
if (deltaElvFt > 25) { return CElevationPlane::null(); }
|
||||||
|
|
||||||
|
if (!situation.isNull())
|
||||||
|
{
|
||||||
|
const double distanceOldNewM = (distance.isNull() ? oldSituation.calculateGreatCircleDistance(newSituation) : distance).value(CLengthUnit::m());
|
||||||
|
const double distanceSituationNewM = situation.calculateGreatCircleDistance(newSituation).value(CLengthUnit::m());
|
||||||
|
const double distRatio = distanceSituationNewM / distanceOldNewM;
|
||||||
|
|
||||||
|
// very close to the situations we return tehir elevation
|
||||||
|
if (distRatio < 0.05) { return newSituation.getGroundElevationPlane(); }
|
||||||
|
if (distRatio > 0.95) { return oldSituation.getGroundElevationPlane(); }
|
||||||
|
|
||||||
|
const double situationElvFt = newElvFt - distRatio * deltaElvFt;
|
||||||
|
return CElevationPlane(situation, situationElvFt, CElevationPlane::singlePointRadius());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const double elvSumFt = oldElvFt + newElvFt;
|
||||||
|
const double elvFt = 0.5 * elvSumFt;
|
||||||
|
return CElevationPlane(newSituation, elvFt, CElevationPlane::singlePointRadius());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CVariant CAircraftSituation::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
|
CVariant CAircraftSituation::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
|
||||||
{
|
{
|
||||||
if (index.isMyself()) { return CVariant::from(*this); }
|
if (index.isMyself()) { return CVariant::from(*this); }
|
||||||
@@ -563,6 +644,11 @@ namespace BlackMisc
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CAircraftSituation::presetGroundElevation(const CAircraftSituation &oldSituation, const CAircraftSituation &newSituation, const CAircraftSituationChange &change)
|
||||||
|
{
|
||||||
|
return CAircraftSituation::presetGroundElevation(*this, oldSituation, newSituation, change);
|
||||||
|
}
|
||||||
|
|
||||||
CAircraftSituation::IsOnGround CAircraftSituation::isOnGroundByElevation() const
|
CAircraftSituation::IsOnGround CAircraftSituation::isOnGroundByElevation() const
|
||||||
{
|
{
|
||||||
return this->isOnGroundByElevation(m_cg);
|
return this->isOnGroundByElevation(m_cg);
|
||||||
|
|||||||
@@ -116,6 +116,7 @@ namespace BlackMisc
|
|||||||
{
|
{
|
||||||
NoElevationInfo,
|
NoElevationInfo,
|
||||||
TransferredElevation, //!< transferred from nearby situation
|
TransferredElevation, //!< transferred from nearby situation
|
||||||
|
Interpolated, //!< interpolated between 2 elevations
|
||||||
FromProvider, //!< from BlackMisc::Simulation::ISimulationEnvironmentProvider
|
FromProvider, //!< from BlackMisc::Simulation::ISimulationEnvironmentProvider
|
||||||
FromCache, //!< from cache
|
FromCache, //!< from cache
|
||||||
SituationChange, //!< from BlackMisc::Aviation::CAircraftSituationChange
|
SituationChange, //!< from BlackMisc::Aviation::CAircraftSituationChange
|
||||||
@@ -283,8 +284,16 @@ namespace BlackMisc
|
|||||||
bool canTransferGroundElevation(const CAircraftSituation &otherSituation, const PhysicalQuantities::CLength &radius = Geo::CElevationPlane::singlePointRadius()) const;
|
bool canTransferGroundElevation(const CAircraftSituation &otherSituation, const PhysicalQuantities::CLength &radius = Geo::CElevationPlane::singlePointRadius()) const;
|
||||||
|
|
||||||
//! Transfer from "this" situation to \c otherSituation
|
//! 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;
|
bool transferGroundElevation(CAircraftSituation &otherSituation, 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
|
||||||
|
bool presetGroundElevation(const Aviation::CAircraftSituation &oldSituation, const Aviation::CAircraftSituation &newSituation, const CAircraftSituationChange &change);
|
||||||
|
|
||||||
//! Is on ground by elevation data, requires elevation and CG
|
//! Is on ground by elevation data, requires elevation and CG
|
||||||
//! @{
|
//! @{
|
||||||
IsOnGround isOnGroundByElevation() const;
|
IsOnGround isOnGroundByElevation() const;
|
||||||
@@ -471,6 +480,17 @@ namespace BlackMisc
|
|||||||
}
|
}
|
||||||
//! @}
|
//! @}
|
||||||
|
|
||||||
|
//! Preset the ground elevation based on info we already have
|
||||||
|
//! \remark either sets a gnd. elevation or sets it to null
|
||||||
|
//! \remark situationToPreset position is unknown
|
||||||
|
//! \remark situationToPreset needs to be between oldSituation and newSituation
|
||||||
|
//! \sa CAircraftSituation::transferGroundElevation
|
||||||
|
static bool presetGroundElevation(CAircraftSituation &situationToPreset, const CAircraftSituation &oldSituation, const CAircraftSituation &newSituation, const CAircraftSituationChange &change);
|
||||||
|
|
||||||
|
//! 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());
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CCallsign m_correspondingCallsign;
|
CCallsign m_correspondingCallsign;
|
||||||
Geo::CCoordinateGeodetic m_position; //!< NULL position as default
|
Geo::CCoordinateGeodetic m_position; //!< NULL position as default
|
||||||
|
|||||||
@@ -38,6 +38,18 @@ namespace BlackMisc
|
|||||||
CCoordinateGeodetic(coordinate), m_radius(radius)
|
CCoordinateGeodetic(coordinate), m_radius(radius)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
CElevationPlane::CElevationPlane(const ICoordinateGeodetic &coordinate, const CAltitude &altitude, const CLength &radius) :
|
||||||
|
CCoordinateGeodetic(coordinate), m_radius(radius)
|
||||||
|
{
|
||||||
|
this->setGeodeticHeight(altitude);
|
||||||
|
}
|
||||||
|
|
||||||
|
CElevationPlane::CElevationPlane(const ICoordinateGeodetic &coordinate, double altitudeMSLft, const CLength &radius) :
|
||||||
|
CCoordinateGeodetic(coordinate), m_radius(radius)
|
||||||
|
{
|
||||||
|
this->setGeodeticHeight(CAltitude(altitudeMSLft, CAltitude::MeanSeaLevel, CLengthUnit::ft()));
|
||||||
|
}
|
||||||
|
|
||||||
void CElevationPlane::setRadiusOrMinimum(const CLength &radius)
|
void CElevationPlane::setRadiusOrMinimum(const CLength &radius)
|
||||||
{
|
{
|
||||||
m_radius = ((radius.isNull() || radius < CElevationPlane::singlePointRadius())) ? CElevationPlane::singlePointRadius() : radius;
|
m_radius = ((radius.isNull() || radius < CElevationPlane::singlePointRadius())) ? CElevationPlane::singlePointRadius() : radius;
|
||||||
|
|||||||
@@ -39,6 +39,12 @@ namespace BlackMisc
|
|||||||
//! Plane at given coordinates with radius
|
//! Plane at given coordinates with radius
|
||||||
CElevationPlane(const ICoordinateGeodetic &coordinate, const PhysicalQuantities::CLength &radius);
|
CElevationPlane(const ICoordinateGeodetic &coordinate, const PhysicalQuantities::CLength &radius);
|
||||||
|
|
||||||
|
//! Plane at given coordinates with radius and altitude
|
||||||
|
CElevationPlane(const ICoordinateGeodetic &coordinate, const Aviation::CAltitude &altitude, const PhysicalQuantities::CLength &radius);
|
||||||
|
|
||||||
|
//! Plane at given coordinates with radius and altitude
|
||||||
|
CElevationPlane(const ICoordinateGeodetic &coordinate, double altitudeMSLft, const PhysicalQuantities::CLength &radius);
|
||||||
|
|
||||||
//! Constructors from CCoordinateGeodetic
|
//! Constructors from CCoordinateGeodetic
|
||||||
using CCoordinateGeodetic::CCoordinateGeodetic;
|
using CCoordinateGeodetic::CCoordinateGeodetic;
|
||||||
|
|
||||||
|
|||||||
@@ -424,9 +424,9 @@ namespace BlackMisc
|
|||||||
currentSituation.setCallsign(m_callsign);
|
currentSituation.setCallsign(m_callsign);
|
||||||
}
|
}
|
||||||
|
|
||||||
// do not set elevation here, as we do not know where the situation will be
|
// preset elevation here, as we do not know where the situation will be after the interpolation step!
|
||||||
// after the interpolation step!
|
const bool preset = currentSituation.presetGroundElevation(oldSituation, newSituation, m_situationsChange);
|
||||||
this->presetGroundElevation(currentSituation, oldSituation, newSituation);
|
Q_UNUSED(preset);
|
||||||
|
|
||||||
// fetch CG once
|
// fetch CG once
|
||||||
const CLength cg(this->getModelCG());
|
const CLength cg(this->getModelCG());
|
||||||
@@ -434,47 +434,6 @@ namespace BlackMisc
|
|||||||
return currentSituation;
|
return currentSituation;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Derived>
|
|
||||||
bool CInterpolator<Derived>::presetGroundElevation(CAircraftSituation &situation, const CAircraftSituation &oldSituation, const CAircraftSituation &newSituation) const
|
|
||||||
{
|
|
||||||
// IMPORTANT: we do not know what the situation will be interpolated to, so we cannot transfer
|
|
||||||
situation.resetGroundElevation();
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (oldSituation.equalNormalVectorDouble(newSituation))
|
|
||||||
{
|
|
||||||
if (oldSituation.hasGroundElevation())
|
|
||||||
{
|
|
||||||
// same positions, we can use existing elevation
|
|
||||||
situation.setGroundElevation(oldSituation.getGroundElevationPlane(), CAircraftSituation::TransferredElevation);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const CLength distance = newSituation.calculateGreatCircleDistance(oldSituation);
|
|
||||||
if (distance < newSituation.getDistancePerTime(250))
|
|
||||||
{
|
|
||||||
if (oldSituation.hasGroundElevation())
|
|
||||||
{
|
|
||||||
// almost same positions, we can use existing elevation
|
|
||||||
situation.setGroundElevation(oldSituation.getGroundElevationPlane(), CAircraftSituation::TransferredElevation);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const CLength allowedStdDev(3, CLengthUnit::ft());
|
|
||||||
QPair<CAltitude, CAltitude> elvDevMean = m_situationsChange.getElevationStdDevAndMean();
|
|
||||||
if (!elvDevMean.first.isNull() && elvDevMean.first < allowedStdDev)
|
|
||||||
{
|
|
||||||
// not much change in known elevations
|
|
||||||
situation.setGroundElevation(elvDevMean.second, CAircraftSituation::SituationChange);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (false);
|
|
||||||
return situation.hasGroundElevation();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
void CInterpolator<Derived>::initCorrespondingModel(const CAircraftModel &model)
|
void CInterpolator<Derived>::initCorrespondingModel(const CAircraftModel &model)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -247,10 +247,6 @@ namespace BlackMisc
|
|||||||
//! Current interpolated situation
|
//! Current interpolated situation
|
||||||
Aviation::CAircraftSituation getInterpolatedSituation();
|
Aviation::CAircraftSituation getInterpolatedSituation();
|
||||||
|
|
||||||
//! Preset the ground elevation based on info we already have
|
|
||||||
//! \remark either sets a gnd.elevation or sets it to null
|
|
||||||
bool presetGroundElevation(Aviation::CAircraftSituation &situation, const Aviation::CAircraftSituation &oldSituation, const Aviation::CAircraftSituation &newSituation) const;
|
|
||||||
|
|
||||||
//! Parts before given offset time
|
//! Parts before given offset time
|
||||||
Aviation::CAircraftParts getInterpolatedParts();
|
Aviation::CAircraftParts getInterpolatedParts();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user