mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-22 14:55:36 +08:00
Ref T259, Ref T243 situation/parts/lights adjustments
* guessing now in parts/lights (so it can be used with all sims) * minor renamings * init FSX data definitions from parts
This commit is contained in:
@@ -8,11 +8,12 @@
|
||||
*/
|
||||
|
||||
#include "blackmisc/aviation/aircraftlights.h"
|
||||
#include "blackmisc/aviation/aircraftsituation.h"
|
||||
#include "blackmisc/stringutils.h"
|
||||
#include "blackmisc/variant.h"
|
||||
#include <QStringBuilder>
|
||||
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackMisc::PhysicalQuantities;
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
@@ -36,6 +37,52 @@ namespace BlackMisc
|
||||
return CAircraftLights {false, false, false, false, false, false, false, false};
|
||||
}
|
||||
|
||||
CAircraftLights CAircraftLights::guessedLights(const CAircraftSituation &situation)
|
||||
{
|
||||
const bool isOnGround = situation.getOnGround() == CAircraftSituation::OnGround;
|
||||
const double gsKts = situation.getGroundSpeed().value(CSpeedUnit::kts());
|
||||
CAircraftLights lights;
|
||||
lights.setCabinOn(true);
|
||||
lights.setRecognitionOn(true);
|
||||
|
||||
// when first detected moving, lights on
|
||||
if (isOnGround)
|
||||
{
|
||||
lights.setTaxiOn(true);
|
||||
lights.setBeaconOn(true);
|
||||
lights.setNavOn(true);
|
||||
|
||||
if (gsKts > 5)
|
||||
{
|
||||
// mode taxi
|
||||
lights.setTaxiOn(true);
|
||||
lights.setLandingOn(false);
|
||||
}
|
||||
else if (gsKts > 30)
|
||||
{
|
||||
// mode accelaration for takeoff
|
||||
lights.setTaxiOn(false);
|
||||
lights.setLandingOn(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// slow movements or parking
|
||||
lights.setTaxiOn(false);
|
||||
lights.setLandingOn(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// not on ground
|
||||
lights.setTaxiOn(false);
|
||||
lights.setBeaconOn(true);
|
||||
lights.setNavOn(true);
|
||||
// landing lights for < 10000ft (normally MSL, here ignored)
|
||||
lights.setLandingOn(situation.getAltitude().value(CLengthUnit::ft()) < 10000);
|
||||
}
|
||||
return lights;
|
||||
}
|
||||
|
||||
QString CAircraftLights::convertToQString(bool i18n) const
|
||||
{
|
||||
Q_UNUSED(i18n);
|
||||
@@ -58,24 +105,15 @@ namespace BlackMisc
|
||||
const ColumnIndex i = index.frontCasted<ColumnIndex>();
|
||||
switch (i)
|
||||
{
|
||||
case IndexBeacon:
|
||||
return CVariant::from(m_beaconOn);
|
||||
case IndexLanding:
|
||||
return CVariant::from(m_landingOn);
|
||||
case IndexLogo:
|
||||
return CVariant::from(m_logoOn);
|
||||
case IndexNav:
|
||||
return CVariant::from(m_navOn);
|
||||
case IndexStrobe:
|
||||
return CVariant::from(m_strobeOn);
|
||||
case IndexTaxi:
|
||||
return CVariant::from(m_taxiOn);
|
||||
case IndexRecognition:
|
||||
return CVariant::from(m_recognition);
|
||||
case IndexCabin:
|
||||
return CVariant::from(m_cabin);
|
||||
default:
|
||||
return CValueObject::propertyByIndex(index);
|
||||
case IndexBeacon: return CVariant::from(m_beaconOn);
|
||||
case IndexLanding: return CVariant::from(m_landingOn);
|
||||
case IndexLogo: return CVariant::from(m_logoOn);
|
||||
case IndexNav: return CVariant::from(m_navOn);
|
||||
case IndexStrobe: return CVariant::from(m_strobeOn);
|
||||
case IndexTaxi: return CVariant::from(m_taxiOn);
|
||||
case IndexRecognition: return CVariant::from(m_recognition);
|
||||
case IndexCabin: return CVariant::from(m_cabin);
|
||||
default: return CValueObject::propertyByIndex(index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,33 +125,15 @@ namespace BlackMisc
|
||||
const ColumnIndex i = index.frontCasted<ColumnIndex>();
|
||||
switch (i)
|
||||
{
|
||||
case IndexBeacon:
|
||||
this->m_beaconOn = variant.toBool();
|
||||
break;
|
||||
case IndexLanding:
|
||||
this->m_landingOn = variant.toBool();
|
||||
break;
|
||||
case IndexLogo:
|
||||
this->m_logoOn = variant.toBool();
|
||||
break;
|
||||
case IndexNav:
|
||||
this->m_navOn = variant.toBool();
|
||||
break;
|
||||
case IndexStrobe:
|
||||
this->m_strobeOn = variant.toBool();
|
||||
break;
|
||||
case IndexTaxi:
|
||||
this->m_taxiOn = variant.toBool();
|
||||
break;
|
||||
case IndexCabin:
|
||||
this->m_cabin = variant.toBool();
|
||||
break;
|
||||
case IndexRecognition:
|
||||
this->m_recognition = variant.toBool();
|
||||
break;
|
||||
default:
|
||||
CValueObject::setPropertyByIndex(index, variant);
|
||||
break;
|
||||
case IndexBeacon: m_beaconOn = variant.toBool(); break;
|
||||
case IndexLanding: m_landingOn = variant.toBool(); break;
|
||||
case IndexLogo: m_logoOn = variant.toBool(); break;
|
||||
case IndexNav: m_navOn = variant.toBool(); break;
|
||||
case IndexStrobe: m_strobeOn = variant.toBool(); break;
|
||||
case IndexTaxi: m_taxiOn = variant.toBool(); break;
|
||||
case IndexCabin: m_cabin = variant.toBool(); break;
|
||||
case IndexRecognition: m_recognition = variant.toBool(); break;
|
||||
default: CValueObject::setPropertyByIndex(index, variant); break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,5 +160,10 @@ namespace BlackMisc
|
||||
m_recognition = false;
|
||||
m_cabin = false;
|
||||
}
|
||||
|
||||
void CAircraftLights::guessLights(const CAircraftSituation &situation)
|
||||
{
|
||||
*this = guessedLights(situation);
|
||||
}
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
@@ -26,6 +26,8 @@ namespace BlackMisc
|
||||
{
|
||||
namespace Aviation
|
||||
{
|
||||
class CAircraftSituation;
|
||||
|
||||
//! Value object encapsulating information about aircraft's lights
|
||||
class BLACKMISC_EXPORT CAircraftLights :
|
||||
public CValueObject<CAircraftLights>,
|
||||
@@ -111,6 +113,9 @@ namespace BlackMisc
|
||||
//! All off
|
||||
void setAllOff();
|
||||
|
||||
//! Guess the lights
|
||||
void guessLights(const CAircraftSituation &situation);
|
||||
|
||||
//! \copydoc BlackMisc::Mixin::Index::propertyByIndex
|
||||
CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const;
|
||||
|
||||
@@ -126,6 +131,9 @@ namespace BlackMisc
|
||||
//! Returns object with all lights switched off
|
||||
static CAircraftLights allLightsOff();
|
||||
|
||||
//! Guessed lights
|
||||
static CAircraftLights guessedLights(const CAircraftSituation &situation);
|
||||
|
||||
private:
|
||||
bool m_strobeOn = false;
|
||||
bool m_landingOn = false;
|
||||
|
||||
@@ -7,14 +7,16 @@
|
||||
* contained in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "blackmisc/aviation/aircraftparts.h"
|
||||
#include "aircraftparts.h"
|
||||
#include "aircraftlights.h"
|
||||
#include "aircraftsituation.h"
|
||||
#include "blackmisc/comparefunctions.h"
|
||||
#include "blackmisc/stringutils.h"
|
||||
|
||||
#include "QStringBuilder"
|
||||
#include <QtGlobal>
|
||||
|
||||
using namespace BlackMisc;
|
||||
using namespace BlackMisc::PhysicalQuantities;
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
@@ -39,6 +41,45 @@ namespace BlackMisc
|
||||
return json;
|
||||
}
|
||||
|
||||
CAircraftParts CAircraftParts::guessedParts(const CAircraftSituation &situation, bool vtol, int engineNumber)
|
||||
{
|
||||
CAircraftParts parts;
|
||||
CAircraftEngineList engines;
|
||||
parts.setLights(CAircraftLights::guessedLights(situation));
|
||||
|
||||
const bool onGround = situation.isOnGround();
|
||||
if (onGround)
|
||||
{
|
||||
parts.setGearDown(true);
|
||||
engines.initEngines(engineNumber, situation.isMoving());
|
||||
}
|
||||
else
|
||||
{
|
||||
parts.setGearDown(false);
|
||||
engines.initEngines(engineNumber, true);
|
||||
if (vtol)
|
||||
{
|
||||
|
||||
}
|
||||
else if (situation.hasGroundElevation())
|
||||
{
|
||||
const double aGroundFt = situation.getHeightAboveGround().value(CLengthUnit::ft());
|
||||
if (aGroundFt < 1000)
|
||||
{
|
||||
parts.setGearDown(true);
|
||||
parts.setFlapsPercent(25);
|
||||
}
|
||||
else if (aGroundFt < 2000)
|
||||
{
|
||||
parts.setGearDown(true);
|
||||
parts.setFlapsPercent(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
parts.setEngines(engines);
|
||||
return parts;
|
||||
}
|
||||
|
||||
CVariant CAircraftParts::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
|
||||
{
|
||||
if (index.isMyself()) { return CVariant::from(*this); }
|
||||
@@ -92,6 +133,15 @@ namespace BlackMisc
|
||||
return 0;
|
||||
}
|
||||
|
||||
CAircraftLights CAircraftParts::getAdjustedLights() const
|
||||
{
|
||||
CAircraftLights lights = this->getLights();
|
||||
const bool anyEngine = this->isAnyEngineOn();
|
||||
lights.setRecognitionOn(anyEngine);
|
||||
lights.setCabinOn(anyEngine);
|
||||
return lights;
|
||||
}
|
||||
|
||||
void CAircraftParts::setAllLightsOn()
|
||||
{
|
||||
m_lights.setAllOn();
|
||||
@@ -117,6 +167,11 @@ namespace BlackMisc
|
||||
return m_engines.isAnyEngineOn();
|
||||
}
|
||||
|
||||
void CAircraftParts::guessParts(const CAircraftSituation &situation)
|
||||
{
|
||||
*this = guessedParts(situation);
|
||||
}
|
||||
|
||||
double CAircraftParts::isOnGroundInterpolated() const
|
||||
{
|
||||
if (m_isOnGroundInterpolated < 0)
|
||||
|
||||
@@ -29,6 +29,8 @@ namespace BlackMisc
|
||||
{
|
||||
namespace Aviation
|
||||
{
|
||||
class CAircraftSituation;
|
||||
|
||||
//! Value object encapsulating information of aircraft's parts
|
||||
class BLACKMISC_EXPORT CAircraftParts :
|
||||
public CValueObject<CAircraftParts>,
|
||||
@@ -68,7 +70,10 @@ namespace BlackMisc
|
||||
//! Get aircraft lights
|
||||
CAircraftLights getLights() const { return m_lights; }
|
||||
|
||||
//! Reference to lights, meant wor easy direct changes of the values
|
||||
//! Lights adjusted depending on engines
|
||||
CAircraftLights getAdjustedLights() const;
|
||||
|
||||
//! Reference to lights, meant for easy direct changes of the values
|
||||
CAircraftLights &lights() { return m_lights; }
|
||||
|
||||
//! Set aircraft lights
|
||||
@@ -125,12 +130,17 @@ namespace BlackMisc
|
||||
//! Set aircraft on ground
|
||||
void setOnGround(bool onGround) { m_isOnGround = onGround; }
|
||||
|
||||
//! Guess the parts
|
||||
void guessParts(const CAircraftSituation &situation);
|
||||
|
||||
//! Is aircraft on ground? (Smoothly interpolated between 0 and 1.)
|
||||
//! \remark 1..on ground 0..not on ground
|
||||
//! \deprecated
|
||||
double isOnGroundInterpolated() const;
|
||||
|
||||
//! Set aircraft on ground. (Smoothly interpolated between 0 and 1.)
|
||||
//! \remark 1..on ground 0..not on ground
|
||||
//! \deprecated
|
||||
void setOnGroundInterpolated(double onGround) { m_isOnGroundInterpolated = onGround; }
|
||||
|
||||
//! \copydoc BlackMisc::Mixin::String::toQString
|
||||
@@ -139,6 +149,9 @@ namespace BlackMisc
|
||||
//! Incremental JSON object
|
||||
QJsonObject toIncrementalJson() const;
|
||||
|
||||
//! Guessed parts
|
||||
static CAircraftParts guessedParts(const CAircraftSituation &situation, bool vtol = false, int engineNumber = 4);
|
||||
|
||||
private:
|
||||
CAircraftLights m_lights;
|
||||
CAircraftEngineList m_engines;
|
||||
|
||||
@@ -98,11 +98,16 @@ namespace BlackMisc
|
||||
case CAircraftSituation::InFromParts: return inFromParts;
|
||||
case CAircraftSituation::InNoGroundInfo: return InNoGroundInfo;
|
||||
case CAircraftSituation::NotSet:
|
||||
default:
|
||||
return unknown;
|
||||
default: return unknown;
|
||||
}
|
||||
}
|
||||
|
||||
const CLength &CAircraftSituation::deltaNearGround()
|
||||
{
|
||||
static const CLength small(0.5, CLengthUnit::m());
|
||||
return small;
|
||||
}
|
||||
|
||||
CVariant CAircraftSituation::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
|
||||
{
|
||||
if (index.isMyself()) { return CVariant::from(*this); }
|
||||
@@ -122,8 +127,8 @@ namespace BlackMisc
|
||||
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 CVariant::fromValue(m_isOnGround);
|
||||
case IndexIsOnGroundString: return CVariant::fromValue(this->isOnGroundAsString());
|
||||
case IndexIsOnGround: return CVariant::fromValue(m_onGround);
|
||||
case IndexIsOnGroundString: return CVariant::fromValue(this->onGroundAsString());
|
||||
case IndexOnGroundReliability: return CVariant::fromValue(m_onGroundDetails);
|
||||
case IndexOnGroundReliabilityString: return CVariant::fromValue(this->getOnDetailsAsString());
|
||||
default: return CValueObject::propertyByIndex(index);
|
||||
@@ -144,7 +149,7 @@ namespace BlackMisc
|
||||
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_isOnGround = variant.toInt(); break;
|
||||
case IndexIsOnGround: m_onGround = variant.toInt(); break;
|
||||
case IndexOnGroundReliability: m_onGroundDetails = variant.toInt(); break;
|
||||
default: CValueObject::setPropertyByIndex(index, variant); break;
|
||||
}
|
||||
@@ -166,7 +171,7 @@ namespace BlackMisc
|
||||
case IndexCallsign: return m_correspondingCallsign.comparePropertyByIndex(index.copyFrontRemoved(), compareValue.getCallsign());
|
||||
case IndexIsOnGround:
|
||||
case IndexIsOnGroundString:
|
||||
return Compare::compare(m_isOnGround, compareValue.m_isOnGround);
|
||||
return Compare::compare(m_onGround, compareValue.m_onGround);
|
||||
case IndexOnGroundReliability:
|
||||
case IndexOnGroundReliabilityString:
|
||||
return Compare::compare(m_onGroundDetails, compareValue.m_onGroundDetails);
|
||||
@@ -194,23 +199,73 @@ namespace BlackMisc
|
||||
m_onGroundDetails = CAircraftSituation::NotSet;
|
||||
}
|
||||
|
||||
const QString &CAircraftSituation::isOnGroundAsString() const
|
||||
const QString &CAircraftSituation::onGroundAsString() const
|
||||
{
|
||||
return CAircraftSituation::isOnGroundToString(this->isOnGround());
|
||||
return CAircraftSituation::isOnGroundToString(this->getOnGround());
|
||||
}
|
||||
|
||||
bool CAircraftSituation::isOnGroundInfoAvailable() const
|
||||
{
|
||||
return this->isOnGround() != CAircraftSituation::OnGroundSituationUnknown &&
|
||||
return this->getOnGround() != CAircraftSituation::OnGroundSituationUnknown &&
|
||||
this->getOnGroundDetails() != CAircraftSituation::NotSet;
|
||||
}
|
||||
|
||||
void CAircraftSituation::setOnGround(bool onGround)
|
||||
{
|
||||
this->setOnGround(onGround ? OnGround : NotOnGround);
|
||||
}
|
||||
|
||||
void CAircraftSituation::setOnGround(CAircraftSituation::IsOnGround onGround)
|
||||
{
|
||||
m_onGround = static_cast<int>(onGround);
|
||||
m_onGroundFactor = (onGround == OnGround) ? 1.0 : 0.0;
|
||||
}
|
||||
|
||||
void CAircraftSituation::setOnGround(CAircraftSituation::IsOnGround onGround, CAircraftSituation::OnGroundDetails details)
|
||||
{
|
||||
this->setOnGround(onGround);
|
||||
this->setOnGroundDetails(details);
|
||||
}
|
||||
|
||||
void CAircraftSituation::setOnGroundFactor(double groundFactor)
|
||||
{
|
||||
if (groundFactor < 0.0) { m_onGroundFactor = -1.0; return; }
|
||||
if (groundFactor > 1.0) { m_onGroundFactor = 1.0; return; }
|
||||
m_onGroundFactor = groundFactor;
|
||||
}
|
||||
|
||||
bool CAircraftSituation::guessOnGround(bool vtol, const PhysicalQuantities::CLength &cg)
|
||||
{
|
||||
if (this->getOnGroundDetails() == NotSet) { return false; }
|
||||
IsOnGround og = this->isOnGroundByElevation(cg);
|
||||
if (og != OnGroundSituationUnknown)
|
||||
{
|
||||
this->setOnGround(og, CAircraftSituation::OnGroundByGuessing);
|
||||
return true;
|
||||
}
|
||||
|
||||
// we guess on speed, pitch and bank by excluding situations
|
||||
this->setOnGround(CAircraftSituation::NotOnGround, CAircraftSituation::OnGroundByGuessing);
|
||||
if (qAbs(this->getPitch().value(CAngleUnit::deg())) > 10) { return true; }
|
||||
if (qAbs(this->getBank().value(CAngleUnit::deg())) > 10) { return true; }
|
||||
if (this->getGroundSpeed().value(CSpeedUnit::km_h()) > 50) { return true; }
|
||||
|
||||
// on VTOL we stop here
|
||||
if (vtol) { return false; }
|
||||
|
||||
// not sure, but this is a guess
|
||||
this->setOnGround(CAircraftSituation::OnGround, CAircraftSituation::OnGroundByGuessing);
|
||||
return true;
|
||||
}
|
||||
|
||||
CLength CAircraftSituation::getGroundDistance(const CLength ¢erOfGravity) const
|
||||
{
|
||||
if (centerOfGravity.isNull() || !this->hasGroundElevation()) { return CLength::null(); }
|
||||
const CAltitude groundPlusCG = this->getGroundElevation().withOffset(centerOfGravity);
|
||||
const CLength groundDistance = (this->getAltitude() - groundPlusCG);
|
||||
return groundDistance;
|
||||
}
|
||||
|
||||
const QString &CAircraftSituation::getOnDetailsAsString() const
|
||||
{
|
||||
return CAircraftSituation::onGroundDetailsToString(this->getOnGroundDetails());
|
||||
@@ -218,7 +273,15 @@ namespace BlackMisc
|
||||
|
||||
QString CAircraftSituation::getOnGroundInfo() const
|
||||
{
|
||||
return this->isOnGroundAsString() % QLatin1Char(' ') % this->getOnDetailsAsString();
|
||||
return this->onGroundAsString() % QLatin1Char(' ') % this->getOnDetailsAsString();
|
||||
}
|
||||
|
||||
CAircraftSituation::IsOnGround CAircraftSituation::isOnGroundByElevation(const CLength &cg) const
|
||||
{
|
||||
const CLength groundDistance = this->getGroundDistance(cg);
|
||||
if (groundDistance.isNull()) { return OnGroundSituationUnknown; }
|
||||
if (groundDistance.isNegativeWithEpsilonConsidered() || groundDistance.abs() < deltaNearGround()) { return OnGround; }
|
||||
return NotOnGround;
|
||||
}
|
||||
|
||||
bool CAircraftSituation::hasGroundElevation() const
|
||||
@@ -292,18 +355,17 @@ namespace BlackMisc
|
||||
}
|
||||
else
|
||||
{
|
||||
static const CLength small(0.5, CLengthUnit::m());
|
||||
const CAltitude groundPlusCG = this->getGroundElevation().withOffset(centerOfGravity);
|
||||
const CLength groundDistance = (this->getAltitude() - groundPlusCG);
|
||||
if (groundDistance.abs() < small) { return this->getAltitude(); }
|
||||
const bool toGround = (this->getAltitude() < groundPlusCG) || (forceToGround && this->isOnGround() == OnGround);
|
||||
if (toGround)
|
||||
{
|
||||
// underflow or overflow forced to ground
|
||||
if (corrected) { *corrected = true; }
|
||||
return groundPlusCG;
|
||||
}
|
||||
return this->getAltitude();
|
||||
if (groundPlusCG.isNull()) { return this->getAltitude(); }
|
||||
const CLength groundDistance = this->getAltitude() - groundPlusCG;
|
||||
const bool underOrNearGround = groundDistance.isNegativeWithEpsilonConsidered() || groundDistance.abs() < deltaNearGround();
|
||||
const bool forceDragGnd = (dragToGround && this->getOnGround() == OnGround) && (this->hasInboundGroundInformation() || this->getOnGroundDetails() == OnGroundByGuessing);
|
||||
const bool toGround = underOrNearGround || forceDragGnd;
|
||||
if (!toGround) { return this->getAltitude(); }
|
||||
|
||||
// underflow or overflow forced to ground
|
||||
if (corrected) { *corrected = true; }
|
||||
return groundPlusCG;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,6 +375,12 @@ namespace BlackMisc
|
||||
m_pressureAltitude = altitude;
|
||||
}
|
||||
|
||||
bool CAircraftSituation::isMoving() const
|
||||
{
|
||||
const double gsKmh = this->getGroundSpeed().value(CSpeedUnit::km_h());
|
||||
return gsKmh >= 1.0;
|
||||
}
|
||||
|
||||
CLength CAircraftSituation::getDistancePerTime(const CTime &time) const
|
||||
{
|
||||
if (this->getGroundSpeed().isNull()) { return CLength(0, CLengthUnit::nullUnit()); }
|
||||
|
||||
@@ -147,23 +147,38 @@ namespace BlackMisc
|
||||
virtual Geo::CLongitude longitude() const override { return m_position.longitude(); }
|
||||
|
||||
//! On ground?
|
||||
IsOnGround isOnGround() const { return static_cast<CAircraftSituation::IsOnGround>(m_isOnGround); }
|
||||
IsOnGround getOnGround() const { return static_cast<CAircraftSituation::IsOnGround>(m_onGround); }
|
||||
|
||||
//! Is on ground?
|
||||
bool isOnGround() const { return this->getOnGround() == OnGround; }
|
||||
|
||||
//! On ground?
|
||||
const QString &isOnGroundAsString() const;
|
||||
const QString &onGroundAsString() const;
|
||||
|
||||
//! On ground info available?
|
||||
bool isOnGroundInfoAvailable() const;
|
||||
|
||||
//! Set on ground
|
||||
void setOnGround(bool onGround) { this->setOnGround(onGround ? OnGround : NotOnGround); }
|
||||
void setOnGround(bool onGround);
|
||||
|
||||
//! Set on ground
|
||||
void setOnGround(CAircraftSituation::IsOnGround onGround) { m_isOnGround = static_cast<int>(onGround); }
|
||||
void setOnGround(CAircraftSituation::IsOnGround onGround);
|
||||
|
||||
//! Set on ground
|
||||
void 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);
|
||||
|
||||
//! Guess on ground flag
|
||||
bool guessOnGround(bool vtol = false, const PhysicalQuantities::CLength &cg = PhysicalQuantities::CLength::null());
|
||||
|
||||
//! 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); }
|
||||
|
||||
@@ -191,6 +206,9 @@ namespace BlackMisc
|
||||
//! Elevation of the ground directly beneath
|
||||
const Geo::CElevationPlane &getGroundElevationPlane() const { return m_groundElevationPlane; }
|
||||
|
||||
//! 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;
|
||||
|
||||
@@ -222,8 +240,9 @@ namespace BlackMisc
|
||||
//! Get altitude
|
||||
const CAltitude &getAltitude() const { return m_position.geodeticHeight(); }
|
||||
|
||||
//! Get altitude under consideration of ground elevation
|
||||
CAltitude getCorrectedAltitude(const PhysicalQuantities::CLength ¢erOfGravity = {}, bool forceToGround = true, bool *corrected = nullptr) const;
|
||||
//! Get altitude under consideration of ground elevation and ground flag
|
||||
//! \remark with dragToGround it will also compensate overflows, otherwise ony underflow
|
||||
CAltitude getCorrectedAltitude(const PhysicalQuantities::CLength ¢erOfGravity = PhysicalQuantities::CLength::null(), bool dragToGround = true, bool *corrected = nullptr) const;
|
||||
|
||||
//! Set altitude
|
||||
void setAltitude(const CAltitude &altitude) { m_position.setGeodeticHeight(altitude); }
|
||||
@@ -252,6 +271,9 @@ namespace BlackMisc
|
||||
//! Set ground speed
|
||||
void setGroundSpeed(const PhysicalQuantities::CSpeed &groundspeed) { m_groundSpeed = groundspeed; }
|
||||
|
||||
//! Is moving? Means ground speed > epsilon
|
||||
bool isMoving() const;
|
||||
|
||||
//! Distance per time
|
||||
PhysicalQuantities::CLength getDistancePerTime(const PhysicalQuantities::CTime &time) const;
|
||||
|
||||
@@ -293,18 +315,22 @@ namespace BlackMisc
|
||||
//! Enum to string
|
||||
static const QString &onGroundDetailsToString(OnGroundDetails reliability);
|
||||
|
||||
//! Delta distance, near to ground
|
||||
static const PhysicalQuantities::CLength &deltaNearGround();
|
||||
|
||||
private:
|
||||
CCallsign m_correspondingCallsign;
|
||||
Geo::CCoordinateGeodetic m_position; // NULL position
|
||||
Geo::CCoordinateGeodetic m_position; //!< NULL position as default
|
||||
Aviation::CAltitude m_pressureAltitude { 0, nullptr };
|
||||
CHeading m_heading;
|
||||
PhysicalQuantities::CAngle m_pitch;
|
||||
PhysicalQuantities::CAngle m_bank;
|
||||
PhysicalQuantities::CSpeed m_groundSpeed;
|
||||
Geo::CElevationPlane m_groundElevationPlane; //!< NULL elevation as default
|
||||
int m_isOnGround = static_cast<int>(CAircraftSituation::OnGroundSituationUnknown);
|
||||
int m_onGroundDetails = static_cast<int>(CAircraftSituation::NotSet);
|
||||
CHeading m_heading { 0, nullptr };
|
||||
PhysicalQuantities::CAngle m_pitch { 0, nullptr };
|
||||
PhysicalQuantities::CAngle m_bank { 0, nullptr };
|
||||
PhysicalQuantities::CSpeed m_groundSpeed { 0, nullptr };
|
||||
bool m_isInterim = false;
|
||||
Geo::CElevationPlane m_groundElevationPlane; //!< NULL elevation as default
|
||||
int m_onGround = static_cast<int>(CAircraftSituation::OnGroundSituationUnknown);
|
||||
int m_onGroundDetails = static_cast<int>(CAircraftSituation::NotSet);
|
||||
double m_onGroundFactor = -1; //!< interpolated ground flag, 1..on ground, 0..not on ground, -1 no info
|
||||
|
||||
BLACK_METACLASS(
|
||||
CAircraftSituation,
|
||||
@@ -316,8 +342,9 @@ namespace BlackMisc
|
||||
BLACK_METAMEMBER(bank),
|
||||
BLACK_METAMEMBER(groundSpeed),
|
||||
BLACK_METAMEMBER(groundElevationPlane),
|
||||
BLACK_METAMEMBER(isOnGround),
|
||||
BLACK_METAMEMBER(onGround),
|
||||
BLACK_METAMEMBER(onGroundDetails),
|
||||
BLACK_METAMEMBER(onGroundFactor),
|
||||
BLACK_METAMEMBER(timestampMSecsSinceEpoch),
|
||||
BLACK_METAMEMBER(timeOffsetMs),
|
||||
BLACK_METAMEMBER(isInterim)
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace BlackMisc
|
||||
{
|
||||
if (situation.isNewerThanAdjusted(latest))
|
||||
{
|
||||
situation.setOnGround(latest.isOnGround(), latest.getOnGroundDetails());
|
||||
situation.setOnGround(latest.getOnGround(), latest.getOnGroundDetails());
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
*/
|
||||
|
||||
#include "simconnectdatadefinition.h"
|
||||
#include "blackmisc/aviation/aircraftparts.h"
|
||||
#include "blackmisc/aviation/aircraftenginelist.h"
|
||||
#include "blackmisc/logmessage.h"
|
||||
#include <tuple>
|
||||
|
||||
@@ -186,6 +188,16 @@ namespace BlackSimPlugin
|
||||
return hr;
|
||||
}
|
||||
|
||||
DataDefinitionRemoteAircraftPartsWithoutLights::DataDefinitionRemoteAircraftPartsWithoutLights()
|
||||
{
|
||||
this->resetToInvalid();
|
||||
}
|
||||
|
||||
DataDefinitionRemoteAircraftPartsWithoutLights::DataDefinitionRemoteAircraftPartsWithoutLights(const CAircraftParts &parts)
|
||||
{
|
||||
this->initFromParts(parts);
|
||||
}
|
||||
|
||||
bool DataDefinitionRemoteAircraftPartsWithoutLights::operator==(const DataDefinitionRemoteAircraftPartsWithoutLights &rhs) const
|
||||
{
|
||||
return std::tie(flapsLeadingEdgeLeftPercent, flapsLeadingEdgeRightPercent, flapsTrailingEdgeLeftPercent, flapsTrailingEdgeRightPercent,
|
||||
@@ -204,6 +216,19 @@ namespace BlackSimPlugin
|
||||
engine4Combustion = on ? 1 : 0;
|
||||
}
|
||||
|
||||
void DataDefinitionRemoteAircraftPartsWithoutLights::setEngine(int number1based, bool on)
|
||||
{
|
||||
double v = on ? 1.0 : 0.0;
|
||||
switch (number1based)
|
||||
{
|
||||
case 1: engine1Combustion = v; break;
|
||||
case 2: engine2Combustion = v; break;
|
||||
case 3: engine3Combustion = v; break;
|
||||
case 4: engine4Combustion = v; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
void DataDefinitionRemoteAircraftPartsWithoutLights::resetAllFlaps()
|
||||
{
|
||||
flapsLeadingEdgeLeftPercent = 0;
|
||||
@@ -231,6 +256,21 @@ namespace BlackSimPlugin
|
||||
engine4Combustion = -1;
|
||||
}
|
||||
|
||||
void DataDefinitionRemoteAircraftPartsWithoutLights::initFromParts(const CAircraftParts &parts)
|
||||
{
|
||||
gearHandlePosition = parts.isGearDown() ? 1.0 : 0.0;
|
||||
flapsTrailingEdgeLeftPercent = flapsTrailingEdgeRightPercent = parts.getFlapsPercent() / 100.0;
|
||||
flapsLeadingEdgeLeftPercent = flapsLeadingEdgeRightPercent = parts.getFlapsPercent() * 0.2 / 100.0;
|
||||
spoilersHandlePosition = parts.isSpoilersOut() ? 1.0 : 0.0;
|
||||
this->setAllEngines(false); // init
|
||||
|
||||
int e = 1;
|
||||
for (const CAircraftEngine &engine : parts.getEngines())
|
||||
{
|
||||
this->setEngine(e++, engine.isOn());
|
||||
}
|
||||
}
|
||||
|
||||
CAircraftLights DataDefinitionRemoteAircraftLights::toLights() const
|
||||
{
|
||||
return CAircraftLights(lightStrobe, lightLanding, lightTaxi, lightBeacon, lightNav, lightLogo, lightRecognition, lightCabin);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <algorithm>
|
||||
#include <QString>
|
||||
|
||||
namespace BlackMisc { namespace Aviation { class CAircraftParts; }}
|
||||
namespace BlackSimPlugin
|
||||
{
|
||||
namespace FsxCommon
|
||||
@@ -85,12 +86,21 @@ namespace BlackSimPlugin
|
||||
double engine3Combustion; //!< Engine 3 combustion flag
|
||||
double engine4Combustion; //!< Engine 4 combustion flag
|
||||
|
||||
//! Ctor
|
||||
DataDefinitionRemoteAircraftPartsWithoutLights();
|
||||
|
||||
//! Ctor
|
||||
DataDefinitionRemoteAircraftPartsWithoutLights(const BlackMisc::Aviation::CAircraftParts &parts);
|
||||
|
||||
//! Equal to other parts
|
||||
bool operator==(const DataDefinitionRemoteAircraftPartsWithoutLights &rhs) const;
|
||||
|
||||
//! All engines on/off
|
||||
void setAllEngines(bool on);
|
||||
|
||||
//! Set given engine
|
||||
void setEngine(int number1based, bool on);
|
||||
|
||||
//! Reset all flaps
|
||||
void resetAllFlaps();
|
||||
|
||||
@@ -99,6 +109,9 @@ namespace BlackSimPlugin
|
||||
|
||||
//! Reset to invalid values
|
||||
void resetToInvalid();
|
||||
|
||||
//! Init from parts
|
||||
void initFromParts(const BlackMisc::Aviation::CAircraftParts &parts);
|
||||
};
|
||||
|
||||
//! Data for aircraft lighs
|
||||
|
||||
@@ -111,11 +111,11 @@ namespace BlackMiscTest
|
||||
|
||||
CAircraftSituation s0 = situations[0];
|
||||
s0.adjustGroundFlag(partsOnGround);
|
||||
QVERIFY2(s0.isOnGround(), "Supposed to be on ground");
|
||||
QVERIFY2(s0.getOnGround(), "Supposed to be on ground");
|
||||
|
||||
s0 = situations[0];
|
||||
s0.adjustGroundFlag(partsNotOnGround);
|
||||
QVERIFY2(!s0.isOnGround(), "Supposed to be not on ground");
|
||||
QVERIFY2(!s0.getOnGround(), "Supposed to be not on ground");
|
||||
|
||||
qint64 distanceMs = -1;
|
||||
const qint64 Offset = 33;
|
||||
|
||||
Reference in New Issue
Block a user