Ref T259, Ref T243 removed interpolation hints

* no longer needed with providers in that form
* pure refactoring commit, just guarantees compilation
* already minor adjustments to use providers
This commit is contained in:
Klaus Basan
2018-03-20 20:15:26 +01:00
parent 476768f6ec
commit 0c06ac26f7
37 changed files with 140 additions and 586 deletions

View File

@@ -1,223 +0,0 @@
/* Copyright (C) 2016
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
#include "interpolationhints.h"
#include "interpolationlogger.h"
#include "blackmisc/aviation/aircraftsituation.h"
using namespace BlackMisc::Aviation;
using namespace BlackMisc::Geo;
using namespace BlackMisc::PhysicalQuantities;
#include <QStringBuilder>
namespace BlackMisc
{
namespace Simulation
{
CInterpolationHints::CInterpolationHints() { }
CInterpolationHints::CInterpolationHints(bool isVtolAircraft) : m_isVtol(isVtolAircraft)
{ }
CInterpolationHints::CInterpolationHints(bool isVtolAircraft, bool hasParts, bool log) :
m_isVtol(isVtolAircraft), m_hasParts(hasParts), m_logInterpolation(log)
{ }
const CElevationPlane &CInterpolationHints::getElevationPlane(ICoordinateGeodetic &reference, const CLength &radius, SituationLog *log) const
{
if (m_elevationPlane.isNull())
{
if (log)
{
static const QString lm("By provider (no valid plane)");
log->elevationInfo = lm;
}
return CElevationPlane::null();
}
const CLength d = reference.calculateGreatCircleDistance(m_elevationPlane);
if (d <= radius)
{
if (log)
{
static const QString lm("Using elevation plane, distance: %1");
log->elevationInfo = lm.arg(d.valueRoundedWithUnit(CLengthUnit::m(), 1));
}
return m_elevationPlane;
}
else
{
if (log)
{
static const QString lm("Invalid elevation plane, distance: %1");
log->elevationInfo = lm.arg(d.valueRoundedWithUnit(CLengthUnit::m(), 1));
}
return CElevationPlane::null();
}
}
CAltitude CInterpolationHints::getGroundElevation(const CAircraftSituation &situation, bool useProvider, bool forceProvider, SituationLog *log) const
{
return this->getGroundElevation(situation, CLength::null(), useProvider, forceProvider, log);
}
CAltitude CInterpolationHints::getGroundElevation(const CAircraftSituation &situation, const CLength &validRadius, bool useProvider, bool forceProvider, SituationLog *log) const
{
Q_ASSERT_X(!(forceProvider && !useProvider), Q_FUNC_INFO, "Invalid parameter combination");
if (forceProvider && useProvider && m_elevationProvider)
{
if (log)
{
static const QString lm("By provider (forced)");
log->elevationInfo = lm;
}
Q_ASSERT_X(false, Q_FUNC_INFO, "Elevation provider must no longer be used");
return m_elevationProvider(situation);
}
const CLength radius = CLength::maxValue(validRadius, m_elevationPlane.getRadius());
const bool validPlane = m_elevationPlane.isWithinRange(situation, radius);
if (!validPlane && useProvider && m_elevationProvider)
{
if (log)
{
static const QString lm("By provider (no valid plane)");
log->elevationInfo = lm;
}
return m_elevationProvider(situation);
}
if (validPlane)
{
if (log)
{
static const QString lm("Using elevation plane, radius: %1");
log->elevationInfo = lm.arg(radius.valueRoundedWithUnit(CLengthUnit::m(), 1));
}
return m_elevationPlane.getAltitude();
}
if (log)
{
static const QString lm("Not using provider, no valid plane");
log->elevationInfo = lm;
}
return CAltitude::null();
}
CAltitude CInterpolationHints::getGroundElevation(const CAircraftSituation &situation, const CLength &validRadius, SituationLog *log) const
{
return this->getGroundElevation(situation, validRadius, false, false, log);
}
CAltitude CInterpolationHints::getGroundElevation(const CAircraftSituation &situation, SituationLog *log) const
{
return this->getGroundElevation(situation, CLength::null(), log);
}
void CInterpolationHints::resetElevationPlane()
{
m_elevationPlane = CElevationPlane();
}
bool CInterpolationHints::isWithinRange(const Geo::ICoordinateGeodetic &coordinate) const
{
if (m_elevationPlane.isNull()) { return false; }
return m_elevationPlane.isWithinRange(coordinate);
}
const CLength &CInterpolationHints::getCGAboveGroundOrZero() const
{
static const CLength zero;
return this->hasCGAboveGround() ? this->getCGAboveGround() : zero;
}
void CInterpolationHints::setAircraftParts(const CAircraftParts &parts, bool hasParts)
{
m_hasParts = hasParts;
m_aircraftParts = parts;
}
bool CInterpolationHints::hasElevationProvider() const
{
return static_cast<bool>(m_elevationProvider);
}
CVariant CInterpolationHints::propertyByIndex(const CPropertyIndex &index) const
{
if (index.isMyself()) { return CVariant::from(*this); }
const ColumnIndex i = index.frontCasted<ColumnIndex>();
switch (i)
{
case IndexCenterOfGravity: return m_cgAboveGround.propertyByIndex(index.copyFrontRemoved());
case IndexElevationPlane: return m_elevationPlane.propertyByIndex(index.copyFrontRemoved());
case IndexIsVtolAircraft: return CVariant::fromValue(m_isVtol);
default: return CValueObject::propertyByIndex(index);
}
}
void CInterpolationHints::setPropertyByIndex(const CPropertyIndex &index, const CVariant &variant)
{
if (index.isMyself()) { (*this) = variant.to<CInterpolationHints>(); return; }
const ColumnIndex i = index.frontCasted<ColumnIndex>();
switch (i)
{
case IndexCenterOfGravity:
m_cgAboveGround.setPropertyByIndex(index.copyFrontRemoved(), variant);
break;
case IndexElevationPlane:
m_elevationPlane.setPropertyByIndex(index.copyFrontRemoved(), variant);
break;
case IndexIsVtolAircraft:
m_isVtol = variant.toBool();
break;
default:
CValueObject::setPropertyByIndex(index, variant);
break;
}
}
QString CInterpolationHints::convertToQString(bool i18n) const
{
Q_UNUSED(i18n);
return this->asString(true, true);
}
QString CInterpolationHints::asString(bool withParts, bool withElevationPlane) const
{
return
QStringLiteral("VTOL: ") % boolToYesNo(m_isVtol) %
QStringLiteral(" parts: ") % boolToYesNo(m_hasParts) %
(
withParts && m_hasParts ?
QStringLiteral(" parts: ") % m_aircraftParts.toQString(true) :
QStringLiteral("")
) %
QStringLiteral(" CG: ") % m_cgAboveGround.valueRoundedWithUnit(CLengthUnit::m(), 1) %
(
withElevationPlane ?
QStringLiteral(" elv.plane: ") % m_elevationPlane.toQString(true) :
QStringLiteral(" elv.plane: ") % boolToNullNotNull(m_elevationPlane.isNull())
) %
QStringLiteral(" elv.pr.: ") % boolToYesNo(m_elevationProvider ? true : false);
}
QString CInterpolationHints::debugInfo(const CElevationPlane &deltaElevation) const
{
static const QString s("Lat: %1 Lng: %2 Elv: %3");
if (m_elevationPlane.isNull() || deltaElevation.isNull()) return "null";
return s.arg(
(deltaElevation.latitude() - m_elevationPlane.latitude()).valueRoundedWithUnit(CAngleUnit::deg(), 10),
(deltaElevation.longitude() - m_elevationPlane.longitude()).valueRoundedWithUnit(CAngleUnit::deg(), 10),
(deltaElevation.geodeticHeight() - m_elevationPlane.geodeticHeight()).valueRoundedWithUnit(CLengthUnit::ft(), 2)
);
}
} // namespace
} // namespace

View File

@@ -1,179 +0,0 @@
/* Copyright (C) 2016
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
//! \file
#ifndef BLACKMISC_SIMULATION_INTERPOLATIONHINTS_H
#define BLACKMISC_SIMULATION_INTERPOLATIONHINTS_H
#include "blackmisc/blackmiscexport.h"
#include "blackmisc/geo/elevationplane.h"
#include "blackmisc/valueobject.h"
#include "blackmisc/aviation/aircraftparts.h"
namespace BlackMisc
{
namespace Aviation { class CAircraftSituation; }
namespace Simulation
{
struct SituationLog;
//! Hints for interpolator such as ground elevation
class BLACKMISC_EXPORT CInterpolationHints : public CValueObject<CInterpolationHints>
{
public:
//! Property indexes
enum ColumnIndex
{
IndexElevationPlane = CPropertyIndex::GlobalIndexCInterpolationHints,
IndexCenterOfGravity,
IndexIsVtolAircraft
};
//! Default constructor.
CInterpolationHints();
//! Constructor
CInterpolationHints(bool isVtolAircraft);
//! Constructor
CInterpolationHints(bool isVtolAircraft, bool hasParts, bool log);
//! Get elevation plane
const Geo::CElevationPlane &getElevationPlane() const { return m_elevationPlane;}
//! Get elevation plane
const Geo::CElevationPlane &getElevationPlane(Geo::ICoordinateGeodetic &reference, const PhysicalQuantities::CLength &radius, SituationLog *log = nullptr) const;
//! Set elevation
//! \remark used to store a ground elevation and use it as well for nearby situatons
void setElevationPlane(const Geo::CElevationPlane &elevation) { m_elevationPlane = elevation; }
//! Elevation plane set to null
void resetElevationPlane();
private:
//! \todo KB 2018-03 ground flag refactoring
//! Get elevation from CInterpolationHints::getElevationProvider or CInterpolationHints::getElevation
//! \remark avoid unnecessary calls on XPlane (calling elevation provider)
//! \param situation where to check
//! \param useProvider using the provider if available
//! \param forceProvider use the provider and ignore any elevation plane
//! \param log optional chance to write info about elevation
//! \see setElevationProvider
//! \see setElevationPlane
//! \deprecated
Aviation::CAltitude getGroundElevation(const Aviation::CAircraftSituation &situation, bool useProvider, bool forceProvider = false, SituationLog *log = nullptr) const;
//! Get elevation from CInterpolationHints::getElevationProvider or CInterpolationHints::getElevation
//! \remark if validRadius is >= Geo::CElevationPlane::radius use validRadius
//! \deprecated
Aviation::CAltitude getGroundElevation(const Aviation::CAircraftSituation &situation, const PhysicalQuantities::CLength &validRadius, bool useProvider, bool forceProvider = false, SituationLog *log = nullptr) const;
//! Get ground elevation by using the elevation plane
//! \deprecated
Aviation::CAltitude getGroundElevation(const Aviation::CAircraftSituation &situation, const PhysicalQuantities::CLength &validRadius, SituationLog *log = nullptr) const;
//! Get ground elevation by using the elevation plane
//! \deprecated
Aviation::CAltitude getGroundElevation(const Aviation::CAircraftSituation &situation, SituationLog *log = nullptr) const;
public:
//! Check if elevation is within radius and can be used
bool isWithinRange(const Geo::ICoordinateGeodetic &coordinate) const;
//! Get CG above ground
const PhysicalQuantities::CLength &getCGAboveGround() const { return m_cgAboveGround;}
//! Get CG above ground or 0 ("Zero")
const PhysicalQuantities::CLength &getCGAboveGroundOrZero() const;
//! Has CG above ground
bool hasCGAboveGround() const { return m_cgAboveGround.isNull(); }
//! Set CG above ground
void setCGAboveGround(const PhysicalQuantities::CLength &cgAboveGround) { m_cgAboveGround = cgAboveGround; }
//! VTOL aircraft?
bool isVtolAircraft() const { return m_isVtol; }
//! VTOL aircraft
void setVtolAircraft(bool vtol) { m_isVtol = vtol; }
//! Log interpolation?
bool isLoggingInterpolation() const { return m_logInterpolation; }
//! Log interpolation?
void setLoggingInterpolation(bool log) { m_logInterpolation = log; }
//! Has valid aircraft parts?
bool hasAircraftParts() const { return m_hasParts; }
//! Aircraft parts required for interpolation
Aviation::CAircraftParts getAircraftParts() const { return m_aircraftParts; }
//! Set aircraft parts required for interpolation if any
//! \remark when used to reset value (default object) use hasParts false. Needed as there is no null parts object
void setAircraftParts(const Aviation::CAircraftParts &parts, bool hasParts = true);
//! Function object that can obtain ground elevation
using ElevationProvider = std::function<Aviation::CAltitude(const Aviation::CAircraftSituation &)>;
//! Has elevation provider?
//! \deprecated
bool hasElevationProvider() const;
//! Set function object that can obtain ground elevation
//! \remark either a provider can be used or an elevation plan can be set
//! \see setElevationPlane
//! \see getGroundElevation
//! \deprecated
void setElevationProvider(const ElevationProvider &ep) { m_elevationProvider = ep; }
//! \copydoc BlackMisc::Mixin::Index::propertyByIndex
CVariant propertyByIndex(const CPropertyIndex &index) const;
//! \copydoc BlackMisc::Mixin::Index::setPropertyByIndex
void setPropertyByIndex(const CPropertyIndex &index, const CVariant &variant);
//! \copydoc BlackMisc::Mixin::String::toQString
QString convertToQString(bool i18n = false) const;
//! Formatted as string
QString asString(bool withParts, bool withElevationPlane) const;
//! For debugging
QString debugInfo(const Geo::CElevationPlane &deltaElevation) const;
private:
bool m_isVtol = false; //!< VTOL aircraft?
bool m_hasParts = false; //!< Has valid aircraft parts?
bool m_logInterpolation = false; //!< Log.interpolation
Aviation::CAircraftParts m_aircraftParts; //!< Aircraft parts
Geo::CElevationPlane m_elevationPlane; //!< Aircraft's elevation if available
ElevationProvider m_elevationProvider; //!< Provider of ground elevation (lazy computation)
PhysicalQuantities::CLength m_cgAboveGround { 0, nullptr }; //!< center of gravity above ground
BLACK_METACLASS(
CInterpolationHints,
BLACK_METAMEMBER(isVtol),
BLACK_METAMEMBER(elevationPlane),
BLACK_METAMEMBER(cgAboveGround),
BLACK_METAMEMBER(hasParts),
BLACK_METAMEMBER(aircraftParts),
BLACK_METAMEMBER(logInterpolation)
// elevationProvider not included
);
};
} // namespace
} // namespace
Q_DECLARE_METATYPE(BlackMisc::Simulation::CInterpolationHints)
#endif // guard

View File

@@ -407,7 +407,7 @@ namespace BlackMisc
}
QString SituationLog::toQString(
bool withHints, bool withSetup,
bool withSetup,
bool withCurrentSituation,
bool withElevation, bool withOtherPositions, bool withDeltaTimes, const QString &separator) const
{
@@ -419,11 +419,6 @@ namespace BlackMisc
QStringLiteral(" | type: ") % this->interpolationType() %
QStringLiteral(" | gnd.fa.: ") % QString::number(groundFactor) %
QStringLiteral(" | #nw.sit.: ") % QString::number(noNetworkSituations) %
(
withHints ?
separator % QStringLiteral("hints: ") % usedHints.asString(false, true) :
QStringLiteral("")
) %
(
withSetup ?
separator % QStringLiteral("setup: ") % usedSetup.toQString(true) :

View File

@@ -13,7 +13,6 @@
#define BLACKMISC_SIMULATION_INTERPOLATIONLOGGER_H
#include "interpolationrenderingsetup.h"
#include "interpolationhints.h"
#include "blackmisc/simulation/remoteaircraftprovider.h"
#include "blackmisc/aviation/aircraftpartslist.h"
#include "blackmisc/aviation/aircraftsituationlist.h"
@@ -48,7 +47,6 @@ namespace BlackMisc
Aviation::CAircraftSituation situationCurrent; //!< interpolated situation
PhysicalQuantities::CLength cgAboveGround; //!< center of gravity
CInterpolationAndRenderingSetupPerCallsign usedSetup; //!< used setup
CInterpolationHints usedHints; //!< hints
//! Delta time between interpolation and current time
double deltaCurrentToInterpolatedTime() const
@@ -72,10 +70,9 @@ namespace BlackMisc
}
//! To string
QString toQString(
bool withHints, bool withSetup,
bool withCurrentSituation, bool withElevation,
bool withOtherPositions, bool withDeltaTimes, const QString &separator = {" "}) const;
QString toQString(bool withSetup,
bool withCurrentSituation, bool withElevation,
bool withOtherPositions, bool withDeltaTimes, const QString &separator = {" "}) const;
};
//! Log entry for parts interpolation

View File

@@ -9,7 +9,6 @@
#include "interpolator.h"
#include "blackconfig/buildconfig.h"
#include "blackmisc/simulation/interpolationhints.h"
#include "blackmisc/simulation/interpolationlogger.h"
#include "blackmisc/simulation/interpolatorlinear.h"
#include "blackmisc/simulation/interpolatorspline.h"
@@ -54,14 +53,14 @@ namespace BlackMisc
template <typename Derived>
CAircraftSituation CInterpolator<Derived>::getInterpolatedSituation(
qint64 currentTimeMsSinceEpoc,
const CInterpolationAndRenderingSetupPerCallsign &setup, const CInterpolationHints &hints,
const CInterpolationAndRenderingSetupPerCallsign &setup,
CInterpolationStatus &status)
{
Q_ASSERT_X(!m_callsign.isEmpty(), Q_FUNC_INFO, "Missing callsign");
// this code is used by linear and spline interpolator
status.reset();
const bool doLogging = this->hasAttachedLogger() && hints.isLoggingInterpolation();
const bool doLogging = this->hasAttachedLogger() && setup.logInterpolation();
SituationLog log;
SituationLog *logP = doLogging ? &log : nullptr;
@@ -81,15 +80,15 @@ namespace BlackMisc
// * As XP uses lazy init we will call getGroundElevation only when needed
// * default here via getElevationPlane
// CAltitude currentGroundElevation(hints.getGroundElevation(currentSituation, currentSituation.getDistancePerTime(1000), true, false, logP));
const CElevationPlane currentGroundElevation = hints.getElevationPlane(currentSituation, currentSituation.getDistancePerTime(1000), logP);
currentSituation.setGroundElevation(currentGroundElevation); // set as default
const CElevationPlane currentGroundElevation = this->findClosestElevationWithinRange(currentSituation, currentSituation.getDistancePerTime(1000));
currentSituation.setGroundElevationChecked(currentGroundElevation); // set as default
// data, split situations by time
if (currentTimeMsSinceEpoc < 0) { currentTimeMsSinceEpoc = QDateTime::currentMSecsSinceEpoch(); }
// interpolant function from derived class
// CInterpolatorLinear::Interpolant or CInterpolatorSpline::Interpolant
const auto interpolant = derived()->getInterpolant(currentTimeMsSinceEpoc, setup, hints, status, log);
const auto interpolant = derived()->getInterpolant(currentTimeMsSinceEpoc, setup, status, log);
// succeeded so far?
if (!status.isInterpolated())
@@ -99,12 +98,12 @@ namespace BlackMisc
}
// use derived interpolant function
currentSituation.setPosition(interpolant.interpolatePosition(setup, hints));
currentSituation.setAltitude(interpolant.interpolateAltitude(setup, hints));
currentSituation.setPosition(interpolant.interpolatePosition(setup));
currentSituation.setAltitude(interpolant.interpolateAltitude(setup));
currentSituation.setMSecsSinceEpoch(interpolant.getInterpolatedTime());
// PBH before ground so we can use PBH in guessing ground
if (setup.isForcingFullInterpolation() || hints.isVtolAircraft() || status.isInterpolated())
if (setup.isForcingFullInterpolation() || status.isInterpolated())
{
const auto pbh = interpolant.pbh();
currentSituation.setHeading(pbh.getHeading());
@@ -118,9 +117,9 @@ namespace BlackMisc
constexpr double NoGroundFactor = -1;
double groundFactor = NoGroundFactor;
if (hints.hasAircraftParts())
if (setup.isAircraftPartsEnabled())
{
groundFactor = hints.getAircraftParts().isOnGroundInterpolated();
// groundFactor = hints.getAircraftParts().isOnGroundInterpolated();
if (groundFactor > 0.0)
{
// if not having an ground elevation yet, we fetch from provider (if there is a provider)
@@ -131,8 +130,9 @@ namespace BlackMisc
if (!currentGroundElevation.isNull())
{
Q_ASSERT_X(currentGroundElevation.getReferenceDatum() == CAltitude::MeanSeaLevel, Q_FUNC_INFO, "Need MSL value");
const CAltitude groundElevationCG = currentGroundElevation.withOffset(hints.getCGAboveGround());
Q_ASSERT_X(currentGroundElevation.getAltitude().getReferenceDatum() == CAltitude::MeanSeaLevel, Q_FUNC_INFO, "Need MSL value");
const CLength cg = this->getCG(m_callsign);
const CAltitude groundElevationCG = currentGroundElevation.getAltitude().withOffset(cg);
currentSituation.setGroundElevationChecked(currentGroundElevation);
// alt = ground + aboveGround * groundFactor
// = ground + (altitude - ground) * groundFactor
@@ -146,7 +146,7 @@ namespace BlackMisc
// depending on ground factor set ground flag and reliability
// it will use the hints ground flag or elevation/CG or guessing
CInterpolator::setGroundFlagFromInterpolator(hints, groundFactor, currentSituation);
// CInterpolator::setGroundFlagFromInterpolator(hints, groundFactor, currentSituation);
// we transfer ground elevation for future usage
if (currentSituation.hasGroundElevation())
@@ -165,7 +165,6 @@ namespace BlackMisc
log.callsign = m_callsign;
log.groundFactor = groundFactor;
log.situationCurrent = currentSituation;
log.usedHints = hints;
log.usedSetup = setup;
m_logger->logInterpolation(log);
}
@@ -412,7 +411,7 @@ namespace BlackMisc
}
template <typename Derived>
void CInterpolator<Derived>::setGroundFlagFromInterpolator(const CInterpolationHints &hints, double groundFactor, CAircraftSituation &situation)
void CInterpolator<Derived>::setGroundFlagFromInterpolator(double groundFactor, CAircraftSituation &situation) const
{
// by interpolation
if (groundFactor >= 1.0)
@@ -428,15 +427,17 @@ namespace BlackMisc
// on elevation and CG
// remark: to some extend redundant as situation.getCorrectedAltitude() already corrects altitude
Q_ASSERT_X(!m_callsign.isEmpty(), Q_FUNC_INFO, "Need callsign");
if (situation.hasGroundElevation())
{
static const CLength onGroundThresholdLimit(1.0, CLengthUnit::m());
static const CLength notOnGroundThresholdLimit(10.0, CLengthUnit::m()); // upper boundary
CLength offset = onGroundThresholdLimit; // very small offset from allowed
CAircraftSituation::OnGroundReliability reliability = CAircraftSituation::OnGroundByElevation;
if (hints.hasCGAboveGround())
CAircraftSituation::OnGroundDetails reliability = CAircraftSituation::OnGroundByElevation;
CLength cg = this->getCG(m_callsign);
if (!cg.isNull())
{
offset += hints.getCGAboveGround();
offset += cg;
reliability = CAircraftSituation::OnGroundByElevationAndCG;
}
else
@@ -465,7 +466,7 @@ namespace BlackMisc
}
// for VTOL aircraft we give up
if (hints.isVtolAircraft())
if (this->isVtolAircraft(m_callsign))
{
situation.setOnGround(CAircraftSituation::OnGroundSituationUnknown, CAircraftSituation::OnGroundReliabilityNoSet);
return;

View File

@@ -14,6 +14,8 @@
#include "interpolationrenderingsetup.h"
#include "blackmisc/simulation/remoteaircraftprovider.h"
#include "blackmisc/simulation/interpolationsetupprovider.h"
#include "blackmisc/simulation/simulationenvironmentprovider.h"
#include "blackmisc/aviation/aircraftpartslist.h"
#include "blackmisc/aviation/aircraftsituation.h"
#include "blackmisc/aviation/aircraftpartslist.h"
@@ -29,7 +31,6 @@ namespace BlackMisc
namespace Aviation { class CCallsign; }
namespace Simulation
{
class CInterpolationHints;
class CInterpolationLogger;
class CInterpolatorLinear;
class CInterpolatorSpline;
@@ -38,14 +39,18 @@ namespace BlackMisc
//! Interpolator, calculation inbetween positions
template <typename Derived>
class CInterpolator : public QObject
class CInterpolator :
public CSimulationEnvironmentAware,
public CInterpolationSetupAware,
public CRemoteAircraftAware,
public QObject
{
public:
//! Log categories
const CLogCategoryList &getLogCategories();
//! Current interpolated situation
Aviation::CAircraftSituation getInterpolatedSituation(qint64 currentTimeSinceEpoc, const CInterpolationAndRenderingSetupPerCallsign &setup, const CInterpolationHints &hints, CInterpolationStatus &status);
Aviation::CAircraftSituation getInterpolatedSituation(qint64 currentTimeSinceEpoc, const CInterpolationAndRenderingSetupPerCallsign &setup, CInterpolationStatus &status);
//! Parts before given offset time (aka pending parts)
Aviation::CAircraftParts getInterpolatedParts(
@@ -78,7 +83,6 @@ namespace BlackMisc
}
//! Attach an observer to read the interpolator's state for debugging
//! \remark situation logging requires CInterpolationHints::isLoggingInterpolation to be \c true
//! \remark parts logging has a \c bool \c log flag
void attachLogger(CInterpolationLogger *logger) { m_logger = logger; }
@@ -112,7 +116,7 @@ namespace BlackMisc
CInterpolator(const QString &objectName, const Aviation::CCallsign &callsign, QObject *parent);
//! Set on ground flag
static void setGroundFlagFromInterpolator(const CInterpolationHints &hints, double groundFactor, Aviation::CAircraftSituation &situation);
void setGroundFlagFromInterpolator(double groundFactor, Aviation::CAircraftSituation &situation) const;
private:
CInterpolationLogger *m_logger = nullptr;

View File

@@ -15,7 +15,6 @@
#include "blackmisc/aviation/aircraftparts.h"
#include "blackmisc/aviation/aircraftsituation.h"
#include "blackmisc/aviation/callsign.h"
#include "blackmisc/simulation/interpolationhints.h"
#include "blackmisc/simulation/interpolationlogger.h"
#include "blackmisc/simulation/interpolationrenderingsetup.h"
#include "blackmisc/simulation/interpolator.h"
@@ -38,11 +37,11 @@ namespace BlackMisc
//! \copydoc CInterpolator::getInterpolatedSituation
BlackMisc::Aviation::CAircraftSituation getInterpolatedSituation(
qint64, const CInterpolationAndRenderingSetupGlobal &, const CInterpolationHints &, CInterpolationStatus &) { return {}; }
qint64, const CInterpolationAndRenderingSetupPerCallsign &, CInterpolationStatus &) { return {}; }
//! \copydoc CInterpolator::getInterpolatedParts
BlackMisc::Aviation::CAircraftParts getInterpolatedParts(
qint64, const CInterpolationAndRenderingSetupGlobal &, CPartsStatus &, bool = false) const { return {}; }
qint64, const CInterpolationAndRenderingSetupPerCallsign &, CPartsStatus &, bool = false) const { return {}; }
//! \copydoc CInterpolator::addAircraftSituation
void addAircraftSituation(const BlackMisc::Aviation::CAircraftSituation &) {}

View File

@@ -14,7 +14,6 @@
#include "blackmisc/geo/coordinategeodetic.h"
#include "blackmisc/pq/length.h"
#include "blackmisc/pq/physicalquantity.h"
#include "blackmisc/simulation/interpolationhints.h"
#include "blackmisc/logmessage.h"
#include "blackmisc/compare.h"
#include "blackmisc/verify.h"
@@ -49,11 +48,12 @@ namespace BlackMisc
m_pbh(m_simulationTimeFraction, situation1, situation2)
{}
CInterpolatorLinear::Interpolant CInterpolatorLinear::getInterpolant(qint64 currentTimeMsSinceEpoc,
const CInterpolationAndRenderingSetupPerCallsign &setup, const CInterpolationHints &hints, CInterpolationStatus &status, SituationLog &log) const
CInterpolatorLinear::Interpolant CInterpolatorLinear::getInterpolant(
qint64 currentTimeMsSinceEpoc,
const CInterpolationAndRenderingSetupPerCallsign &setup,
CInterpolationStatus &status, SituationLog &log) const
{
Q_UNUSED(setup);
Q_UNUSED(hints);
status.reset();
// with the latest updates of T243 the order and the offsets are supposed to be correct
@@ -118,11 +118,10 @@ namespace BlackMisc
// take hint into account to calculate elevation and above ground level
// do not call for XP (lazy init)
if (!hints.hasElevationProvider())
{
oldSituation.setGroundElevationChecked(hints.getElevationPlane());
newSituation.setGroundElevationChecked(hints.getElevationPlane());
}
const CElevationPlane planeOld = this->findClosestElevationWithinRange(oldSituation, CElevationPlane::singlePointRadius());
const CElevationPlane planeNew = this->findClosestElevationWithinRange(newSituation, CElevationPlane::singlePointRadius());
oldSituation.setGroundElevationChecked(planeOld);
newSituation.setGroundElevationChecked(planeNew);
CAircraftSituation currentSituation(oldSituation); // also sets ground elevation if available
@@ -144,7 +143,7 @@ namespace BlackMisc
currentSituation.setMSecsSinceEpoch(interpolatedTime);
status.setInterpolatedAndCheckSituation(true, currentSituation);
if (this->hasAttachedLogger() && hints.isLoggingInterpolation())
if (this->hasAttachedLogger() && setup.logInterpolation())
{
log.tsCurrent = currentTimeMsSinceEpoc;
log.deltaSampleTimesMs = sampleDeltaTimeMs;
@@ -159,10 +158,9 @@ namespace BlackMisc
return { oldSituation, newSituation, simulationTimeFraction, interpolatedTime };
}
CCoordinateGeodetic CInterpolatorLinear::Interpolant::interpolatePosition(const CInterpolationAndRenderingSetupPerCallsign &setup, const CInterpolationHints &hints) const
CCoordinateGeodetic CInterpolatorLinear::Interpolant::interpolatePosition(const CInterpolationAndRenderingSetupPerCallsign &setup) const
{
Q_UNUSED(setup);
Q_UNUSED(hints);
const std::array<double, 3> oldVec(m_oldSituation.getPosition().normalVectorDouble());
const std::array<double, 3> newVec(m_newSituation.getPosition().normalVectorDouble());
@@ -175,10 +173,9 @@ namespace BlackMisc
return currentPosition;
}
CAltitude CInterpolatorLinear::Interpolant::interpolateAltitude(const CInterpolationAndRenderingSetupPerCallsign &setup, const CInterpolationHints &hints) const
CAltitude CInterpolatorLinear::Interpolant::interpolateAltitude(const CInterpolationAndRenderingSetupPerCallsign &setup) const
{
Q_UNUSED(setup);
Q_UNUSED(hints);
// Interpolate altitude: Alt = (AltB - AltA) * t + AltA
// avoid underflow below ground elevation by using getCorrectedAltitude

View File

@@ -49,8 +49,8 @@ namespace BlackMisc
//! Perform the interpolation
//! @{
Geo::CCoordinateGeodetic interpolatePosition(const CInterpolationAndRenderingSetupPerCallsign &setup, const CInterpolationHints &hints) const;
Aviation::CAltitude interpolateAltitude(const CInterpolationAndRenderingSetupPerCallsign &setup, const CInterpolationHints &hints) const;
Geo::CCoordinateGeodetic interpolatePosition(const CInterpolationAndRenderingSetupPerCallsign &setup) const;
Aviation::CAltitude interpolateAltitude(const CInterpolationAndRenderingSetupPerCallsign &setup) const;
//! @}
//! Interpolator for pitch, bank, heading, groundspeed
@@ -75,8 +75,7 @@ namespace BlackMisc
};
//! Get the interpolant for the given time point
Interpolant getInterpolant(qint64 currentTimeMsSinceEpoc, const CInterpolationAndRenderingSetupPerCallsign &setup,
const CInterpolationHints &hints, CInterpolationStatus &status, SituationLog &log) const;
Interpolant getInterpolant(qint64 currentTimeMsSinceEpoc, const CInterpolationAndRenderingSetupPerCallsign &setup, CInterpolationStatus &status, SituationLog &log) const;
};
} // ns
} // ns

View File

@@ -24,13 +24,13 @@ namespace BlackMisc
{}
CAircraftSituation CInterpolatorMulti::getInterpolatedSituation(qint64 currentTimeSinceEpoc,
const CInterpolationAndRenderingSetupPerCallsign &setup,
const CInterpolationHints &hints, CInterpolationStatus &status)
const CInterpolationAndRenderingSetupPerCallsign &setup,
CInterpolationStatus &status)
{
switch (m_mode)
{
case ModeLinear: return m_linear.getInterpolatedSituation(currentTimeSinceEpoc, setup, hints, status);
case ModeSpline: return m_spline.getInterpolatedSituation(currentTimeSinceEpoc, setup, hints, status);
case ModeLinear: return m_linear.getInterpolatedSituation(currentTimeSinceEpoc, setup, status);
case ModeSpline: return m_spline.getInterpolatedSituation(currentTimeSinceEpoc, setup, status);
default: break;
}
return {};

View File

@@ -34,10 +34,11 @@ namespace BlackMisc
Aviation::CAircraftSituation getInterpolatedSituation(
qint64 currentTimeSinceEpoc,
const CInterpolationAndRenderingSetupPerCallsign &setup,
const CInterpolationHints &hints, CInterpolationStatus &status);
CInterpolationStatus &status);
//! \copydoc CInterpolator::getInterpolatedParts
Aviation::CAircraftParts getInterpolatedParts(qint64 currentTimeSinceEpoc,
Aviation::CAircraftParts getInterpolatedParts(
qint64 currentTimeSinceEpoc,
const CInterpolationAndRenderingSetupPerCallsign &setup,
CPartsStatus &partsStatus, bool log = false) const;

View File

@@ -8,7 +8,6 @@
*/
#include "blackmisc/simulation/interpolatorspline.h"
#include "blackmisc/simulation/interpolationhints.h"
#include "blackmisc/logmessage.h"
#include "blackmisc/verify.h"
@@ -95,11 +94,12 @@ namespace BlackMisc
}
}
CInterpolatorSpline::Interpolant CInterpolatorSpline::getInterpolant(qint64 currentTimeMsSinceEpoc,
const CInterpolationAndRenderingSetupPerCallsign &setup, const CInterpolationHints &hints, CInterpolationStatus &status,
SituationLog &log)
CInterpolatorSpline::Interpolant CInterpolatorSpline::getInterpolant(
qint64 currentTimeMsSinceEpoc,
const CInterpolationAndRenderingSetupPerCallsign &setup,
CInterpolationStatus &status,
SituationLog &log)
{
Q_UNUSED(hints);
Q_UNUSED(setup);
// recalculate derivatives only if they changed
@@ -135,17 +135,19 @@ namespace BlackMisc
// - on an airport the plane does not move very fast, or not at all
// - and the elevation remains (almost) constant for a wider area
// - flying the ground elevation not really matters
if (!hints.getElevationPlane().isNull())
{
// do not override existing values
m_s[0].setGroundElevationChecked(hints.getElevationPlane());
m_s[1].setGroundElevationChecked(hints.getElevationPlane());
m_s[2].setGroundElevationChecked(hints.getElevationPlane());
}
const CElevationPlane plane0 = this->findClosestElevationWithinRange(m_s[0], CElevationPlane::singlePointRadius());
const CElevationPlane plane1 = this->findClosestElevationWithinRange(m_s[1], CElevationPlane::singlePointRadius());
const CElevationPlane plane2 = this->findClosestElevationWithinRange(m_s[2], CElevationPlane::singlePointRadius());
const double a0 = m_s[0].getCorrectedAltitude(hints.getCGAboveGround()).value();
const double a1 = m_s[1].getCorrectedAltitude(hints.getCGAboveGround()).value();
const double a2 = m_s[2].getCorrectedAltitude(hints.getCGAboveGround()).value();
// do not override existing values
m_s[0].setGroundElevationChecked(plane0);
m_s[1].setGroundElevationChecked(plane1);
m_s[2].setGroundElevationChecked(plane2);
const CLength cg = this->getCG(m_callsign);
const double a0 = m_s[0].getCorrectedAltitude(cg).value();
const double a1 = m_s[1].getCorrectedAltitude(cg).value();
const double a2 = m_s[2].getCorrectedAltitude(cg).value();
const std::array<std::array<double, 3>, 3> normals {{ m_s[0].getPosition().normalVectorDouble(), m_s[1].getPosition().normalVectorDouble(), m_s[2].getPosition().normalVectorDouble() }};
PosArray pa;
@@ -190,7 +192,7 @@ namespace BlackMisc
status.setInterpolated(true);
m_interpolant.setTimes(currentTimeMsSinceEpoc, timeFraction, interpolatedTime);
if (this->hasAttachedLogger() && hints.isLoggingInterpolation())
if (this->hasAttachedLogger() && setup.logInterpolation())
{
log.interpolationSituations.push_back(m_s[0]);
log.interpolationSituations.push_back(m_s[1]);
@@ -205,10 +207,9 @@ namespace BlackMisc
return m_interpolant;
}
CCoordinateGeodetic CInterpolatorSpline::Interpolant::interpolatePosition(const CInterpolationAndRenderingSetupPerCallsign &setup, const CInterpolationHints &hints) const
CCoordinateGeodetic CInterpolatorSpline::Interpolant::interpolatePosition(const CInterpolationAndRenderingSetupPerCallsign &setup) const
{
Q_UNUSED(setup);
Q_UNUSED(hints);
const double newX = evalSplineInterval(m_currentTimeMsSinceEpoc, m_pa.t[1], m_pa.t[2], m_pa.x[1], m_pa.x[2], m_pa.dx[1], m_pa.dx[2]);
const double newY = evalSplineInterval(m_currentTimeMsSinceEpoc, m_pa.t[1], m_pa.t[2], m_pa.y[1], m_pa.y[2], m_pa.dy[1], m_pa.dy[2]);
@@ -219,10 +220,9 @@ namespace BlackMisc
return currentPosition;
}
CAltitude CInterpolatorSpline::Interpolant::interpolateAltitude(const CInterpolationAndRenderingSetupPerCallsign &setup, const CInterpolationHints &hints) const
CAltitude CInterpolatorSpline::Interpolant::interpolateAltitude(const CInterpolationAndRenderingSetupPerCallsign &setup) const
{
Q_UNUSED(setup);
Q_UNUSED(hints);
const double newA = evalSplineInterval(m_currentTimeMsSinceEpoc, m_pa.t[1], m_pa.t[2], m_pa.a[1], m_pa.a[2], m_pa.da[1], m_pa.da[2]);
return CAltitude(newA, m_altitudeUnit);

View File

@@ -63,8 +63,8 @@ namespace BlackMisc
//! Perform the interpolation
//! @{
Geo::CCoordinateGeodetic interpolatePosition(const CInterpolationAndRenderingSetupPerCallsign &setup, const CInterpolationHints &hints) const;
Aviation::CAltitude interpolateAltitude(const CInterpolationAndRenderingSetupPerCallsign &setup, const CInterpolationHints &hints) const;
Geo::CCoordinateGeodetic interpolatePosition(const CInterpolationAndRenderingSetupPerCallsign &setup) const;
Aviation::CAltitude interpolateAltitude(const CInterpolationAndRenderingSetupPerCallsign &setup) const;
//! @}
//! Interpolator for pitch, bank, heading, groundspeed
@@ -92,8 +92,7 @@ namespace BlackMisc
//! Strategy used by CInterpolator::getInterpolatedSituation
Interpolant getInterpolant(qint64 currentTimeMsSinceEpoc,
const CInterpolationAndRenderingSetupPerCallsign &setup,
const CInterpolationHints &hints, CInterpolationStatus &status, SituationLog &log);
const CInterpolationAndRenderingSetupPerCallsign &setup, CInterpolationStatus &status, SituationLog &log);
private:
qint64 m_prevSampleAdjustedTime = 0; //!< previous sample time + offset

View File

@@ -32,7 +32,6 @@ namespace BlackMisc
CInterpolationAndRenderingSetupPerCallsign::registerMetadata();
CInterpolationAndRenderingSetupGlobal::registerMetadata();
CInterpolationSetupList::registerMetadata();
CInterpolationHints::registerMetadata();
CMatchingStatisticsEntry::registerMetadata();
CMatchingStatistics::registerMetadata();
CModelSettings::registerMetadata();

View File

@@ -28,6 +28,12 @@ namespace BlackMisc
return this->provider()->isAircraftInRange(callsign);
}
bool CRemoteAircraftAware::isVtolAircraft(const CCallsign &callsign) const
{
Q_ASSERT_X(this->provider(), Q_FUNC_INFO, "No object available");
return this->provider()->isVtolAircraft(callsign);
}
int CRemoteAircraftAware::getAircraftInRangeCount() const
{
Q_ASSERT_X(this->provider(), Q_FUNC_INFO, "No object available");

View File

@@ -75,6 +75,10 @@ namespace BlackMisc
//! \threadsafe
virtual bool isAircraftInRange(const BlackMisc::Aviation::CCallsign &callsign) const = 0;
//! Is VTOL aircraft?
//! \threadsafe
virtual bool isVtolAircraft(const BlackMisc::Aviation::CCallsign &callsign) const = 0;
//! Current snapshot
//! \threadsafe
virtual BlackMisc::Simulation::CAirspaceAircraftSnapshot getLatestAirspaceAircraftSnapshot() const = 0;
@@ -195,6 +199,9 @@ namespace BlackMisc
//! \copydoc IRemoteAircraftProvider::isAircraftInRange
bool isAircraftInRange(const BlackMisc::Aviation::CCallsign &callsign) const;
//! \copydoc IRemoteAircraftProvider::isVtolAircraft
bool isVtolAircraft(const BlackMisc::Aviation::CCallsign &callsign) const;
//! \copydoc IRemoteAircraftProvider::getAircraftInRangeCount
int getAircraftInRangeCount() const;

View File

@@ -19,7 +19,6 @@
#include "blackmisc/simulation/airspaceaircraftsnapshot.h"
#include "blackmisc/simulation/distributorlist.h"
#include "blackmisc/simulation/distributorlistpreferences.h"
#include "blackmisc/simulation/interpolationhints.h"
#include "blackmisc/simulation/interpolationrenderingsetup.h"
#include "blackmisc/simulation/interpolationsetuplist.h"
#include "blackmisc/simulation/matchingstatistics.h"

View File

@@ -36,7 +36,7 @@ namespace BlackMisc
return this->rememberGroundElevation(elevationPlane, elevationPlane.getRadius());
}
bool ISimulationEnvironmentProvider::insertCG(const CLength &cg, const Aviation::CCallsign &cs)
bool ISimulationEnvironmentProvider::insertCG(const CLength &cg, const CCallsign &cs)
{
if (cs.isEmpty()) { return false; }
const bool remove = cg.isNull();
@@ -77,7 +77,7 @@ namespace BlackMisc
return delta;
}
CElevationPlane ISimulationEnvironmentProvider::findClosestElevationWithinRange(const ICoordinateGeodetic &reference, const PhysicalQuantities::CLength &range)
CElevationPlane ISimulationEnvironmentProvider::findClosestElevationWithinRange(const ICoordinateGeodetic &reference, const PhysicalQuantities::CLength &range) const
{
return this->getElevationCoordinates().findClosestWithinRange(reference, range);
}
@@ -153,7 +153,7 @@ namespace BlackMisc
this->clearCGs();
}
CElevationPlane CSimulationEnvironmentAware::findClosestElevationWithinRange(const ICoordinateGeodetic &reference, const PhysicalQuantities::CLength &range)
CElevationPlane CSimulationEnvironmentAware::findClosestElevationWithinRange(const ICoordinateGeodetic &reference, const PhysicalQuantities::CLength &range) const
{
if (!this->hasProvider()) { return CElevationPlane::null(); }
return this->provider()->findClosestElevationWithinRange(reference, range);
@@ -177,6 +177,12 @@ namespace BlackMisc
return this->provider()->getDefaultModel();
}
CLength CSimulationEnvironmentAware::getCG(const CCallsign &callsign) const
{
if (!this->hasProvider()) { return CLength::null(); }
return this->provider()->getCG(callsign);
}
bool CSimulationEnvironmentAware::hasCG(const CCallsign &callsign) const
{
if (!this->hasProvider()) { return false; }

View File

@@ -37,7 +37,7 @@ namespace BlackMisc
//! Find closest elevation
//! \threadsafe
Geo::CElevationPlane findClosestElevationWithinRange(const Geo::ICoordinateGeodetic &reference, const PhysicalQuantities::CLength &range);
Geo::CElevationPlane findClosestElevationWithinRange(const Geo::ICoordinateGeodetic &reference, const PhysicalQuantities::CLength &range) const;
//! Get the represented plugin
//! \threadsafe
@@ -122,7 +122,7 @@ namespace BlackMisc
void setSimulationEnvironmentProvider(ISimulationEnvironmentProvider *provider) { this->setProvider(provider); }
//! \copydoc ISimulationEnvironmentProvider::findClosestElevationWithinRange
Geo::CElevationPlane findClosestElevationWithinRange(const Geo::ICoordinateGeodetic &reference, const PhysicalQuantities::CLength &range);
Geo::CElevationPlane findClosestElevationWithinRange(const Geo::ICoordinateGeodetic &reference, const PhysicalQuantities::CLength &range) const;
//! \copydoc ISimulationEnvironmentProvider::getSimulatorPluginInfo
CSimulatorPluginInfo getSimulatorPluginInfo() const;