mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-22 14:55:36 +08:00
refactor: Move OnGround information to own class
This commit is contained in:
@@ -1584,13 +1584,13 @@ namespace BlackCore
|
||||
while (false); // do we need elevation, find on
|
||||
|
||||
// do we already have ground details?
|
||||
if (situation.getOnGroundDetails() == CAircraftSituation::NotSetGroundDetails)
|
||||
if (situation.getOnGroundInfo().getGroundDetails() == COnGroundInfo::NotSetGroundDetails)
|
||||
{
|
||||
const CClient client = this->getClientOrDefaultForCallsign(callsign);
|
||||
if (client.hasCapability(CClient::FsdWithGroundFlag))
|
||||
{
|
||||
// we rely on situation gnd.flag
|
||||
correctedSituation.setOnGroundDetails(CAircraftSituation::InFromNetwork);
|
||||
correctedSituation.setOnGroundDetails(COnGroundInfo::InFromNetwork);
|
||||
}
|
||||
else if (client.hasCapability(CClient::FsdWithAircraftConfig))
|
||||
{
|
||||
|
||||
@@ -1241,7 +1241,8 @@ namespace BlackCore::Fsd
|
||||
CAngle(dataUpdate.m_bank, CAngleUnit::deg()),
|
||||
CSpeed(dataUpdate.m_groundSpeed, CSpeedUnit::kts()));
|
||||
situation.setPressureAltitude(CAltitude(dataUpdate.m_altitudePressure, CAltitude::MeanSeaLevel, CAltitude::PressureAltitude, CLengthUnit::ft()));
|
||||
situation.setOnGround(dataUpdate.m_onGround);
|
||||
const COnGroundInfo og(dataUpdate.m_onGround ? COnGroundInfo::OnGround : COnGroundInfo::NotOnGround, COnGroundInfo::InFromNetwork);
|
||||
situation.setOnGroundInfo(og);
|
||||
|
||||
// Ref T297, default offset time
|
||||
situation.setCurrentUtcTime();
|
||||
@@ -1279,8 +1280,8 @@ namespace BlackCore::Fsd
|
||||
CAngle(-data.m_pitch, CAngleUnit::deg()),
|
||||
CAngle(-data.m_bank, CAngleUnit::deg()),
|
||||
CSpeed(data.m_groundSpeed, CSpeedUnit::kts()));
|
||||
situation.setOnGround(data.m_onGround);
|
||||
situation.setOnGroundDetails(CAircraftSituation::InFromNetwork);
|
||||
const COnGroundInfo og(data.m_onGround ? COnGroundInfo::OnGround : COnGroundInfo::NotOnGround, COnGroundInfo::InFromNetwork);
|
||||
situation.setOnGroundInfo(og);
|
||||
|
||||
// Ref T297, default offset time
|
||||
situation.setCurrentUtcTime();
|
||||
@@ -1771,7 +1772,8 @@ namespace BlackCore::Fsd
|
||||
CAngle(interimPilotDataUpdate.m_pitch, CAngleUnit::deg()),
|
||||
CAngle(interimPilotDataUpdate.m_bank, CAngleUnit::deg()),
|
||||
CSpeed(interimPilotDataUpdate.m_groundSpeed, CSpeedUnit::kts()));
|
||||
situation.setOnGround(interimPilotDataUpdate.m_onGround);
|
||||
const COnGroundInfo og(interimPilotDataUpdate.m_onGround ? COnGroundInfo::OnGround : COnGroundInfo::NotOnGround, COnGroundInfo::InFromNetwork);
|
||||
situation.setOnGroundInfo(og);
|
||||
|
||||
// Ref T297, default offset time
|
||||
situation.setCurrentUtcTime();
|
||||
|
||||
@@ -28,8 +28,6 @@ namespace BlackGui::Models
|
||||
m_columns.addColumn(CColumn("longitude", CAircraftSituation::IndexLongitude, new CLatLonFormatter()));
|
||||
m_columns.addColumn(CColumn("gs.", CAircraftSituation::IndexGroundSpeed, new CSpeedKtsFormatter()));
|
||||
m_columns.addColumn(CColumn::standardString("PBH", "pitch bank heading", CAircraftSituation::IndexPBHInfo));
|
||||
m_columns.addColumn(CColumn("on gnd.", "is on gnd.", CAircraftSituation::IndexIsOnGround, new CBoolIconFormatter("yes", "no"), true));
|
||||
m_columns.addColumn(CColumn::standardString("reliability", CAircraftSituation::IndexOnGroundReliabilityString));
|
||||
m_columns.addColumn(CColumn::standardString("gnd.elv.", CAircraftSituation::IndexGroundElevationPlusInfo));
|
||||
m_columns.addColumn(CColumn::standardString("gnd.elv.alt.", { CAircraftSituation::IndexGroundElevationPlane, CElevationPlane::IndexGeodeticHeightAsString }));
|
||||
m_columns.addColumn(CColumn("elv.radius", { CAircraftSituation::IndexGroundElevationPlane, CElevationPlane::IndexRadius }, new CPhysiqalQuantiyFormatter<CLengthUnit, CLength>(CLengthUnit::m(), 1)));
|
||||
|
||||
@@ -90,6 +90,8 @@ add_library(misc SHARED
|
||||
aviation/modulator.h
|
||||
aviation/navsystem.h
|
||||
aviation/percallsign.h
|
||||
aviation/ongroundinfo.cpp
|
||||
aviation/ongroundinfo.h
|
||||
aviation/registermetadataaviation.cpp
|
||||
aviation/registermetadataaviation.h
|
||||
aviation/selcal.cpp
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace BlackMisc::Aviation
|
||||
|
||||
CAircraftLights CAircraftSituation::guessLights() const
|
||||
{
|
||||
const bool isOnGround = getOnGround() == CAircraftSituation::OnGround;
|
||||
const bool isOnGround = this->isOnGround();
|
||||
const double gsKts = getGroundSpeed().value(CSpeedUnit::kts());
|
||||
CAircraftLights lights;
|
||||
lights.setCabinOn(true);
|
||||
@@ -81,8 +81,6 @@ namespace BlackMisc::Aviation
|
||||
void CAircraftSituation::registerMetadata()
|
||||
{
|
||||
CValueObject<CAircraftSituation>::registerMetadata();
|
||||
qRegisterMetaType<CAircraftSituation::IsOnGround>();
|
||||
qRegisterMetaType<CAircraftSituation::OnGroundDetails>();
|
||||
qRegisterMetaType<CAircraftSituation::AltitudeCorrection>();
|
||||
qRegisterMetaType<CAircraftSituation::GndElevationInfo>();
|
||||
}
|
||||
@@ -116,12 +114,11 @@ namespace BlackMisc::Aviation
|
||||
u" | " % m_position.toQString(i18n) %
|
||||
u" | alt: " % this->getAltitude().valueRoundedWithUnit(CLengthUnit::ft(), 1) %
|
||||
u' ' % this->getCorrectedAltitude().valueRoundedWithUnit(CLengthUnit::ft(), 1) %
|
||||
u"[cor] | og: " % this->getOnGroundInfo() %
|
||||
u"[cor] | og: " % this->getOnGroundInfo().toQString(i18n) %
|
||||
u" | CG: " %
|
||||
(m_cg.isNull() ? QStringLiteral("null") : m_cg.valueRoundedWithUnit(CLengthUnit::m(), 1) % u' ' % m_cg.valueRoundedWithUnit(CLengthUnit::ft(), 1)) %
|
||||
u" | offset: " %
|
||||
(m_sceneryOffset.isNull() ? QStringLiteral("null") : m_sceneryOffset.valueRoundedWithUnit(CLengthUnit::m(), 1) % u' ' % m_sceneryOffset.valueRoundedWithUnit(CLengthUnit::ft(), 1)) %
|
||||
u" | factor [0..1]: " % QString::number(m_onGroundFactor, 'f', 2) %
|
||||
u" | skip ng: " % boolToYesNo(this->canLikelySkipNearGroundInterpolation()) %
|
||||
u" | bank: " % m_bank.toQString(i18n) %
|
||||
u" | pitch: " % m_pitch.toQString(i18n) %
|
||||
@@ -131,44 +128,6 @@ namespace BlackMisc::Aviation
|
||||
u" | elevation [" % this->getGroundElevationInfoAsString() % u"]: " % (m_groundElevationPlane.toQString(i18n));
|
||||
}
|
||||
|
||||
const QString &CAircraftSituation::isOnGroundToString(CAircraftSituation::IsOnGround onGround)
|
||||
{
|
||||
static const QString notog("not on ground");
|
||||
static const QString og("on ground");
|
||||
static const QString unknown("unknown");
|
||||
|
||||
switch (onGround)
|
||||
{
|
||||
case CAircraftSituation::NotOnGround: return notog;
|
||||
case CAircraftSituation::OnGround: return og;
|
||||
case CAircraftSituation::OnGroundSituationUnknown:
|
||||
default: return unknown;
|
||||
}
|
||||
}
|
||||
|
||||
const QString &CAircraftSituation::onGroundDetailsToString(CAircraftSituation::OnGroundDetails reliability)
|
||||
{
|
||||
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");
|
||||
|
||||
switch (reliability)
|
||||
{
|
||||
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::NotSetGroundDetails:
|
||||
default: return unknown;
|
||||
}
|
||||
}
|
||||
|
||||
const QString &CAircraftSituation::altitudeCorrectionToString(CAircraftSituation::AltitudeCorrection correction)
|
||||
{
|
||||
static const QString under("underflow");
|
||||
@@ -315,10 +274,7 @@ namespace BlackMisc::Aviation
|
||||
case IndexGroundSpeed: return m_groundSpeed.propertyByIndex(index.copyFrontRemoved());
|
||||
case IndexGroundElevationPlane: return m_groundElevationPlane.propertyByIndex(index.copyFrontRemoved());
|
||||
case IndexCallsign: return m_correspondingCallsign.propertyByIndex(index.copyFrontRemoved());
|
||||
case IndexIsOnGround: return QVariant::fromValue(m_onGround);
|
||||
case IndexIsOnGroundString: return QVariant::fromValue(this->onGroundAsString());
|
||||
case IndexOnGroundReliability: return QVariant::fromValue(m_onGroundDetails);
|
||||
case IndexOnGroundReliabilityString: return QVariant::fromValue(this->getOnGroundDetailsAsString());
|
||||
case IndexIsOnGroundInfo: return m_onGroundInfo.propertyByIndex(index.copyFrontRemoved());
|
||||
case IndexGroundElevationInfo: return QVariant::fromValue(this->getGroundElevationInfo());
|
||||
case IndexGroundElevationInfoTransferred: return QVariant::fromValue(this->isGroundElevationInfoTransferred());
|
||||
case IndexGroundElevationInfoString: return QVariant::fromValue(this->getGroundElevationInfoAsString());
|
||||
@@ -353,8 +309,7 @@ namespace BlackMisc::Aviation
|
||||
case IndexGroundSpeed: m_groundSpeed.setPropertyByIndex(index.copyFrontRemoved(), variant); break;
|
||||
case IndexGroundElevationPlane: m_groundElevationPlane.setPropertyByIndex(index.copyFrontRemoved(), variant); break;
|
||||
case IndexCallsign: m_correspondingCallsign.setPropertyByIndex(index.copyFrontRemoved(), variant); break;
|
||||
case IndexIsOnGround: m_onGround = variant.toInt(); break;
|
||||
case IndexOnGroundReliability: m_onGroundDetails = variant.toInt(); break;
|
||||
case IndexIsOnGroundInfo: m_onGroundInfo.setPropertyByIndex(index.copyFrontRemoved(), variant); break;
|
||||
case IndexGroundElevationInfo: m_elvInfo = variant.toInt(); break;
|
||||
case IndexGroundElevationInfoTransferred: m_isElvInfoTransferred = variant.toBool(); break;
|
||||
case IndexGroundElevationPlusInfo: break;
|
||||
@@ -387,12 +342,7 @@ namespace BlackMisc::Aviation
|
||||
return Compare::compare(this->getGroundElevationInfo(), compareValue.getGroundElevationInfo());
|
||||
}
|
||||
case IndexCallsign: return m_correspondingCallsign.comparePropertyByIndex(index.copyFrontRemoved(), compareValue.getCallsign());
|
||||
case IndexIsOnGround:
|
||||
case IndexIsOnGroundString:
|
||||
return Compare::compare(m_onGround, compareValue.m_onGround);
|
||||
case IndexOnGroundReliability:
|
||||
case IndexOnGroundReliabilityString:
|
||||
return Compare::compare(m_onGroundDetails, compareValue.m_onGroundDetails);
|
||||
case IndexIsOnGroundInfo: return m_onGroundInfo.comparePropertyByIndex(index.copyFrontRemoved(), compareValue.getOnGroundInfo());
|
||||
case IndexGroundElevationInfo:
|
||||
case IndexGroundElevationInfoString:
|
||||
{
|
||||
@@ -461,7 +411,7 @@ namespace BlackMisc::Aviation
|
||||
m_velocity = {};
|
||||
m_groundElevationPlane.setNull();
|
||||
m_groundSpeed.setNull();
|
||||
m_onGroundDetails = CAircraftSituation::NotSetGroundDetails;
|
||||
m_onGroundInfo = {};
|
||||
m_elvInfo = NoElevationInfo;
|
||||
m_isElvInfoTransferred = false;
|
||||
m_cg.setNull();
|
||||
@@ -470,63 +420,19 @@ namespace BlackMisc::Aviation
|
||||
|
||||
bool CAircraftSituation::isOnGroundFromParts() const
|
||||
{
|
||||
return this->isOnGround() && this->getOnGroundDetails() == InFromParts;
|
||||
return this->isOnGround() && m_onGroundInfo.getGroundDetails() == COnGroundInfo::InFromParts;
|
||||
}
|
||||
|
||||
bool CAircraftSituation::isOnGroundFromNetwork() const
|
||||
{
|
||||
return this->isOnGround() && this->getOnGroundDetails() == InFromNetwork;
|
||||
}
|
||||
|
||||
const QString &CAircraftSituation::onGroundAsString() const
|
||||
{
|
||||
return CAircraftSituation::isOnGroundToString(this->getOnGround());
|
||||
return this->isOnGround() && m_onGroundInfo.getGroundDetails() == COnGroundInfo::InFromNetwork;
|
||||
}
|
||||
|
||||
bool CAircraftSituation::isOnGroundInfoAvailable() const
|
||||
{
|
||||
if (this->hasInboundGroundDetails()) { return true; }
|
||||
return this->getOnGround() != CAircraftSituation::OnGroundSituationUnknown &&
|
||||
this->getOnGroundDetails() != CAircraftSituation::NotSetGroundDetails;
|
||||
}
|
||||
|
||||
bool CAircraftSituation::setOnGround(bool onGround)
|
||||
{
|
||||
return this->setOnGround(onGround ? OnGround : NotOnGround);
|
||||
}
|
||||
|
||||
bool CAircraftSituation::setOnGround(CAircraftSituation::IsOnGround onGround)
|
||||
{
|
||||
if (this->getOnGround() == onGround) { return false; }
|
||||
const int og = static_cast<int>(onGround);
|
||||
m_onGround = og;
|
||||
m_onGroundFactor = (onGround == OnGround) ? 1.0 : 0.0;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CAircraftSituation::setOnGround(CAircraftSituation::IsOnGround onGround, CAircraftSituation::OnGroundDetails details)
|
||||
{
|
||||
const bool set = this->setOnGround(onGround);
|
||||
this->setOnGroundDetails(details);
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
void CAircraftSituation::setOnGroundFactor(double groundFactor)
|
||||
{
|
||||
if (groundFactor < 0.0)
|
||||
{
|
||||
groundFactor = -1.0;
|
||||
}
|
||||
else if (groundFactor < 0.001)
|
||||
{
|
||||
groundFactor = 0.0;
|
||||
}
|
||||
else if (groundFactor > 0.999)
|
||||
{
|
||||
groundFactor = 1.0;
|
||||
}
|
||||
m_onGroundFactor = groundFactor;
|
||||
return m_onGroundInfo.getOnGround() != COnGroundInfo::OnGroundSituationUnknown &&
|
||||
m_onGroundInfo.getGroundDetails() != COnGroundInfo::NotSetGroundDetails;
|
||||
}
|
||||
|
||||
bool CAircraftSituation::shouldGuessOnGround() const
|
||||
@@ -544,39 +450,22 @@ namespace BlackMisc::Aviation
|
||||
|
||||
bool CAircraftSituation::hasGroundDetailsForGndInterpolation() const
|
||||
{
|
||||
return this->getOnGroundDetails() != CAircraftSituation::NotSetGroundDetails;
|
||||
return m_onGroundInfo.getGroundDetails() != COnGroundInfo::NotSetGroundDetails;
|
||||
}
|
||||
|
||||
const QString &CAircraftSituation::getOnGroundDetailsAsString() const
|
||||
COnGroundInfo CAircraftSituation::getOnGroundInfo() const
|
||||
{
|
||||
return CAircraftSituation::onGroundDetailsToString(this->getOnGroundDetails());
|
||||
return m_onGroundInfo;
|
||||
}
|
||||
|
||||
bool CAircraftSituation::setOnGroundDetails(CAircraftSituation::OnGroundDetails details)
|
||||
void CAircraftSituation::setOnGroundDetails(COnGroundInfo::OnGroundDetails details)
|
||||
{
|
||||
if (this->getOnGroundDetails() == details) { return false; }
|
||||
m_onGroundDetails = static_cast<int>(details);
|
||||
return true;
|
||||
m_onGroundInfo.setOnGroundDetails(details);
|
||||
}
|
||||
|
||||
bool CAircraftSituation::setOnGroundFromGroundFactorFromInterpolation(double threshold)
|
||||
void CAircraftSituation::setOnGroundInfo(const Aviation::COnGroundInfo &info)
|
||||
{
|
||||
this->setOnGroundDetails(OnGroundByInterpolation);
|
||||
if (this->getOnGroundFactor() < 0.0)
|
||||
{
|
||||
this->setOnGround(NotSetGroundDetails);
|
||||
return false;
|
||||
}
|
||||
|
||||
// set on ground but leave factor untouched
|
||||
const bool og = this->getOnGroundFactor() > threshold; // 1.0 means on ground
|
||||
m_onGround = og ? OnGround : NotOnGround;
|
||||
return true;
|
||||
}
|
||||
|
||||
QString CAircraftSituation::getOnGroundInfo() const
|
||||
{
|
||||
return this->onGroundAsString() % u' ' % this->getOnGroundDetailsAsString();
|
||||
m_onGroundInfo = info;
|
||||
}
|
||||
|
||||
CAircraftSituation::GndElevationInfo CAircraftSituation::getGroundElevationInfo() const
|
||||
@@ -640,21 +529,6 @@ namespace BlackMisc::Aviation
|
||||
return true;
|
||||
}
|
||||
|
||||
CAircraftSituation::IsOnGround CAircraftSituation::isOnGroundByElevation(const CLength &cg) const
|
||||
{
|
||||
const CLength groundDistance = this->getGroundDistance(cg);
|
||||
if (groundDistance.isNull()) { return OnGroundSituationUnknown; }
|
||||
if (groundDistance.isNegativeWithEpsilonConsidered()) { return OnGround; }
|
||||
if (groundDistance.abs() < deltaNearGround()) { return OnGround; }
|
||||
if (!cg.isNull())
|
||||
{
|
||||
// smaller than percentage from CG
|
||||
const CLength cgFactor(cg * 0.1);
|
||||
if (groundDistance.abs() < cgFactor.abs()) { return OnGround; }
|
||||
}
|
||||
return NotOnGround;
|
||||
}
|
||||
|
||||
bool CAircraftSituation::hasGroundElevation() const
|
||||
{
|
||||
return !this->getGroundElevation().isNull();
|
||||
@@ -662,7 +536,7 @@ namespace BlackMisc::Aviation
|
||||
|
||||
bool CAircraftSituation::hasInboundGroundDetails() const
|
||||
{
|
||||
return this->getOnGroundDetails() == CAircraftSituation::InFromParts || this->getOnGroundDetails() == CAircraftSituation::InFromNetwork;
|
||||
return m_onGroundInfo.getGroundDetails() == COnGroundInfo::InFromParts || m_onGroundInfo.getGroundDetails() == COnGroundInfo::InFromNetwork;
|
||||
}
|
||||
|
||||
bool CAircraftSituation::setGroundElevation(const CAltitude &altitude, GndElevationInfo info, bool transferred)
|
||||
@@ -810,7 +684,7 @@ namespace BlackMisc::Aviation
|
||||
if (correction) { *correction = NoCorrection; }
|
||||
return groundPlusCG;
|
||||
}
|
||||
const bool forceDragToGround = (enableDragToGround && this->getOnGround() == OnGround) && (this->hasInboundGroundDetails() || this->getOnGroundDetails() == OnGroundByGuessing);
|
||||
const bool forceDragToGround = (enableDragToGround && isOnGround()) && (this->hasInboundGroundDetails() || m_onGroundInfo.getGroundDetails() == COnGroundInfo::OnGroundByGuessing);
|
||||
if (forceDragToGround)
|
||||
{
|
||||
if (correction) { *correction = DraggedToGround; }
|
||||
@@ -971,14 +845,14 @@ namespace BlackMisc::Aviation
|
||||
static const qint64 Max = std::numeric_limits<qint64>::max();
|
||||
if (differenceMs) { *differenceMs = Max; }
|
||||
|
||||
if (this->getOnGroundDetails() == CAircraftSituation::InFromNetwork) { return false; }
|
||||
if (alwaysSetDetails) { this->setOnGroundDetails(InFromParts); }
|
||||
if (m_onGroundInfo.getGroundDetails() == COnGroundInfo::InFromNetwork) { return false; }
|
||||
if (alwaysSetDetails) { m_onGroundInfo.setOnGroundDetails(COnGroundInfo::InFromParts); }
|
||||
const qint64 d = this->getAdjustedTimeDifferenceMs(parts.getAdjustedMSecsSinceEpoch());
|
||||
const bool adjust = (d >= 0) || qAbs(d) < (timeDeviationFactor * parts.getTimeOffsetMs()); // future or past within deviation range
|
||||
if (!adjust) { return false; }
|
||||
|
||||
if (differenceMs) { *differenceMs = d; }
|
||||
this->setOnGround(parts.isOnGround() ? CAircraftSituation::OnGround : CAircraftSituation::NotOnGround, CAircraftSituation::InFromParts);
|
||||
m_onGroundInfo = COnGroundInfo(parts.isOnGround() ? COnGroundInfo::OnGround : COnGroundInfo::NotOnGround, COnGroundInfo::InFromParts);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -988,8 +862,8 @@ namespace BlackMisc::Aviation
|
||||
static const qint64 Max = std::numeric_limits<qint64>::max();
|
||||
if (differenceMs) { *differenceMs = Max; }
|
||||
|
||||
if (this->getOnGroundDetails() == CAircraftSituation::InFromNetwork) { return false; }
|
||||
if (alwaysSetDetails) { this->setOnGroundDetails(InFromParts); }
|
||||
if (m_onGroundInfo.getGroundDetails() == COnGroundInfo::InFromNetwork) { return false; }
|
||||
if (alwaysSetDetails) { m_onGroundInfo.setOnGroundDetails(COnGroundInfo::InFromParts); }
|
||||
if (partsList.isEmpty()) { return false; }
|
||||
|
||||
CAircraftParts bestParts;
|
||||
@@ -1009,8 +883,8 @@ namespace BlackMisc::Aviation
|
||||
}
|
||||
if (!adjust) { return false; }
|
||||
|
||||
const CAircraftSituation::IsOnGround og = bestParts.isOnGround() ? CAircraftSituation::OnGround : CAircraftSituation::NotOnGround;
|
||||
this->setOnGround(og, CAircraftSituation::InFromParts);
|
||||
const COnGroundInfo::IsOnGround og = bestParts.isOnGround() ? COnGroundInfo::OnGround : COnGroundInfo::NotOnGround;
|
||||
m_onGroundInfo = COnGroundInfo(og, COnGroundInfo::InFromParts);
|
||||
return true;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "blackmisc/aviation/altitude.h"
|
||||
#include "blackmisc/aviation/callsign.h"
|
||||
#include "blackmisc/aviation/ongroundinfo.h"
|
||||
#include "blackmisc/aviation/heading.h"
|
||||
#include "blackmisc/aviation/aircraftvelocity.h"
|
||||
#include "blackmisc/blackmiscexport.h"
|
||||
@@ -60,10 +61,7 @@ namespace BlackMisc
|
||||
IndexAltitude,
|
||||
IndexHeading,
|
||||
IndexBank,
|
||||
IndexIsOnGround,
|
||||
IndexIsOnGroundString,
|
||||
IndexOnGroundReliability,
|
||||
IndexOnGroundReliabilityString,
|
||||
IndexIsOnGroundInfo,
|
||||
IndexPitch,
|
||||
IndexPBHInfo,
|
||||
IndexVelocity,
|
||||
@@ -79,29 +77,6 @@ namespace BlackMisc
|
||||
IndexCanLikelySkipNearGroundInterpolation
|
||||
};
|
||||
|
||||
//! Is on ground?
|
||||
enum IsOnGround
|
||||
{
|
||||
NotOnGround,
|
||||
OnGround,
|
||||
OnGroundSituationUnknown
|
||||
};
|
||||
|
||||
//! Reliability of on ground information
|
||||
enum OnGroundDetails
|
||||
{
|
||||
NotSetGroundDetails,
|
||||
// interpolated situation
|
||||
OnGroundByInterpolation, //!< strongest for remote aircraft
|
||||
OnGroundByElevationAndCG,
|
||||
OnGroundByGuessing, //!< weakest
|
||||
// received situation
|
||||
InFromNetwork, //!< received from network
|
||||
InFromParts, //!< set from aircraft parts
|
||||
// send information
|
||||
OutOnGroundOwnAircraft //!< sending on ground
|
||||
};
|
||||
|
||||
//! How was altitude corrected?
|
||||
enum AltitudeCorrection
|
||||
{
|
||||
@@ -205,11 +180,8 @@ namespace BlackMisc
|
||||
//! \copydoc Geo::ICoordinateGeodetic::longitude()
|
||||
virtual Geo::CLongitude longitude() const override { return m_position.longitude(); }
|
||||
|
||||
//! On ground?
|
||||
IsOnGround getOnGround() const { return static_cast<CAircraftSituation::IsOnGround>(m_onGround); }
|
||||
|
||||
//! Is on ground?
|
||||
bool isOnGround() const { return this->getOnGround() == OnGround; }
|
||||
bool isOnGround() const { return m_onGroundInfo.getOnGround() == COnGroundInfo::OnGround; }
|
||||
|
||||
//! On ground by parts?
|
||||
bool isOnGroundFromParts() const;
|
||||
@@ -217,50 +189,26 @@ namespace BlackMisc
|
||||
//! On ground by network flag?
|
||||
bool isOnGroundFromNetwork() const;
|
||||
|
||||
//! On ground?
|
||||
const QString &onGroundAsString() const;
|
||||
|
||||
//! On ground info available?
|
||||
bool isOnGroundInfoAvailable() const;
|
||||
|
||||
//! Set on ground
|
||||
bool setOnGround(bool onGround);
|
||||
|
||||
//! Set on ground
|
||||
bool setOnGround(CAircraftSituation::IsOnGround onGround);
|
||||
|
||||
//! Set on ground
|
||||
bool setOnGround(CAircraftSituation::IsOnGround onGround, CAircraftSituation::OnGroundDetails details);
|
||||
|
||||
//! On ground factor 0..1 (on ground), -1 not set
|
||||
double getOnGroundFactor() const { return m_onGroundFactor; }
|
||||
|
||||
//! Set on ground factor 0..1 (on ground), -1 not set
|
||||
void setOnGroundFactor(double groundFactor);
|
||||
|
||||
//! Should we guess on ground?
|
||||
bool shouldGuessOnGround() const;
|
||||
|
||||
//! Distance to ground, null if impossible to calculate
|
||||
PhysicalQuantities::CLength getGroundDistance(const PhysicalQuantities::CLength ¢erOfGravity) const;
|
||||
|
||||
//! On ground reliability
|
||||
OnGroundDetails getOnGroundDetails() const { return static_cast<CAircraftSituation::OnGroundDetails>(m_onGroundDetails); }
|
||||
|
||||
//! Do the ground details permit ground interpolation?
|
||||
bool hasGroundDetailsForGndInterpolation() const;
|
||||
|
||||
//! On ground reliability as string
|
||||
const QString &getOnGroundDetailsAsString() const;
|
||||
|
||||
//! On ground details
|
||||
bool setOnGroundDetails(CAircraftSituation::OnGroundDetails details);
|
||||
void setOnGroundDetails(COnGroundInfo::OnGroundDetails details);
|
||||
|
||||
//! Set on ground as interpolated from ground fatcor
|
||||
bool setOnGroundFromGroundFactorFromInterpolation(double threshold = 0.5);
|
||||
//! On ground info
|
||||
Aviation::COnGroundInfo getOnGroundInfo() const;
|
||||
|
||||
//! On ground info as string
|
||||
QString getOnGroundInfo() const;
|
||||
//! Set the on ground info
|
||||
void setOnGroundInfo(const Aviation::COnGroundInfo &info);
|
||||
|
||||
//! \copydoc Geo::ICoordinateGeodetic::geodeticHeight
|
||||
const CAltitude &geodeticHeight() const override { return m_position.geodeticHeight(); }
|
||||
@@ -313,11 +261,6 @@ namespace BlackMisc
|
||||
//! \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 PhysicalQuantities::CLength &cg) const;
|
||||
//! @}
|
||||
|
||||
//! Is ground elevation value available
|
||||
bool hasGroundElevation() const;
|
||||
|
||||
@@ -482,12 +425,6 @@ namespace BlackMisc
|
||||
//! Get flag indicating this is an interim position update
|
||||
bool isInterim() const { return m_isInterim; }
|
||||
|
||||
//! Enum to string
|
||||
static const QString &isOnGroundToString(IsOnGround onGround);
|
||||
|
||||
//! Enum to string
|
||||
static const QString &onGroundDetailsToString(OnGroundDetails reliability);
|
||||
|
||||
//! Enum to string
|
||||
static const QString &altitudeCorrectionToString(AltitudeCorrection correction);
|
||||
|
||||
@@ -569,10 +506,8 @@ namespace BlackMisc
|
||||
CAircraftVelocity m_velocity;
|
||||
bool m_isInterim = false; //!< interim situation?
|
||||
bool m_isElvInfoTransferred = false; //!< the gnd.elevation has been transferred
|
||||
int m_onGround = static_cast<int>(CAircraftSituation::OnGroundSituationUnknown);
|
||||
int m_onGroundDetails = static_cast<int>(CAircraftSituation::NotSetGroundDetails);
|
||||
int m_elvInfo = static_cast<int>(CAircraftSituation::NoElevationInfo); //!< where did we gnd.elevation from?
|
||||
double m_onGroundFactor = -1; //!< interpolated ground flag, 1..on ground, 0..not on ground, -1 no info
|
||||
Aviation::COnGroundInfo m_onGroundInfo;
|
||||
|
||||
BLACK_METACLASS(
|
||||
CAircraftSituation,
|
||||
@@ -588,11 +523,9 @@ namespace BlackMisc
|
||||
BLACK_METAMEMBER(hasVelocity),
|
||||
BLACK_METAMEMBER(velocity),
|
||||
BLACK_METAMEMBER(groundElevationPlane),
|
||||
BLACK_METAMEMBER(onGround),
|
||||
BLACK_METAMEMBER(onGroundDetails),
|
||||
BLACK_METAMEMBER(onGroundInfo),
|
||||
BLACK_METAMEMBER(elvInfo),
|
||||
BLACK_METAMEMBER(isElvInfoTransferred),
|
||||
BLACK_METAMEMBER(onGroundFactor),
|
||||
BLACK_METAMEMBER(timestampMSecsSinceEpoch),
|
||||
BLACK_METAMEMBER(timeOffsetMs),
|
||||
BLACK_METAMEMBER(isInterim)
|
||||
@@ -602,8 +535,6 @@ namespace BlackMisc
|
||||
} // namespace
|
||||
|
||||
Q_DECLARE_METATYPE(BlackMisc::Aviation::CAircraftSituation)
|
||||
Q_DECLARE_METATYPE(BlackMisc::Aviation::CAircraftSituation::IsOnGround)
|
||||
Q_DECLARE_METATYPE(BlackMisc::Aviation::CAircraftSituation::OnGroundDetails)
|
||||
Q_DECLARE_METATYPE(BlackMisc::Aviation::CAircraftSituation::AltitudeCorrection)
|
||||
Q_DECLARE_METATYPE(BlackMisc::Aviation::CAircraftSituation::GndElevationInfo)
|
||||
|
||||
|
||||
@@ -94,21 +94,21 @@ namespace BlackMisc::Aviation
|
||||
{
|
||||
if (situation.getGroundSpeed().isNegativeWithEpsilonConsidered())
|
||||
{
|
||||
situation.setOnGround(CAircraftSituation::OnGround, CAircraftSituation::OnGroundByGuessing);
|
||||
situation.setOnGroundInfo({ COnGroundInfo::OnGround, COnGroundInfo::OnGroundByGuessing });
|
||||
if (details) { *details = QStringLiteral("No VTOL, push back"); }
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!situation.isMoving())
|
||||
{
|
||||
situation.setOnGround(CAircraftSituation::OnGround, CAircraftSituation::OnGroundByGuessing);
|
||||
situation.setOnGroundInfo({ COnGroundInfo::OnGround, COnGroundInfo::OnGroundByGuessing });
|
||||
if (details) { *details = QStringLiteral("No VTOL, not moving => on ground"); }
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// not on ground is default
|
||||
situation.setOnGround(CAircraftSituation::NotOnGround, CAircraftSituation::OnGroundByGuessing);
|
||||
situation.setOnGroundInfo({ COnGroundInfo::NotOnGround, COnGroundInfo::OnGroundByGuessing });
|
||||
|
||||
CLength cg = situation.hasCG() ? situation.getCG() : model.getCG();
|
||||
CSpeed guessedRotateSpeed = CSpeed::null();
|
||||
@@ -146,11 +146,12 @@ namespace BlackMisc::Aviation
|
||||
// we can detect "on ground" (underflow, near ground), but not "not on ground" because of overflow
|
||||
|
||||
// we can detect on ground for underflow, but not for overflow (so we can not rely on NotOnGround)
|
||||
CAircraftSituation::IsOnGround og = situation.isOnGroundByElevation(cg);
|
||||
if (og == CAircraftSituation::OnGround)
|
||||
COnGroundInfo og(cg, situation.getGroundDistance(cg));
|
||||
if (og.getOnGround() == COnGroundInfo::OnGround)
|
||||
{
|
||||
if (details) { *details = QStringLiteral("elevation on ground"); }
|
||||
situation.setOnGround(og, CAircraftSituation::OnGroundByGuessing);
|
||||
og.setOnGroundDetails(COnGroundInfo::OnGroundByGuessing);
|
||||
situation.setOnGroundInfo(og);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -166,7 +167,7 @@ namespace BlackMisc::Aviation
|
||||
}
|
||||
|
||||
// here we stick to ground until we detect rotate up
|
||||
situation.setOnGround(CAircraftSituation::OnGround, CAircraftSituation::OnGroundByGuessing);
|
||||
situation.setOnGroundInfo({ COnGroundInfo::OnGround, COnGroundInfo::OnGroundByGuessing });
|
||||
if (details) { *details = QStringLiteral("waiting for rotating up"); }
|
||||
return true;
|
||||
}
|
||||
@@ -183,7 +184,7 @@ namespace BlackMisc::Aviation
|
||||
if (vtol)
|
||||
{
|
||||
// no idea
|
||||
situation.setOnGround(CAircraftSituation::OnGroundSituationUnknown, CAircraftSituation::NotSetGroundDetails);
|
||||
situation.setOnGroundInfo({ COnGroundInfo::OnGroundSituationUnknown, COnGroundInfo::NotSetGroundDetails });
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -193,7 +194,7 @@ namespace BlackMisc::Aviation
|
||||
// does the value make any sense?
|
||||
if (situation.getGroundSpeed() < guessedRotateSpeed)
|
||||
{
|
||||
situation.setOnGround(CAircraftSituation::OnGround, CAircraftSituation::OnGroundByGuessing);
|
||||
situation.setOnGroundInfo({ COnGroundInfo::OnGround, COnGroundInfo::OnGroundByGuessing });
|
||||
if (details) { *details = QStringLiteral("Guessing, max.guessed gs.") + guessedRotateSpeed.valueRoundedWithUnit(CSpeedUnit::kts(), 1); }
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ namespace BlackMisc
|
||||
//! \copydoc BlackMisc::Aviation::CAircraftSituationList::containsPushBack
|
||||
bool containsPushBack() const { return m_containsPushBack; }
|
||||
|
||||
//! \copydoc BlackMisc::Aviation::CAircraftSituationList::elevationStandardDeviationAndMean
|
||||
//! Elevation standard deviation and mean
|
||||
CAltitudePair getElevationStdDevAndMean() const { return CAltitudePair(m_elvStdDev, m_elvMean); }
|
||||
|
||||
//! Guess on ground flag
|
||||
|
||||
@@ -55,22 +55,22 @@ namespace BlackMisc::Aviation
|
||||
int c = 0;
|
||||
for (CAircraftSituation &situation : *this)
|
||||
{
|
||||
situation.setOnGroundDetails(CAircraftSituation::InFromParts);
|
||||
situation.setOnGroundDetails(COnGroundInfo::InFromParts);
|
||||
if (situation.adjustGroundFlag(parts, true, timeDeviationFactor)) { c++; };
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
bool CAircraftSituationList::containsOnGroundDetails(CAircraftSituation::OnGroundDetails details) const
|
||||
bool CAircraftSituationList::containsOnGroundDetails(COnGroundInfo::OnGroundDetails details) const
|
||||
{
|
||||
return this->contains(&CAircraftSituation::getOnGroundDetails, details);
|
||||
return std::any_of(begin(), end(), [&details](const CAircraftSituation &sit) { return sit.getOnGroundInfo().getGroundDetails() == details; });
|
||||
}
|
||||
|
||||
bool CAircraftSituationList::areAllOnGroundDetailsSame(CAircraftSituation::OnGroundDetails details) const
|
||||
bool CAircraftSituationList::areAllOnGroundDetailsSame(COnGroundInfo::OnGroundDetails details) const
|
||||
{
|
||||
for (const CAircraftSituation &situation : *this)
|
||||
{
|
||||
if (situation.getOnGroundDetails() != details) { return false; }
|
||||
if (situation.getOnGroundInfo().getGroundDetails() != details) { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -79,24 +79,14 @@ namespace BlackMisc::Aviation
|
||||
{
|
||||
if (this->isEmpty()) { return false; }
|
||||
if (this->containsNullPositionOrHeight()) { return false; }
|
||||
for (const CAircraftSituation &situation : *this)
|
||||
{
|
||||
const CAircraftSituation::IsOnGround og = situation.getOnGround();
|
||||
if (og != CAircraftSituation::OnGround) { return false; }
|
||||
}
|
||||
return true;
|
||||
return std::all_of(begin(), end(), [](const CAircraftSituation &situation) { return situation.isOnGround(); });
|
||||
}
|
||||
|
||||
bool CAircraftSituationList::isConstNotOnGround() const
|
||||
{
|
||||
if (this->isEmpty()) { return false; }
|
||||
if (this->containsNullPositionOrHeight()) { return false; }
|
||||
for (const CAircraftSituation &situation : *this)
|
||||
{
|
||||
const CAircraftSituation::IsOnGround og = situation.getOnGround();
|
||||
if (og != CAircraftSituation::NotOnGround) { return false; }
|
||||
}
|
||||
return true;
|
||||
return std::all_of(begin(), end(), [](const CAircraftSituation &situation) { return situation.getOnGroundInfo().getOnGround() == COnGroundInfo::NotOnGround; });
|
||||
}
|
||||
|
||||
bool CAircraftSituationList::isConstDescending(bool alreadySortedLatestFirst) const
|
||||
@@ -178,27 +168,27 @@ namespace BlackMisc::Aviation
|
||||
return true;
|
||||
}
|
||||
|
||||
QPair<bool, CAircraftSituation::IsOnGround> CAircraftSituationList::isGndFlagStableChanging(bool alreadySortedLatestFirst) const
|
||||
QPair<bool, COnGroundInfo::IsOnGround> CAircraftSituationList::isGndFlagStableChanging(bool alreadySortedLatestFirst) const
|
||||
{
|
||||
if (this->size() < 2) { return QPair<bool, CAircraftSituation::IsOnGround>(false, CAircraftSituation::OnGroundSituationUnknown); }
|
||||
if (this->size() < 2) { return QPair<bool, COnGroundInfo::IsOnGround>(false, COnGroundInfo::OnGroundSituationUnknown); }
|
||||
|
||||
const CAircraftSituationList sorted(alreadySortedLatestFirst ? (*this) : this->getSortedAdjustedLatestFirst());
|
||||
const CAircraftSituation::IsOnGround f = sorted.front().getOnGround();
|
||||
const CAircraftSituation::IsOnGround t = sorted.back().getOnGround();
|
||||
QPair<bool, CAircraftSituation::IsOnGround> ret(false, f); // changing to front (latest)
|
||||
const COnGroundInfo::IsOnGround f = sorted.front().getOnGroundInfo().getOnGround();
|
||||
const COnGroundInfo::IsOnGround t = sorted.back().getOnGroundInfo().getOnGround();
|
||||
QPair<bool, COnGroundInfo::IsOnGround> ret(false, f); // changing to front (latest)
|
||||
if (f == t) { return ret; }
|
||||
|
||||
bool changed = false;
|
||||
|
||||
for (const CAircraftSituation &s : sorted)
|
||||
{
|
||||
if (!changed && s.getOnGround() == f) { continue; } // find 1st changing
|
||||
if (!changed && s.getOnGroundInfo().getOnGround() == f) { continue; } // find 1st changing
|
||||
if (!changed)
|
||||
{
|
||||
changed = true;
|
||||
continue;
|
||||
} // just changed
|
||||
if (s.getOnGround() != t) { return ret; } // jitter, something like gnd, no gnd, gnd
|
||||
if (s.getOnGroundInfo().getOnGround() != t) { return ret; } // jitter, something like gnd, no gnd, gnd
|
||||
}
|
||||
ret.first = changed;
|
||||
return ret;
|
||||
@@ -210,8 +200,8 @@ namespace BlackMisc::Aviation
|
||||
|
||||
const CAircraftSituationList sorted(alreadySortedLatestFirst ? (*this) : this->getSortedAdjustedLatestFirst());
|
||||
const CAircraftSituation latest = sorted.front();
|
||||
if (latest.getOnGround() != CAircraftSituation::NotOnGround) { return false; }
|
||||
const int c = this->countOnGround(CAircraftSituation::OnGround);
|
||||
if (latest.getOnGroundInfo().getOnGround() != COnGroundInfo::NotOnGround) { return false; }
|
||||
const int c = this->countOnGround(COnGroundInfo::OnGround);
|
||||
return this->size() - 1 == c; // all others on ground
|
||||
}
|
||||
|
||||
@@ -221,21 +211,21 @@ namespace BlackMisc::Aviation
|
||||
|
||||
const CAircraftSituationList sorted(alreadySortedLatestFirst ? (*this) : this->getSortedAdjustedLatestFirst());
|
||||
const CAircraftSituation latest = sorted.front();
|
||||
if (latest.getOnGround() != CAircraftSituation::OnGround) { return false; }
|
||||
const int c = this->countOnGround(CAircraftSituation::NotOnGround);
|
||||
if (latest.getOnGroundInfo().getOnGround() != COnGroundInfo::OnGround) { return false; }
|
||||
const int c = this->countOnGround(COnGroundInfo::NotOnGround);
|
||||
return this->size() - 1 == c; // all others not on ground
|
||||
}
|
||||
|
||||
bool CAircraftSituationList::isTakingOff(bool alreadySortedLatestFirst) const
|
||||
{
|
||||
const QPair<bool, CAircraftSituation::IsOnGround> r = this->isGndFlagStableChanging(alreadySortedLatestFirst);
|
||||
return r.first && r.second == CAircraftSituation::NotOnGround;
|
||||
const QPair<bool, COnGroundInfo::IsOnGround> r = this->isGndFlagStableChanging(alreadySortedLatestFirst);
|
||||
return r.first && r.second == COnGroundInfo::NotOnGround;
|
||||
}
|
||||
|
||||
bool CAircraftSituationList::isTouchingDown(bool alreadySortedLatestFirst) const
|
||||
{
|
||||
const QPair<bool, CAircraftSituation::IsOnGround> r = this->isGndFlagStableChanging(alreadySortedLatestFirst);
|
||||
return r.first && r.second == CAircraftSituation::OnGround;
|
||||
const QPair<bool, COnGroundInfo::IsOnGround> r = this->isGndFlagStableChanging(alreadySortedLatestFirst);
|
||||
return r.first && r.second == COnGroundInfo::OnGround;
|
||||
}
|
||||
|
||||
bool CAircraftSituationList::isRotatingUp(bool alreadySortedLatestFirst) const
|
||||
@@ -258,14 +248,9 @@ namespace BlackMisc::Aviation
|
||||
return false;
|
||||
}
|
||||
|
||||
int CAircraftSituationList::countOnGround(CAircraftSituation::IsOnGround og) const
|
||||
int CAircraftSituationList::countOnGround(COnGroundInfo::IsOnGround og) const
|
||||
{
|
||||
int c = 0;
|
||||
for (const CAircraftSituation &situation : *this)
|
||||
{
|
||||
if (situation.getOnGround() == og) { c++; }
|
||||
}
|
||||
return c;
|
||||
return std::count_if(begin(), end(), [&og](const CAircraftSituation &situation) { return situation.getOnGroundInfo().getOnGround() == og; });
|
||||
}
|
||||
|
||||
CAircraftSituation CAircraftSituationList::findClosestElevationWithinRange(const ICoordinateGeodetic &coordinate, const CLength &range) const
|
||||
@@ -293,24 +278,20 @@ namespace BlackMisc::Aviation
|
||||
return situationWithElevation;
|
||||
}
|
||||
|
||||
int CAircraftSituationList::setOnGround(CAircraftSituation::IsOnGround og)
|
||||
void CAircraftSituationList::setOnGroundInfo(const COnGroundInfo &info)
|
||||
{
|
||||
int c = 0;
|
||||
for (CAircraftSituation &situation : *this)
|
||||
{
|
||||
if (situation.setOnGround(og)) { c++; }
|
||||
situation.setOnGroundInfo(info);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
int CAircraftSituationList::setOnGroundDetails(CAircraftSituation::OnGroundDetails details)
|
||||
void CAircraftSituationList::setOnGroundDetails(COnGroundInfo::OnGroundDetails details)
|
||||
{
|
||||
int c = 0;
|
||||
for (CAircraftSituation &situation : *this)
|
||||
{
|
||||
if (situation.setOnGroundDetails(details)) { c++; }
|
||||
situation.setOnGroundDetails(details);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
int CAircraftSituationList::addAltitudeOffset(const CLength &offset)
|
||||
|
||||
@@ -66,14 +66,14 @@ namespace BlackMisc
|
||||
int adjustGroundFlag(const CAircraftParts &parts, double timeDeviationFactor = 0.1);
|
||||
|
||||
//! Contains on ground details?
|
||||
bool containsOnGroundDetails(CAircraftSituation::OnGroundDetails details) const;
|
||||
bool containsOnGroundDetails(COnGroundInfo::OnGroundDetails details) const;
|
||||
|
||||
//! Contains any push back?
|
||||
//! \remark only valid for non VTOL aircraft
|
||||
bool containsPushBack() const;
|
||||
|
||||
//! Are all on ground details the same?
|
||||
bool areAllOnGroundDetailsSame(CAircraftSituation::OnGroundDetails details) const;
|
||||
bool areAllOnGroundDetailsSame(COnGroundInfo::OnGroundDetails details) const;
|
||||
|
||||
//! Are all situations on ground?
|
||||
bool isConstOnGround() const;
|
||||
@@ -94,7 +94,7 @@ namespace BlackMisc
|
||||
bool isConstDecelarating(bool alreadySortedLatestFirst = false) const;
|
||||
|
||||
//! Is the ground flag changing for the situations
|
||||
QPair<bool, CAircraftSituation::IsOnGround> isGndFlagStableChanging(bool alreadySortedLatestFirst = false) const;
|
||||
QPair<bool, COnGroundInfo::IsOnGround> isGndFlagStableChanging(bool alreadySortedLatestFirst = false) const;
|
||||
|
||||
//! Is just taking off?
|
||||
bool isJustTakingOff(bool alreadySortedLatestFirst = false) const;
|
||||
@@ -111,17 +111,17 @@ namespace BlackMisc
|
||||
//! Is rotating up?
|
||||
bool isRotatingUp(bool alreadySortedLatestFirst = false) const;
|
||||
|
||||
//! Count the number of situations with CAircraftSituation::IsOnGround
|
||||
int countOnGround(CAircraftSituation::IsOnGround og) const;
|
||||
//! Count the number of situations with COnGroundInfo::IsOnGround
|
||||
int countOnGround(COnGroundInfo::IsOnGround og) const;
|
||||
|
||||
//! CLosest elevation within given range
|
||||
CAircraftSituation findClosestElevationWithinRange(const Geo::ICoordinateGeodetic &coordinate, const PhysicalQuantities::CLength &range = Geo::CElevationPlane::singlePointRadius()) const;
|
||||
|
||||
//! Set on ground
|
||||
int setOnGround(CAircraftSituation::IsOnGround og);
|
||||
void setOnGroundInfo(const COnGroundInfo &info);
|
||||
|
||||
//! Set on ground details for all situations
|
||||
int setOnGroundDetails(CAircraftSituation::OnGroundDetails details);
|
||||
void setOnGroundDetails(COnGroundInfo::OnGroundDetails details);
|
||||
|
||||
//! Add an offset to each altitude
|
||||
int addAltitudeOffset(const PhysicalQuantities::CLength &offset);
|
||||
|
||||
180
src/blackmisc/aviation/ongroundinfo.cpp
Normal file
180
src/blackmisc/aviation/ongroundinfo.cpp
Normal file
@@ -0,0 +1,180 @@
|
||||
// SPDX-FileCopyrightText: Copyright (C) swift Project Community / Contributors
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
|
||||
|
||||
#include "blackmisc/aviation/ongroundinfo.h"
|
||||
#include "blackmisc/verify.h"
|
||||
|
||||
BLACK_DEFINE_VALUEOBJECT_MIXINS(BlackMisc::Aviation, COnGroundInfo)
|
||||
|
||||
using namespace BlackMisc::PhysicalQuantities;
|
||||
|
||||
namespace BlackMisc::Aviation
|
||||
{
|
||||
|
||||
COnGroundInfo::COnGroundInfo(IsOnGround onGround, OnGroundDetails details) : m_onGroundDetails(static_cast<int>(details))
|
||||
{
|
||||
switch (onGround)
|
||||
{
|
||||
case IsOnGround::OnGroundSituationUnknown:
|
||||
m_onGroundFactor = -1.0;
|
||||
break;
|
||||
case IsOnGround::OnGround:
|
||||
m_onGroundFactor = 1.0;
|
||||
break;
|
||||
case IsOnGround::NotOnGround:
|
||||
m_onGroundFactor = 0.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const QString &COnGroundInfo::isOnGroundToString(IsOnGround onGround)
|
||||
{
|
||||
static const QString notog("not on ground");
|
||||
static const QString og("on ground");
|
||||
static const QString unknown("unknown");
|
||||
|
||||
switch (onGround)
|
||||
{
|
||||
case IsOnGround::NotOnGround: return notog;
|
||||
case IsOnGround::OnGround: return og;
|
||||
case IsOnGround::OnGroundSituationUnknown:
|
||||
default: return unknown;
|
||||
}
|
||||
}
|
||||
|
||||
const QString &COnGroundInfo::onGroundDetailsToString(OnGroundDetails reliability)
|
||||
{
|
||||
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");
|
||||
|
||||
switch (reliability)
|
||||
{
|
||||
case OnGroundDetails::OnGroundByElevationAndCG: return elvCg;
|
||||
case OnGroundDetails::OnGroundByGuessing: return guess;
|
||||
case OnGroundDetails::OnGroundByInterpolation: return interpolation;
|
||||
case OnGroundDetails::OutOnGroundOwnAircraft: return outOwnAircraft;
|
||||
case OnGroundDetails::InFromNetwork: return inNetwork;
|
||||
case OnGroundDetails::InFromParts: return inFromParts;
|
||||
case OnGroundDetails::NotSetGroundDetails:
|
||||
default: return unknown;
|
||||
}
|
||||
}
|
||||
|
||||
void COnGroundInfo::registerMetadata()
|
||||
{
|
||||
CValueObject<COnGroundInfo>::registerMetadata();
|
||||
qRegisterMetaType<IsOnGround>();
|
||||
qRegisterMetaType<OnGroundDetails>();
|
||||
}
|
||||
|
||||
COnGroundInfo::COnGroundInfo(double interpolatedGndFactor) : m_onGroundDetails(static_cast<int>(OnGroundDetails::OnGroundByInterpolation)), m_onGroundFactor(interpolatedGndFactor)
|
||||
{
|
||||
// Clip small ground factor values
|
||||
if (m_onGroundFactor < 0.0)
|
||||
{
|
||||
m_onGroundFactor = -1.0;
|
||||
}
|
||||
else if (m_onGroundFactor < 0.001)
|
||||
{
|
||||
m_onGroundFactor = 0.0;
|
||||
}
|
||||
else if (m_onGroundFactor > 0.999)
|
||||
{
|
||||
m_onGroundFactor = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
COnGroundInfo::COnGroundInfo(const CLength &cg, const CLength &groundDistance)
|
||||
{
|
||||
m_onGroundDetails = static_cast<int>(OnGroundDetails::OnGroundByElevationAndCG);
|
||||
if (groundDistance.isNull())
|
||||
{
|
||||
m_onGroundFactor = -1.0;
|
||||
}
|
||||
else if (groundDistance.isNegativeWithEpsilonConsidered()) { m_onGroundFactor = 1.0; }
|
||||
else if (groundDistance.abs() < deltaNearGround()) { m_onGroundFactor = 1.0; }
|
||||
else if (!cg.isNull())
|
||||
{
|
||||
// smaller than percentage from CG
|
||||
const CLength cgFactor(cg * 0.1);
|
||||
if (groundDistance.abs() < cgFactor.abs()) { m_onGroundFactor = 1.0; }
|
||||
}
|
||||
m_onGroundFactor = 0.0;
|
||||
}
|
||||
|
||||
bool COnGroundInfo::isOnGround() const
|
||||
{
|
||||
BLACK_VERIFY_X(m_onGroundFactor >= 0.0, Q_FUNC_INFO, "Should only be called with positive groundfactors");
|
||||
if (m_onGroundDetails == OnGroundDetails::OnGroundByInterpolation)
|
||||
{
|
||||
return m_onGroundFactor > m_groundFactorThreshold;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Math::CMathUtils::epsilonEqual(m_onGroundFactor, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
COnGroundInfo::IsOnGround COnGroundInfo::getOnGround() const
|
||||
{
|
||||
if (this->m_onGroundFactor < 0.0)
|
||||
{
|
||||
return OnGroundSituationUnknown;
|
||||
}
|
||||
|
||||
const bool onGround = isOnGround();
|
||||
return onGround ? OnGround : NotOnGround;
|
||||
}
|
||||
|
||||
COnGroundInfo::OnGroundDetails COnGroundInfo::getGroundDetails() const
|
||||
{
|
||||
return static_cast<COnGroundInfo::OnGroundDetails>(m_onGroundDetails);
|
||||
}
|
||||
|
||||
const CLength &COnGroundInfo::deltaNearGround()
|
||||
{
|
||||
static const CLength small(0.5, CLengthUnit::m());
|
||||
return small;
|
||||
}
|
||||
|
||||
QString COnGroundInfo::convertToQString(bool /*i18n*/) const
|
||||
{
|
||||
return u" | factor: " % QString::number(m_onGroundFactor, 'f', 2) %
|
||||
u" | source: " % onGroundDetailsToString(static_cast<OnGroundDetails>(m_onGroundDetails));
|
||||
}
|
||||
|
||||
QVariant COnGroundInfo::propertyByIndex(CPropertyIndexRef index) const
|
||||
{
|
||||
if (index.isMyself()) { return QVariant::fromValue(*this); }
|
||||
|
||||
const ColumnIndex i = index.frontCasted<ColumnIndex>();
|
||||
switch (i)
|
||||
{
|
||||
case IndexOnGroundFactor: return QVariant::fromValue(m_onGroundFactor);
|
||||
case IndexOnGroundDetails: return QVariant::fromValue(m_onGroundDetails);
|
||||
default: return CValueObject::propertyByIndex(index);
|
||||
}
|
||||
}
|
||||
|
||||
void COnGroundInfo::setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant)
|
||||
{
|
||||
if (index.isMyself())
|
||||
{
|
||||
(*this) = variant.value<COnGroundInfo>();
|
||||
return;
|
||||
}
|
||||
|
||||
const ColumnIndex i = index.frontCasted<ColumnIndex>();
|
||||
switch (i)
|
||||
{
|
||||
case IndexOnGroundFactor: m_onGroundFactor = variant.toDouble(); break;
|
||||
case IndexOnGroundDetails: m_onGroundDetails = variant.toInt(); break;
|
||||
default: CValueObject::setPropertyByIndex(index, variant); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
130
src/blackmisc/aviation/ongroundinfo.h
Normal file
130
src/blackmisc/aviation/ongroundinfo.h
Normal file
@@ -0,0 +1,130 @@
|
||||
// SPDX-FileCopyrightText: Copyright (C) swift Project Community / Contributors
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
|
||||
|
||||
//! \file
|
||||
|
||||
#ifndef BLACKMISC_AVIATION_ONGROUNDINFO_H
|
||||
#define BLACKMISC_AVIATION_ONGROUNDINFO_H
|
||||
|
||||
#include "blackmisc/blackmiscexport.h"
|
||||
#include "blackmisc/valueobject.h"
|
||||
#include "blackmisc/pq/length.h"
|
||||
|
||||
BLACK_DECLARE_VALUEOBJECT_MIXINS(BlackMisc::Aviation, COnGroundInfo)
|
||||
|
||||
namespace BlackMisc::Aviation
|
||||
{
|
||||
//! Information about the ground status
|
||||
class BLACKMISC_EXPORT COnGroundInfo : public CValueObject<COnGroundInfo>
|
||||
{
|
||||
public:
|
||||
//! Is on ground?
|
||||
enum IsOnGround
|
||||
{
|
||||
NotOnGround,
|
||||
OnGround,
|
||||
OnGroundSituationUnknown
|
||||
};
|
||||
|
||||
//! Reliability of on ground information
|
||||
enum OnGroundDetails
|
||||
{
|
||||
NotSetGroundDetails,
|
||||
// interpolated situation
|
||||
OnGroundByInterpolation, //!< strongest for remote aircraft
|
||||
OnGroundByElevationAndCG,
|
||||
OnGroundByGuessing, //!< weakest
|
||||
// received situation
|
||||
InFromNetwork, //!< received from network
|
||||
InFromParts, //!< set from aircraft parts
|
||||
// send information
|
||||
OutOnGroundOwnAircraft //!< sending on ground
|
||||
};
|
||||
|
||||
//! Properties by index
|
||||
enum ColumnIndex
|
||||
{
|
||||
IndexOnGroundFactor = CPropertyIndexRef::GlobalIndexCOnGroundInfo,
|
||||
IndexOnGroundDetails,
|
||||
};
|
||||
|
||||
COnGroundInfo() = default;
|
||||
|
||||
//! Create GroundInfo with fixed decision (on ground, not on ground or not known) and with
|
||||
//! info about the source of this knowledge
|
||||
COnGroundInfo(IsOnGround onGround, OnGroundDetails details);
|
||||
|
||||
//! Create GroundInfo from information about CG and distance from ground
|
||||
COnGroundInfo(const PhysicalQuantities::CLength &cg, const PhysicalQuantities::CLength &groundDistance);
|
||||
|
||||
//! Create GroundInfo from interpolated ground factor
|
||||
explicit COnGroundInfo(double interpolatedGndFactor);
|
||||
|
||||
//! Get the ground factor
|
||||
//! Use this for interpolation only!!
|
||||
//! For just checking if the info is OnGround or NotOnGround use the getOnGround() method instead.
|
||||
double getGroundFactor() const { return m_onGroundFactor; }
|
||||
|
||||
//! When source of knowledge changes
|
||||
void setOnGroundDetails(OnGroundDetails details)
|
||||
{
|
||||
// TODO Assert not by interpolation
|
||||
m_onGroundDetails = static_cast<int>(details);
|
||||
}
|
||||
|
||||
//! Is on ground?
|
||||
//! \return IsOnGround state of this object
|
||||
IsOnGround getOnGround() const;
|
||||
|
||||
//! Get ground details
|
||||
//! \return ground details of this object
|
||||
OnGroundDetails getGroundDetails() const;
|
||||
|
||||
//! \copydoc Mixin::String::toQString
|
||||
QString convertToQString(bool i18n = false) const;
|
||||
|
||||
//! \copydoc Mixin::Index::propertyByIndex
|
||||
QVariant propertyByIndex(CPropertyIndexRef index) const;
|
||||
|
||||
//! \copydoc Mixin::Index::setPropertyByIndex
|
||||
void setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant);
|
||||
|
||||
//! Register metadata
|
||||
static void registerMetadata();
|
||||
|
||||
//! Enum to string
|
||||
static const QString &isOnGroundToString(IsOnGround onGround);
|
||||
|
||||
//! Enum to string
|
||||
static const QString &onGroundDetailsToString(OnGroundDetails reliability);
|
||||
|
||||
//! Delta distance, near to ground
|
||||
static const PhysicalQuantities::CLength &deltaNearGround();
|
||||
|
||||
private:
|
||||
//! Check if the aircraft is considered to be on the ground.
|
||||
//! Depending on the data source, different definitions are used on when the aircraft
|
||||
//! is considered to be on the ground.
|
||||
//! This method should only be called when the m_onGroundFactor is >= 0.0, as it is only does a binary
|
||||
//! decision.
|
||||
//! \return true, if the aircraft is considered to be on the ground
|
||||
bool isOnGround() const;
|
||||
|
||||
int m_onGroundDetails = static_cast<int>(OnGroundDetails::NotSetGroundDetails);
|
||||
double m_onGroundFactor = -1.0; //!< interpolated ground flag, 1..on ground, 0..not on ground, -1 no info
|
||||
|
||||
static constexpr double m_groundFactorThreshold = 0.95; //!< With m_onGroundDetails == "OnGroundByInterpolation", this is the threshold used to decide if the ground factor is OnGround or NotOnGround
|
||||
|
||||
BLACK_METACLASS(
|
||||
COnGroundInfo,
|
||||
BLACK_METAMEMBER(onGroundDetails),
|
||||
BLACK_METAMEMBER(onGroundFactor));
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Q_DECLARE_METATYPE(BlackMisc::Aviation::COnGroundInfo)
|
||||
Q_DECLARE_METATYPE(BlackMisc::Aviation::COnGroundInfo::IsOnGround)
|
||||
Q_DECLARE_METATYPE(BlackMisc::Aviation::COnGroundInfo::OnGroundDetails)
|
||||
|
||||
#endif // BLACKMISC_AVIATION_ONGROUNDINFO_H
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "blackmisc/aviation/aircraftpartslist.h"
|
||||
#include "blackmisc/aviation/livery.h"
|
||||
#include "blackmisc/aviation/liverylist.h"
|
||||
#include "blackmisc/aviation/ongroundinfo.h"
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
@@ -86,6 +87,7 @@ namespace BlackMisc
|
||||
CSelcal::registerMetadata();
|
||||
CTrack::registerMetadata();
|
||||
CTransponder::registerMetadata();
|
||||
COnGroundInfo::registerMetadata();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace BlackMisc::Network
|
||||
{
|
||||
if (situation.getCallsign().isEmpty()) { return false; } // no callsign
|
||||
if (!situation.isOnGround()) { return false; } // nothing to adjust
|
||||
if (situation.getOnGroundDetails() != CAircraftSituation::InFromNetwork) { return false; } // not from network
|
||||
if (situation.getOnGroundInfo().getGroundDetails() != COnGroundInfo::InFromNetwork) { return false; } // not from network
|
||||
return this->addClientGndCapability(situation.getCallsign());
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ namespace BlackMisc
|
||||
GlobalIndexCPresentWeather = 4200,
|
||||
GlobalIndexCWindLayer = 4300,
|
||||
GlobalIndexCWeatherScenario = 4700,
|
||||
GlobalIndexCOnGroundInfo = 4800,
|
||||
GlobalIndexICoordinateGeodetic = 5000,
|
||||
GlobalIndexICoordinateWithRelativePosition = 5100,
|
||||
GlobalIndexCCoordinateGeodetic = 5200,
|
||||
|
||||
@@ -361,9 +361,9 @@ namespace BlackMisc::Simulation
|
||||
u"<td class=\"cur\">" % log.situationCurrent.getGroundElevation().valueRoundedWithUnit(ft, 1) % u" " % log.situationCurrent.getGroundElevationInfoAsString() % u"</td>" %
|
||||
|
||||
u"<td>" % QString::number(log.groundFactor) % u"</td>" %
|
||||
u"<td class=\"old\">" % situationOld.getOnGroundInfo() % u"</td>" %
|
||||
u"<td class=\"new\">" % situationNew.getOnGroundInfo() % u"</td>" %
|
||||
u"<td class=\"cur\">" % log.situationCurrent.getOnGroundInfo() % u"</td>" %
|
||||
u"<td class=\"old\">" % situationOld.getOnGroundInfo().toQString() % u"</td>" %
|
||||
u"<td class=\"new\">" % situationNew.getOnGroundInfo().toQString() % u"</td>" %
|
||||
u"<td class=\"cur\">" % log.situationCurrent.getOnGroundInfo().toQString() % u"</td>" %
|
||||
|
||||
// tableRows +=
|
||||
u"<td>" % log.cgAboveGround.valueRoundedWithUnit(ft, 0) % u"</td>" %
|
||||
|
||||
@@ -74,14 +74,6 @@ namespace BlackMisc::Simulation
|
||||
return cg;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
double CInterpolator<Derived>::groundInterpolationFactor()
|
||||
{
|
||||
// done here so we can change value without "larfer" recompilations
|
||||
static constexpr double f = 0.95;
|
||||
return f;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
CAircraftSituationList CInterpolator<Derived>::remoteAircraftSituationsAndChange(const CInterpolationAndRenderingSetupPerCallsign &setup)
|
||||
{
|
||||
@@ -181,10 +173,10 @@ namespace BlackMisc::Simulation
|
||||
if (setup.isNull() || !setup.isAircraftPartsEnabled()) { return sorted; }
|
||||
|
||||
bool details = false;
|
||||
if (situations.containsOnGroundDetails(CAircraftSituation::InFromParts))
|
||||
if (situations.containsOnGroundDetails(COnGroundInfo::InFromParts))
|
||||
{
|
||||
// if a client supports parts, all ground situations are supposed to be parts based
|
||||
details = situations.areAllOnGroundDetailsSame(CAircraftSituation::InFromParts);
|
||||
details = situations.areAllOnGroundDetailsSame(COnGroundInfo::InFromParts);
|
||||
BLACK_VERIFY_X(details, Q_FUNC_INFO, "Once gnd.from parts -> always gnd. from parts");
|
||||
}
|
||||
|
||||
@@ -300,7 +292,7 @@ namespace BlackMisc::Simulation
|
||||
}
|
||||
|
||||
// correct altitude itself
|
||||
if (!interpolateGndFlag && currentSituation.getOnGroundDetails() != CAircraftSituation::OnGroundByGuessing)
|
||||
if (!interpolateGndFlag && currentSituation.getOnGroundInfo().getGroundDetails() != COnGroundInfo::OnGroundByGuessing)
|
||||
{
|
||||
// just in case
|
||||
altCorrection = currentSituation.correctAltitude(true); // we have CG set
|
||||
@@ -377,7 +369,7 @@ namespace BlackMisc::Simulation
|
||||
{
|
||||
log.tsCurrent = m_currentTimeMsSinceEpoch;
|
||||
log.callsign = m_callsign;
|
||||
log.groundFactor = currentSituation.getOnGroundFactor();
|
||||
log.groundFactor = currentSituation.getOnGroundInfo().getGroundFactor();
|
||||
log.altCorrection = CAircraftSituation::altitudeCorrectionToString(altCorrection);
|
||||
log.situationCurrent = currentSituation;
|
||||
log.interpolantRecalc = interpolant.isRecalculated();
|
||||
@@ -524,7 +516,7 @@ namespace BlackMisc::Simulation
|
||||
CLength guessedCG = model.getCG();
|
||||
model.getAircraftIcaoCode().guessModelParameters(guessedCG, guessedVRotate);
|
||||
|
||||
if (situation.getOnGroundDetails() != CAircraftSituation::NotSetGroundDetails)
|
||||
if (situation.getOnGroundInfo().getGroundDetails() != COnGroundInfo::NotSetGroundDetails)
|
||||
{
|
||||
do
|
||||
{
|
||||
@@ -613,10 +605,10 @@ namespace BlackMisc::Simulation
|
||||
}
|
||||
else
|
||||
{
|
||||
if (situation.getOnGroundDetails() != CAircraftSituation::NotSetGroundDetails)
|
||||
if (situation.getOnGroundInfo().getGroundDetails() != COnGroundInfo::NotSetGroundDetails)
|
||||
{
|
||||
// we have no ground elevation but a ground info
|
||||
if (situation.getOnGroundDetails() == CAircraftSituation::OnGroundByGuessing)
|
||||
if (situation.getOnGroundInfo().getGroundDetails() == COnGroundInfo::OnGroundByGuessing)
|
||||
{
|
||||
// should be OK
|
||||
if (details) { *details = QStringLiteral("on ground, no elv."); }
|
||||
|
||||
@@ -113,10 +113,6 @@ namespace BlackMisc::Simulation
|
||||
//! Do logging
|
||||
bool doLogging() const;
|
||||
|
||||
//! Decides threshold when situation is considered on ground
|
||||
//! \sa BlackMisc::Aviation::CAircraftSituation::setOnGroundFromGroundFactorFromInterpolation
|
||||
static double groundInterpolationFactor();
|
||||
|
||||
const Aviation::CCallsign m_callsign; //!< corresponding callsign
|
||||
CAircraftModel m_model; //!< corresponding model (required for CG)
|
||||
|
||||
|
||||
@@ -84,21 +84,20 @@ namespace BlackMisc::Simulation
|
||||
|
||||
if (interpolateGndFactor)
|
||||
{
|
||||
const double startGroundFactor = m_startSituation.getOnGroundFactor();
|
||||
const double endGroundFactor = m_endSituation.getOnGroundFactor();
|
||||
const double startGroundFactor = m_startSituation.getOnGroundInfo().getGroundFactor();
|
||||
const double endGroundFactor = m_endSituation.getOnGroundInfo().getGroundFactor();
|
||||
if (CAircraftSituation::isGfEqualAirborne(startGroundFactor, endGroundFactor))
|
||||
{
|
||||
interpolatedSituation.setOnGround(false);
|
||||
interpolatedSituation.setOnGroundInfo({ COnGroundInfo::NotOnGround, COnGroundInfo::OnGroundByInterpolation });
|
||||
}
|
||||
else if (CAircraftSituation::isGfEqualOnGround(startGroundFactor, endGroundFactor))
|
||||
{
|
||||
interpolatedSituation.setOnGround(true);
|
||||
interpolatedSituation.setOnGroundInfo({ COnGroundInfo::OnGround, COnGroundInfo::OnGroundByInterpolation });
|
||||
}
|
||||
else
|
||||
{
|
||||
const double interpolatedGroundFactor = (endGroundFactor - startGroundFactor) * tf + startGroundFactor;
|
||||
interpolatedSituation.setOnGroundFactor(interpolatedGroundFactor);
|
||||
interpolatedSituation.setOnGroundFromGroundFactorFromInterpolation(groundInterpolationFactor());
|
||||
interpolatedSituation.setOnGroundInfo(COnGroundInfo(interpolatedGroundFactor));
|
||||
}
|
||||
}
|
||||
return interpolatedSituation;
|
||||
|
||||
@@ -218,7 +218,7 @@ namespace BlackMisc::Simulation
|
||||
const double a1 = m_s[1].getCorrectedAltitude(cg).value(altUnit);
|
||||
const double a2 = m_s[2].getCorrectedAltitude(cg).value(altUnit); // latest
|
||||
pa.a = { { a0, a1, a2 } };
|
||||
pa.gnd = { { m_s[0].getOnGroundFactor(), m_s[1].getOnGroundFactor(), m_s[2].getOnGroundFactor() } };
|
||||
pa.gnd = { { m_s[0].getOnGroundInfo().getGroundFactor(), m_s[1].getOnGroundInfo().getGroundFactor(), m_s[2].getOnGroundInfo().getGroundFactor() } };
|
||||
pa.da = getDerivatives(pa.t, pa.a);
|
||||
pa.dgnd = getDerivatives(pa.t, pa.gnd);
|
||||
|
||||
@@ -365,24 +365,20 @@ namespace BlackMisc::Simulation
|
||||
{
|
||||
const double gnd1 = m_pa.gnd[1];
|
||||
const double gnd2 = m_pa.gnd[2]; // latest
|
||||
do
|
||||
{
|
||||
newSituation.setOnGroundDetails(CAircraftSituation::OnGroundByInterpolation);
|
||||
|
||||
if (CAircraftSituation::isGfEqualAirborne(gnd1, gnd2))
|
||||
{
|
||||
newSituation.setOnGround(false);
|
||||
break;
|
||||
newSituation.setOnGroundInfo({ COnGroundInfo::NotOnGround, COnGroundInfo::OnGroundByInterpolation });
|
||||
}
|
||||
if (CAircraftSituation::isGfEqualOnGround(gnd1, gnd2))
|
||||
else if (CAircraftSituation::isGfEqualOnGround(gnd1, gnd2))
|
||||
{
|
||||
newSituation.setOnGround(true);
|
||||
break;
|
||||
newSituation.setOnGroundInfo({ COnGroundInfo::OnGround, COnGroundInfo::OnGroundByInterpolation });
|
||||
}
|
||||
else
|
||||
{
|
||||
const double newGnd = evalSplineInterval(m_currentTimeMsSinceEpoc, t1, t2, gnd1, gnd2, m_pa.dgnd[1], m_pa.dgnd[2]);
|
||||
newSituation.setOnGroundFactor(newGnd);
|
||||
newSituation.setOnGroundFromGroundFactorFromInterpolation(groundInterpolationFactor());
|
||||
newSituation.setOnGroundInfo(COnGroundInfo(newGnd));
|
||||
}
|
||||
while (false);
|
||||
}
|
||||
return newSituation;
|
||||
}
|
||||
|
||||
@@ -303,7 +303,7 @@ namespace BlackMisc::Simulation
|
||||
// unify all inbound ground information
|
||||
if (situation.hasInboundGroundDetails())
|
||||
{
|
||||
newSituationsList.setOnGroundDetails(situation.getOnGroundDetails());
|
||||
newSituationsList.setOnGroundDetails(situation.getOnGroundInfo().getGroundDetails());
|
||||
}
|
||||
}
|
||||
m_latestSituationByCallsign[cs] = situationCorrected;
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace BlackSimPlugin::Flightgear
|
||||
this->pitchesDeg.push_back(situation.getPitch().value(BlackMisc::PhysicalQuantities::CAngleUnit::deg()));
|
||||
this->rollsDeg.push_back(situation.getBank().value(BlackMisc::PhysicalQuantities::CAngleUnit::deg()));
|
||||
this->headingsDeg.push_back(situation.getHeading().value(BlackMisc::PhysicalQuantities::CAngleUnit::deg()));
|
||||
this->onGrounds.push_back(situation.getOnGround() == BlackMisc::Aviation::CAircraftSituation::OnGround);
|
||||
this->onGrounds.push_back(situation.isOnGround());
|
||||
this->groundSpeedKts.push_back(situation.getGroundSpeed().value(BlackMisc::PhysicalQuantities::CSpeedUnit::kts()));
|
||||
}
|
||||
|
||||
|
||||
@@ -652,7 +652,7 @@ namespace BlackSimPlugin::FsxCommon
|
||||
aircraftSituation.setPressureAltitude(CAltitude(simulatorOwnAircraft.pressureAltitudeM, CAltitude::MeanSeaLevel, CAltitude::PressureAltitude, CLengthUnit::m()));
|
||||
// set on ground also in situation for consistency and future usage
|
||||
// it is duplicated in parts
|
||||
aircraftSituation.setOnGround(dtb(simulatorOwnAircraft.simOnGround) ? CAircraftSituation::OnGround : CAircraftSituation::NotOnGround, CAircraftSituation::OutOnGroundOwnAircraft);
|
||||
aircraftSituation.setOnGroundInfo({ dtb(simulatorOwnAircraft.simOnGround) ? COnGroundInfo::OnGround : COnGroundInfo::NotOnGround, COnGroundInfo::OutOnGroundOwnAircraft });
|
||||
|
||||
CAircraftVelocity aircraftVelocity(simulatorOwnAircraft.velocityWorldX,
|
||||
simulatorOwnAircraft.velocityWorldY,
|
||||
@@ -2236,7 +2236,7 @@ namespace BlackSimPlugin::FsxCommon
|
||||
// send GND flag also when underflow detection is available
|
||||
if ((sendGnd || forceUnderflowDetection) && situation.isOnGroundInfoAvailable())
|
||||
{
|
||||
const bool onGround = (situation.getOnGround() == CAircraftSituation::OnGround);
|
||||
const bool onGround = situation.isOnGround();
|
||||
position.OnGround = onGround ? 1U : 0U;
|
||||
}
|
||||
|
||||
|
||||
@@ -953,7 +953,7 @@ namespace BlackSimPlugin::XPlane
|
||||
// adjust altitude to compensate for XP12 temperature effect
|
||||
const CLength relativeAltitude = interpolatedSituation.geodeticHeight() - getOwnAircraftPosition().geodeticHeight();
|
||||
const double altitudeDeltaWeight = 2 - qBound(3000.0, relativeAltitude.abs().value(CLengthUnit::ft()), 6000.0) / 3000;
|
||||
const CLength alt = interpolatedSituation.getAltitude() + m_altitudeDelta * altitudeDeltaWeight * (1 - interpolatedSituation.getOnGroundFactor());
|
||||
const CLength alt = interpolatedSituation.getAltitude() + m_altitudeDelta * altitudeDeltaWeight * (1 - interpolatedSituation.getOnGroundInfo().getGroundFactor());
|
||||
interpolatedSituation.setAltitude({ alt, interpolatedSituation.getAltitude().getReferenceDatum() });
|
||||
|
||||
// update situation
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace BlackSimPlugin::XPlane
|
||||
this->pitchesDeg.push_back(situation.getPitch().value(BlackMisc::PhysicalQuantities::CAngleUnit::deg()));
|
||||
this->rollsDeg.push_back(situation.getBank().value(BlackMisc::PhysicalQuantities::CAngleUnit::deg()));
|
||||
this->headingsDeg.push_back(situation.getHeading().value(BlackMisc::PhysicalQuantities::CAngleUnit::deg()));
|
||||
this->onGrounds.push_back(situation.getOnGround() == BlackMisc::Aviation::CAircraftSituation::OnGround);
|
||||
this->onGrounds.push_back(situation.isOnGround());
|
||||
}
|
||||
|
||||
QStringList callsigns; //!< List of callsigns
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace BlackMiscTest
|
||||
void CTestAircraftSituation::allGndFlagsAndTakeOff() const
|
||||
{
|
||||
CAircraftSituationList situations = testSituations();
|
||||
situations.setOnGround(CAircraftSituation::OnGround);
|
||||
situations.setOnGroundInfo({ COnGroundInfo::OnGround, COnGroundInfo::NotSetGroundDetails });
|
||||
const CAircraftSituationChange change(situations, cg(), false);
|
||||
QVERIFY2(change.isConstOnGround(), "Expect const on ground");
|
||||
QVERIFY(!change.isConstNotOnGround());
|
||||
@@ -87,7 +87,7 @@ namespace BlackMiscTest
|
||||
QVERIFY(situations.isSortedAdjustedLatestFirstWithoutNullPositions());
|
||||
|
||||
CAircraftSituation f = situations.front();
|
||||
f.setOnGround(false);
|
||||
f.setOnGroundInfo({ COnGroundInfo::NotOnGround, COnGroundInfo::NotSetGroundDetails });
|
||||
situations.pop_front();
|
||||
situations.push_front(f);
|
||||
const CAircraftSituationChange change2(situations, cg(), false);
|
||||
@@ -100,7 +100,7 @@ namespace BlackMiscTest
|
||||
void CTestAircraftSituation::allNotGndFlagsAndTouchdown() const
|
||||
{
|
||||
CAircraftSituationList situations = testSetDescendingAltitudes(testSituations());
|
||||
situations.setOnGround(CAircraftSituation::NotOnGround);
|
||||
situations.setOnGroundInfo({ COnGroundInfo::NotOnGround, COnGroundInfo::NotSetGroundDetails });
|
||||
const CAircraftSituationChange change(situations, cg(), false);
|
||||
QVERIFY2(change.isConstNotOnGround(), "Expect const not on ground");
|
||||
QVERIFY(!change.isConstOnGround());
|
||||
@@ -111,7 +111,7 @@ namespace BlackMiscTest
|
||||
QVERIFY(situations.isSortedAdjustedLatestFirstWithoutNullPositions());
|
||||
|
||||
CAircraftSituation f = situations.front();
|
||||
f.setOnGround(true);
|
||||
f.setOnGroundInfo({ COnGroundInfo::OnGround, COnGroundInfo::NotSetGroundDetails });
|
||||
situations.pop_front();
|
||||
situations.push_front(f);
|
||||
const CAircraftSituationChange change2(situations, cg(), false);
|
||||
@@ -215,7 +215,8 @@ namespace BlackMiscTest
|
||||
corAlt = situation.getCorrectedAltitude(true, &correction);
|
||||
QVERIFY2(corAlt == alt, "Expect same altitude, no overflow since not on gnd.");
|
||||
|
||||
situation.setOnGround(CAircraftSituation::OnGround, CAircraftSituation::InFromNetwork);
|
||||
situation.setOnGroundInfo({ COnGroundInfo::OnGround, COnGroundInfo::InFromNetwork });
|
||||
|
||||
corAlt = situation.getCorrectedAltitude(true, &correction);
|
||||
QVERIFY2(correction == CAircraftSituation::DraggedToGround, "Expect dragged to gnd.");
|
||||
QVERIFY2(corAlt < alt, "Expect corrected altitude dragged to gnd.");
|
||||
|
||||
@@ -132,27 +132,27 @@ namespace BlackMiscTest
|
||||
for (int i = 0; i < number; i++)
|
||||
{
|
||||
CAircraftSituation s = createTestSituation(cs, i, ts, deltaT, 0);
|
||||
s.setOnGround(CAircraftSituation::OnGroundSituationUnknown, CAircraftSituation::NotSetGroundDetails);
|
||||
s.setOnGroundInfo({ COnGroundInfo::OnGroundSituationUnknown, COnGroundInfo::NotSetGroundDetails });
|
||||
situations.push_back(s);
|
||||
}
|
||||
|
||||
CAircraftSituation s0 = situations[0];
|
||||
s0.adjustGroundFlag(partsOnGround, true);
|
||||
QVERIFY2(s0.getOnGround(), "Supposed to be on ground");
|
||||
QVERIFY2(s0.getOnGroundInfo().getOnGround(), "Supposed to be on ground");
|
||||
|
||||
s0 = situations[0];
|
||||
s0.adjustGroundFlag(partsNotOnGround, true);
|
||||
QVERIFY2(!s0.getOnGround(), "Supposed to be not on ground");
|
||||
QVERIFY2(!s0.getOnGroundInfo().getOnGround(), "Supposed to be not on ground");
|
||||
|
||||
qint64 distanceMs = -1;
|
||||
const qint64 Offset = 33;
|
||||
partsOnGround.addMsecsToOffset(Offset);
|
||||
CAircraftSituation s1 = situations[1];
|
||||
s1.setOnGroundDetails(CAircraftSituation::NotSetGroundDetails);
|
||||
s1.setOnGroundInfo({ COnGroundInfo::OnGroundSituationUnknown, COnGroundInfo::NotSetGroundDetails });
|
||||
s1.adjustGroundFlag(partsOnGround, true, 0.1, &distanceMs);
|
||||
QVERIFY2(s1.getOnGround(), "Supposed to be on ground");
|
||||
QVERIFY2(s1.getOnGroundInfo().getOnGround(), "Supposed to be on ground");
|
||||
QVERIFY2(distanceMs == deltaT - Offset, "Offset time wrong");
|
||||
QVERIFY2(s1.getOnGroundDetails() == CAircraftSituation::InFromParts, "Wrong details");
|
||||
QVERIFY2(s1.getOnGroundInfo().getGroundDetails() == COnGroundInfo::InFromParts, "Wrong details");
|
||||
}
|
||||
|
||||
CAircraftParts CTestInterpolatorParts::createTestParts(int number, qint64 ts, qint64 deltaT, bool onGround)
|
||||
|
||||
Reference in New Issue
Block a user