diff --git a/src/blackmisc/aviation/aircraftsituation.cpp b/src/blackmisc/aviation/aircraftsituation.cpp index 8f37ae577..388f8dc6a 100644 --- a/src/blackmisc/aviation/aircraftsituation.cpp +++ b/src/blackmisc/aviation/aircraftsituation.cpp @@ -318,6 +318,7 @@ namespace BlackMisc::Aviation case IndexHeading: return m_heading.propertyByIndex(index.copyFrontRemoved()); case IndexPitch: return m_pitch.propertyByIndex(index.copyFrontRemoved()); case IndexPBHInfo: return QVariant::fromValue(this->getPBHInfo()); + case IndexVelocity: return QVariant::fromValue(this->getVelocity()); case IndexBank: return m_bank.propertyByIndex(index.copyFrontRemoved()); case IndexCG: return m_cg.propertyByIndex(index.copyFrontRemoved()); case IndexSceneryOffset: return m_sceneryOffset.propertyByIndex(index.copyFrontRemoved()); @@ -348,6 +349,7 @@ namespace BlackMisc::Aviation case IndexPosition: m_position.setPropertyByIndex(index.copyFrontRemoved(), variant); break; case IndexPitch: m_pitch.setPropertyByIndex(index.copyFrontRemoved(), variant); break; case IndexBank: m_bank.setPropertyByIndex(index.copyFrontRemoved(), variant); break; + case IndexVelocity: m_velocity.setPropertyByIndex(index.copyFrontRemoved(), variant); break; case IndexCG: m_cg.setPropertyByIndex(index.copyFrontRemoved(), variant); break; case IndexSceneryOffset: m_sceneryOffset.setPropertyByIndex(index.copyFrontRemoved(), variant); break; case IndexGroundSpeed: m_groundSpeed.setPropertyByIndex(index.copyFrontRemoved(), variant); break; @@ -372,6 +374,7 @@ namespace BlackMisc::Aviation { case IndexPosition: return m_position.comparePropertyByIndex(index.copyFrontRemoved(), compareValue.getPosition()); case IndexAltitude: return this->getAltitude().comparePropertyByIndex(index.copyFrontRemoved(), compareValue.getAltitude()); + case IndexVelocity: return m_velocity.comparePropertyByIndex(index.copyFrontRemoved(), compareValue.getVelocity()); case IndexPBHInfo: // fall through case IndexPitch: return m_pitch.comparePropertyByIndex(index.copyFrontRemoved(), compareValue.getPitch()); case IndexBank: return m_bank.comparePropertyByIndex(index.copyFrontRemoved(), compareValue.getBank()); @@ -457,6 +460,7 @@ namespace BlackMisc::Aviation m_heading.setNull(); m_pitch.setNull(); m_bank.setNull(); + m_velocity = {}; m_groundElevationPlane.setNull(); m_groundSpeed.setNull(); m_onGroundDetails = CAircraftSituation::NotSetGroundDetails; diff --git a/src/blackmisc/aviation/aircraftsituation.h b/src/blackmisc/aviation/aircraftsituation.h index afdb1c756..fc93a9f53 100644 --- a/src/blackmisc/aviation/aircraftsituation.h +++ b/src/blackmisc/aviation/aircraftsituation.h @@ -14,6 +14,7 @@ #include "blackmisc/aviation/altitude.h" #include "blackmisc/aviation/callsign.h" #include "blackmisc/aviation/heading.h" +#include "blackmisc/aviation/aircraftvelocity.h" #include "blackmisc/blackmiscexport.h" #include "blackmisc/geo/elevationplane.h" #include "blackmisc/geo/coordinategeodetic.h" @@ -66,6 +67,7 @@ namespace BlackMisc IndexOnGroundReliabilityString, IndexPitch, IndexPBHInfo, + IndexVelocity, IndexGroundSpeed, IndexGroundElevationPlane, IndexGroundElevationInfo, @@ -415,6 +417,12 @@ namespace BlackMisc //! Get PBH info (all together) QString getPBHInfo() const; + //! Set 6DOF velocity + void setVelocity(const CAircraftVelocity &velocity) { m_velocity = velocity; } + + //! Get 6DOF velocity + const CAircraftVelocity &getVelocity() const { return m_velocity; } + //! Get ground speed const PhysicalQuantities::CSpeed &getGroundSpeed() const { return m_groundSpeed; } @@ -565,6 +573,7 @@ namespace BlackMisc PhysicalQuantities::CSpeed m_groundSpeed { 0, nullptr }; PhysicalQuantities::CLength m_cg { 0, nullptr }; PhysicalQuantities::CLength m_sceneryOffset { 0, nullptr }; + CAircraftVelocity m_velocity; bool m_isInterim = false; //!< interim situation? bool m_isElvInfoTransferred = false; //!< the gnd.elevation has been transferred int m_onGround = static_cast(CAircraftSituation::OnGroundSituationUnknown); @@ -590,6 +599,7 @@ namespace BlackMisc BLACK_METAMEMBER(groundSpeed), BLACK_METAMEMBER(cg), BLACK_METAMEMBER(sceneryOffset), + BLACK_METAMEMBER(velocity), BLACK_METAMEMBER(groundElevationPlane), BLACK_METAMEMBER(onGround), BLACK_METAMEMBER(onGroundDetails), diff --git a/src/blackmisc/aviation/aircraftvelocity.cpp b/src/blackmisc/aviation/aircraftvelocity.cpp new file mode 100644 index 000000000..0f338acdf --- /dev/null +++ b/src/blackmisc/aviation/aircraftvelocity.cpp @@ -0,0 +1,99 @@ +/* Copyright (C) 2021 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated, + * or distributed except according to the terms contained in the LICENSE file. + */ + +#include "blackmisc/aviation/aircraftvelocity.h" +#include "blackmisc/verify.h" +#include + +using namespace BlackMisc::PhysicalQuantities; + +BLACK_DEFINE_VALUEOBJECT_MIXINS(BlackMisc::Aviation, CAircraftVelocity) + +namespace BlackMisc::Aviation +{ + const CSpeedUnit CAircraftVelocity::c_xyzUnit = CSpeedUnit::m_s(); + const CAngleUnit CAircraftVelocity::c_pbhAngleUnit = CAngleUnit::rad(); + const CTimeUnit CAircraftVelocity::c_pbhTimeUnit = CTimeUnit::s(); + + CAircraftVelocity::CAircraftVelocity() = default; + + CAircraftVelocity::CAircraftVelocity(double x, double y, double z, CSpeedUnit xyzUnit, double pitch, double roll, double heading, CAngleUnit pbhAngleUnit, CTimeUnit pbhTimeUnit) + { + setLinearVelocity(x, y, z, xyzUnit); + setAngularVelocity(pitch, roll, heading, pbhAngleUnit, pbhTimeUnit); + } + + void CAircraftVelocity::setLinearVelocity(double x, double y, double z, CSpeedUnit xyzUnit) + { + m_x = c_xyzUnit.convertFrom(x, xyzUnit); + m_y = c_xyzUnit.convertFrom(y, xyzUnit); + m_z = c_xyzUnit.convertFrom(z, xyzUnit); + } + + void CAircraftVelocity::setAngularVelocity(double pitch, double roll, double heading, CAngleUnit pbhAngleUnit, CTimeUnit pbhTimeUnit) + { + m_pitch = pbhTimeUnit.convertFrom(c_pbhAngleUnit.convertFrom(pitch, pbhAngleUnit), c_pbhTimeUnit); + m_roll = pbhTimeUnit.convertFrom(c_pbhAngleUnit.convertFrom(roll, pbhAngleUnit), c_pbhTimeUnit); + m_heading = pbhTimeUnit.convertFrom(c_pbhAngleUnit.convertFrom(heading, pbhAngleUnit), c_pbhTimeUnit); + } + + double CAircraftVelocity::getVelocityX(CSpeedUnit unit) const + { + return unit.convertFrom(m_x, c_xyzUnit); + } + + double CAircraftVelocity::getVelocityY(CSpeedUnit unit) const + { + return unit.convertFrom(m_y, c_xyzUnit); + } + + double CAircraftVelocity::getVelocityZ(CSpeedUnit unit) const + { + return unit.convertFrom(m_z, c_xyzUnit); + } + + double CAircraftVelocity::getPitchVelocity(CAngleUnit angleUnit, CTimeUnit timeUnit) const + { + return c_pbhTimeUnit.convertFrom(angleUnit.convertFrom(m_pitch, c_pbhAngleUnit), timeUnit); + } + + double CAircraftVelocity::getRollVelocity(CAngleUnit angleUnit, CTimeUnit timeUnit) const + { + return c_pbhTimeUnit.convertFrom(angleUnit.convertFrom(m_roll, c_pbhAngleUnit), timeUnit); + } + + double CAircraftVelocity::getHeadingVelocity(CAngleUnit angleUnit, CTimeUnit timeUnit) const + { + return c_pbhTimeUnit.convertFrom(angleUnit.convertFrom(m_heading, c_pbhAngleUnit), timeUnit); + } + + QString CAircraftVelocity::convertToQString(bool i18n) const + { + return u"Velocity: " % QStringLiteral("%1 %2 %3 ").arg(m_x).arg(m_y).arg(m_z) % c_xyzUnit.convertToQString(i18n) % + u" | Rotation: " % QStringLiteral("%1 %2 %3 ").arg(m_pitch).arg(m_roll).arg(m_heading) % + c_pbhAngleUnit.convertToQString(i18n) % u"/" % c_pbhTimeUnit.convertToQString(i18n); + } + + QVariant CAircraftVelocity::propertyByIndex(CPropertyIndexRef index) const + { + BLACK_VERIFY(index.isMyself()); + return QVariant::fromValue(*this); + } + + void CAircraftVelocity::setPropertyByIndex(CPropertyIndexRef index, const QVariant &variant) + { + BLACK_VERIFY(index.isMyself()); + *this = variant.value(); + } + + int CAircraftVelocity::comparePropertyByIndex(CPropertyIndexRef index, const CAircraftVelocity &compareValue) const + { + BLACK_VERIFY(index.isMyself()); + return compare(*this, compareValue); + } +} diff --git a/src/blackmisc/aviation/aircraftvelocity.h b/src/blackmisc/aviation/aircraftvelocity.h new file mode 100644 index 000000000..93df2935a --- /dev/null +++ b/src/blackmisc/aviation/aircraftvelocity.h @@ -0,0 +1,102 @@ +/* Copyright (C) 2021 + * swift project Community / Contributors + * + * This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution. No part of swift project, including this file, may be copied, modified, propagated, + * or distributed except according to the terms contained in the LICENSE file. + */ + +//! \file + +#ifndef BLACKMISC_AVIATION_AIRCRAFTVELOCITY_H +#define BLACKMISC_AVIATION_AIRCRAFTVELOCITY_H + +#include "blackmisc/pq/speed.h" +#include "blackmisc/pq/angle.h" +#include "blackmisc/pq/time.h" +#include "blackmisc/valueobject.h" +#include "blackmisc/propertyindexref.h" +#include "blackmisc/metaclass.h" +#include "blackmisc/blackmiscexport.h" + +BLACK_DECLARE_VALUEOBJECT_MIXINS(BlackMisc::Aviation, CAircraftVelocity) + +namespace BlackMisc::Aviation +{ + //! Velocity and angular velocity for 6DOF bodies + class BLACKMISC_EXPORT CAircraftVelocity : public CValueObject + { + public: + //! Property index + enum ColumnIndex + { + IndexVelocityX = CPropertyIndexRef::GlobalIndexCAircraftVelocity, + IndexVelocityY, + IndexVelocityZ, + IndexPitchVelocity, + IndexRollVelocity, + IndexHeadingVelocity + }; + + //! Default constructor + CAircraftVelocity(); + + //! Constructor + CAircraftVelocity(double x, double y, double z, PhysicalQuantities::CSpeedUnit xyzUnit, + double pitch, double roll, double heading, PhysicalQuantities::CAngleUnit pbhAngleUnit, PhysicalQuantities::CTimeUnit pbhTimeUnit); + + //! Setter + //! @{ + void setLinearVelocity(double x, double y, double z, PhysicalQuantities::CSpeedUnit xyzUnit); + void setAngularVelocity(double pitch, double roll, double heading, PhysicalQuantities::CAngleUnit pbhAngleUnit, PhysicalQuantities::CTimeUnit pbhTimeUnit); + //! @} + + //! Getter + //! @{ + double getVelocityX(PhysicalQuantities::CSpeedUnit unit) const; + double getVelocityY(PhysicalQuantities::CSpeedUnit unit) const; + double getVelocityZ(PhysicalQuantities::CSpeedUnit unit) const; + double getPitchVelocity(PhysicalQuantities::CAngleUnit angleUnit, PhysicalQuantities::CTimeUnit timeUnit) const; + double getRollVelocity(PhysicalQuantities::CAngleUnit angleUnit, PhysicalQuantities::CTimeUnit timeUnit) const; + double getHeadingVelocity(PhysicalQuantities::CAngleUnit angleUnit, PhysicalQuantities::CTimeUnit timeUnit) 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); + + //! \copydoc Mixin::Index::comparePropertyByIndex + int comparePropertyByIndex(CPropertyIndexRef index, const CAircraftVelocity &compareValue) const; + + private: + static const PhysicalQuantities::CSpeedUnit c_xyzUnit; + static const PhysicalQuantities::CAngleUnit c_pbhAngleUnit; //!< \todo Create a dedicated PQ class for angular velocity + static const PhysicalQuantities::CTimeUnit c_pbhTimeUnit; + + double m_x = 0; + double m_y = 0; + double m_z = 0; + double m_pitch = 0; + double m_roll = 0; + double m_heading = 0; + + BLACK_METACLASS( + CAircraftVelocity, + BLACK_METAMEMBER(x), + BLACK_METAMEMBER(y), + BLACK_METAMEMBER(z), + BLACK_METAMEMBER(pitch), + BLACK_METAMEMBER(roll), + BLACK_METAMEMBER(heading) + ); + }; +} + +Q_DECLARE_METATYPE(BlackMisc::Aviation::CAircraftVelocity) + +#endif diff --git a/src/blackmisc/aviation/aviation.h b/src/blackmisc/aviation/aviation.h index 010b891db..c1f820ee3 100644 --- a/src/blackmisc/aviation/aviation.h +++ b/src/blackmisc/aviation/aviation.h @@ -32,6 +32,7 @@ #include "blackmisc/aviation/aircraftsituation.h" #include "blackmisc/aviation/aircraftsituationchange.h" #include "blackmisc/aviation/aircraftsituationlist.h" +#include "blackmisc/aviation/aircraftvelocity.h" #include "blackmisc/aviation/airlineicaocode.h" #include "blackmisc/aviation/airlineicaocodelist.h" #include "blackmisc/aviation/airport.h" diff --git a/src/blackmisc/aviation/registermetadataaviation.cpp b/src/blackmisc/aviation/registermetadataaviation.cpp index 6a10fc3b2..c64e0334d 100644 --- a/src/blackmisc/aviation/registermetadataaviation.cpp +++ b/src/blackmisc/aviation/registermetadataaviation.cpp @@ -29,6 +29,7 @@ namespace BlackMisc CAircraftSituation::registerMetadata(); CAircraftSituationChange::registerMetadata(); CAircraftSituationList::registerMetadata(); + CAircraftVelocity::registerMetadata(); CAirlineIcaoCode::registerMetadata(); CAirlineIcaoCodeList::registerMetadata(); CAirportIcaoCode::registerMetadata(); diff --git a/src/blackmisc/propertyindexref.h b/src/blackmisc/propertyindexref.h index 5b82673ea..b07bfff05 100644 --- a/src/blackmisc/propertyindexref.h +++ b/src/blackmisc/propertyindexref.h @@ -41,6 +41,7 @@ namespace BlackMisc GlobalIndexCDirectories = 1200, GlobalIndexCCrashInfo = 1300, GlobalIndexCCrashSettings = 1400, + GlobalIndexCAircraftVelocity = 1900, GlobalIndexCCallsign = 2000, GlobalIndexCAircraftSituation = 2100, GlobalIndexCAircraftSituationChange = 2200, diff --git a/src/blackmisc/simulation/simulatedaircraft.cpp b/src/blackmisc/simulation/simulatedaircraft.cpp index 9c3713ae8..0eb726203 100644 --- a/src/blackmisc/simulation/simulatedaircraft.cpp +++ b/src/blackmisc/simulation/simulatedaircraft.cpp @@ -94,7 +94,13 @@ namespace BlackMisc::Simulation void CSimulatedAircraft::setSituation(const CAircraftSituation &situation) { + CAircraftVelocity velocity = m_situation.getVelocity(); m_situation = situation; + if (m_situation.getVelocity() == CAircraftVelocity{}) + { + m_situation.setVelocity(velocity); + } + m_situation.setCallsign(this->getCallsign()); this->setSupportingGndFlag(situation.hasInboundGroundDetails()); } diff --git a/src/blackmisc/simulation/simulatedaircraft.h b/src/blackmisc/simulation/simulatedaircraft.h index 4700b6a17..5eb6f6a4e 100644 --- a/src/blackmisc/simulation/simulatedaircraft.h +++ b/src/blackmisc/simulation/simulatedaircraft.h @@ -112,9 +112,15 @@ namespace BlackMisc //! Get situation. const Aviation::CAircraftSituation &getSituation() const { return m_situation; } - //! Set situation. + //! Set situation. Won't overwrite the velocity unless it held the default value. void setSituation(const Aviation::CAircraftSituation &situation); + //! Get 6DOF velocity. + const Aviation::CAircraftVelocity &getVelocity() const { return m_situation.getVelocity(); } + + //! Set 6DOF velocity. + void setVelocity(const Aviation::CAircraftVelocity &velocity) { m_situation.setVelocity(velocity); } + //! Get user const Network::CUser &getPilot() const { return m_pilot; } diff --git a/tests/blackcore/context/testcontext/testcontext.cpp b/tests/blackcore/context/testcontext/testcontext.cpp index 01a514771..8c214c282 100644 --- a/tests/blackcore/context/testcontext/testcontext.cpp +++ b/tests/blackcore/context/testcontext/testcontext.cpp @@ -72,7 +72,7 @@ namespace BlackCoreTest const CSimulatedAircraft aircraft; const CSimulatedAircraftList aircraftList; - constexpr int MaxSize = 210; + constexpr int MaxSize = 220; // max size in dbus spec is 255 int s = CDBusUtils::dBusSignatureSize(model); QVERIFY2(s < MaxSize, "CAircraftModel");